Etapa completada (local) — widgets de Mirada Empresa
This commit is contained in:
74
components/dashboard/segmentacion-bar.tsx
Normal file
74
components/dashboard/segmentacion-bar.tsx
Normal file
@@ -0,0 +1,74 @@
|
||||
'use client'
|
||||
import { useEffect, useState } from 'react'
|
||||
import {
|
||||
isSuppressed,
|
||||
type SegmentacionData,
|
||||
type SuppressedPayload,
|
||||
type DashboardFilters,
|
||||
} from '@/lib/dashboard-types'
|
||||
import { queries } from '@/lib/dashboard-queries'
|
||||
import { WidgetShell } from './widget-shell'
|
||||
|
||||
export function SegmentacionBar({ surveyId, filters }: { surveyId: string; filters: DashboardFilters }) {
|
||||
const [data, setData] = useState<SegmentacionData | SuppressedPayload | null>(null)
|
||||
const [error, setError] = useState(false)
|
||||
|
||||
useEffect(() => {
|
||||
setData(null); setError(false)
|
||||
queries.meSegmentacion(surveyId, filters)
|
||||
.then((d) => setData(d as SegmentacionData | SuppressedPayload))
|
||||
.catch(() => setError(true))
|
||||
}, [surveyId, JSON.stringify(filters)])
|
||||
|
||||
const status = error ? 'error' : data === null ? 'loading' : isSuppressed(data) ? 'suppressed' : 'ok'
|
||||
const ok = status === 'ok' ? (data as SegmentacionData) : null
|
||||
|
||||
return (
|
||||
<WidgetShell
|
||||
title="Dónde se concentra la carga"
|
||||
subtitle="4.1 cruzado con 2.6 (nivel) y 2.7 (modalidad) — % de cuidadores por segmento"
|
||||
status={status}
|
||||
n={ok?.n}
|
||||
colSpan={12}
|
||||
>
|
||||
{ok && (
|
||||
<div className="db-grid" style={{ gap: '24px' }}>
|
||||
<div style={{ gridColumn: 'span 6' }}>
|
||||
<p className="db-widget-subtitle" style={{ marginBottom: 8 }}>Por nivel organizacional</p>
|
||||
{ok.por_nivel.length === 0 && (
|
||||
<p className="db-suppressed-hint">Ningún nivel alcanza n≥5 con este filtro.</p>
|
||||
)}
|
||||
<ul className="db-bar-list" aria-label="Cuidadores por nivel organizacional">
|
||||
{ok.por_nivel.map((row) => (
|
||||
<li key={row.nivel} className="db-bar-item">
|
||||
<span className="db-bar-label">{row.nivel}</span>
|
||||
<div className="db-bar-track">
|
||||
<div className="db-bar-fill" style={{ width: `${row.pct}%`, background: '#5e7299' }} />
|
||||
</div>
|
||||
<span className="db-bar-pct">{row.pct}%</span>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
<div style={{ gridColumn: 'span 6' }}>
|
||||
<p className="db-widget-subtitle" style={{ marginBottom: 8 }}>Por modalidad de trabajo</p>
|
||||
{ok.por_modalidad.length === 0 && (
|
||||
<p className="db-suppressed-hint">Ninguna modalidad alcanza n≥5 con este filtro.</p>
|
||||
)}
|
||||
<ul className="db-bar-list" aria-label="Cuidadores por modalidad de trabajo">
|
||||
{ok.por_modalidad.map((row) => (
|
||||
<li key={row.modalidad} className="db-bar-item">
|
||||
<span className="db-bar-label">{row.modalidad}</span>
|
||||
<div className="db-bar-track">
|
||||
<div className="db-bar-fill" style={{ width: `${row.pct}%`, background: '#5e7299' }} />
|
||||
</div>
|
||||
<span className="db-bar-pct">{row.pct}%</span>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</WidgetShell>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user