Files
novalon-website/src/components/sections/products-section.tsx
T
张翔 ef4b6d1022 refactor: 重构所有 Section 组件为医疗健康风格
- ProductsSection: 浅灰背景、蓝红配色
- AboutSection: 白色背景、专业蓝图标
- NewsSection: 浅灰背景、蓝红强调
- ContactSection: 白色背景、蓝图标、红强调
2026-02-23 08:11:11 +08:00

127 lines
5.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 { motion } from 'framer-motion';
import { useInView } from 'framer-motion';
import { useRef } from 'react';
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from '@/components/ui/card';
import { Button } from '@/components/ui/button';
import { Badge } from '@/components/ui/badge';
import { ArrowRight, Check, TrendingUp } from 'lucide-react';
import { PRODUCTS } from '@/lib/constants';
export function ProductsSection() {
const ref = useRef(null);
const isInView = useInView(ref, { once: true, margin: '-100px' });
return (
<section id="products" className="py-24 bg-[#F5F7FA] relative overflow-hidden" ref={ref}>
<div className="absolute top-1/2 left-0 w-[400px] h-[400px] bg-[rgba(0,94,184,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"
>
<span className="inline-flex items-center gap-2 px-5 py-2.5 rounded-full border border-[#005EB8]/30 bg-[#E8F4FD] text-[#005EB8] text-sm font-medium mb-4">
</span>
<h2 className="text-4xl md:text-5xl font-bold text-[#1A1A2E] mb-6">
<span className="text-[#C41E3A]"></span>
</h2>
<p className="text-lg text-[#718096]">
</p>
</motion.div>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
{PRODUCTS.map((product, idx) => (
<motion.div
key={product.id}
initial={{ opacity: 0, y: 20 }}
animate={isInView ? { opacity: 1, y: 0 } : {}}
transition={{ duration: 0.5, delay: 0.1 + idx * 0.1 }}
>
<Card className="h-full flex flex-col group cursor-pointer border-[#E2E8F0] hover:border-[#005EB8]">
<CardHeader>
<Badge variant="secondary" className="w-fit mb-3">
{product.category}
</Badge>
<CardTitle>{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-[#1A1A2E] 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-white text-[#4A5568] rounded border border-[#E2E8F0]"
>
<Check className="w-3 h-3 mr-1 text-[#005EB8]" />
{feature}
</span>
))}
</div>
</div>
<div className="mb-4">
<p className="text-sm font-medium text-[#1A1A2E] 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-[#718096] flex items-start">
<span className="text-[#005EB8] mr-1.5"></span>
{benefit}
</li>
))}
</ul>
</div>
<Button variant="outline" className="w-full mt-auto">
<ArrowRight className="ml-2 w-4 h-4" />
</Button>
</CardContent>
</Card>
</motion.div>
))}
</div>
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={isInView ? { opacity: 1, y: 0 } : {}}
transition={{ duration: 0.6, delay: 0.5 }}
className="mt-20 text-center"
>
<div className="bg-white rounded-2xl p-12 border border-[#E2E8F0] relative overflow-hidden">
<div className="absolute inset-0 pointer-events-none">
<div className="absolute top-0 right-0 w-64 h-64 bg-[rgba(0,94,184,0.03)] rounded-full blur-3xl" />
<div className="absolute bottom-0 left-0 w-48 h-48 bg-[rgba(196,30,58,0.02)] rounded-full blur-3xl" />
</div>
<div className="relative z-10">
<h3 className="text-2xl sm:text-3xl font-bold text-[#1A1A2E] mb-4">
</h3>
<p className="text-[#718096] mb-8 max-w-2xl mx-auto">
</p>
<Button size="lg">
<ArrowRight className="ml-2 w-4 h-4" />
</Button>
</div>
</div>
</motion.div>
</div>
</section>
);
}