127 lines
4.3 KiB
TypeScript
127 lines
4.3 KiB
TypeScript
'use client'
|
|
import { useEffect, useState } from 'react'
|
|
import {
|
|
isSuppressed,
|
|
type RiesgoRotacionData,
|
|
type AusentismoData,
|
|
type PresentismoData,
|
|
type CarreraCongeladaData,
|
|
type SuppressedPayload,
|
|
type DashboardFilters,
|
|
} from '@/lib/dashboard-types'
|
|
import { queries } from '@/lib/dashboard-queries'
|
|
import { WidgetShell } from './widget-shell'
|
|
|
|
type Riesgo = RiesgoRotacionData | SuppressedPayload
|
|
type Ausentismo = AusentismoData | SuppressedPayload
|
|
type Presentismo = PresentismoData | SuppressedPayload
|
|
type Carrera = CarreraCongeladaData | SuppressedPayload
|
|
|
|
interface Senal {
|
|
label: string
|
|
pct: number | null
|
|
color: 'rose' | 'amber'
|
|
}
|
|
|
|
// Combina E2 (riesgo) + E3 (ausentismo) + E4 (presentismo) — núcleo — y
|
|
// E5 (carrera congelada) — [SEC] — en una sola card de 4 barras, igual al
|
|
// mockup ("Señales de impacto laboral"). Cada señal se suprime POR FILA
|
|
// (n<5 individual) sin tumbar las demás; la card entera solo se suprime
|
|
// si las 4 vienen suprimidas a la vez.
|
|
export function SenalesImpactoBar({ surveyId, filters }: { surveyId: string; filters: DashboardFilters }) {
|
|
const [riesgo, setRiesgo] = useState<Riesgo | null>(null)
|
|
const [ausentismo, setAusentismo] = useState<Ausentismo | null>(null)
|
|
const [presentismo, setPresentismo] = useState<Presentismo | null>(null)
|
|
const [carrera, setCarrera] = useState<Carrera | null>(null)
|
|
const [error, setError] = useState(false)
|
|
|
|
useEffect(() => {
|
|
setRiesgo(null); setAusentismo(null); setPresentismo(null); setCarrera(null); setError(false)
|
|
Promise.all([
|
|
queries.meRiesgoRotacion(surveyId, filters),
|
|
queries.meAusentismo(surveyId, filters),
|
|
queries.mePresentismo(surveyId, filters),
|
|
queries.meCarreraCongelada(surveyId, filters),
|
|
])
|
|
.then(([r, a, p, c]) => {
|
|
setRiesgo(r as Riesgo)
|
|
setAusentismo(a as Ausentismo)
|
|
setPresentismo(p as Presentismo)
|
|
setCarrera(c as Carrera)
|
|
})
|
|
.catch(() => setError(true))
|
|
}, [surveyId, JSON.stringify(filters)])
|
|
|
|
const loading = riesgo === null || ausentismo === null || presentismo === null || carrera === null
|
|
const allSuppressed =
|
|
!loading &&
|
|
isSuppressed(riesgo) && isSuppressed(ausentismo) && isSuppressed(presentismo) && isSuppressed(carrera)
|
|
|
|
const status = error ? 'error' : loading ? 'loading' : allSuppressed ? 'suppressed' : 'ok'
|
|
|
|
const rows: Senal[] = !loading
|
|
? [
|
|
{
|
|
label: 'Presentismo',
|
|
pct: !isSuppressed(presentismo) ? presentismo.pct_presentismo : null,
|
|
color: 'amber',
|
|
},
|
|
{
|
|
label: 'Ausentismo frecuente',
|
|
pct: !isSuppressed(ausentismo) ? ausentismo.pct_ausentismo_recurrente : null,
|
|
color: 'amber',
|
|
},
|
|
{
|
|
label: 'Riesgo de salida',
|
|
pct: !isSuppressed(riesgo) ? riesgo.pct_riesgo : null,
|
|
color: 'rose',
|
|
},
|
|
{
|
|
label: 'Carrera congelada',
|
|
pct: !isSuppressed(carrera) ? carrera.pct_carrera_congelada : null,
|
|
color: 'rose',
|
|
},
|
|
]
|
|
: []
|
|
|
|
const repN = !loading && !isSuppressed(riesgo) ? riesgo.n_cuidadores : undefined
|
|
|
|
return (
|
|
<WidgetShell
|
|
title="Señales de impacto laboral"
|
|
subtitle="7.2 · 7.3 · 7.6 · 7.5 — sobre la población cuidadora"
|
|
status={status}
|
|
n={repN}
|
|
colSpan={6}
|
|
>
|
|
{!loading && (
|
|
<ul className="db-bar-list" aria-label="Señales de impacto laboral">
|
|
{rows.map((row) => (
|
|
<li key={row.label} className="db-bar-item">
|
|
<span className="db-bar-label">{row.label}</span>
|
|
{row.pct !== null ? (
|
|
<>
|
|
<div className="db-bar-track">
|
|
<div
|
|
className="db-bar-fill"
|
|
style={{ width: `${row.pct}%`, background: row.color === 'rose' ? '#f06b6b' : '#f0b429' }}
|
|
/>
|
|
</div>
|
|
<span className="db-bar-pct">{row.pct}%</span>
|
|
</>
|
|
) : (
|
|
<>
|
|
<div className="db-bar-track" />
|
|
<span className="db-bar-pct" style={{ color: '#6b7280' }}>
|
|
n<5
|
|
</span>
|
|
</>
|
|
)}
|
|
</li>
|
|
))}
|
|
</ul>
|
|
)}
|
|
</WidgetShell>
|
|
)
|
|
}
|