'use client'; import { motion, useScroll, useTransform } from 'framer-motion'; import { useRef, useState, useEffect } from 'react'; import { ScrollReveal, StaggerReveal } from '@/components/ui/scroll-reveal'; import { StaticLink } from '@/components/ui/static-link'; import { SectionHeader } from '@/components/sections/section-header'; import { ServiceCard } from '@/components/sections/service-card'; import { ScrollProgress } from '@/components/ui/scroll-progress'; import { useReducedMotion } from '@/hooks/use-reduced-motion'; import { ArrowRight, Quote, Building2, Target, Lightbulb, TrendingUp } from 'lucide-react'; import { Button } from '@/components/ui/button'; import { AnimatedCounter } from '@/components/ui/animated-counter'; const EASE = [0.22, 1, 0.36, 1] as const; export interface CaseDetailData { id: string; client: string; industry: string; title: string; subtitle: string; challenge: string; solution: string; result: string; metrics: { value: string; label: string; highlight?: boolean }[]; timeline: { phase: string; duration: string; description: string }[]; services: { id: string; title: string; description: string }[]; testimonial?: { quote: string; author: string; role: string }; projectDuration?: string; departments?: string[]; dataScale?: string; businessProblem?: string; verified?: boolean; } interface CaseDetailHeroProps { data: CaseDetailData; } function CaseDetailHero({ data }: CaseDetailHeroProps) { const shouldReduceMotion = useReducedMotion(); const heroRef = useRef(null); const { scrollYProgress } = useScroll({ target: heroRef, offset: ['start start', 'end start'], }); const opacity = useTransform(scrollYProgress, [0, 0.6], [1, 0]); const contentY = useTransform(scrollYProgress, [0, 1], [0, 50]); return (
{data.industry} {data.client} {/* Bain-style: big result number first */}
{data.metrics[0]?.value || '40%'}
{data.metrics[0]?.label || '核心成果提升'}
{data.title} {data.subtitle} {/* Quick stats row */} {data.metrics.slice(1, 4).map((m, i) => (
{m.value}
{m.label}
))}
{/* Verifiable dimensions */} {data.projectDuration && (
项目周期 {data.projectDuration}
)} {data.departments && data.departments.length > 0 && (
涉及部门 {data.departments.join('、')}
)} {data.dataScale && (
数据规模 {data.dataScale}
)} {data.verified && (
✓ 客户授权公开
)}
); } function ChallengeSection({ data }: { data: CaseDetailData }) { return (
{data.businessProblem && (
具体业务问题

{data.businessProblem}

)}
面临的挑战

{data.challenge}

); } function SolutionSection({ data }: { data: CaseDetailData }) { return (
核心思路

{data.solution}

实施路径
{data.timeline.map((t, i) => (
{i + 1}

{t.phase}

{t.duration}

{t.description}

))}
); } function ResultsSection({ data }: { data: CaseDetailData }) { const resultsRef = useRef(null); const [inView, setInView] = useState(false); const shouldReduceMotion = useReducedMotion(); useEffect(() => { if (!resultsRef.current) return; const observer = new IntersectionObserver( ([entry]) => { if (entry?.isIntersecting) { setInView(true); observer.disconnect(); } }, { threshold: 0.2 } ); observer.observe(resultsRef.current); return () => observer.disconnect(); }, []); const parseValue = (val: string): { num: number; suffix: string; isNumeric: boolean } => { const match = val.match(/^([\d.]+)(.*)$/); if (match && match[1] && !isNaN(parseFloat(match[1]))) { return { num: parseFloat(match[1]), suffix: match[2] || '', isNumeric: true }; } return { num: 0, suffix: val, isNumeric: false }; }; return (
{/* Background decoration */}
项目成果

可量化的业务成果

{data.result}

{data.metrics.slice(0, 4).map((m, i) => { const { num, suffix, isNumeric } = parseValue(m.value); const decimals = String(num).includes('.') ? String(num).split('.')[1]?.length ?? 0 : 0; return (
{m.highlight && (
核心指标
)}
{isNumeric && inView && !shouldReduceMotion ? ( ) : ( <> {isNumeric ? num : suffix} {isNumeric && suffix && ( {suffix} )} )}
{m.label}
); })}
{data.testimonial && (
“{data.testimonial.quote}”
{data.testimonial.author}
{data.testimonial.role}
)}
); } function RelatedServicesSection({ services }: { services: CaseDetailData['services'] }) { return (
{services.slice(0, 3).map((s) => ( ))}
); } function CTASection() { return (

您也想实现类似的 业务突破 ?

免费咨询,48小时内给出初步方案建议

); } export default function CaseDetailPage({ data }: { data: CaseDetailData }) { return (
); }