54 lines
1.9 KiB
TypeScript
54 lines
1.9 KiB
TypeScript
import { RefreshCw } from 'lucide-react';
|
|
import { formatRefreshTime } from '../model';
|
|
|
|
interface OverviewHeaderProps {
|
|
activeYear: number;
|
|
availableYears: number[];
|
|
lastRefreshAt: number;
|
|
refreshing: boolean;
|
|
onSelectYear: (year: number) => void;
|
|
onRefresh: () => void;
|
|
}
|
|
|
|
export function OverviewHeader({
|
|
activeYear,
|
|
availableYears,
|
|
lastRefreshAt,
|
|
refreshing,
|
|
onSelectYear,
|
|
onRefresh,
|
|
}: OverviewHeaderProps) {
|
|
return (
|
|
<div className="bg-white rounded-xl border border-slate-100 px-3 py-1.5 text-[11px] text-slate-400 flex items-center justify-between gap-2">
|
|
<span className="truncate">{lastRefreshAt ? `更新于 ${formatRefreshTime(lastRefreshAt)}` : '数据自 2025-01-01 起'}</span>
|
|
<div className="flex items-center gap-2 flex-shrink-0">
|
|
<div className="flex items-center gap-1 bg-slate-50 rounded-lg p-0.5">
|
|
{availableYears.map(y => {
|
|
const active = y === activeYear;
|
|
return (
|
|
<button
|
|
key={y}
|
|
onClick={() => onSelectYear(y)}
|
|
className={`px-2 py-0.5 text-[11px] font-bold rounded-md transition-all ${
|
|
active ? 'bg-white text-blue-600 shadow-sm' : 'text-slate-400 hover:text-slate-600'
|
|
}`}
|
|
>
|
|
{y}
|
|
</button>
|
|
);
|
|
})}
|
|
</div>
|
|
<button
|
|
onClick={onRefresh}
|
|
disabled={refreshing}
|
|
className="flex items-center gap-1 px-2 py-0.5 rounded-lg bg-blue-50 text-blue-600 hover:bg-blue-100 disabled:opacity-60 disabled:cursor-not-allowed transition-colors"
|
|
title="手动刷新(绕过缓存)"
|
|
>
|
|
<RefreshCw size={11} className={refreshing ? 'animate-spin' : ''} strokeWidth={2.6} />
|
|
<span className="text-[11px] font-bold">刷新</span>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|