feat: 添加预览效果页面并优化交互效果

refactor: 优化代码健壮性和类型安全

style: 更新字体样式和全局CSS

fix: 修复IntersectionObserver潜在空引用问题

chore: 更新依赖和ESLint配置

build: 更新构建ID和路由配置
This commit is contained in:
张翔
2026-02-24 10:24:05 +08:00
parent 64165c4499
commit fecbfd1990
239 changed files with 3403 additions and 5181 deletions
+1 -1
View File
@@ -134,7 +134,7 @@ export default function AboutPage() {
<div className="font-semibold text-black text-sm md:text-base">{milestone.date}</div>
</div>
<div className="flex-1 pb-6 border-l-2 border-gray-200 pl-6 relative">
<div className="absolute -left-[9px] top-1 w-4 h-4 bg-black rounded-full"></div>
<div className="absolute -left-[9px] top-1 w-4 h-4 bg-black rounded-full" />
<h3 className="font-semibold text-black mb-1">{milestone.title}</h3>
<p className="text-gray-600 text-sm leading-relaxed">{milestone.description}</p>
</div>
+3 -4
View File
@@ -1,12 +1,11 @@
'use client';
import { useEffect, useRef, useState } from 'react';
import Image from 'next/image';
import Link from 'next/link';
import { Button } from '@/components/ui/button';
import { Badge } from '@/components/ui/badge';
import { ArrowLeft, Building2, CheckCircle2, TrendingUp, Users, Target } from 'lucide-react';
import { CASES, COMPANY_INFO } from '@/lib/constants';
import { CASES } from '@/lib/constants';
import type { StaticImageData } from 'next/image';
interface CaseResult {
@@ -36,7 +35,7 @@ export function CaseDetailClient({ caseItem }: CaseDetailClientProps) {
useEffect(() => {
const observer = new IntersectionObserver(
([entry]) => {
if (entry.isIntersecting) {
if (entry?.isIntersecting) {
setIsVisible(true);
}
},
@@ -116,7 +115,7 @@ export function CaseDetailClient({ caseItem }: CaseDetailClientProps) {
<section>
<h2 className="text-2xl font-semibold text-[#171717] mb-4"></h2>
<div className="space-y-4">
{caseItem.tags.map((tag, index) => (
{caseItem.tags.map((tag) => (
<div key={tag} className="flex items-start gap-3">
<div className="w-6 h-6 bg-[#C41E3A] rounded-full flex items-center justify-center flex-shrink-0 mt-0.5">
<CheckCircle2 className="w-4 h-4 text-white" />
+1 -2
View File
@@ -13,10 +13,9 @@ export default function ContactPage() {
const [isSubmitting, setIsSubmitting] = useState(false);
const [isSubmitted, setIsSubmitted] = useState(false);
async function handleSubmit(formData: FormData) {
async function handleSubmit(_formData: FormData) {
setIsSubmitting(true);
// Simulate form submission
await new Promise(resolve => setTimeout(resolve, 1500));
setIsSubmitting(false);