refactor completo + truncate de base de datos + reingenieria dashboard
This commit is contained in:
@@ -4,14 +4,57 @@ import { isSuppressed, type KpiData, type SuppressedPayload } from '@/lib/dashbo
|
||||
import { queries } from '@/lib/dashboard-queries'
|
||||
import type { DashboardFilters } from '@/lib/dashboard-types'
|
||||
|
||||
interface KpiCardProps { label: string; value: string; sub?: string }
|
||||
const KPI_DEFS = [
|
||||
{
|
||||
title: 'CUIDADORES ACTIVOS',
|
||||
subtitle: '1.6 + 1.13 · % de la plantilla con responsabilidades de cuidado de otros',
|
||||
getValue: (d: KpiData) => `${d.pct_cuidadores}%`,
|
||||
getN: (d: KpiData) => `n = ${d.n}`,
|
||||
},
|
||||
{
|
||||
title: 'FRECUENCIA DE AUSENTISMO',
|
||||
subtitle: '5.2 · % con ausencias laborales recurrentes (4 o más veces al año)',
|
||||
getValue: (d: KpiData) => `${d.pct_ausencias}%`,
|
||||
getN: () => 'ausencias frecuentes',
|
||||
},
|
||||
{
|
||||
title: 'BIENESTAR',
|
||||
subtitle: '4.3 · autorreporte de bienestar general · escala 1–5',
|
||||
getValue: (d: KpiData) => d.score_bienestar !== null ? d.score_bienestar.toFixed(1) : '—',
|
||||
getN: () => '/ 5',
|
||||
},
|
||||
] as const
|
||||
|
||||
function KpiCard({ label, value, sub }: KpiCardProps) {
|
||||
interface KpiCardProps {
|
||||
title: string
|
||||
subtitle: string
|
||||
value: string
|
||||
valueNote: string
|
||||
suppressed: boolean
|
||||
loading: boolean
|
||||
}
|
||||
|
||||
function KpiCard({ title, subtitle, value, valueNote, suppressed, loading }: KpiCardProps) {
|
||||
return (
|
||||
<div className="db-kpi-card">
|
||||
<span className="db-kpi-value" aria-live="polite">{value}</span>
|
||||
<span className="db-kpi-label">{label}</span>
|
||||
{sub && <span className="db-kpi-sub">{sub}</span>}
|
||||
<span className="db-kpi-title">{title}</span>
|
||||
<span className="db-kpi-subtitle">{subtitle}</span>
|
||||
|
||||
{loading && (
|
||||
<div className="db-skeleton-block" style={{ height: 36, margin: '10px 0 4px', borderRadius: 6 }} />
|
||||
)}
|
||||
{!loading && suppressed && (
|
||||
<div className="db-kpi-suppressed-block" role="status">
|
||||
<span className="db-suppressed-icon" aria-hidden="true">🔒</span>
|
||||
<span className="db-kpi-value db-kpi-value-suppressed">n < 5</span>
|
||||
</div>
|
||||
)}
|
||||
{!loading && !suppressed && (
|
||||
<>
|
||||
<span className="db-kpi-value" aria-live="polite">{value}</span>
|
||||
<span className="db-kpi-note">{valueNote}</span>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -30,33 +73,24 @@ export function KpiCards({ surveyId, filters }: Props) {
|
||||
}, [surveyId, JSON.stringify(filters)])
|
||||
|
||||
if (error) return <p className="db-error">Error al cargar KPIs</p>
|
||||
if (!data) {
|
||||
return (
|
||||
<div className="db-kpi-row">
|
||||
{[1,2,3,4].map(i => <div key={i} className="db-kpi-card db-skeleton-block" style={{height:96}} />)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
if (isSuppressed(data)) {
|
||||
return (
|
||||
<div className="db-kpi-row">
|
||||
{[1,2,3,4].map(i => (
|
||||
<div key={i} className="db-kpi-card db-suppressed-card">
|
||||
<span className="db-suppressed-icon">🔒</span>
|
||||
<span className="db-kpi-sub">n < 5</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const d = data as KpiData
|
||||
const loading = data === null
|
||||
const suppressed = !loading && isSuppressed(data)
|
||||
const ok = !loading && !suppressed
|
||||
|
||||
return (
|
||||
<div className="db-kpi-row">
|
||||
<KpiCard label="Cuidadores activos" value={`${d.pct_cuidadores}%`} sub={`n = ${d.n}`} />
|
||||
<KpiCard label="Score bienestar (0-100)" value={d.score_bienestar !== null ? `${d.score_bienestar}` : '—'} />
|
||||
<KpiCard label="Ausencias frecuentes" value={`${d.pct_ausencias}%`} />
|
||||
<KpiCard label="Total respuestas" value={d.n.toLocaleString('es-PY')} sub="en este corte" />
|
||||
{KPI_DEFS.map((def) => (
|
||||
<KpiCard
|
||||
key={def.title}
|
||||
title={def.title}
|
||||
subtitle={def.subtitle}
|
||||
value={ok ? def.getValue(data as KpiData) : '—'}
|
||||
valueNote={ok ? def.getN(data as KpiData) : ''}
|
||||
suppressed={suppressed}
|
||||
loading={loading}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user