Files
motor-de-encuestas/components/dashboard/piramide-demografica.tsx
2026-06-05 07:18:10 -03:00

81 lines
3.3 KiB
TypeScript

'use client'
import { useEffect, useState } from 'react'
import { isSuppressed, type PiramideData } from '@/lib/dashboard-types'
import { queries } from '@/lib/dashboard-queries'
import type { DashboardFilters } from '@/lib/dashboard-types'
import { WidgetShell } from './widget-shell'
import { ETARIO_ORDER } from '@/lib/dashboard-utils'
const GENERO_COLOR: Record<string, string> = {
'Femenino': '#EE761A',
'Masculino': '#43BBC8',
'No binario/Otro': '#F8AD13',
'Prefiero no decir':'#6b7280',
}
export function PiramideDemografica({ surveyId, filters }: { surveyId: string; filters: DashboardFilters }) {
const [data, setData] = useState<PiramideData | null>(null)
const [sup, setSup] = useState(false)
useEffect(() => {
setData(null); setSup(false)
queries.piramide(surveyId, filters)
.then(d => { if (isSuppressed(d)) setSup(true); else setData(d as PiramideData) })
.catch(() => {})
}, [surveyId, JSON.stringify(filters)])
const status = !data && !sup ? 'loading' : sup ? 'suppressed' : 'ok'
const maxN = data ? Math.max(...data.data.map(c => c.n ?? 0), 1) : 1
const generos = ['Femenino','Masculino','No binario/Otro']
return (
<WidgetShell title="👥 Pirámide demográfica" status={status} n={data?.n_total} colSpan={6}>
{data && (
<div className="db-piramide">
<div className="db-piramide-legend" aria-label="Leyenda">
{generos.map(g => (
<span key={g} className="db-legend-item">
<span className="db-legend-dot" style={{ background: GENERO_COLOR[g] }} />
{g}
</span>
))}
</div>
{ETARIO_ORDER.filter(e => e !== 'Prefiero no decir').map(etario => {
const row = generos.map(gen => {
const cell = data.data.find(c => c.etario === etario && c.genero === gen)
return { gen, n: cell?.n ?? null, suppressed: cell?.suppressed ?? true }
})
return (
<div key={etario} className="db-piramide-row" role="row" aria-label={etario}>
<span className="db-piramide-label">{etario}</span>
<div className="db-piramide-bars">
{row.map(({ gen, n, suppressed }) => (
<div key={gen} className="db-piramide-bar-wrap"
style={{ flex: `0 0 ${Math.max(10, (n ?? 0) / maxN * 100)}%` }}>
<div className="db-piramide-bar"
style={{
width: suppressed ? '100%' : `${(n ?? 0) / maxN * 100}%`,
background: suppressed ? '#2a3547' : GENERO_COLOR[gen],
opacity: suppressed ? 0.4 : 1,
}}
title={suppressed ? 'Datos insuficientes' : `${gen}: n=${n}`}
role="cell"
aria-label={suppressed ? `${gen}: suprimido` : `${gen}: ${n}`}
/>
</div>
))}
</div>
<span className="db-piramide-n">
{row.every(r => r.suppressed) ? '🔒' : row.reduce((s, r) => s + (r.n ?? 0), 0)}
</span>
</div>
)
})}
</div>
)}
</WidgetShell>
)
}