Feat Widgets 1541

This commit is contained in:
2025-09-02 15:39:17 -03:00
parent da581d9714
commit f961f9d8e7
16 changed files with 1306 additions and 81 deletions

View File

@@ -30,20 +30,25 @@ const DEFAULT_MAP_COLOR = '#E0E0E0';
const CATEGORIAS: Categoria[] = [{ id: 5, nombre: 'Senadores' }, { id: 6, nombre: 'Diputados' }];
const SECCION_ID_TO_ROMAN: Record<string, string> = { '1': 'I', '2': 'II', '3': 'III', '4': 'IV', '5': 'V', '6': 'VI', '7': 'VII', '8': 'VIII' };
const ROMAN_TO_SECCION_ID: Record<string, string> = { 'I': '1', 'II': '2', 'III': '3', 'IV': '4', 'V': '5', 'VI': '6', 'VII': '7', 'VIII': '8' };
// --- CORRECCIÓN 1: Mover NOMBRES_SECCIONES aquí para que sea global al archivo ---
const NOMBRES_SECCIONES: Record<string, string> = {
'I': 'Sección Primera', 'II': 'Sección Segunda', 'III': 'Sección Tercera', 'IV': 'Sección Cuarta',
'V': 'Sección Quinta', 'VI': 'Sección Sexta', 'VII': 'Sección Séptima', 'VIII': 'Sección Capital'
};
const MIN_ZOOM = 1;
const MAX_ZOOM = 5;
const TRANSLATE_EXTENT: [[number, number], [number, number]] = [[-100, -600], [1100, 300]];
const INITIAL_POSITION = { center: [-60.5, -37.2] as PointTuple, zoom: MIN_ZOOM };
// --- Componente de Detalle ---
const DetalleSeccion = ({ seccion, categoriaId, onReset }: { seccion: SeccionGeography | null, categoriaId: number, onReset: () => void }) => {
// Obtenemos el ID numérico de la sección a partir de su número romano para llamar a la API
const seccionId = seccion ? ROMAN_TO_SECCION_ID[seccion.properties.seccion] : null;
const { data: resultadosDetalle, isLoading, error } = useQuery<ResultadoDetalleSeccion[]>({
queryKey: ['detalleSeccion', seccionId, categoriaId],
queryFn: () => getDetalleSeccion(seccionId!, categoriaId),
enabled: !!seccionId, // La query solo se ejecuta si hay una sección seleccionada
enabled: !!seccionId,
});
if (!seccion) {
@@ -54,27 +59,17 @@ const DetalleSeccion = ({ seccion, categoriaId, onReset }: { seccion: SeccionGeo
</div>
);
}
if (!seccion) return (<div className="detalle-placeholder"><h3>Resultados por Sección</h3><p>Haga clic en una sección del mapa para ver los resultados detallados.</p></div>);
if (isLoading) return (<div className="detalle-loading"><div className="spinner"></div><p>Cargando resultados de la sección...</p></div>);
if (error) return <div className="detalle-error">Error al cargar los datos de la sección.</div>;
// --- LÓGICA DE NOMBRE DE SECCIÓN ---
// Mapeo de número romano a nombre legible. Se puede mejorar en el futuro.
const NOMBRES_SECCIONES: Record<string, string> = {
'I': 'Sección Primera', 'II': 'Sección Segunda', 'III': 'Sección Tercera', 'IV': 'Sección Cuarta',
'V': 'Sección Quinta', 'VI': 'Sección Sexta', 'VII': 'Sección Séptima', 'VIII': 'Sección Capital'
};
const nombreSeccionLegible = NOMBRES_SECCIONES[seccion.properties.seccion] || "Sección Desconocida";
return (
<div className="detalle-content">
<button className="reset-button-panel" onClick={onReset}> VOLVER</button>
{/* Mostramos el nombre legible de la sección */}
<h3>{nombreSeccionLegible}</h3>
<ul className="resultados-lista">
{/* Mapeamos los resultados obtenidos de la API */}
{resultadosDetalle?.map((r) => (
<li key={r.id}>
<div className="resultado-info">
@@ -82,7 +77,8 @@ const DetalleSeccion = ({ seccion, categoriaId, onReset }: { seccion: SeccionGeo
<span className="partido-votos">{r.votos.toLocaleString('es-AR')} ({r.porcentaje.toFixed(2)}%)</span>
</div>
<div className="progress-bar">
<div className="progress-fill" style={{ width: `${r.porcentaje}%` }}></div>
{/* --- CORRECCIÓN 2: Usar el color de la API --- */}
<div className="progress-fill" style={{ width: `${r.porcentaje}%`, backgroundColor: r.color || DEFAULT_MAP_COLOR }}></div>
</div>
</li>
))}
@@ -163,7 +159,6 @@ const MapaBsAsSecciones = () => {
}
return;
}
// Si el usuario hace zoom out, deseleccionamos la sección para volver a la vista general
if (newPosition.zoom < position.zoom && clickedSeccion !== null) {
setClickedSeccion(null);
}
@@ -230,11 +225,12 @@ const MapaBsAsSecciones = () => {
key={geo.rsmKey + (isSelected ? '-selected' : '')}
geography={geo as any}
data-tooltip-id="seccion-tooltip"
data-tooltip-content={`${geo.properties.fna}: ${nombreGanador}`}
onClick={isClickable ? () => handleGeographyClick(geo) : undefined}
onMouseEnter={() => {
if (isClickable) {
setTooltipContent(`${geo.properties.fna}: ${nombreGanador}`);
// --- CORRECCIÓN 3: Tooltip con nombre de sección ---
const nombreSeccionLegible = NOMBRES_SECCIONES[geo.properties.seccion] || "Sección Desconocida";
setTooltipContent(`${nombreSeccionLegible}: ${nombreGanador}`);
}
}}
onMouseLeave={() => setTooltipContent("")}
@@ -249,7 +245,6 @@ const MapaBsAsSecciones = () => {
</ZoomableGroup>
</ComposableMap>
)}
{/* El botón de volver ahora está aquí, en el componente principal */}
{clickedSeccion && <ControlesMapa onReset={handleReset} />}
<Tooltip id="seccion-tooltip" content={tooltipContent} />
</div>

View File

@@ -96,8 +96,8 @@
}
.party-logo {
flex-shrink: 0;
width: 50px;
height: 50px;
width: 75px;
height: 75px;
}
.party-logo img {
width: 100%;