- 重构 Button、Card、Badge、Input、Textarea 等基础组件 - 新增 Accordion、Alert、Dialog、Dropdown、Form 等 shadcn/ui 组件 - 新增 AnimatedCounter、StatsShowcase、MetricCard 等数据展示组件 - 新增 ScrollReveal 滚动动画组件 - 重构 Toast 通知系统与 Tooltip 提示组件 - 更新设计令牌系统,对齐新品牌视觉
117 lines
5.0 KiB
TypeScript
117 lines
5.0 KiB
TypeScript
'use client';
|
|
|
|
import { ArrowUpRight, Database, Users, BarChart3, FileText, Truck, Building2 } from 'lucide-react';
|
|
import { InkCard } from '@/components/ui/ink-wash/InkCard';
|
|
import type { LucideIcon } from 'lucide-react';
|
|
|
|
interface ProductCardProps {
|
|
title: string;
|
|
description: string;
|
|
href: string;
|
|
index: number;
|
|
status?: '研发中' | '内测中' | '已发布';
|
|
}
|
|
|
|
const productIcons: LucideIcon[] = [Database, Users, FileText, BarChart3, Truck, Building2];
|
|
|
|
const PRODUCT_COLORS = [
|
|
{ bg: 'rgba(var(--color-brand-rgb), 0.08)', text: 'var(--color-brand)', border: 'rgba(var(--color-brand-rgb), 0.12)' },
|
|
{ bg: 'rgba(var(--color-accent-blue-rgb), 0.08)', text: 'var(--color-accent-blue)', border: 'rgba(var(--color-accent-blue-rgb), 0.12)' },
|
|
{ bg: 'rgba(var(--color-accent-purple-rgb), 0.08)', text: 'var(--color-accent-purple)', border: 'rgba(var(--color-accent-purple-rgb), 0.12)' },
|
|
{ bg: 'rgba(var(--color-accent-cyan-rgb), 0.08)', text: 'var(--color-accent-cyan)', border: 'rgba(var(--color-accent-cyan-rgb), 0.12)' },
|
|
{ bg: 'rgba(var(--color-brand-rgb), 0.08)', text: 'var(--color-brand)', border: 'rgba(var(--color-brand-rgb), 0.12)' },
|
|
{ bg: 'rgba(var(--color-accent-blue-rgb), 0.08)', text: 'var(--color-accent-blue)', border: 'rgba(var(--color-accent-blue-rgb), 0.12)' },
|
|
] as const;
|
|
|
|
const productConfig: { icon: LucideIcon; color: { bg: string; text: string; border: string } }[] = productIcons.map((icon, i) => ({
|
|
icon,
|
|
color: PRODUCT_COLORS[i % PRODUCT_COLORS.length] ?? PRODUCT_COLORS[0],
|
|
}));
|
|
|
|
const defaultConfig = {
|
|
icon: Database,
|
|
color: PRODUCT_COLORS[0],
|
|
};
|
|
|
|
const statusConfig = {
|
|
'研发中': { bg: 'rgba(var(--color-brand-rgb), 0.06)', text: 'var(--color-brand)', border: 'rgba(var(--color-brand-rgb), 0.12)' },
|
|
'内测中': { bg: 'rgba(var(--color-warning-rgb), 0.06)', text: 'var(--color-warning)', border: 'rgba(var(--color-warning-rgb), 0.12)' },
|
|
'已发布': { bg: 'rgba(var(--color-success-rgb), 0.06)', text: 'var(--color-success)', border: 'rgba(var(--color-success-rgb), 0.12)' },
|
|
} as const;
|
|
|
|
export function ProductCard({ title, description, href, index, status }: ProductCardProps) {
|
|
const config = productConfig[index] ?? defaultConfig;
|
|
const IconComponent = config.icon;
|
|
const statusStyle = status ? statusConfig[status] : null;
|
|
|
|
return (
|
|
<InkCard
|
|
href={href}
|
|
padding="md" // 使用统一的 padding 规范 (p-5 sm:p-6 md:p-7)
|
|
glow={true}
|
|
mouseFollow={true}
|
|
interactive={true}
|
|
className="group h-full"
|
|
>
|
|
{/* 产品图标 */}
|
|
<div className="flex items-start justify-between mb-4">
|
|
<div
|
|
className="w-11 h-11 rounded-xl flex items-center justify-center flex-shrink-0"
|
|
style={{ backgroundColor: config.color.bg }}
|
|
>
|
|
<IconComponent
|
|
className="w-5 h-5"
|
|
style={{ color: config.color.text }}
|
|
strokeWidth={1.8}
|
|
/>
|
|
</div>
|
|
|
|
{/* 状态标签 + 序号 */}
|
|
<div className="flex items-center gap-2 flex-shrink-0">
|
|
{status && statusStyle && (
|
|
<span
|
|
className="text-[10px] font-medium px-2 py-0.5 rounded-full border whitespace-nowrap"
|
|
style={{
|
|
backgroundColor: statusStyle.bg,
|
|
color: statusStyle.text,
|
|
borderColor: statusStyle.border,
|
|
}}
|
|
>
|
|
{status}
|
|
</span>
|
|
)}
|
|
<span className="text-xs font-mono tracking-widest text-[var(--color-text-subtle)]">
|
|
{String(index + 1).padStart(2, '0')}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
|
|
{/* 标题 */}
|
|
<h3 className="text-base font-semibold mb-2 leading-snug tracking-tight text-[var(--color-text-primary)] group-hover:text-[var(--color-brand)] transition-colors">
|
|
{title}
|
|
</h3>
|
|
|
|
{/* 描述 */}
|
|
<p className="text-sm text-[var(--color-text-muted)] leading-relaxed line-clamp-3 mb-4">
|
|
{description}
|
|
</p>
|
|
|
|
{/* 研发中/内测中 提示 */}
|
|
{(status === '研发中' || status === '内测中') && (
|
|
<div className="flex items-center gap-1.5 text-xs text-[var(--color-brand)]/70 mb-4 px-3 py-2 rounded-lg bg-[var(--color-brand-bg)]/50">
|
|
<svg className="w-3.5 h-3.5 animate-spin" viewBox="0 0 24 24" fill="none">
|
|
<circle cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeDasharray="32 16" />
|
|
</svg>
|
|
<span>{status === '研发中' ? '正在积极开发中,欢迎提前交流需求' : '即将上线,欢迎预约内测体验'}</span>
|
|
</div>
|
|
)}
|
|
|
|
{/* CTA 链接 */}
|
|
<div className="flex items-center gap-1.5 text-sm font-medium text-[var(--color-text-subtle)] group-hover:text-[var(--color-brand)] transition-colors min-h-[44px] mt-auto">
|
|
<span>{status === '研发中' ? '了解规划' : status === '内测中' ? '申请内测' : '了解更多'}</span>
|
|
<ArrowUpRight className="w-4 h-4" strokeWidth={2} />
|
|
</div>
|
|
</InkCard>
|
|
);
|
|
}
|