102 lines
2.9 KiB
TypeScript
102 lines
2.9 KiB
TypeScript
'use client'
|
|
import { Card } from '@/components/ui'
|
|
import { Ticket, Clock, CheckCircle, TrendingUp, AlertCircle, BarChart3 } from 'lucide-react'
|
|
|
|
interface StatsData {
|
|
total: number
|
|
open: number
|
|
in_progress: number
|
|
resolved: number
|
|
closed: number
|
|
thisMonth: number
|
|
avgDuration: number
|
|
slaRate: number
|
|
}
|
|
|
|
interface StatCardProps {
|
|
title: string
|
|
value: string | number
|
|
icon: React.ReactNode
|
|
color: string
|
|
}
|
|
|
|
function StatCard({ title, value, icon, color }: StatCardProps) {
|
|
const displayValue = (value !== undefined && value !== null && !(typeof value === 'number' && isNaN(value))) ? value : '—'
|
|
return (
|
|
<Card>
|
|
<div
|
|
className="dark-bg-card"
|
|
style={{ padding: '1.5rem', display: 'flex', alignItems: 'center', justifyContent: 'space-between', minHeight: '100px' }}
|
|
>
|
|
<div>
|
|
<p className="card-label">{title}</p>
|
|
<p className="card-value">{displayValue}</p>
|
|
</div>
|
|
<div
|
|
className={color}
|
|
style={{ width: '2.5rem', height: '2.5rem', borderRadius: '0.5rem', display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}
|
|
>
|
|
{icon}
|
|
</div>
|
|
</div>
|
|
</Card>
|
|
)
|
|
}
|
|
|
|
export default function StatsOverview({ stats }: { stats: StatsData | null }) {
|
|
if (!stats) return null
|
|
|
|
return (
|
|
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: '1rem' }}>
|
|
<StatCard
|
|
title="总工单数"
|
|
value={stats.total}
|
|
icon={<Ticket size={20} style={{ color: 'white' }} />}
|
|
color="bg-blue-600"
|
|
/>
|
|
<StatCard
|
|
title="本月工单"
|
|
value={stats.thisMonth}
|
|
icon={<TrendingUp size={20} style={{ color: 'white' }} />}
|
|
color="bg-cyan-500"
|
|
/>
|
|
<StatCard
|
|
title="平均处理时长"
|
|
value={`${stats.avgDuration} 分钟`}
|
|
icon={<Clock size={20} style={{ color: 'white' }} />}
|
|
color="bg-amber-500"
|
|
/>
|
|
<StatCard
|
|
title="整体服务可用性"
|
|
value={`${stats.slaRate}%`}
|
|
icon={<CheckCircle size={20} style={{ color: 'white' }} />}
|
|
color={stats.slaRate >= 90 ? 'bg-emerald-500' : stats.slaRate >= 70 ? 'bg-amber-500' : 'bg-red-500'}
|
|
/>
|
|
<StatCard
|
|
title="待处理"
|
|
value={stats.open}
|
|
icon={<AlertCircle size={20} style={{ color: 'white' }} />}
|
|
color="bg-red-500"
|
|
/>
|
|
<StatCard
|
|
title="处理中"
|
|
value={stats.in_progress}
|
|
icon={<Clock size={20} style={{ color: 'white' }} />}
|
|
color="bg-amber-500"
|
|
/>
|
|
<StatCard
|
|
title="已解决"
|
|
value={stats.resolved}
|
|
icon={<CheckCircle size={20} style={{ color: 'white' }} />}
|
|
color="bg-emerald-500"
|
|
/>
|
|
<StatCard
|
|
title="已关闭"
|
|
value={stats.closed}
|
|
icon={<BarChart3 size={20} style={{ color: 'white' }} />}
|
|
color="bg-slate-500"
|
|
/>
|
|
</div>
|
|
)
|
|
}
|