Primer commit — OPSV Dashboard de siniestralidad vial

This commit is contained in:
2026-04-29 13:39:09 -03:00
commit ca7b159657
67 changed files with 12246 additions and 0 deletions
+67
View File
@@ -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>
)
}