113 lines
4.4 KiB
TypeScript
113 lines
4.4 KiB
TypeScript
'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>
|
||
);
|
||
}
|