Dashboard design improved
This commit is contained in:
88
src/components/dashboard/DeviceStatusChart.tsx
Normal file
88
src/components/dashboard/DeviceStatusChart.tsx
Normal file
@@ -0,0 +1,88 @@
|
||||
'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>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user