Files
novalon-website/src/app/(marketing)/solutions/[id]/solution-detail-client.tsx
T
张翔 e83ecddfe5 refactor(project): 全面清理项目代码并重命名项目
- 移除无用文件和空文件夹,清理 effects 和 scripts 目录
- 将项目从 ruixin-website-react 重命名为 novalon-website-react
- 修复所有测试用例,确保 731 个测试全部通过
- 优化组件导入路径和测试 mock 设置
- 更新项目配置文件和依赖管理

关联任务:项目清理与重构
2026-04-27 12:56:22 +08:00

211 lines
8.6 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 { SOLUTIONS } from '@/lib/constants/solutions';
import { PRODUCTS } from '@/lib/constants/products';
import { StaticLink } from '@/components/ui/static-link';
import { CheckCircle } from 'lucide-react';
import {
InkReveal,
FadeUp,
FloatingElement,
StaggerContainer,
StaggerItem,
InkCard,
SealStamp,
} from '@/lib/animations';
import { RippleButton } from '@/components/ui/ripple-button';
import { ScrollReveal, inkRevealVariants, slideInLeftVariants } from '@/components/ui/scroll-animations';
interface SolutionDetailClientProps {
solutionId: string;
}
export function SolutionDetailClient({ solutionId }: SolutionDetailClientProps) {
const solution = SOLUTIONS.find((s) => s.id === solutionId) || null;
if (!solution) {
return (
<div className="min-h-screen flex items-center justify-center">
<p className="text-[#999999]">...</p>
</div>
);
}
return (
<main className="min-h-screen">
{/* Section 1: Hero */}
<section className="relative py-24 md:py-32 bg-gradient-to-b from-white to-[#F8F8F8]">
<div className="container-wide">
<div className="max-w-4xl mx-auto text-center">
<SealStamp
delay={0.1}
className="inline-block px-4 py-2 bg-[#C41E3A]/20 rounded-full text-[#C41E3A] text-sm mb-6"
>
{solution.industry}
</SealStamp>
<InkReveal delay={0.2}>
<h1 className="text-4xl md:text-5xl lg:text-6xl font-bold text-[#1C1C1C] mb-4">
{solution.title}
</h1>
</InkReveal>
<InkReveal delay={0.4}>
<p className="text-lg md:text-xl text-[#5C5C5C] mb-4">{solution.subtitle}</p>
</InkReveal>
<InkReveal delay={0.5}>
<p className="text-base text-[#5C5C5C] leading-relaxed mb-10 max-w-2xl mx-auto">
{solution.description}
</p>
</InkReveal>
<InkReveal delay={0.6}>
<div className="flex flex-col sm:flex-row gap-4 justify-center">
<RippleButton
href="/contact"
className="border-2 border-[#C41E3A] text-[#C41E3A] hover:bg-[#C41E3A] hover:text-white px-8 py-4 rounded-lg text-lg font-semibold inline-flex items-center justify-center"
rippleColor="rgba(196, 30, 58, 0.2)"
>
</RippleButton>
<RippleButton
href="/contact"
className="bg-[#C41E3A] hover:bg-[#A01830] text-white px-8 py-4 rounded-lg text-lg font-semibold inline-flex items-center justify-center"
rippleColor="rgba(255, 255, 255, 0.3)"
>
</RippleButton>
</div>
</InkReveal>
</div>
</div>
</section>
{/* Section 2: Challenges */}
<section className="py-20 md:py-28 bg-white">
<div className="container-wide">
<ScrollReveal variants={slideInLeftVariants} className="mb-12">
<h2 className="text-3xl md:text-4xl font-bold text-[#1C1C1C]"></h2>
<p className="text-[#5C5C5C] mt-2"></p>
</ScrollReveal>
<StaggerContainer className="grid md:grid-cols-2 gap-6 max-w-5xl">
{solution.challenges.map((challenge, index) => (
<StaggerItem key={index}>
<InkCard
className="p-6 bg-[#FFFBF5] rounded-2xl border border-[#C41E3A]/10"
hoverScale={1.02}
hoverShadow="0 20px 40px rgba(196, 30, 58, 0.08)"
>
<div className="flex items-start gap-3">
<span className="flex-shrink-0 w-8 h-8 rounded-full bg-[#C41E3A]/10 flex items-center justify-center text-[#C41E3A] font-bold text-sm">
{index + 1}
</span>
<p className="text-[#1C1C1C] leading-relaxed">{challenge}</p>
</div>
</InkCard>
</StaggerItem>
))}
</StaggerContainer>
</div>
</section>
{/* Section 3: Our Solutions */}
<section className="py-20 md:py-28 bg-[#F8F8F8]">
<div className="container-wide">
<ScrollReveal variants={inkRevealVariants} className="mb-12 text-center">
<h2 className="text-3xl md:text-4xl font-bold text-[#1C1C1C]"></h2>
<p className="text-[#5C5C5C] mt-2"></p>
</ScrollReveal>
<StaggerContainer className="max-w-3xl mx-auto space-y-6">
{solution.solutions.map((item, index) => (
<StaggerItem key={index}>
<div className="flex items-start gap-4 p-6 bg-white rounded-2xl border border-[#E5E5E5]">
<CheckCircle className="w-6 h-6 text-[#C41E3A] flex-shrink-0 mt-0.5" />
<p className="text-[#1C1C1C] leading-relaxed text-lg">{item}</p>
</div>
</StaggerItem>
))}
</StaggerContainer>
</div>
</section>
{/* Section 4: Related Products */}
{solution.relatedProducts.length > 0 && (
<section className="py-16 md:py-20 bg-white">
<div className="container-wide">
<div className="text-center mb-10">
<h2 className="text-2xl md:text-3xl font-bold text-[#1C1C1C]">
</h2>
<p className="text-[#5C5C5C] mt-2"></p>
</div>
<div className="grid sm:grid-cols-2 gap-6 max-w-3xl mx-auto">
{solution.relatedProducts.map((productId) => {
const product = PRODUCTS.find((p) => p.id === productId);
if (!product) {return null;}
return (
<FadeUp key={productId}>
<StaticLink href={`/products/${productId}`}>
<div className="group p-6 bg-[#F8F8F8] rounded-2xl border border-[#E5E5E5] hover:border-[#C41E3A]/30 transition-all">
<span className="inline-block px-3 py-1 bg-[#C41E3A]/10 text-[#C41E3A] text-xs font-semibold rounded-full mb-3">
{product.category}
</span>
<h3 className="text-lg font-bold text-[#1C1C1C] mb-2 group-hover:text-[#C41E3A] transition-colors">
{product.title}
</h3>
<p className="text-sm text-[#5C5C5C] line-clamp-2">{product.description}</p>
</div>
</StaticLink>
</FadeUp>
);
})}
</div>
</div>
</section>
)}
{/* Section 6: CTA */}
<section className="relative py-24 md:py-32 bg-gradient-to-r from-[#C41E3A] to-[#E85D75] overflow-hidden">
<FloatingElement
amplitude={8}
duration={5}
delay={0.5}
className="absolute -top-20 -right-20 pointer-events-none"
>
<div className="w-[280px] h-[280px] bg-white/10 rounded-full" />
</FloatingElement>
<FloatingElement
amplitude={6}
duration={4}
delay={1}
className="absolute -bottom-16 -left-16 pointer-events-none"
>
<div className="w-[220px] h-[220px] bg-white/10 rounded-full" />
</FloatingElement>
<div className="container-wide">
<div className="max-w-3xl mx-auto text-center">
<InkReveal delay={0}>
<h2 className="text-3xl md:text-4xl font-bold text-white mb-6">
{solution.industry}
</h2>
</InkReveal>
<FadeUp delay={0.15}>
<p className="text-lg text-white/90 mb-10">
</p>
</FadeUp>
<FadeUp delay={0.3}>
<div className="flex flex-col sm:flex-row gap-4 justify-center">
<RippleButton
href="/contact"
rippleColor="rgba(196, 30, 58, 0.3)"
className="bg-white text-[#C41E3A] px-8 py-4 rounded-lg text-lg font-semibold inline-flex items-center justify-center w-full sm:w-auto"
>
</RippleButton>
</div>
</FadeUp>
</div>
</div>
</section>
</main>
);
}