Files
jiwei-tech/src/components/Testimonials.tsx
2025-06-19 20:20:47 +08:00

202 lines
9.2 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.

import {
Card,
CardContent,
CardHeader,
CardTitle,
} from "@/components/ui/card";
import { AnimatedGridPattern } from "@/components/ui/animated-grid-pattern";
import { cn } from "@/lib/utils";
// 服务对比数据
interface ServiceComparisonProps {
title: string;
features: string[];
icon: string;
isCenter?: boolean;
}
const serviceComparisons: ServiceComparisonProps[] = [
{
title: "传统IT服务",
features: ["被动响应", "人工维护", "定期检查", "故障后处理", "单一技术栈"],
icon: "traditional",
},
{
title: "稷维科技服务",
features: [
"7x24智能监控",
"主动预警机制",
"快速响应处理",
"全栈技术支持",
"一站式解决方案",
"微信小程序", "支付宝小程序",
"企业官网", "电商平台"
],
icon: "intelligent",
isCenter: true,
},
{
title: "客户收益",
features: ["运维成本降低60%", "故障时间减少80%", "业务效率提升50%", "技术风险可控"],
icon: "benefits",
},
];
// 图标组件
const ServiceIcon = ({ type }: { type: string }) => {
const iconClass = "w-12 h-12 text-primary";
switch (type) {
case "traditional":
return (
<svg className={iconClass} fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" d="M11.42 15.17L17.25 21A2.652 2.652 0 0021 17.25l-5.877-5.877M11.42 15.17l2.496-3.03c.317-.384.74-.626 1.208-.766M11.42 15.17l-4.655 5.653a2.548 2.548 0 11-3.586-3.586l6.837-5.63m5.108-.233c.55-.164 1.163-.188 1.743-.14a4.5 4.5 0 004.486-6.336l-3.276 3.277a3.004 3.004 0 01-2.25-2.25l3.276-3.276a4.5 4.5 0 00-6.336 4.486c.091 1.076-.071 2.264-.904 2.95l-.102.085m-1.745 1.437L5.909 7.5H4.5L2.25 3.75l1.5-1.5L7.5 4.5v1.409l4.26 4.26m-1.745 1.437l1.745-1.437m6.615 8.206L15.75 15.75M4.867 19.125h.008v.008h-.008v-.008z" />
</svg>
);
case "intelligent":
return (
<svg className={iconClass} fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" d="M9.813 15.904L9 18.75l-.813-2.846a4.5 4.5 0 00-3.09-3.09L2.25 12l2.846-.813a4.5 4.5 0 003.09-3.09L9 5.25l.813 2.846a4.5 4.5 0 003.09 3.09L15.75 12l-2.846.813a4.5 4.5 0 00-3.09 3.09zM18.259 8.715L18 9.75l-.259-1.035a3.375 3.375 0 00-2.455-2.456L14.25 6l1.036-.259a3.375 3.375 0 002.455-2.456L18 2.25l.259 1.035a3.375 3.375 0 002.456 2.456L21.75 6l-1.035.259a3.375 3.375 0 00-2.456 2.456zM16.894 20.567L16.5 21.75l-.394-1.183a2.25 2.25 0 00-1.423-1.423L13.5 18.75l1.183-.394a2.25 2.25 0 001.423-1.423l.394-1.183.394 1.183a2.25 2.25 0 001.423 1.423l1.183.394-1.183.394a2.25 2.25 0 00-1.423 1.423z" />
</svg>
);
case "benefits":
return (
<svg className={iconClass} fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" d="M2.25 18L9 11.25l4.306 4.307a11.95 11.95 0 010 1.606c.216.363.692.83 1.595.83h.06a13.5 13.5 0 006.803-1.876l4.736-2.703a11.95 11.95 0 00-.864-1.591L11.5 9.75H9.75L5.5 5.5a7.5 7.5 0 00-10.606 10.606L2.25 18z" />
<path strokeLinecap="round" strokeLinejoin="round" d="M18 7.5L21 4.5 19.5 3 16.5 6l1.5 1.5z" />
</svg>
);
default:
return null;
}
};
export const Testimonials = () => {
return (
<section
id="testimonials"
className="relative container py-16 sm:py-20 overflow-hidden"
>
<AnimatedGridPattern
numSquares={30}
maxOpacity={0.1}
duration={3}
repeatDelay={1}
className={cn(
"[mask-image:radial-gradient(1000px_circle_at_center,white,transparent)]",
"inset-x-0 inset-y-[-30%] h-[200%] skew-y-12"
)}
/>
<div className="relative z-10">
{/* 主标题 */}
<div className="text-center mb-12">
<h2 className="text-2xl lg:text-3xl font-bold mb-4">
<span className="bg-gradient-to-r from-primary/80 to-primary text-transparent bg-clip-text">
IT技术服务商
</span>
</h2>
<p className="text-base text-muted-foreground max-w-3xl mx-auto leading-relaxed">
IT技术服务IT成本
</p>
</div>
{/* 服务对比图 */}
<div className="relative max-w-6xl mx-auto">
<div className="grid md:grid-cols-3 gap-6 lg:gap-8">
{serviceComparisons.map((service, index) => (
<div key={service.title} className="relative">
{/* 连接箭头(仅在桌面显示) */}
{index < serviceComparisons.length - 1 && (
<div className="hidden md:block absolute top-1/3 -right-4 lg:-right-6 z-10">
<svg className="w-6 h-6 text-primary/60" fill="none" viewBox="0 0 24 24" strokeWidth={2} stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" d="M13.5 4.5L21 12m0 0l-7.5 7.5M21 12H3" />
</svg>
</div>
)}
<Card className={`relative h-full transition-all duration-300 hover:scale-105 ${
service.isCenter
? 'border-2 border-primary/30 bg-gradient-to-br from-primary/5 to-primary/10 shadow-lg'
: 'border border-border/50 bg-gradient-to-br from-background/90 to-muted/20'
}`}>
<CardHeader className="text-center pb-3">
{/* 图标 */}
<div className="flex justify-center mb-3">
<div className={`relative p-3 rounded-xl ${
service.isCenter
? 'bg-gradient-to-br from-primary/10 to-primary/20'
: 'bg-muted/40'
}`}>
<ServiceIcon type={service.icon} />
{service.isCenter && (
<div className="absolute inset-0 rounded-xl bg-gradient-to-r from-primary/20 via-transparent to-primary/20 opacity-30" />
)}
</div>
</div>
<CardTitle className={`text-lg font-bold ${
service.isCenter ? 'text-primary' : 'text-foreground'
}`}>
{service.title}
</CardTitle>
</CardHeader>
<CardContent className="space-y-2">
{service.isCenter ? (
// 中间卡片的特殊布局
<div className="space-y-3">
<div className="text-center">
<span className="text-sm font-medium text-primary/80"></span>
</div>
<div className="grid grid-cols-1 gap-2">
{service.features.slice(0, 5).map((feature, featureIndex) => (
<div key={featureIndex} className="text-center p-2 bg-primary/5 rounded-lg border border-primary/20">
<span className="text-xs font-medium">{feature}</span>
</div>
))}
</div>
<div className="text-center">
<span className="text-sm font-medium text-primary/80"></span>
</div>
<div className="grid grid-cols-2 gap-2">
{service.features.slice(5, 7).map((feature, featureIndex) => (
<div key={featureIndex} className="text-center p-2 bg-primary/5 rounded border border-primary/20">
<span className="text-xs font-medium">{feature}</span>
</div>
))}
</div>
<div className="grid grid-cols-2 gap-2">
{service.features.slice(7, 9).map((feature, featureIndex) => (
<div key={featureIndex} className="text-center p-2 bg-primary/5 rounded border border-primary/20">
<span className="text-xs font-medium">{feature}</span>
</div>
))}
</div>
</div>
) : (
// 左右两侧卡片的标准布局
<div className="space-y-2">
{service.features.map((feature, featureIndex) => (
<div key={featureIndex} className="flex items-center space-x-2">
<div className="w-1.5 h-1.5 bg-primary/60 rounded-full flex-shrink-0" />
<span className="text-sm text-muted-foreground">{feature}</span>
</div>
))}
</div>
)}
</CardContent>
</Card>
</div>
))}
</div>
</div>
</div>
</section>
);
};