Files
novalon-website/docs/plans/2026-02-26-website-optimization-implementation.md
T

53 KiB
Raw Blame History

网站优化重构实施计划

For Claude: REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.

Goal: 统一网站交互模式、优化首页结构、统一配色方案,提升用户体验和品牌一致性。

Architecture: 采用 Next.js App Router 架构,服务详情页使用故事化叙事风格,移除模态框交互,统一使用独立页面。首页精简 About Section,新增 Cases Section。

Tech Stack: Next.js 16, React 19, TypeScript, Tailwind CSS, Framer Motion


实施阶段概览

阶段 1: 服务详情页重构(高优先级)

  • 创建服务详情页面
  • 删除服务详情模态框
  • 修改服务卡片添加链接

阶段 2: 首页结构优化(高优先级)

  • 精简首页 About Section
  • 新增首页 Cases Section
  • 更新首页 Section 顺序

阶段 3: 导航与链接统一(中优先级)

  • 更新导航链接
  • 创建服务列表页
  • 更新 Footer 链接

阶段 4: 配色方案统一(中优先级)

  • 移除紫色,统一使用品牌红
  • 更新所有相关组件

阶段 1: 服务详情页重构

Task 1.1: 创建服务详情页面

Files:

  • Create: src/app/(marketing)/services/[id]/page.tsx
  • Create: src/app/(marketing)/services/[id]/client.tsx

Step 1: 创建服务详情客户端组件

// src/app/(marketing)/services/[id]/client.tsx
'use client';

import { useEffect, useRef, useState } from 'react';
import Link from 'next/link';
import { Button } from '@/components/ui/button';
import { Badge } from '@/components/ui/badge';
import { Card, CardContent } from '@/components/ui/card';
import { PageHeader } from '@/components/ui/page-header';
import { 
  ArrowLeft, 
  CheckCircle2, 
  TrendingUp, 
  Users, 
  Target, 
  Clock, 
  MessageCircle,
  ArrowRight
} from 'lucide-react';
import { SERVICES, CASES } from '@/lib/constants';

interface ServiceDetailClientProps {
  service: typeof SERVICES[number];
}

const iconMap: Record<string, React.ComponentType<{ className?: string }>> = {
  Code: () => (
    <svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
      <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4" />
    </svg>
  ),
  Cloud: () => (
    <svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
      <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M3 15a4 4 0 004 4h9a5 5 0 10-.1-9.999 5.002 5.002 0 10-9.78 2.096A4.001 4.001 0 003 15z" />
    </svg>
  ),
  BarChart3: () => (
    <svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
      <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z" />
    </svg>
  ),
  Shield: () => (
    <svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
      <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z" />
    </svg>
  ),
};

const challenges = {
  software: [
    { title: '需求不明确', description: '业务部门提不出清晰需求,开发团队反复返工' },
    { title: '技术选型困难', description: '技术栈更新快,不知道该选什么技术方案' },
    { title: '项目延期', description: '开发进度难以把控,上线时间一拖再拖' },
    { title: '维护成本高', description: '系统上线后问题不断,运维压力巨大' },
  ],
  cloud: [
    { title: '资源浪费', description: '服务器资源利用率低,成本居高不下' },
    { title: '扩展困难', description: '业务增长时系统无法快速扩容' },
    { title: '迁移风险', description: '担心数据丢失、业务中断' },
    { title: '安全顾虑', description: '不确定云端数据是否安全' },
  ],
  data: [
    { title: '数据孤岛', description: '各系统数据分散,无法整合分析' },
    { title: '决策盲区', description: '缺乏数据支撑,决策凭感觉' },
    { title: '报表滞后', description: '手工制作报表,时效性差' },
    { title: '价值难挖', description: '数据很多,但不知道怎么用' },
  ],
  security: [
    { title: '安全漏洞', description: '系统存在未知漏洞,随时可能被攻击' },
    { title: '合规压力', description: '监管要求越来越严,不知如何应对' },
    { title: '内部威胁', description: '员工操作不规范,数据泄露风险' },
    { title: '应急能力弱', description: '安全事件发生后不知所措' },
  ],
};

const outcomes = {
  software: [
    { value: '30%', label: '开发效率提升' },
    { value: '50%', label: '返工率降低' },
    { value: '100%', label: '按时交付率' },
  ],
  cloud: [
    { value: '40%', label: '成本降低' },
    { value: '99.9%', label: '可用性保障' },
    { value: '10x', label: '弹性扩展能力' },
  ],
  data: [
    { value: '70%', label: '决策效率提升' },
    { value: '实时', label: '数据更新' },
    { value: '100+', label: '可视化报表' },
  ],
  security: [
    { value: '99%', label: '漏洞修复率' },
    { value: '100%', label: '合规达标' },
    { value: '24/7', label: '安全监控' },
  ],
};

export function ServiceDetailClient({ service }: ServiceDetailClientProps) {
  const [isVisible, setIsVisible] = useState(false);
  const contentRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    const observer = new IntersectionObserver(
      ([entry]) => {
        if (entry?.isIntersecting) {
          setIsVisible(true);
        }
      },
      { threshold: 0.1 }
    );

    if (contentRef.current) {
      observer.observe(contentRef.current);
    }

    return () => observer.disconnect();
  }, []);

  const serviceChallenges = challenges[service.id as keyof typeof challenges] || [];
  const serviceOutcomes = outcomes[service.id as keyof typeof outcomes] || [];
  const relatedCases = CASES.slice(0, 2);

  const Icon = iconMap[service.icon];

  return (
    <main className="min-h-screen bg-white">
      <div className="relative overflow-hidden bg-gradient-to-b from-[#FAFAFA] to-white">
        <div className="container-wide relative z-10 pt-32 pb-20">
          <Link href="/services">
            <Button variant="ghost" className="text-[#5C5C5C] hover:text-[#C41E3A] hover:bg-[#C41E3A]/10">
              <ArrowLeft className="w-4 h-4 mr-2" />
              返回服务列表
            </Button>
          </Link>
          <div className="max-w-4xl mt-8">
            <div className="flex items-center gap-4 mb-6">
              <div className="w-16 h-16 bg-[#C41E3A] rounded-2xl flex items-center justify-center text-white">
                {Icon && <Icon />}
              </div>
              <div>
                <Badge className="mb-2 bg-[#C41E3A]/10 text-[#C41E3A] hover:bg-[#C41E3A]/20">
                  核心业务
                </Badge>
                <h1 className="text-3xl sm:text-4xl lg:text-5xl font-semibold text-[#1C1C1C]">
                  {service.title}
                </h1>
              </div>
            </div>
            <p className="text-lg text-[#5C5C5C] leading-relaxed">
              {service.description}
            </p>
          </div>
        </div>
      </div>

      <div ref={contentRef} className="container-wide py-12 md:py-16">
        <div className="max-w-4xl mx-auto space-y-16">
          
          <section className="bg-gradient-to-br from-[#FFFBF5] to-white rounded-2xl p-8 border border-[#C41E3A]/20">
            <div className="flex items-center gap-3 mb-6">
              <div className="w-12 h-12 bg-[#C41E3A] 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>
            <div className="grid md:grid-cols-2 gap-4">
              {serviceChallenges.map((challenge, index) => (
                <div 
                  key={index}
                  className="p-4 bg-white rounded-lg border border-[#E5E5E5] hover:border-[#C41E3A] transition-colors"
                >
                  <h3 className="font-semibold text-[#1C1C1C] mb-2">{challenge.title}</h3>
                  <p className="text-sm text-[#5C5C5C]">{challenge.description}</p>
                </div>
              ))}
            </div>
          </section>

          <section className="bg-gradient-to-br from-[#F5F7FA] to-white rounded-2xl p-8 border border-[#E5E5E5]">
            <div className="flex items-center gap-3 mb-6">
              <div className="w-12 h-12 bg-[#C41E3A] 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>
            <p className="text-lg text-[#5C5C5C] leading-relaxed mb-6">
              {service.overview}
            </p>
            <div className="space-y-3">
              {service.features.map((feature, index) => (
                <div key={index} className="flex items-start gap-3">
                  <CheckCircle2 className="w-5 h-5 text-[#C41E3A] mt-0.5 flex-shrink-0" />
                  <span className="text-[#1C1C1C]">{feature}</span>
                </div>
              ))}
            </div>
          </section>

          <section className="bg-gradient-to-br from-[#FFFBF5] to-white rounded-2xl p-8 border border-[#C41E3A]/20">
            <div className="flex items-center gap-3 mb-6">
              <div className="w-12 h-12 bg-[#C41E3A] 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>
            <div className="space-y-4">
              {service.process.map((step, index) => (
                <div key={index} className="flex items-start gap-4">
                  <div className="w-10 h-10 bg-[#C41E3A] rounded-full flex items-center justify-center flex-shrink-0 text-white font-semibold">
                    {index + 1}
                  </div>
                  <div className="flex-1 pb-4">
                    <p className="text-[#1C1C1C] font-medium">{step}</p>
                  </div>
                </div>
              ))}
            </div>
          </section>

          <section className="bg-gradient-to-br from-[#F5F7FA] to-white rounded-2xl p-8 border border-[#E5E5E5]">
            <div className="flex items-center gap-3 mb-6">
              <div className="w-12 h-12 bg-[#C41E3A] rounded-xl flex items-center justify-center">
                <TrendingUp className="w-6 h-6 text-white" />
              </div>
              <h2 className="text-2xl font-semibold text-[#1C1C1C]">
                您将获得的改变
              </h2>
            </div>
            <div className="grid sm:grid-cols-3 gap-4">
              {serviceOutcomes.map((outcome, index) => (
                <div 
                  key={index}
                  className="p-6 bg-white rounded-lg border border-[#E5E5E5] hover:border-[#C41E3A] transition-colors text-center"
                >
                  <div className="text-3xl font-bold text-[#C41E3A] mb-2">
                    {outcome.value}
                  </div>
                  <div className="text-sm text-[#5C5C5C]">{outcome.label}</div>
                </div>
              ))}
            </div>
            <div className="mt-6 p-4 bg-white rounded-lg border border-[#E5E5E5]">
              <p className="text-sm text-[#5C5C5C]">
                {service.benefits.map(b => b).join('')}
              </p>
            </div>
          </section>

          <section className="bg-gradient-to-br from-[#FFFBF5] to-white rounded-2xl p-8 border border-[#C41E3A]/20">
            <div className="flex items-center gap-3 mb-6">
              <div className="w-12 h-12 bg-[#C41E3A] rounded-xl flex items-center justify-center">
                <Users className="w-6 h-6 text-white" />
              </div>
              <h2 className="text-2xl font-semibold text-[#1C1C1C]">
                相关案例
              </h2>
            </div>
            <div className="grid md:grid-cols-2 gap-4">
              {relatedCases.map((caseItem) => (
                <Link
                  key={caseItem.id}
                  href={`/cases/${caseItem.id}`}
                  className="group p-4 bg-white rounded-lg border border-[#E5E5E5] hover:border-[#C41E3A] transition-colors"
                >
                  <Badge variant="secondary" className="mb-2">
                    {caseItem.industry}
                  </Badge>
                  <h3 className="font-semibold text-[#1C1C1C] group-hover:text-[#C41E3A] transition-colors">
                    {caseItem.title}
                  </h3>
                  <p className="text-sm text-[#5C5C5C] mt-2 line-clamp-2">
                    {caseItem.description}
                  </p>
                </Link>
              ))}
            </div>
          </section>

          <div className="flex justify-center gap-4 pt-8 border-t border-[#E5E5E5]">
            <Button variant="outline" size="lg" asChild>
              <Link href="/services">
                查看其他服务
              </Link>
            </Button>
            <Button size="lg" className="bg-[#C41E3A] hover:bg-[#A01830] text-white" asChild>
              <Link href="/contact">
                开始您的转型之旅
                <ArrowRight className="ml-2 w-4 h-4" />
              </Link>
            </Button>
          </div>
        </div>
      </div>
    </main>
  );
}

Step 2: 创建服务详情页面入口

// src/app/(marketing)/services/[id]/page.tsx
import { Metadata } from 'next';
import { notFound } from 'next/navigation';
import { SERVICES } from '@/lib/constants';
import { ServiceDetailClient } from './client';

export async function generateStaticParams() {
  return SERVICES.map((service) => ({
    id: service.id,
  }));
}

export async function generateMetadata({ params }: { params: Promise<{ id: string }> }): Promise<Metadata> {
  const { id } = await params;
  const service = SERVICES.find((s) => s.id === id);

  if (!service) {
    return {
      title: '服务未找到',
    };
  }

  return {
    title: `${service.title} - 睿新致远`,
    description: service.description,
  };
}

export default async function ServiceDetailPage({ params }: { params: Promise<{ id: string }> }) {
  const { id } = await params;
  const service = SERVICES.find((s) => s.id === id);

  if (!service) {
    notFound();
  }

  return <ServiceDetailClient service={service} />;
}

Step 3: 验证文件创建成功

Run: ls -la src/app/\(marketing\)/services/

Expected: 目录和文件已创建

Step 4: Commit

git add src/app/\(marketing\)/services/
git commit -m "feat: add service detail page with storytelling style"

Task 1.2: 创建服务列表页面

Files:

  • Create: src/app/(marketing)/services/page.tsx

Step 1: 创建服务列表页面

// src/app/(marketing)/services/page.tsx
'use client';

import Link from 'next/link';
import { motion } from 'framer-motion';
import { useInView } from 'framer-motion';
import { useRef } from 'react';
import { Button } from '@/components/ui/button';
import { Badge } from '@/components/ui/badge';
import { Card, CardContent } from '@/components/ui/card';
import { PageHeader } from '@/components/ui/page-header';
import { ArrowRight, Code, Cloud, BarChart3, Shield } from 'lucide-react';
import { SERVICES } from '@/lib/constants';

const iconMap: Record<string, React.ComponentType<{ className?: string }>> = {
  Code,
  Cloud,
  BarChart3,
  Shield,
};

export default function ServicesPage() {
  const contentRef = useRef(null);
  const isContentInView = useInView(contentRef, { once: true, margin: '-100px' });

  return (
    <div className="min-h-screen bg-white">
      <PageHeader
        title="核心业务"
        description="专业技术团队,为您提供全方位的数字化解决方案"
      />

      <div className="container-wide relative z-10 py-16" ref={contentRef}>
        <div className="max-w-6xl mx-auto">
          <div className="grid md:grid-cols-2 gap-8">
            {SERVICES.map((service, index) => {
              const Icon = iconMap[service.icon];
              return (
                <motion.div
                  key={service.id}
                  initial={{ opacity: 0, y: 20 }}
                  animate={isContentInView ? { opacity: 1, y: 0 } : {}}
                  transition={{ duration: 0.5, delay: index * 0.1 }}
                >
                  <Link
                    href={`/services/${service.id}`}
                    className="group bg-white rounded-2xl border border-[#E5E5E5] overflow-hidden hover:shadow-xl transition-all duration-300 block h-full"
                  >
                    <div className="p-8">
                      <div className="flex items-start gap-4 mb-4">
                        <div className="w-14 h-14 rounded-xl bg-[#F5F5F5] flex items-center justify-center group-hover:bg-[#C41E3A] transition-all duration-300">
                          {Icon && <Icon className="w-7 h-7 text-[#1C1C1C] group-hover:text-white transition-colors" />}
                        </div>
                        <div className="flex-1">
                          <h3 className="text-xl font-semibold text-[#1C1C1C] mb-2 group-hover:text-[#C41E3A] transition-colors">
                            {service.title}
                          </h3>
                          <p className="text-[#5C5C5C] text-sm leading-relaxed">
                            {service.description}
                          </p>
                        </div>
                      </div>

                      <div className="mt-6 pt-4 border-t border-[#E5E5E5]">
                        <div className="flex flex-wrap gap-2 mb-4">
                          {service.features.slice(0, 3).map((feature, idx) => (
                            <Badge key={idx} variant="secondary" className="text-xs">
                              {feature.split('')[0]}
                            </Badge>
                          ))}
                        </div>
                        <div className="flex items-center text-[#C41E3A] font-medium group-hover:translate-x-2 transition-transform">
                          了解详情
                          <ArrowRight className="w-4 h-4 ml-2" />
                        </div>
                      </div>
                    </div>
                  </Link>
                </motion.div>
              );
            })}
          </div>
        </div>
      </div>

      <motion.div
        initial={{ opacity: 0, y: 20 }}
        animate={isContentInView ? { opacity: 1, y: 0 } : {}}
        transition={{ duration: 0.6, delay: 0.4 }}
        className="bg-[#F5F5F5] py-16"
      >
        <div className="container-wide text-center">
          <h2 className="text-3xl font-bold text-[#1C1C1C] mb-6">
            准备开始您的数字化转型之旅?
          </h2>
          <p className="text-lg text-[#5C5C5C] mb-8 max-w-2xl mx-auto">
            让我们与您同行,共创美好未来
          </p>
          <Button 
            size="lg" 
            className="bg-[#C41E3A] hover:bg-[#A01830] text-white"
            asChild
          >
            <Link href="/contact">
              立即咨询
              <ArrowRight className="ml-2 w-4 h-4" />
            </Link>
          </Button>
        </div>
      </motion.div>
    </div>
  );
}

Step 2: 验证文件创建成功

Run: ls -la src/app/\(marketing\)/services/page.tsx

Expected: 文件已创建

Step 3: Commit

git add src/app/\(marketing\)/services/page.tsx
git commit -m "feat: add services list page"

Task 1.3: 修改服务卡片组件添加链接

Files:

  • Modify: src/components/sections/services-section.tsx

Step 1: 移除模态框相关代码,添加链接

Read: src/components/sections/services-section.tsx

Replace entire file with:

'use client';

import { motion } from 'framer-motion';
import { useInView } from 'framer-motion';
import { useRef } from 'react';
import Link from 'next/link';
import { Code, Cloud, BarChart3, Shield, ArrowRight } from 'lucide-react';
import { Card, CardContent } from '@/components/ui/card';
import { Button } from '@/components/ui/button';
import { SERVICES } from '@/lib/constants';

const iconMap: Record<string, React.ComponentType<{ className?: string }>> = {
  Code,
  Cloud,
  BarChart3,
  Shield,
};

export function ServicesSection() {
  const ref = useRef(null);
  const isInView = useInView(ref, { once: true, margin: '-100px' });

  return (
    <section id="solutions" aria-labelledby="solutions-heading" 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 id="solutions-heading" 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-2 lg:grid-cols-4 gap-6">
          {SERVICES.map((service, index) => {
            const Icon = iconMap[service.icon];
            return (
              <motion.div
                key={service.id}
                initial={{ opacity: 0, y: 20 }}
                whileInView={{ opacity: 1, y: 0 }}
                viewport={{ once: true }}
                transition={{ duration: 0.5, delay: index * 0.1 }}
              >
                <Link href={`/services/${service.id}`}>
                  <Card className="p-6 h-full group cursor-pointer border-[#E5E5E5] hover:border-[#C41E3A] transition-colors">
                    <CardContent className="p-0">
                      <div className="w-12 h-12 rounded-xl bg-[#F5F5F5] flex items-center justify-center mb-4 group-hover:bg-[#C41E3A] transition-all duration-300">
                        {Icon && <Icon className="w-6 h-6 text-[#1C1C1C] group-hover:text-white transition-colors" />}
                      </div>
                      <h3 className="text-xl font-semibold text-[#1C1C1C] mb-3 group-hover:text-[#C41E3A] transition-colors">{service.title}</h3>
                      <p className="text-[#5C5C5C] text-sm leading-relaxed">{service.description}</p>
                      <div className="mt-4 flex items-center text-[#C41E3A] text-sm font-medium opacity-0 group-hover:opacity-100 transition-opacity">
                        了解详情
                        <ArrowRight className="ml-1 w-4 h-4" />
                      </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="/services">
              查看全部服务
              <ArrowRight className="ml-2 w-4 h-4 transition-transform group-hover:translate-x-1" />
            </Link>
          </Button>
        </motion.div>
      </div>
    </section>
  );
}

Step 2: 验证修改

Run: npm run lint

Expected: 无 lint 错误

Step 3: Commit

git add src/components/sections/services-section.tsx
git commit -m "refactor: remove modal, add link navigation for services"

Task 1.4: 删除服务详情模态框组件

Files:

  • Delete: src/components/services/service-detail-modal.tsx

Step 1: 删除模态框组件文件

Run: rm src/components/services/service-detail-modal.tsx

Step 2: 验证删除成功

Run: ls src/components/services/

Expected: 目录为空或不存在

Step 3: 如果目录为空,删除目录

Run: rmdir src/components/services/ 2>/dev/null || true

Step 4: Commit

git add -A
git commit -m "refactor: remove service detail modal component"

阶段 2: 首页结构优化

Task 2.1: 精简首页 About Section

Files:

  • Modify: src/components/sections/about-section.tsx

Step 1: 精简 About Section 内容

Read: src/components/sections/about-section.tsx

Replace entire file with:

'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 { COMPANY_INFO, STATS } from '@/lib/constants';
import { ArrowRight } from 'lucide-react';

export function AboutSection() {
  const ref = useRef(null);
  const isInView = useInView(ref, { once: true, margin: '-100px' });

  return (
    <section id="about" className="py-24 bg-[#FAFAFA] relative" ref={ref}>
      <div className="absolute inset-0 bg-[linear-gradient(rgba(28,28,28,0.02)_1px,transparent_1px),linear-gradient(90deg,rgba(28,28,28,0.02)_1px,transparent_1px)] bg-[size:40px_40px]" />
      <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="max-w-4xl mx-auto"
        >
          <div className="text-center mb-12">
            <h2 className="text-4xl md:text-5xl font-bold text-[#1C1C1C] mb-6">
              关于 <span className="tracking-tight font-calligraphy text-[#C41E3A]" style={{ fontWeight: 'normal', WebkitFontSmoothing: 'antialiased', MozOsxFontSmoothing: 'grayscale', textRendering: 'optimizeLegibility' }}>{COMPANY_INFO.shortName}</span>
            </h2>
            <p className="text-lg text-[#5C5C5C] mb-8">
              {COMPANY_INFO.slogan}
            </p>
          </div>

          <div className="bg-white rounded-2xl p-8 mb-12 border border-[#E5E5E5]">
            <p className="text-lg text-[#5C5C5C] leading-relaxed text-center mb-6">
              "企业需要的,不是一个高高在上的'专家',也不是一个做完就跑的'卖家',而是一个能坐下来、一起想办法的同行者。"
            </p>
            <p className="text-[#1C1C1C] font-medium text-center">
              我们只做一件事:成为您数字化转型路上,信得过的成长伙伴。
            </p>
          </div>

          <motion.div 
            initial={{ opacity: 0, y: 20 }}
            animate={isInView ? { opacity: 1, y: 0 } : {}}
            transition={{ duration: 0.6, delay: 0.2 }}
            className="grid grid-cols-2 md:grid-cols-4 gap-6 mb-12"
          >
            {STATS.map((stat, idx) => (
              <Card key={idx} className="text-center border-[#E5E5E5]">
                <CardContent className="pt-6">
                  <div className="text-3xl sm:text-4xl font-bold text-[#C41E3A] mb-2">{stat.value}</div>
                  <div className="text-sm text-[#5C5C5C]">{stat.label}</div>
                </CardContent>
              </Card>
            ))}
          </motion.div>

          <motion.div
            initial={{ opacity: 0, y: 20 }}
            animate={isInView ? { opacity: 1, y: 0 } : {}}
            transition={{ duration: 0.6, delay: 0.3 }}
            className="text-center"
          >
            <Button size="lg" variant="outline" className="group" asChild>
              <Link href="/about">
                了解更多关于我们
                <ArrowRight className="ml-2 w-4 h-4 transition-transform group-hover:translate-x-1" />
              </Link>
            </Button>
          </motion.div>
        </motion.div>
      </div>
    </section>
  );
}

Step 2: 验证修改

Run: npm run lint

Expected: 无 lint 错误

Step 3: Commit

git add src/components/sections/about-section.tsx
git commit -m "refactor: simplify about section on homepage"

Task 2.2: 创建首页 Cases Section

Files:

  • Create: src/components/sections/cases-section.tsx

Step 1: 创建 Cases Section 组件

// src/components/sections/cases-section.tsx
'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>
  );
}

Step 2: 验证文件创建成功

Run: ls -la src/components/sections/cases-section.tsx

Expected: 文件已创建

Step 3: Commit

git add src/components/sections/cases-section.tsx
git commit -m "feat: add cases section to homepage"

Task 2.3: 更新首页 Section 顺序

Files:

  • Modify: src/app/(marketing)/page.tsx

Step 1: 更新首页导入和 Section 顺序

Read: src/app/(marketing)/page.tsx

Replace entire file with:

"use client";

import dynamic from 'next/dynamic';
import { Header } from "@/components/layout/header";
import { Footer } from "@/components/layout/footer";
import { HeroSection } from "@/components/sections/hero-section";
import { SectionSkeleton } from "@/components/ui/loading-skeleton";

const ServicesSection = dynamic(
  () => import('@/components/sections/services-section').then(mod => ({ default: mod.ServicesSection })),
  { 
    loading: () => <SectionSkeleton />,
    ssr: true 
  }
);

const ProductsSection = dynamic(
  () => import('@/components/sections/products-section').then(mod => ({ default: mod.ProductsSection })),
  { 
    loading: () => <SectionSkeleton />,
    ssr: true 
  }
);

const CasesSection = dynamic(
  () => import('@/components/sections/cases-section').then(mod => ({ default: mod.CasesSection })),
  { 
    loading: () => <SectionSkeleton />,
    ssr: true 
  }
);

const AboutSection = dynamic(
  () => import('@/components/sections/about-section').then(mod => ({ default: mod.AboutSection })),
  { 
    loading: () => <SectionSkeleton />,
    ssr: true 
  }
);

const NewsSection = dynamic(
  () => import('@/components/sections/news-section').then(mod => ({ default: mod.NewsSection })),
  { 
    loading: () => <SectionSkeleton />,
    ssr: true 
  }
);

const ContactSection = dynamic(
  () => import('@/components/sections/contact-section').then(mod => ({ default: mod.ContactSection })),
  { 
    loading: () => <SectionSkeleton />,
    ssr: true 
  }
);

export default function HomePage() {
  return (
    <main className="min-h-screen bg-white dark:bg-[var(--color-bg-primary)]">
      <Header />
      <HeroSection />
      <ServicesSection />
      <ProductsSection />
      <CasesSection />
      <AboutSection />
      <NewsSection />
      <ContactSection />
      <Footer />
    </main>
  );
}

Step 2: 验证修改

Run: npm run lint

Expected: 无 lint 错误

Step 3: Commit

git add src/app/\(marketing\)/page.tsx
git commit -m "refactor: update homepage section order with cases section"

阶段 3: 导航与链接统一

Task 3.1: 更新导航链接

Files:

  • Modify: src/lib/constants.ts
  • Modify: src/components/layout/header.tsx

Step 1: 更新导航配置

Read: src/lib/constants.ts

Find the NAVIGATION constant and replace with:

// Navigation Items - 独立页面导航
export const NAVIGATION = [
  { id: 'home', label: '首页', href: '/' },
  { id: 'services', label: '核心业务', href: '/services' },
  { id: 'products', label: '产品服务', href: '/products' },
  { id: 'about', label: '关于我们', href: '/about' },
  { id: 'news', label: '新闻动态', href: '/news' },
  { id: 'contact', label: '联系我们', href: '/contact' },
] as const;

Step 2: 更新 Header 组件

Read: src/components/layout/header.tsx

Replace the navigation handling logic to use Link instead of anchor scroll:

'use client';

import { useState, useEffect, useCallback, useRef } from 'react';
import Link from 'next/link';
import { usePathname } from 'next/navigation';
import { Menu, X } from 'lucide-react';
import { motion, AnimatePresence } from 'framer-motion';
import { Button } from '@/components/ui/button';
import { COMPANY_INFO, NAVIGATION } from '@/lib/constants';
import { useFocusTrap } from '@/hooks/use-focus-trap';

export function Header() {
  const [isOpen, setIsOpen] = useState(false);
  const [isScrolled, setIsScrolled] = useState(false);
  const pathname = usePathname();
  const focusTrapRef = useFocusTrap<HTMLDivElement>(isOpen);

  useEffect(() => {
    const handleScroll = () => {
      setIsScrolled(window.scrollY > 20);
    };

    window.addEventListener('scroll', handleScroll, { passive: true });
    handleScroll();

    return () => {
      window.removeEventListener('scroll', handleScroll);
    };
  }, []);

  const handleKeyDown = useCallback((e: React.KeyboardEvent) => {
    if (e.key === 'Enter' || e.key === ' ') {
      e.preventDefault();
      setIsOpen(!isOpen);
    }
    if (e.key === 'Escape' && isOpen) {
      setIsOpen(false);
    }
  }, [isOpen]);

  return (
    <>
      <header 
        className={`
          fixed top-0 left-0 right-0 z-50
          transition-all duration-300 ease-out
          ${isScrolled 
            ? 'bg-white/95 backdrop-blur-xl border-b border-[#E2E8F0] shadow-sm' 
            : 'bg-transparent'
          }
        `}
      >
        <div className="container-wide">
          <div className="flex items-center justify-between h-16">
            <Link 
              href="/"
              className="flex items-center group focus:outline-none focus:ring-2 focus:ring-[#C41E3A] focus:ring-offset-2 rounded-sm"
            >
              <img 
                src="/logo.svg" 
                alt={COMPANY_INFO.name}
                className="h-8 w-auto transition-transform duration-200 group-hover:scale-105"
              />
            </Link>

            <nav className="hidden md:flex items-center gap-1" role="navigation" aria-label="主导航">
              {NAVIGATION.map((item) => (
                <Link
                  key={item.id}
                  href={item.href}
                  className={`
                    relative px-3 py-1.5 text-sm font-medium
                    transition-all duration-300
                    focus:outline-none focus:ring-2 focus:ring-[#C41E3A] focus:ring-offset-2 rounded-sm
                    ${pathname === item.href || (item.href !== '/' && pathname.startsWith(item.href))
                      ? 'text-[#1C1C1C]'
                      : 'text-[#3D3D3D] hover:text-[#1C1C1C]'
                    }
                  `}
                  aria-current={pathname === item.href ? 'page' : undefined}
                >
                  {item.label}
                  {(pathname === item.href || (item.href !== '/' && pathname.startsWith(item.href))) && (
                    <motion.span 
                      layoutId="activeNav"
                      className="absolute bottom-0 left-1/2 -translate-x-1/2 w-6 h-0.5 bg-[#C41E3A] rounded-full"
                      transition={{ type: "spring", stiffness: 380, damping: 30 }}
                    />
                  )}
                </Link>
              ))}
            </nav>

            <div className="hidden md:flex items-center gap-3">
              <Button 
                size="sm"
                asChild
              >
                <Link href="/contact">立即咨询</Link>
              </Button>
            </div>

            <button
              className="md:hidden p-2 -mr-2 text-[#3D3D3D] hover:text-[#1C1C1C] transition-colors focus:outline-none focus:ring-2 focus:ring-[#C41E3A] focus:ring-offset-2 rounded-sm"
              onClick={() => setIsOpen(!isOpen)}
              onKeyDown={handleKeyDown}
              aria-expanded={isOpen}
              aria-controls="mobile-menu"
              aria-label={isOpen ? '关闭菜单' : '打开菜单'}
            >
              {isOpen ? <X className="w-5 h-5" /> : <Menu className="w-5 h-5" />}
            </button>
          </div>
        </div>
      </header>

      <AnimatePresence>
        {isOpen && (
          <motion.div 
            ref={focusTrapRef}
            initial={{ opacity: 0 }}
            animate={{ opacity: 1 }}
            exit={{ opacity: 0 }}
            className="fixed inset-0 z-40 md:hidden"
          >
            <div 
              className="absolute inset-0 bg-black/20 backdrop-blur-sm"
              onClick={() => setIsOpen(false)}
              aria-hidden="true"
            />
            <motion.div 
              initial={{ y: -20, opacity: 0 }}
              animate={{ y: 0, opacity: 1 }}
              exit={{ y: -20, opacity: 0 }}
              transition={{ type: "spring", stiffness: 300, damping: 30 }}
              className="absolute top-16 left-0 right-0 bg-white/95 backdrop-blur-xl border-b border-[#E2E8F0] shadow-lg"
              id="mobile-menu"
              role="navigation"
              aria-label="移动端导航"
            >
              <nav className="container-wide py-4">
                {NAVIGATION.map((item, index) => (
                  <motion.div
                    key={item.id}
                    initial={{ x: -20, opacity: 0 }}
                    animate={{ x: 0, opacity: 1 }}
                    transition={{ delay: index * 0.05 }}
                  >
                    <Link
                      href={item.href}
                      onClick={() => setIsOpen(false)}
                      className={`
                        block px-4 py-3 text-base font-medium
                        transition-all duration-300
                        border-l-2
                        focus:outline-none focus:ring-2 focus:ring-[#C41E3A] focus:ring-inset
                        ${pathname === item.href || (item.href !== '/' && pathname.startsWith(item.href))
                          ? 'text-[#1C1C1C] border-[#C41E3A] bg-[#FEF2F4]'
                          : 'text-[#3D3D3D] border-transparent hover:text-[#1C1C1C] hover:bg-[#F5F5F5]'
                        }
                      `}
                    >
                      {item.label}
                    </Link>
                  </motion.div>
                ))}
                <div className="mt-4 px-4 pt-4 border-t border-[#E2E8F0] space-y-3">
                  <Button 
                    className="w-full"
                    asChild
                  >
                    <Link href="/contact" onClick={() => setIsOpen(false)}>
                      联系我们
                    </Link>
                  </Button>
                </div>
              </nav>
            </motion.div>
          </motion.div>
        )}
      </AnimatePresence>
    </>
  );
}

Step 3: 验证修改

Run: npm run lint

Expected: 无 lint 错误

Step 4: Commit

git add src/lib/constants.ts src/components/layout/header.tsx
git commit -m "refactor: update navigation to use independent page links"

Task 3.2: 创建产品列表页面

Files:

  • Create: src/app/(marketing)/products/page.tsx

Step 1: 创建产品列表页面

// src/app/(marketing)/products/page.tsx
'use client';

import Link from 'next/link';
import { motion } from 'framer-motion';
import { useInView } from 'framer-motion';
import { useRef } from 'react';
import { Button } from '@/components/ui/button';
import { Badge } from '@/components/ui/badge';
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from '@/components/ui/card';
import { PageHeader } from '@/components/ui/page-header';
import { ArrowRight, Check, TrendingUp } from 'lucide-react';
import { PRODUCTS } from '@/lib/constants';

export default function ProductsPage() {
  const contentRef = useRef(null);
  const isContentInView = useInView(contentRef, { once: true, margin: '-100px' });

  return (
    <div className="min-h-screen bg-white">
      <PageHeader
        title="产品服务"
        description="自主研发的企业级产品,助力企业高效运营,实现数字化转型"
      />

      <div className="container-wide relative z-10 py-16" ref={contentRef}>
        <div className="max-w-6xl mx-auto">
          <div className="grid grid-cols-1 md:grid-cols-2 gap-8">
            {PRODUCTS.map((product, index) => (
              <motion.div
                key={product.id}
                initial={{ opacity: 0, y: 20 }}
                animate={isContentInView ? { opacity: 1, y: 0 } : {}}
                transition={{ duration: 0.5, delay: index * 0.1 }}
              >
                <Link href={`/products/${product.id}`}>
                  <Card className="h-full group cursor-pointer border-[#E5E5E5] hover:border-[#C41E3A] transition-colors">
                    <CardHeader>
                      <Badge variant="secondary" className="w-fit mb-3">
                        {product.category}
                      </Badge>
                      <CardTitle className="group-hover:text-[#C41E3A] transition-colors">{product.title}</CardTitle>
                    </CardHeader>
                    <CardContent className="flex-1 flex flex-col">
                      <CardDescription className="text-base leading-relaxed mb-4 flex-1">
                        {product.description}
                      </CardDescription>
                      
                      <div className="mb-4">
                        <p className="text-sm font-medium text-[#1C1C1C] mb-2">核心功能</p>
                        <div className="flex flex-wrap gap-1.5">
                          {product.features.slice(0, 4).map((feature, idx) => (
                            <span 
                              key={idx} 
                              className="inline-flex items-center text-xs px-2 py-1 bg-[#FAFAFA] text-[#3D3D3D] rounded border border-[#E5E5E5]"
                            >
                              <Check className="w-3 h-3 mr-1 text-[#C41E3A]" />
                              {feature}
                            </span>
                          ))}
                        </div>
                      </div>

                      <div className="mb-4">
                        <p className="text-sm font-medium text-[#1C1C1C] mb-2 flex items-center">
                          <TrendingUp className="w-4 h-4 mr-1 text-[#C41E3A]" />
                          核心价值
                        </p>
                        <ul className="space-y-1">
                          {product.benefits.map((benefit, idx) => (
                            <li key={idx} className="text-xs text-[#5C5C5C] flex items-start">
                              <span className="text-[#C41E3A] mr-1.5"></span>
                              {benefit}
                            </li>
                          ))}
                        </ul>
                      </div>

                      <Button variant="outline" className="w-full mt-auto group-hover:bg-[#C41E3A] group-hover:text-white group-hover:border-[#C41E3A] transition-colors">
                        了解详情
                        <ArrowRight className="ml-2 w-4 h-4" />
                      </Button>
                    </CardContent>
                  </Card>
                </Link>
              </motion.div>
            ))}
          </div>
        </div>
      </div>

      <motion.div
        initial={{ opacity: 0, y: 20 }}
        animate={isContentInView ? { opacity: 1, y: 0 } : {}}
        transition={{ duration: 0.6, delay: 0.4 }}
        className="bg-[#F5F5F5] py-16"
      >
        <div className="container-wide text-center">
          <h2 className="text-3xl font-bold text-[#1C1C1C] mb-6">
            需要定制化解决方案?
          </h2>
          <p className="text-lg text-[#5C5C5C] mb-8 max-w-2xl mx-auto">
            我们的专业团队可以根据您的业务需求,提供量身定制的产品开发和系统集成服务
          </p>
          <Button 
            size="lg" 
            className="bg-[#C41E3A] hover:bg-[#A01830] text-white"
            asChild
          >
            <Link href="/contact">
              联系我们
              <ArrowRight className="ml-2 w-4 h-4" />
            </Link>
          </Button>
        </div>
      </motion.div>
    </div>
  );
}

Step 2: 验证文件创建成功

Run: ls -la src/app/\(marketing\)/products/page.tsx

Expected: 文件已创建

Step 3: Commit

git add src/app/\(marketing\)/products/page.tsx
git commit -m "feat: add products list page"

Files:

  • Modify: src/components/layout/footer.tsx

Step 1: 更新 Footer 导航链接

Read: src/components/layout/footer.tsx

Replace the navigation links section with:

<div>
  <h3 className="font-semibold text-lg mb-6 text-[#1C1C1C]">快速链接</h3>
  <ul className="space-y-3">
    {NAVIGATION.map((item) => (
      <li key={item.id}>
        <Link
          href={item.href}
          className="text-[#3D3D3D] hover:text-[#C41E3A] transition-colors"
        >
          {item.label}
        </Link>
      </li>
    ))}
  </ul>
</div>

Step 2: 验证修改

Run: npm run lint

Expected: 无 lint 错误

Step 3: Commit

git add src/components/layout/footer.tsx
git commit -m "refactor: update footer navigation links"

阶段 4: 配色方案统一

Task 4.1: 更新案例详情页配色

Files:

  • Modify: src/app/(marketing)/cases/[id]/client.tsx

Step 1: 将紫色替换为品牌红

Read: src/app/(marketing)/cases/[id]/client.tsx

Replace all occurrences of:

  • #4F46E5#C41E3A
  • rgba(79,70,229,rgba(196,30,58,

Key replacements:

// Before
<div className="w-12 h-12 bg-[#4F46E5] rounded-xl flex items-center justify-center">

// After
<div className="w-12 h-12 bg-[#C41E3A] rounded-xl flex items-center justify-center">

Step 2: 验证修改

Run: npm run lint

Expected: 无 lint 错误

Step 3: Commit

git add src/app/\(marketing\)/cases/\[id\]/client.tsx
git commit -m "style: unify color scheme to brand red in case detail page"

Task 4.2: 更新 Solutions 页面配色

Files:

  • Modify: src/app/(marketing)/solutions/page.tsx

Step 1: 将紫色替换为品牌红

Read: src/app/(marketing)/solutions/page.tsx

Replace all occurrences of:

  • #4F46E5#C41E3A
  • rgba(79,70,229,rgba(196,30,58,

Step 2: 验证修改

Run: npm run lint

Expected: 无 lint 错误

Step 3: Commit

git add src/app/\(marketing\)/solutions/page.tsx
git commit -m "style: unify color scheme to brand red in solutions page"

Task 4.3: 更新 Products Section 配色

Files:

  • Modify: src/components/sections/products-section.tsx

Step 1: 将紫色替换为品牌红

Read: src/components/sections/products-section.tsx

Replace all occurrences of:

  • #4F46E5#C41E3A
  • rgba(79,70,229,rgba(196,30,58,

Step 2: 验证修改

Run: npm run lint

Expected: 无 lint 错误

Step 3: Commit

git add src/components/sections/products-section.tsx
git commit -m "style: unify color scheme to brand red in products section"

阶段 5: 清理与验证

Task 5.1: 删除旧的 Solutions 页面(可选)

Files:

  • Delete: src/app/(marketing)/solutions/ (如果与 services 重复)

Step 1: 检查是否需要删除

Run: ls -la src/app/\(marketing\)/solutions/

如果 solutions 页面与 services 功能重复,考虑重定向或删除。

Step 2: 如果决定保留,更新导航

确保导航指向正确的页面。


Task 5.2: 运行完整测试

Step 1: 运行 lint 检查

Run: npm run lint

Expected: 无错误

Step 2: 运行类型检查

Run: npm run typecheck || npx tsc --noEmit

Expected: 无类型错误

Step 3: 运行构建

Run: npm run build

Expected: 构建成功

Step 4: 本地测试

Run: npm run dev

手动测试以下页面:

  • / - 首页
  • /services - 服务列表
  • /services/[id] - 服务详情
  • /products - 产品列表
  • /products/[id] - 产品详情
  • /cases - 案例列表
  • /cases/[id] - 案例详情
  • /about - 关于我们
  • /news - 新闻列表
  • /contact - 联系我们

Task 5.3: 最终提交

Step 1: 检查所有更改

Run: git status

Step 2: 提交所有更改

git add -A
git commit -m "refactor: complete website optimization - unified navigation, colors, and structure"

实施完成检查清单

  • 服务详情页创建完成
  • 服务列表页创建完成
  • 服务模态框已删除
  • 首页 About Section 已精简
  • 首页 Cases Section 已添加
  • 导航链接已统一
  • 产品列表页已创建
  • Footer 链接已更新
  • 配色方案已统一
  • Lint 检查通过
  • 类型检查通过
  • 构建成功
  • 手动测试通过