Files
novalon-website/src/app/(marketing)/cases/[id]/client.tsx
T
张翔 6ae0f1274f refactor: 页面组件优化与墨韵分割线组件化
- 提取 AnimatedInkDivider 组件替代硬编码 ink-divider div
- 重构各营销页面组件代码结构优化
- 修正统计数据:自研产品 4 -> 6
- 更新 about 页面测试用例
2026-04-29 19:15:58 +08:00

269 lines
12 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 { StaticLink } from '@/components/ui/static-link';
import { Button } from '@/components/ui/button';
import { Badge } from '@/components/ui/badge';
import { BackButton } from '@/components/ui/back-button';
import {
Target,
Quote,
Clock,
MessageCircle,
Award,
TrendingUp,
} from 'lucide-react';
import { InkReveal, StaggerContainer, StaggerItem } from '@/lib/animations';
import { ScrollReveal } from '@/components/ui/scroll-animations';
interface CaseKeyMoment {
title: string;
description: string;
}
interface CaseResult {
label: string;
value: string;
}
interface CaseTestimonial {
quote: string;
author: string;
role: string;
}
interface CaseItem {
id: string;
title: string;
excerpt: string;
content: string;
category: string;
slug: string;
date: string;
image?: string;
challenge: string;
solution: string;
keyMoments: CaseKeyMoment[];
results: CaseResult[];
testimonial?: CaseTestimonial;
duration: string;
}
interface CaseDetailClientProps {
caseItem: CaseItem;
}
export function CaseDetailClient({ caseItem }: CaseDetailClientProps) {
return (
<div className="min-h-screen bg-white">
{/* Hero - InkReveal */}
<div className="relative overflow-hidden bg-gradient-to-b from-[#FAFAFA] to-white">
<div className="container-wide relative z-10 pt-32 pb-20">
<BackButton />
<InkReveal className="max-w-4xl mt-8">
<Badge className="mb-4 bg-[var(--color-brand-primary)]/10 text-[var(--color-brand-primary)] hover:bg-[var(--color-brand-primary)]/20">
{caseItem.category}
</Badge>
<h1 className="text-3xl sm:text-4xl lg:text-5xl font-semibold text-[#1C1C1C] mb-2">
{caseItem.title}
</h1>
<p className="text-lg text-[#5C5C5C]">{caseItem.excerpt}</p>
</InkReveal>
</div>
</div>
<div className="container-wide py-12 md:py-16">
<div className="grid lg:grid-cols-3 gap-8 lg:gap-12">
<div className="lg:col-span-2 space-y-12">
{/* 客户遇到的成长瓶颈 - ScrollReveal */}
<ScrollReveal>
<section className="bg-gradient-to-br from-[#FFFBF5] to-white rounded-2xl p-8 border border-[var(--color-brand-primary)]/20">
<div className="flex items-center gap-3 mb-6">
<div className="w-12 h-12 bg-[var(--color-brand-primary)] rounded-xl flex items-center justify-center">
<MessageCircle className="w-6 h-6 text-white" />
</div>
<h2 className="text-2xl font-semibold text-[#1C1C1C]">
</h2>
</div>
<p className="text-[#5C5C5C] leading-relaxed text-lg">
{caseItem.challenge}
</p>
</section>
</ScrollReveal>
{/* 我们如何智连未来 - ScrollReveal */}
<ScrollReveal delay={0.1}>
<section className="bg-gradient-to-br from-[#FFFBF5] to-white rounded-2xl p-8 border border-[var(--color-brand-primary)]/20">
<div className="flex items-center gap-3 mb-6">
<div className="w-12 h-12 bg-[var(--color-brand-primary)] rounded-xl flex items-center justify-center">
<Target className="w-6 h-6 text-white" />
</div>
<h2 className="text-2xl font-semibold text-[#1C1C1C]">
</h2>
</div>
<div className="prose prose-base max-w-none [&_h3]:text-xl [&_h3]:font-semibold [&_h3]:text-[#1C1C1C] [&_h3]:mt-8 [&_h3]:mb-4 [&_p]:text-[#5C5C5C] [&_p]:leading-[1.8] [&_p]:mb-4 [&_p]:text-base">
<p className="text-[#5C5C5C] leading-relaxed text-lg">
{caseItem.solution}
</p>
</div>
</section>
</ScrollReveal>
{/* 共同成长的故事 - StaggerContainer */}
{caseItem.keyMoments && caseItem.keyMoments.length > 0 && (
<ScrollReveal delay={0.15}>
<section className="bg-gradient-to-br from-[#FFFBF5] to-white rounded-2xl p-8 border border-[var(--color-brand-primary)]/20">
<div className="flex items-center gap-3 mb-6">
<div className="w-12 h-12 bg-[var(--color-brand-primary)] rounded-xl flex items-center justify-center">
<Clock className="w-6 h-6 text-white" />
</div>
<h2 className="text-2xl font-semibold text-[#1C1C1C]">
</h2>
</div>
<StaggerContainer className="space-y-4" staggerDelay={0.1}>
{caseItem.keyMoments.map((moment, index) => (
<StaggerItem key={index}>
<div className="p-4 bg-white rounded-lg border border-[#E5E5E5] hover:border-[var(--color-brand-primary)]/30 hover:shadow-sm transition-all duration-300">
<div className="flex items-start gap-3">
<Quote className="w-5 h-5 text-[var(--color-brand-primary)] flex-shrink-0 mt-0.5" />
<div>
<h4 className="font-semibold text-[#1C1C1C] mb-2">
{moment.title}
</h4>
<p className="text-sm text-[#737373]">
{moment.description}
</p>
</div>
</div>
</div>
</StaggerItem>
))}
</StaggerContainer>
</section>
</ScrollReveal>
)}
{/* 今天,他们走到了哪里 - StaggerContainer 数据指标 */}
{caseItem.results && caseItem.results.length > 0 && (
<ScrollReveal delay={0.2}>
<section className="bg-gradient-to-br from-[#FFFBF5] to-white rounded-2xl p-8 border border-[var(--color-brand-primary)]/20">
<div className="flex items-center gap-3 mb-6">
<div className="w-12 h-12 bg-[var(--color-brand-primary)] rounded-xl flex items-center justify-center">
<Award className="w-6 h-6 text-white" />
</div>
<h2 className="text-2xl font-semibold text-[#1C1C1C]">
</h2>
</div>
<StaggerContainer className="grid sm:grid-cols-3 gap-4" staggerDelay={0.12}>
{caseItem.results.map((result, index) => (
<StaggerItem key={index}>
<div className="p-6 bg-white rounded-lg border border-[#E5E5E5] hover:border-[var(--color-brand-primary)] hover:shadow-md transition-all duration-300 text-center">
<TrendingUp className="w-8 h-8 text-[var(--color-brand-primary)] mb-3 mx-auto" />
<div className="text-2xl font-semibold text-[var(--color-brand-primary)] mb-1">
{result.value}
</div>
<div className="text-sm text-[#737373]">
{result.label}
</div>
</div>
</StaggerItem>
))}
</StaggerContainer>
</section>
</ScrollReveal>
)}
{/* 客户证言精选 - ScrollReveal */}
{caseItem.testimonial && (
<ScrollReveal delay={0.25}>
<section className="bg-gradient-to-br from-[#FFFBF5] to-white rounded-2xl p-8 border border-[var(--color-brand-primary)]/20">
<div className="flex items-center gap-3 mb-6">
<div className="w-12 h-12 bg-[var(--color-brand-primary)] rounded-xl flex items-center justify-center">
<Quote className="w-6 h-6 text-white" />
</div>
<h2 className="text-2xl font-semibold text-[#1C1C1C]">
</h2>
</div>
<div className="p-6 bg-white rounded-lg border border-[#E5E5E5]">
<Quote className="w-8 h-8 text-[var(--color-brand-primary)] mb-4" />
<p className="text-lg text-[#5C5C5C] leading-relaxed mb-4">
{caseItem.testimonial.quote}
</p>
<div className="flex items-center gap-3">
<div className="w-12 h-12 bg-[var(--color-brand-primary)] rounded-full flex items-center justify-center">
<span className="text-white font-semibold"></span>
</div>
<div>
<p className="font-semibold text-[#1C1C1C]">
{caseItem.testimonial.author}
</p>
<p className="text-sm text-[#737373]">
{caseItem.testimonial.role}
</p>
</div>
</div>
</div>
</section>
</ScrollReveal>
)}
</div>
{/* 侧边栏 */}
<div className="space-y-6">
<ScrollReveal delay={0.1}>
<div className="p-6 bg-[#FAFAFA] rounded-lg border border-[#E5E5E5]">
<h3 className="text-lg font-semibold text-[#1C1C1C] mb-4">
</h3>
<dl className="space-y-3">
<div>
<dt className="text-sm text-[#737373]"></dt>
<dd className="text-[#1C1C1C] font-medium">
{caseItem.testimonial?.author || '客户企业'}
</dd>
</div>
<div>
<dt className="text-sm text-[#737373]"></dt>
<dd className="text-[#1C1C1C] font-medium">
{caseItem.category}
</dd>
</div>
<div>
<dt className="text-sm text-[#737373]"></dt>
<dd className="text-[#1C1C1C] font-medium">
{caseItem.duration || '3年'}
</dd>
</div>
<div>
<dt className="text-sm text-[#737373]"></dt>
<dd className="text-[#1C1C1C] font-medium">{caseItem.date}</dd>
</div>
</dl>
</div>
</ScrollReveal>
<ScrollReveal delay={0.2}>
<div className="p-6 bg-gradient-to-br from-[var(--color-brand-primary)] to-[#8B1429] rounded-lg text-white">
<h3 className="text-lg font-semibold mb-2"></h3>
<p className="text-sm text-white/80 mb-4">
</p>
<Button
className="w-full bg-white text-[var(--color-brand-primary)] hover:bg-white/90"
asChild
>
<StaticLink href="/contact"></StaticLink>
</Button>
</div>
</ScrollReveal>
</div>
</div>
</div>
</div>
);
}