From 5ef3eb1af24e3d0f1ce58882f7bb35f2a1f8cb88 Mon Sep 17 00:00:00 2001 From: dmolinari Date: Wed, 22 Oct 2025 10:29:02 -0300 Subject: [PATCH] Fix Llamadas de Ambitos Para Resultados --- Elecciones-Web/frontend/src/apiService.ts | 25 ++++++--- .../nacionales/PanelNacionalWidget.tsx | 31 +++-------- .../Controllers/ResultadosController.cs | 53 +++++++++++++------ .../net9.0/Elecciones.Api.AssemblyInfo.cs | 2 +- .../Debug/net9.0/rjsmcshtml.dswa.cache.json | 2 +- .../Debug/net9.0/rjsmrazor.dswa.cache.json | 2 +- .../net9.0/Elecciones.Core.AssemblyInfo.cs | 2 +- .../Elecciones.Database.AssemblyInfo.cs | 2 +- .../Elecciones.Infrastructure.AssemblyInfo.cs | 2 +- 9 files changed, 70 insertions(+), 51 deletions(-) diff --git a/Elecciones-Web/frontend/src/apiService.ts b/Elecciones-Web/frontend/src/apiService.ts index 0640af1..887bdfe 100644 --- a/Elecciones-Web/frontend/src/apiService.ts +++ b/Elecciones-Web/frontend/src/apiService.ts @@ -246,11 +246,24 @@ export const getEstablecimientosPorMunicipio = async (municipioId: string): Prom return response.data; }; -export const getPanelElectoral = async (eleccionId: number, ambitoId: string | null, categoriaId: number): Promise => { - // Construimos la URL base - let url = ambitoId - ? `/elecciones/${eleccionId}/panel/${ambitoId}` - : `/elecciones/${eleccionId}/panel`; +export const getPanelElectoral = async ( + eleccionId: number, + ambitoId: string | null, + categoriaId: number, + nivel: 'pais' | 'provincia' | 'municipio' +): Promise => { + + let url: string; + + // Construimos la URL con el prefijo correcto. + if (nivel === 'pais' || !ambitoId) { + url = `/elecciones/${eleccionId}/panel`; + } else if (nivel === 'provincia') { + url = `/elecciones/${eleccionId}/panel/distrito:${ambitoId}`; + } else { // nivel === 'municipio' + url = `/elecciones/${eleccionId}/panel/municipio:${ambitoId}`; + } + url += `?categoriaId=${categoriaId}`; try { @@ -259,8 +272,6 @@ export const getPanelElectoral = async (eleccionId: number, ambitoId: string | n } catch (error) { if (axios.isAxiosError(error) && error.response?.status === 404) { console.warn(`API devolvió 404 para ${url}. Devolviendo un estado vacío.`); - - // Devolvemos el objeto vacío PERO con la nueva bandera activada return { ambitoNombre: 'Sin Datos', mapaData: [], diff --git a/Elecciones-Web/frontend/src/features/legislativas/nacionales/PanelNacionalWidget.tsx b/Elecciones-Web/frontend/src/features/legislativas/nacionales/PanelNacionalWidget.tsx index 63d9c25..c0fa758 100644 --- a/Elecciones-Web/frontend/src/features/legislativas/nacionales/PanelNacionalWidget.tsx +++ b/Elecciones-Web/frontend/src/features/legislativas/nacionales/PanelNacionalWidget.tsx @@ -7,7 +7,6 @@ import { MapaNacional } from './components/MapaNacional'; import { PanelResultados } from './components/PanelResultados'; import { Breadcrumbs } from './components/Breadcrumbs'; import { MunicipioSearch } from './components/MunicipioSearch'; -// 1. La importación de CSS ahora se hace como un módulo import styles from './PanelNacional.module.css'; import Select from 'react-select'; import type { PanelElectoralDto, ResultadoTicker } from '../../../types/types'; @@ -18,19 +17,9 @@ import { ImageWithFallback } from '../../../components/common/ImageWithFallback' import { assetBaseUrl } from '../../../apiService'; import { useQueryClient } from '@tanstack/react-query'; -// --- COMPONENTE INTERNO PARA LA TARJETA DE RESULTADOS EN MÓVIL --- -interface MobileResultsCardProps { - eleccionId: number; - ambitoId: string | null; - categoriaId: number; - ambitoNombre: string; - ambitoNivel: 'pais' | 'provincia' | 'municipio'; -} - +// --- SUB-COMPONENTE PARA UNA FILA DE RESULTADO --- const formatPercent = (num: number) => `${(num || 0).toFixed(2).replace('.', ',')}%`; -// --- SUB-COMPONENTE PARA UNA FILA DE RESULTADO --- -// 2. Todas las props 'className' ahora usan el objeto 'styles' const ResultRow = ({ partido }: { partido: ResultadoTicker }) => (
@@ -71,8 +60,8 @@ const MobileResultsCard = ({ const [isExpanded, setIsExpanded] = useState(false); const { data } = useSuspenseQuery({ - queryKey: ['panelElectoral', eleccionId, ambitoId, categoriaId], - queryFn: () => getPanelElectoral(eleccionId, ambitoId, categoriaId), + queryKey: ['panelElectoral', eleccionId, ambitoId, categoriaId, ambitoNivel], + queryFn: () => getPanelElectoral(eleccionId, ambitoId, categoriaId, ambitoNivel), refetchInterval: 30000, }); @@ -86,7 +75,6 @@ const MobileResultsCard = ({ return null; } - // 3. Clases condicionales también se construyen con el objeto 'styles' const cardClasses = [ styles.mobileResultsCardContainer, isExpanded ? styles.expanded : '', @@ -95,7 +83,6 @@ const MobileResultsCard = ({ return (
- {/* Sección Colapsable con Resultados */}
setIsExpanded(!isExpanded)}>
@@ -114,8 +101,6 @@ const MobileResultsCard = ({ )}
- - {/* Footer Fijo con Botones de Navegación */}