Files
novalon-website/src/app/(marketing)/services/page.tsx
T
2026-02-26 21:23:45 +08:00

113 lines
4.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
'use client';
import Link from 'next/link';
import { motion } from 'framer-motion';
import { useInView } from 'framer-motion';
import { useRef } from 'react';
import { Button } from '@/components/ui/button';
import { Badge } from '@/components/ui/badge';
import { Card, CardContent } from '@/components/ui/card';
import { PageHeader } from '@/components/ui/page-header';
import { ArrowRight, Code, Cloud, BarChart3, Shield } from 'lucide-react';
import { SERVICES } from '@/lib/constants';
const iconMap: Record<string, React.ComponentType<{ className?: string }>> = {
Code,
Cloud,
BarChart3,
Shield,
};
export default function ServicesPage() {
const contentRef = useRef(null);
const isContentInView = useInView(contentRef, { once: true, margin: '-100px' });
return (
<div className="min-h-screen bg-white">
<PageHeader
title="核心业务"
description="专业技术团队,为您提供全方位的数字化解决方案"
/>
<div className="container-wide relative z-10 py-16" ref={contentRef}>
<div className="max-w-6xl mx-auto">
<div className="grid md:grid-cols-2 gap-8">
{SERVICES.map((service, index) => {
const Icon = iconMap[service.icon];
return (
<motion.div
key={service.id}
initial={{ opacity: 0, y: 20 }}
animate={isContentInView ? { opacity: 1, y: 0 } : {}}
transition={{ duration: 0.5, delay: index * 0.1 }}
>
<Link
href={`/services/${service.id}`}
className="group bg-white rounded-2xl border border-[#E5E5E5] overflow-hidden hover:shadow-xl transition-all duration-300 block h-full"
>
<div className="p-8">
<div className="flex items-start gap-4 mb-4">
<div className="w-14 h-14 rounded-xl bg-[#F5F5F5] flex items-center justify-center group-hover:bg-[#C41E3A] transition-all duration-300">
{Icon && <Icon className="w-7 h-7 text-[#1C1C1C] group-hover:text-white transition-colors" />}
</div>
<div className="flex-1">
<h3 className="text-xl font-semibold text-[#1C1C1C] mb-2 group-hover:text-[#C41E3A] transition-colors">
{service.title}
</h3>
<p className="text-[#5C5C5C] text-sm leading-relaxed">
{service.description}
</p>
</div>
</div>
<div className="mt-6 pt-4 border-t border-[#E5E5E5]">
<div className="flex flex-wrap gap-2 mb-4">
{service.features.slice(0, 3).map((feature, idx) => (
<Badge key={idx} variant="secondary" className="text-xs">
{feature.split('')[0]}
</Badge>
))}
</div>
<div className="flex items-center text-[#C41E3A] font-medium group-hover:translate-x-2 transition-transform">
<ArrowRight className="w-4 h-4 ml-2" />
</div>
</div>
</div>
</Link>
</motion.div>
);
})}
</div>
</div>
</div>
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={isContentInView ? { opacity: 1, y: 0 } : {}}
transition={{ duration: 0.6, delay: 0.4 }}
className="bg-[#F5F5F5] py-16"
>
<div className="container-wide text-center">
<h2 className="text-3xl font-bold text-[#1C1C1C] mb-6">
</h2>
<p className="text-lg text-[#5C5C5C] mb-8 max-w-2xl mx-auto">
</p>
<Button
size="lg"
className="bg-[#C41E3A] hover:bg-[#A01830] text-white"
asChild
>
<Link href="/contact">
<ArrowRight className="ml-2 w-4 h-4" />
</Link>
</Button>
</div>
</motion.div>
</div>
);
}