89 lines
2.9 KiB
TypeScript
89 lines
2.9 KiB
TypeScript
'use client'
|
|
|
|
import { PieChart, Pie, Cell, ResponsiveContainer, Tooltip } from 'recharts'
|
|
import type { DeviceStatusBreakdown } from '@/mocks/dashboardData'
|
|
|
|
interface DeviceStatusChartProps {
|
|
data: DeviceStatusBreakdown
|
|
}
|
|
|
|
const COLORS = {
|
|
online: '#22c55e',
|
|
offline: '#64748b',
|
|
advertencia: '#eab308',
|
|
}
|
|
|
|
export default function DeviceStatusChart({ data }: DeviceStatusChartProps) {
|
|
const total = data.online + data.offline + data.advertencia
|
|
const segments = [
|
|
{ name: 'En Línea', value: data.online, color: COLORS.online },
|
|
{ name: 'Fuera de Línea', value: data.offline, color: COLORS.offline },
|
|
{ name: 'Advertencia', value: data.advertencia, color: COLORS.advertencia },
|
|
].filter((s) => s.value > 0)
|
|
|
|
if (total === 0) {
|
|
return (
|
|
<div className="card p-6">
|
|
<h3 className="font-medium text-gray-200 mb-4">Estado de Dispositivos</h3>
|
|
<div className="flex h-48 items-center justify-center text-gray-500 text-sm">
|
|
Sin datos
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
return (
|
|
<div className="card p-6">
|
|
<h3 className="font-medium text-gray-200 mb-4">Estado de Dispositivos</h3>
|
|
<div className="flex flex-col sm:flex-row items-center gap-4">
|
|
<div className="w-full max-w-[200px] h-[200px]">
|
|
<ResponsiveContainer width="100%" height="100%">
|
|
<PieChart>
|
|
<Pie
|
|
data={segments}
|
|
cx="50%"
|
|
cy="50%"
|
|
innerRadius={56}
|
|
outerRadius={80}
|
|
paddingAngle={2}
|
|
dataKey="value"
|
|
>
|
|
{segments.map((entry, index) => (
|
|
<Cell key={index} fill={entry.color} stroke="transparent" />
|
|
))}
|
|
</Pie>
|
|
<Tooltip
|
|
contentStyle={{
|
|
backgroundColor: 'var(--card)',
|
|
border: '1px solid var(--border)',
|
|
borderRadius: '8px',
|
|
}}
|
|
formatter={(value: number) => [
|
|
`${value} (${total > 0 ? Math.round((value / total) * 100) : 0}%)`,
|
|
'',
|
|
]}
|
|
/>
|
|
</PieChart>
|
|
</ResponsiveContainer>
|
|
</div>
|
|
<ul className="flex flex-col gap-2 w-full sm:w-auto">
|
|
{segments.map((s) => (
|
|
<li key={s.name} className="flex items-center justify-between gap-4 text-sm">
|
|
<span className="flex items-center gap-2">
|
|
<span
|
|
className="h-3 w-3 rounded-full shrink-0"
|
|
style={{ backgroundColor: s.color }}
|
|
/>
|
|
{s.name}
|
|
</span>
|
|
<span className="text-gray-400 tabular-nums">
|
|
{s.value} ({total > 0 ? Math.round((s.value / total) * 100) : 0}%)
|
|
</span>
|
|
</li>
|
|
))}
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|