Feat Front Widgets Refactizados y Ajustes Backend

This commit is contained in:
2025-08-22 21:55:03 -03:00
parent 18e6e8d3c0
commit 5de9d6729c
54 changed files with 2443 additions and 1680 deletions

View File

@@ -0,0 +1,91 @@
// src/components/BancasWidget.tsx
import { useState, useEffect } from 'react';
import { ResponsiveWaffle } from '@nivo/waffle';
import { getBancasPorSeccion } from '../apiService';
import type { ProyeccionBancas } from '../types';
import './BancasWidget.css';
// Paleta de colores consistente
const NIVO_COLORS = ["#1f77b4", "#ff7f0e", "#2ca02c", "#d62728", "#9467bd", "#8c564b", "#e377c2", "#7f7f7f", "#bcbd22", "#17becf"];
// Las Secciones Electorales de la Provincia (esto podría venir de la API en el futuro)
const secciones = [
{ id: '1', nombre: 'Primera Sección' },
{ id: '2', nombre: 'Segunda Sección' },
{ id: '3', nombre: 'Tercera Sección' },
{ id: '4', nombre: 'Cuarta Sección' },
{ id: '5', nombre: 'Quinta Sección' },
{ id: '6', nombre: 'Sexta Sección' },
{ id: '7', nombre: 'Séptima Sección' },
{ id: '8', nombre: 'Octava Sección (Capital)' },
];
export const BancasWidget = () => {
const [seccionActual, setSeccionActual] = useState('1'); // Empezamos con la Primera Sección
const [data, setData] = useState<ProyeccionBancas | null>(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
const fetchData = async () => {
setLoading(true);
try {
const result = await getBancasPorSeccion(seccionActual);
setData(result);
} catch (error) {
console.error(`Error cargando datos de bancas para sección ${seccionActual}:`, error);
setData(null); // Limpiar datos en caso de error
} finally {
setLoading(false);
}
};
fetchData();
}, [seccionActual]); // Se ejecuta cada vez que cambia la sección
const waffleData = data?.proyeccion.map(p => ({
id: p.agrupacionNombre,
label: p.agrupacionNombre,
value: p.bancas,
})) || [];
const totalBancas = waffleData.reduce((sum, current) => sum + current.value, 0);
return (
<div className="bancas-widget-container">
<div className="bancas-header">
<h4>Distribución de Bancas</h4>
<select value={seccionActual} onChange={e => setSeccionActual(e.target.value)}>
{secciones.map(s => <option key={s.id} value={s.id}>{s.nombre}</option>)}
</select>
</div>
<div className="waffle-chart-container">
{loading ? <p>Cargando...</p> : !data ? <p>No hay datos disponibles para esta sección.</p> :
<ResponsiveWaffle
data={waffleData}
total={totalBancas}
rows={8}
columns={10}
fillDirection="bottom"
padding={3}
colors={NIVO_COLORS}
borderColor={{ from: 'color', modifiers: [['darker', 0.3]] }}
animate={true}
legends={[
{
anchor: 'bottom',
direction: 'row',
justify: false,
translateX: 0,
translateY: 40,
itemsSpacing: 4,
itemWidth: 100,
itemHeight: 20,
itemTextColor: '#999',
itemDirection: 'left-to-right',
symbolSize: 20,
},
]}
/>}
</div>
</div>
);
};