37296b5717
改造概要(30项): - 第一轮:Hero重构/Section差异化/SocialProof强化/CTA对比度/About架构 - 第二轮:字体优化/背景交替/Solutions差异化/Footer五列/MegaDropdown修复 - 第三轮:卡片交互/表单层级/CTA统一/时间线标记/连接线/三列布局/移动导航/Button微交互/SEO Schema - P3-2:template.tsx+Framer Motion页面过渡/loading.tsx加载状态 - 清理:删除未用组件/hooks,修复重复移动导航,清理冗余CSS
151 lines
7.0 KiB
TypeScript
151 lines
7.0 KiB
TypeScript
'use client';
|
|
|
|
import { motion } from 'framer-motion';
|
|
import { useReducedMotion } from '@/hooks/use-reduced-motion';
|
|
import { StaticLink } from '@/components/ui/static-link';
|
|
import { Button } from '@/components/ui/button';
|
|
import { PageNav } from '@/components/layout/page-nav';
|
|
import { ArrowRight, AlertTriangle, CheckCircle2, Package } from 'lucide-react';
|
|
import type { Solution } from '@/lib/constants/solutions';
|
|
import type { Product } from '@/lib/constants/products';
|
|
|
|
interface SolutionDetailClientProps {
|
|
solution: Solution;
|
|
relatedProducts: Product[];
|
|
}
|
|
|
|
export function SolutionDetailClient({ solution, relatedProducts }: SolutionDetailClientProps) {
|
|
const shouldReduceMotion = useReducedMotion();
|
|
const fadeUp = shouldReduceMotion ? {} : { initial: { opacity: 0, y: 20 } };
|
|
return (
|
|
<div className="min-h-screen bg-[var(--color-bg-primary)]">
|
|
<div className="pt-32 pb-16">
|
|
<div className="container-wide">
|
|
<PageNav items={[{ label: '解决方案', href: '/solutions' }, { label: solution.title }]} />
|
|
<motion.div
|
|
{...fadeUp}
|
|
animate={shouldReduceMotion ? {} : { opacity: 1, y: 0 }}
|
|
transition={{ duration: 0.5 }}
|
|
className="max-w-4xl mt-8"
|
|
>
|
|
<p className="text-sm font-medium text-[var(--color-brand-primary)] mb-4 tracking-wide uppercase">
|
|
{solution.industry}
|
|
</p>
|
|
<h1 className="text-4xl md:text-5xl font-bold text-[var(--color-text-primary)] mb-4 tracking-tight">
|
|
{solution.title}
|
|
</h1>
|
|
<p className="text-xl text-[var(--color-text-muted)] mb-2">{solution.subtitle}</p>
|
|
<p className="text-lg text-[var(--color-text-muted)] leading-relaxed">
|
|
{solution.description}
|
|
</p>
|
|
</motion.div>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="container-wide pb-20">
|
|
<div className="max-w-4xl space-y-16">
|
|
<motion.section
|
|
{...fadeUp}
|
|
whileInView={shouldReduceMotion ? {} : { opacity: 1, y: 0 }}
|
|
viewport={{ once: true }}
|
|
transition={{ duration: 0.5 }}
|
|
>
|
|
<h2 className="text-2xl font-bold text-[var(--color-text-primary)] mb-6 flex items-center gap-3">
|
|
<AlertTriangle className="w-6 h-6 text-[var(--color-brand-primary)]" />
|
|
行业痛点
|
|
</h2>
|
|
<div className="space-y-3">
|
|
{solution.challenges.map((challenge, index) => (
|
|
<div
|
|
key={index}
|
|
className="flex items-start gap-3 p-4 rounded-lg border-l-4 border-[var(--color-brand-primary)] bg-[var(--color-bg-section)]"
|
|
>
|
|
<span className="text-[var(--color-text-primary)] text-sm">{challenge}</span>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</motion.section>
|
|
|
|
<motion.section
|
|
{...fadeUp}
|
|
whileInView={shouldReduceMotion ? {} : { opacity: 1, y: 0 }}
|
|
viewport={{ once: true }}
|
|
transition={{ duration: 0.5, delay: 0.1 }}
|
|
>
|
|
<h2 className="text-2xl font-bold text-[var(--color-text-primary)] mb-6 flex items-center gap-3">
|
|
<CheckCircle2 className="w-6 h-6 text-[var(--color-brand-primary)]" />
|
|
解决方案
|
|
</h2>
|
|
<div className="space-y-4">
|
|
{solution.solutions.map((sol, index) => (
|
|
<div key={index} className="flex items-start gap-4">
|
|
<div className="w-8 h-8 bg-[var(--color-brand-primary)] rounded-full flex items-center justify-center shrink-0 text-white text-sm font-bold">
|
|
{index + 1}
|
|
</div>
|
|
<p className="text-[var(--color-text-primary)] pt-1 leading-relaxed">{sol}</p>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</motion.section>
|
|
|
|
{relatedProducts.length > 0 && (
|
|
<motion.section
|
|
{...fadeUp}
|
|
whileInView={shouldReduceMotion ? {} : { opacity: 1, y: 0 }}
|
|
viewport={{ once: true }}
|
|
transition={{ duration: 0.5, delay: 0.2 }}
|
|
>
|
|
<h2 className="text-2xl font-bold text-[var(--color-text-primary)] mb-6 flex items-center gap-3">
|
|
<Package className="w-6 h-6 text-[var(--color-brand-primary)]" />
|
|
相关产品
|
|
</h2>
|
|
<div className="grid md:grid-cols-2 gap-4">
|
|
{relatedProducts.map((product) => (
|
|
<StaticLink
|
|
key={product.id}
|
|
href={`/products/${product.id}`}
|
|
className="group block p-6 rounded-xl border border-[var(--color-border-primary)] bg-[var(--color-bg-primary)] hover:border-[var(--color-brand-primary)]/40 hover:shadow-lg transition-all duration-300"
|
|
>
|
|
<div className="flex items-center gap-2 mb-2">
|
|
<h3 className="text-lg font-semibold text-[var(--color-text-primary)] group-hover:text-[var(--color-brand-primary)] transition-colors">
|
|
{product.title}
|
|
</h3>
|
|
{product.status && (
|
|
<span
|
|
className="text-xs font-medium px-3 py-1 rounded-full border shrink-0"
|
|
style={{
|
|
backgroundColor: product.status === '研发中' ? 'rgba(var(--color-brand-primary-rgb), 0.08)' : product.status === '内测中' ? 'rgba(var(--color-warning-rgb), 0.08)' : 'rgba(var(--color-success-rgb), 0.08)',
|
|
color: product.status === '研发中' ? 'var(--color-brand-primary)' : product.status === '内测中' ? 'var(--color-warning)' : 'var(--color-success)',
|
|
borderColor: product.status === '研发中' ? 'rgba(var(--color-brand-primary-rgb), 0.15)' : product.status === '内测中' ? 'rgba(var(--color-warning-rgb), 0.15)' : 'rgba(var(--color-success-rgb), 0.15)',
|
|
}}
|
|
>
|
|
{product.status}
|
|
</span>
|
|
)}
|
|
</div>
|
|
<p className="text-sm text-[var(--color-text-muted)] leading-relaxed">
|
|
{product.description}
|
|
</p>
|
|
</StaticLink>
|
|
))}
|
|
</div>
|
|
</motion.section>
|
|
)}
|
|
|
|
<div className="flex justify-center gap-4 pt-8 border-t border-[var(--color-border-primary)]">
|
|
<Button variant="outline" size="lg" asChild>
|
|
<StaticLink href="/contact">联系我们</StaticLink>
|
|
</Button>
|
|
<Button size="lg" className="bg-[var(--color-brand-primary)] hover:bg-[var(--color-brand-primary-hover)] text-white" asChild>
|
|
<StaticLink href="/contact">
|
|
立即咨询
|
|
<ArrowRight className="ml-2 w-4 h-4" />
|
|
</StaticLink>
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|