// src/components/ResumenGeneralWidget.tsx import { useMemo } from 'react'; import { useQuery } from '@tanstack/react-query'; import { getResumenProvincial, getConfiguracionPublica, assetBaseUrl } from '../apiService'; import type { CategoriaResumen, ResultadoTicker } from '../types/types'; import { ImageWithFallback } from './ImageWithFallback'; import './TickerWidget.css'; const formatPercent = (num: number) => `${(num || 0).toFixed(2).replace('.', ',')}%`; export const ResumenGeneralWidget = () => { const { data: categorias, isLoading, error } = useQuery({ queryKey: ['resumenProvincial'], queryFn: getResumenProvincial, refetchInterval: 180000, }); const { data: configData } = useQuery({ queryKey: ['configuracionPublica'], queryFn: getConfiguracionPublica, staleTime: 0, }); const cantidadAMostrar = parseInt(configData?.TickerResultadosCantidad || '5', 10); const aggregatedData = useMemo(() => { if (!categorias) return null; const legislativeCategories = categorias.filter(c => c.categoriaId === 5 || c.categoriaId === 6); if (legislativeCategories.length === 0) return null; const partyMap = new Map>(); legislativeCategories.forEach(category => { category.resultados.forEach(party => { const existing = partyMap.get(party.id); if (existing) { existing.votos += party.votos; } else { // Clonamos el objeto para no modificar el original partyMap.set(party.id, { ...party }); } }); }); const resultsArray = Array.from(partyMap.values()); const grandTotalVotes = resultsArray.reduce((sum, party) => sum + party.votos, 0); const finalResults: ResultadoTicker[] = resultsArray .map(party => ({ ...party, porcentaje: grandTotalVotes > 0 ? (party.votos * 100 / grandTotalVotes) : 0, })) .sort((a, b) => b.votos - a.votos); const avgMesas = legislativeCategories.reduce((sum, cat) => sum + (cat.estadoRecuento?.mesasTotalizadasPorcentaje ?? 0), 0) / legislativeCategories.length; const avgParticipacion = legislativeCategories.reduce((sum, cat) => sum + (cat.estadoRecuento?.participacionPorcentaje ?? 0), 0) / legislativeCategories.length; return { resultados: finalResults, estadoRecuento: { mesasTotalizadasPorcentaje: avgMesas, participacionPorcentaje: avgParticipacion } }; }, [categorias]); if (isLoading) return
Cargando resumen general...
; if (error || !aggregatedData) return
No hay datos para el resumen general.
; // Lógica para "Otros" let displayResults: ResultadoTicker[] = aggregatedData.resultados; if (aggregatedData.resultados.length > cantidadAMostrar) { const topParties = aggregatedData.resultados.slice(0, cantidadAMostrar - 1); const otherParties = aggregatedData.resultados.slice(cantidadAMostrar - 1); const otrosPorcentaje = otherParties.reduce((sum, party) => sum + party.porcentaje, 0); const otrosEntry: ResultadoTicker = { id: `otros-general`, nombre: 'Otros', nombreCorto: 'Otros', color: '#888888', logoUrl: null, votos: 0, porcentaje: otrosPorcentaje, }; displayResults = [...topParties, otrosEntry]; } else { displayResults = aggregatedData.resultados.slice(0, cantidadAMostrar); } return (

RESUMEN LEGISLATIVO PROVINCIAL

Mesas (Prom.): {formatPercent(aggregatedData.estadoRecuento.mesasTotalizadasPorcentaje)} Part (Prom.): {formatPercent(aggregatedData.estadoRecuento.participacionPorcentaje)}
{displayResults.map(partido => (
{partido.nombreCorto || partido.nombre} {formatPercent(partido.porcentaje)}
))}
); };