import { useState, useMemo, useEffect } from 'react'; import { useQuery } from '@tanstack/react-query'; import Select from 'react-select'; import { getSeccionesElectorales, getRankingMunicipiosPorSeccion } from '../apiService'; import type { MunicipioSimple, ApiResponseRankingMunicipio, RankingPartido } from '../types/types'; import './ResultadosTablaSeccionWidget.css'; type DisplayMode = 'porcentaje' | 'votos' | 'ambos'; type DisplayOption = { value: DisplayMode; label: string; }; const displayModeOptions: readonly DisplayOption[] = [ { value: 'porcentaje', label: 'Ver Porcentajes' }, { value: 'votos', label: 'Ver Votos' }, { value: 'ambos', label: 'Ver Ambos' }, ]; const customSelectStyles = { control: (base: any) => ({ ...base, minWidth: '200px', border: '1px solid #ced4da', boxShadow: 'none', '&:hover': { borderColor: '#86b7fe' } }), menu: (base: any) => ({ ...base, zIndex: 10 }), }; const formatPercent = (porcentaje: number) => `${porcentaje.toFixed(2).replace('.', ',')}%`; // Nueva función para formatear votos con separador de miles const formatVotos = (votos: number) => votos.toLocaleString('es-AR'); // --- NUEVO COMPONENTE HELPER PARA RENDERIZAR CELDAS --- const CellRenderer = ({ partido, mode }: { partido?: RankingPartido, mode: DisplayMode }) => { if (!partido) { return -; } switch (mode) { case 'votos': return {formatVotos(partido.votos)}; case 'ambos': return (
{formatVotos(partido.votos)} {formatPercent(partido.porcentaje)}
); case 'porcentaje': default: return {formatPercent(partido.porcentaje)}; } }; export const ResultadosRankingMunicipioWidget = () => { const [secciones, setSecciones] = useState([]); const [selectedSeccion, setSelectedSeccion] = useState<{ value: string; label: string } | null>(null); const [displayMode, setDisplayMode] = useState(displayModeOptions[0]); useEffect(() => { const fetchSecciones = async () => { const seccionesData = await getSeccionesElectorales(); if (seccionesData && seccionesData.length > 0) { 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; }; seccionesData.sort((a, b) => getOrden(a.nombre) - getOrden(b.nombre)); setSecciones(seccionesData); if (!selectedSeccion) { setSelectedSeccion({ value: seccionesData[0].id, label: seccionesData[0].nombre }); } } }; fetchSecciones(); }, [selectedSeccion]); const seccionOptions = useMemo(() => secciones.map(s => ({ value: s.id, label: s.nombre })), [secciones]); const { data: rankingData, isLoading } = useQuery({ queryKey: ['rankingMunicipiosPorSeccion', selectedSeccion?.value], queryFn: () => getRankingMunicipiosPorSeccion(selectedSeccion!.value), enabled: !!selectedSeccion, }); return (

Resultados por Municipio

setSelectedSeccion(option)} isLoading={secciones.length === 0} styles={customSelectStyles} isSearchable={false} />
{isLoading ?

Cargando...

: !rankingData || rankingData.categorias.length === 0 ?

No hay datos.

: ( {/* --- Fila 1: Nombres de Categorías --- */} {rankingData.categorias.map(cat => ( ))} {/* --- Fila 2: Puestos --- */} {rankingData.categorias.flatMap(cat => [ , ])} {/* --- Fila 3: Sub-cabeceras (Partido y %) --- */} {rankingData.categorias.flatMap(cat => [ , , , ])} {rankingData.resultados.map(municipio => ( {rankingData.categorias.flatMap(cat => { const resCategoria = municipio.resultadosPorCategoria[cat.id]; const primerPuesto = resCategoria?.ranking[0]; const segundoPuesto = resCategoria?.ranking[1]; return [ // --- Celdas para el 1° Puesto --- , , // --- Celdas para el 2° Puesto --- , ]; })} ))}
Municipio {cat.nombre}
1° Puesto2° Puesto
Partido%Partido%
{municipio.municipioNombre} {primerPuesto?.nombreCorto || '-'} {primerPuesto ? : '-'} {segundoPuesto?.nombreCorto || '-'} {segundoPuesto ? : '-'}
)}
); };