Files
novalon-website/src/components/sections/cases-section.tsx
T
2026-02-26 21:25:59 +08:00

99 lines
4.3 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 { motion } from 'framer-motion';
import { useInView } from 'framer-motion';
import { useRef } from 'react';
import Link from 'next/link';
import { Card, CardContent } from '@/components/ui/card';
import { Button } from '@/components/ui/button';
import { Badge } from '@/components/ui/badge';
import { CASES } from '@/lib/constants';
import { ArrowRight, Building2, TrendingUp } from 'lucide-react';
export function CasesSection() {
const ref = useRef(null);
const isInView = useInView(ref, { once: true, margin: '-100px' });
const featuredCases = CASES.slice(0, 3);
return (
<section id="cases" className="py-24 bg-white relative overflow-hidden" ref={ref}>
<div className="absolute top-1/3 left-0 w-[400px] h-[400px] bg-[rgba(196,30,58,0.03)] rounded-full blur-3xl" />
<div className="absolute top-1/3 right-0 w-[300px] h-[300px] bg-[rgba(196,30,58,0.02)] rounded-full blur-3xl" />
<div className="container-wide relative z-10">
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={isInView ? { opacity: 1, y: 0 } : {}}
transition={{ duration: 0.6 }}
className="text-center max-w-3xl mx-auto mb-16"
>
<h2 className="text-4xl md:text-5xl font-bold text-[#1C1C1C] mb-4">
<span className="text-[#C41E3A]"></span>
</h2>
<p className="text-lg text-[#5C5C5C] max-w-2xl mx-auto">
</p>
</motion.div>
<div className="grid grid-cols-1 md:grid-cols-3 gap-8">
{featuredCases.map((caseItem, index) => (
<motion.div
key={caseItem.id}
initial={{ opacity: 0, y: 20 }}
animate={isInView ? { opacity: 1, y: 0 } : {}}
transition={{ duration: 0.5, delay: 0.1 + index * 0.1 }}
>
<Link href={`/cases/${caseItem.id}`}>
<Card className="h-full group cursor-pointer border-[#E5E5E5] hover:border-[#C41E3A] transition-colors overflow-hidden">
<div className="relative h-40 bg-gradient-to-br from-[#F5F5F5] to-[#E5E5E5] flex items-center justify-center">
<Building2 className="w-16 h-16 text-[#C41E3A]/20 group-hover:scale-110 transition-transform duration-300" />
<div className="absolute top-4 right-4">
<Badge className="bg-white/90 text-[#1C1C1C] hover:bg-white">
{caseItem.industry}
</Badge>
</div>
</div>
<CardContent className="p-6">
<div className="flex items-center gap-2 mb-3">
<Building2 className="w-4 h-4 text-[#C41E3A]" />
<span className="text-sm text-[#5C5C5C]">{caseItem.client}</span>
</div>
<h3 className="text-lg font-semibold text-[#1C1C1C] mb-3 group-hover:text-[#C41E3A] transition-colors">
{caseItem.title}
</h3>
<p className="text-[#5C5C5C] text-sm line-clamp-2 mb-4">
{caseItem.description}
</p>
{caseItem.results.length > 0 && (
<div className="flex items-center gap-2 text-[#C41E3A]">
<TrendingUp className="w-4 h-4" />
<span className="text-sm font-medium">{caseItem.results[0].value}</span>
<span className="text-sm text-[#5C5C5C]">{caseItem.results[0].label}</span>
</div>
)}
</CardContent>
</Card>
</Link>
</motion.div>
))}
</div>
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={isInView ? { opacity: 1, y: 0 } : {}}
transition={{ duration: 0.6, delay: 0.4 }}
className="text-center mt-12"
>
<Button variant="outline" size="lg" className="group" asChild>
<Link href="/cases">
<ArrowRight className="ml-2 w-4 h-4 transition-transform group-hover:translate-x-1" />
</Link>
</Button>
</motion.div>
</div>
</section>
);
}