// src/components/BancasPreviasManager.tsx import { useState, useEffect } from 'react'; import { useQuery, useQueryClient } from '@tanstack/react-query'; import { getBancasPrevias, updateBancasPrevias, getAgrupaciones } from '../services/apiService'; import type { BancaPrevia, AgrupacionPolitica } from '../types'; import { TipoCamara } from '../types'; const ELECCION_ID_NACIONAL = 2; export const BancasPreviasManager = () => { const queryClient = useQueryClient(); const [editedBancas, setEditedBancas] = useState>>({}); const { data: agrupaciones = [], isLoading: isLoadingAgrupaciones } = useQuery({ queryKey: ['agrupaciones'], queryFn: getAgrupaciones, }); const { data: bancasPrevias = [], isLoading: isLoadingBancas } = useQuery({ queryKey: ['bancasPrevias', ELECCION_ID_NACIONAL], queryFn: () => getBancasPrevias(ELECCION_ID_NACIONAL), }); useEffect(() => { if (agrupaciones.length > 0) { const initialData: Record> = {}; agrupaciones.forEach(agrupacion => { // Para Diputados const keyDip = `${agrupacion.id}-${TipoCamara.Diputados}`; const existingDip = bancasPrevias.find(b => b.agrupacionPoliticaId === agrupacion.id && b.camara === TipoCamara.Diputados); initialData[keyDip] = { cantidad: existingDip?.cantidad || 0 }; // Para Senadores const keySen = `${agrupacion.id}-${TipoCamara.Senadores}`; const existingSen = bancasPrevias.find(b => b.agrupacionPoliticaId === agrupacion.id && b.camara === TipoCamara.Senadores); initialData[keySen] = { cantidad: existingSen?.cantidad || 0 }; }); setEditedBancas(initialData); } }, [agrupaciones, bancasPrevias]); const handleInputChange = (agrupacionId: string, camara: typeof TipoCamara.Diputados | typeof TipoCamara.Senadores, value: string) => { const key = `${agrupacionId}-${camara}`; const cantidad = parseInt(value, 10); setEditedBancas(prev => ({ ...prev, [key]: { ...prev[key], cantidad: isNaN(cantidad) ? 0 : cantidad } })); }; const handleSave = async () => { const payload: BancaPrevia[] = Object.entries(editedBancas) .map(([key, value]) => { const [agrupacionPoliticaId, camara] = key.split('-'); return { id: 0, eleccionId: ELECCION_ID_NACIONAL, agrupacionPoliticaId, camara: parseInt(camara) as typeof TipoCamara.Diputados | typeof TipoCamara.Senadores, cantidad: value.cantidad || 0, }; }) .filter(b => b.cantidad > 0); try { await updateBancasPrevias(ELECCION_ID_NACIONAL, payload); queryClient.invalidateQueries({ queryKey: ['bancasPrevias', ELECCION_ID_NACIONAL] }); alert('Bancas previas guardadas con éxito.'); } catch (error) { console.error(error); alert('Error al guardar las bancas previas.'); } }; const totalDiputados = Object.entries(editedBancas).reduce((sum, [key, value]) => key.endsWith(`-${TipoCamara.Diputados}`) ? sum + (value.cantidad || 0) : sum, 0); const totalSenadores = Object.entries(editedBancas).reduce((sum, [key, value]) => key.endsWith(`-${TipoCamara.Senadores}`) ? sum + (value.cantidad || 0) : sum, 0); const isLoading = isLoadingAgrupaciones || isLoadingBancas; return (

Gestión de Bancas Previas (Composición Nacional)

Define cuántas bancas retiene cada partido antes de la elección. Estos son los escaños que **no** están en juego.

{isLoading ?

Cargando...

: ( <>
{agrupaciones.map(agrupacion => ( ))}
Agrupación Política Bancas Previas Diputados (Total: {totalDiputados} / 130) Bancas Previas Senadores (Total: {totalSenadores} / 48)
{agrupacion.nombre} handleInputChange(agrupacion.id, TipoCamara.Diputados, e.target.value)} /> handleInputChange(agrupacion.id, TipoCamara.Senadores, e.target.value)} />
)}
); };