mirror of
https://github.com/joeseesun/wechat-radar.git
synced 2026-09-08 04:58:31 +09:00
105 lines
2.9 KiB
TypeScript
105 lines
2.9 KiB
TypeScript
import Link from 'next/link';
|
|
import { Activity, MessageCircle, AtSign, MoonStar } from 'lucide-react';
|
|
|
|
export interface CardsData {
|
|
active_groups: number;
|
|
total_groups: number;
|
|
total_messages: number;
|
|
mentions: number;
|
|
silent_groups: number;
|
|
avg_per_group: number;
|
|
}
|
|
|
|
export default function StatGrid({ cards, days }: { cards?: CardsData; days: number }) {
|
|
return (
|
|
<div className="grid grid-cols-1 gap-4 md:grid-cols-2 xl:grid-cols-4">
|
|
<Card
|
|
icon={<Activity size={14} className="text-[var(--accent)]" />}
|
|
label="活跃群"
|
|
value={cards?.active_groups ?? '—'}
|
|
sub={cards ? `共扫 ${cards.total_groups} 个群` : '等待扫描'}
|
|
/>
|
|
<Card
|
|
icon={<MessageCircle size={14} className="text-[var(--accent)]" />}
|
|
label="总消息"
|
|
value={cards?.total_messages?.toLocaleString() ?? '—'}
|
|
sub={
|
|
cards
|
|
? `过去 ${days * 24}h · 平均每群 ${cards.avg_per_group} 条`
|
|
: '等待扫描'
|
|
}
|
|
/>
|
|
<Card
|
|
icon={<AtSign size={14} className="text-[var(--warn)]" />}
|
|
label="@ 我的"
|
|
value={cards?.mentions ?? 0}
|
|
sub={cards ? '需要回复' : '等待扫描'}
|
|
accent="warn"
|
|
href="/mentions"
|
|
/>
|
|
<Card
|
|
icon={<MoonStar size={14} className="text-[var(--text-3)]" />}
|
|
label="静默群"
|
|
value={cards?.silent_groups ?? '—'}
|
|
sub={cards ? `过去 ${days * 24}h 无活动` : '等待扫描'}
|
|
/>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
function Card({
|
|
icon,
|
|
label,
|
|
value,
|
|
sub,
|
|
accent,
|
|
href,
|
|
}: {
|
|
icon: React.ReactNode;
|
|
label: string;
|
|
value: number | string;
|
|
sub: string;
|
|
accent?: 'warn';
|
|
href?: string;
|
|
}) {
|
|
const className = `card group relative overflow-hidden px-5 py-4 ${
|
|
href
|
|
? 'block transition-colors hover:border-[rgba(213,162,83,0.5)] hover:bg-[var(--surface-2)] focus:outline-none focus:ring-1 focus:ring-[var(--warn)]'
|
|
: ''
|
|
}`;
|
|
const content = (
|
|
<>
|
|
<div className={`absolute inset-x-0 top-0 h-px ${accent === 'warn' ? 'bg-[var(--warn)]' : 'bg-[var(--accent)]'} opacity-60`} />
|
|
<div className="flex items-center justify-between gap-2 text-[12px] text-[var(--text-2)]">
|
|
<span className="flex items-center gap-1.5">
|
|
{icon}
|
|
<span>{label}</span>
|
|
</span>
|
|
<span className="text-[10px] uppercase tracking-[0.14em] text-[var(--text-3)]">Metric</span>
|
|
</div>
|
|
<div
|
|
className={`mt-3 text-[34px] font-semibold leading-none tabular-nums ${
|
|
accent === 'warn' ? 'text-[var(--warn)]' : 'text-[var(--text)]'
|
|
}`}
|
|
>
|
|
{value}
|
|
</div>
|
|
<div className="mt-2 text-[11px] text-[var(--text-3)]">{sub}</div>
|
|
</>
|
|
);
|
|
|
|
if (href) {
|
|
return (
|
|
<Link href={href} className={className} aria-label={`查看${label}消息`}>
|
|
{content}
|
|
</Link>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<div className={className}>
|
|
{content}
|
|
</div>
|
|
);
|
|
}
|