Primer commit — OPSV Dashboard de siniestralidad vial
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
import { PieChart, Pie, Cell, ResponsiveContainer } from 'recharts'
|
||||
import { calcularKPIs } from '../../utils/calculos'
|
||||
import { COLOR } from '../../utils/colores'
|
||||
|
||||
const sectors = [
|
||||
{ key: 'fatales', label: 'Fatales', color: COLOR.fatales },
|
||||
{ key: 'conLes', label: 'Con Lesionados', color: COLOR.conLes },
|
||||
{ key: 'sinLes', label: 'Sin Lesiones', color: COLOR.sinLes },
|
||||
]
|
||||
|
||||
export default function DonutGravedad({ siniestros }) {
|
||||
const kpis = calcularKPIs(siniestros)
|
||||
const data = sectors.map((sector) => ({
|
||||
name: sector.label,
|
||||
value: kpis[sector.key],
|
||||
color: sector.color,
|
||||
}))
|
||||
|
||||
return (
|
||||
<div className="rounded-[28px] border border-opsv-border bg-opsv-surface p-6 shadow-sm">
|
||||
<div className="mb-6 flex items-center justify-between gap-3">
|
||||
<div>
|
||||
<p className="text-sm font-semibold uppercase tracking-[0.35em] text-opsv-muted">Gravedad por categoría</p>
|
||||
<h3 className="mt-2 text-xl font-black text-opsv-navy">Distribución de siniestros</h3>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="relative h-[320px] w-full">
|
||||
<ResponsiveContainer width="100%" height="100%">
|
||||
<PieChart>
|
||||
<Pie
|
||||
data={data}
|
||||
dataKey="value"
|
||||
nameKey="name"
|
||||
cx="50%"
|
||||
cy="50%"
|
||||
innerRadius={72}
|
||||
outerRadius={110}
|
||||
paddingAngle={4}
|
||||
>
|
||||
{data.map((entry) => (
|
||||
<Cell key={entry.name} fill={entry.color} />
|
||||
))}
|
||||
</Pie>
|
||||
</PieChart>
|
||||
</ResponsiveContainer>
|
||||
|
||||
<div className="pointer-events-none absolute inset-0 flex flex-col items-center justify-center text-center">
|
||||
<span className="text-4xl font-black text-opsv-navy">{kpis.total}</span>
|
||||
<span className="mt-1 text-sm uppercase tracking-[0.3em] text-opsv-muted">Total</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mt-8 grid gap-3 sm:grid-cols-3">
|
||||
{data.map((item) => (
|
||||
<div key={item.name} className="rounded-3xl bg-opsv-bg p-4">
|
||||
<div className="flex items-center gap-2 text-sm font-semibold text-opsv-muted">
|
||||
<span className="h-2.5 w-2.5 rounded-full" style={{ background: item.color }} />
|
||||
{item.name}
|
||||
</div>
|
||||
<div className="mt-3 text-3xl font-black text-opsv-navy">{item.value}</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user