// src/features/legislativas/provinciales/BancasWidget.tsx (Corregido) import { useState, useEffect, useMemo } from 'react'; import { useQuery } from '@tanstack/react-query'; import Select from 'react-select'; // --- CAMBIO: Importar react-select --- import { getBancasPorSeccion, getSeccionesElectoralesConCargos } from '../../../apiService'; import type { ProyeccionBancas, MunicipioSimple } from '../../../types/types'; import { Tooltip } from 'react-tooltip'; import './BancasWidget.css'; import type { Property } from 'csstype'; type CamaraType = 'diputados' | 'senadores'; // --- CAMBIO: Estilos para el nuevo selector --- const customSelectStyles = { control: (base: any) => ({ ...base, minWidth: '200px', border: '1px solid #ced4da', boxShadow: 'none', '&:hover': { borderColor: '#86b7fe' } }), menu: (base: any) => ({ ...base, zIndex: 10 }), }; const WaffleDisplay = ({ data }: { data: ProyeccionBancas['proyeccion'] }) => { // El componente WaffleDisplay no necesita cambios en su lógica return (
{data.map(partido => ( partido.bancas > 0 && (
{Array.from({ length: partido.bancas }).map((_, index) => (
))}
) ))}
); }; export const BancasWidget = () => { const [secciones, setSecciones] = useState([]); // --- CAMBIO: Adaptar el estado para react-select --- const [selectedSeccion, setSelectedSeccion] = useState<{ value: string; label: string } | null>(null); const [camaraActiva, setCamaraActiva] = useState('diputados'); useEffect(() => { const fetchSecciones = async () => { try { const seccionesData = await getSeccionesElectoralesConCargos(); if (seccionesData && seccionesData.length > 0) { // --- LÓGICA DE ORDENAMIENTO --- const orden = new Map([ ['Capital', 0], ['Primera', 1], ['Segunda', 2], ['Tercera', 3], ['Cuarta', 4], ['Quinta', 5], ['Sexta', 6], ['Séptima', 7] ]); const getOrden = (nombre: string) => { const match = nombre.match(/Capital|Primera|Segunda|Tercera|Cuarta|Quinta|Sexta|Séptima/); return match ? orden.get(match[0]) ?? 99 : 99; }; // Ordenamos el array de datos ANTES de guardarlo en el estado seccionesData.sort((a, b) => getOrden(a.nombre) - getOrden(b.nombre)); setSecciones(seccionesData); if (!selectedSeccion) { setSelectedSeccion({ value: seccionesData[0].id, label: seccionesData[0].nombre }); } } } catch (err) { console.error("Error cargando secciones electorales:", err); } }; fetchSecciones(); }, [selectedSeccion]); // --- CAMBIO: Formatear opciones para react-select --- const seccionOptions = useMemo(() => secciones.map(s => ({ value: s.id, label: s.nombre })), [secciones]); const seccionSeleccionada = useMemo(() => secciones.find(s => s.id === selectedSeccion?.value), [secciones, selectedSeccion]); const camarasDisponibles = useMemo(() => seccionSeleccionada?.camarasDisponibles || [], [seccionSeleccionada]); useEffect(() => { if (seccionSeleccionada && camarasDisponibles.length > 0) { if (!camarasDisponibles.includes(camaraActiva)) { setCamaraActiva(camarasDisponibles[0]); } } }, [seccionSeleccionada, camarasDisponibles, camaraActiva]); const { data, isLoading, error } = useQuery({ queryKey: ['bancasPorSeccion', selectedSeccion?.value, camaraActiva], queryFn: () => getBancasPorSeccion(1,selectedSeccion!.value, camaraActiva), enabled: !!selectedSeccion && camarasDisponibles.includes(camaraActiva), retry: (failureCount, error: any) => { if (error.response?.status === 404) return false; return failureCount < 3; }, }); const getErrorMessage = () => { if (error) { if ((error as any).response?.status === 404) { return `La proyección para ${camaraActiva} en esta sección aún no está disponible.`; } return "No se pudo conectar para obtener los datos."; } return null; }; const errorMessage = getErrorMessage(); // --- CAMBIO: Ordenar la leyenda (y por lo tanto el gráfico) de más a menos bancas --- const leyendaData = useMemo(() => data?.proyeccion .filter(p => p.bancas > 0) .sort((a, b) => b.bancas - a.bancas) // Ordena de mayor a menor || [], [data]); const totalBancasEnJuego = useMemo(() => data?.proyeccion.reduce((sum, p) => sum + p.bancas, 0) || 0, [data]); return (

Bancas Proyectadas: {totalBancasEnJuego}