121 lines
4.4 KiB
TypeScript
121 lines
4.4 KiB
TypeScript
|
|
// src/components/BancasManager.tsx
|
||
|
|
import { useState } from 'react';
|
||
|
|
import { useQuery, useQueryClient } from '@tanstack/react-query';
|
||
|
|
import { getBancadas, getAgrupaciones, updateBancada, type UpdateBancadaData } from '../services/apiService';
|
||
|
|
import type { Bancada, AgrupacionPolitica } from '../types';
|
||
|
|
import { OcupantesModal } from './OcupantesModal';
|
||
|
|
import './AgrupacionesManager.css'; // Asegúrate de que este CSS tenga los estilos de .chamber-tabs
|
||
|
|
|
||
|
|
const camaras = ['diputados', 'senadores'] as const;
|
||
|
|
|
||
|
|
export const BancasManager = () => {
|
||
|
|
const [activeTab, setActiveTab] = useState<'diputados' | 'senadores'>('diputados');
|
||
|
|
const [modalVisible, setModalVisible] = useState(false);
|
||
|
|
const [bancadaSeleccionada, setBancadaSeleccionada] = useState<Bancada | null>(null);
|
||
|
|
const queryClient = useQueryClient();
|
||
|
|
|
||
|
|
// Obtenemos todas las agrupaciones para poblar el <select>
|
||
|
|
const { data: agrupaciones = [] } = useQuery<AgrupacionPolitica[]>({
|
||
|
|
queryKey: ['agrupaciones'],
|
||
|
|
queryFn: getAgrupaciones
|
||
|
|
});
|
||
|
|
|
||
|
|
// Obtenemos las bancas para la cámara activa (diputados o senadores)
|
||
|
|
const { data: bancadas = [], isLoading, error } = useQuery<Bancada[]>({
|
||
|
|
queryKey: ['bancadas', activeTab],
|
||
|
|
queryFn: () => getBancadas(activeTab),
|
||
|
|
});
|
||
|
|
|
||
|
|
const handleAgrupacionChange = async (bancadaId: number, nuevaAgrupacionId: string | null) => {
|
||
|
|
const bancadaActual = bancadas.find(b => b.id === bancadaId);
|
||
|
|
if (!bancadaActual) return;
|
||
|
|
|
||
|
|
// Si se desasigna el partido (vacante), también se limpia el ocupante
|
||
|
|
const payload: UpdateBancadaData = {
|
||
|
|
agrupacionPoliticaId: nuevaAgrupacionId,
|
||
|
|
nombreOcupante: nuevaAgrupacionId ? (bancadaActual.ocupante?.nombreOcupante ?? null) : null,
|
||
|
|
fotoUrl: nuevaAgrupacionId ? (bancadaActual.ocupante?.fotoUrl ?? null) : null,
|
||
|
|
periodo: nuevaAgrupacionId ? (bancadaActual.ocupante?.periodo ?? null) : null,
|
||
|
|
};
|
||
|
|
|
||
|
|
try {
|
||
|
|
await updateBancada(bancadaId, payload);
|
||
|
|
// Invalida la query para forzar una recarga de datos frescos desde el servidor
|
||
|
|
queryClient.invalidateQueries({ queryKey: ['bancadas', activeTab] });
|
||
|
|
} catch (err) {
|
||
|
|
alert("Error al guardar el cambio.");
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
const handleOpenModal = (bancada: Bancada) => {
|
||
|
|
setBancadaSeleccionada(bancada);
|
||
|
|
setModalVisible(true);
|
||
|
|
};
|
||
|
|
|
||
|
|
if (error) return <p style={{ color: 'red' }}>Error al cargar las bancas.</p>;
|
||
|
|
|
||
|
|
return (
|
||
|
|
<div className="admin-module">
|
||
|
|
<h2>Gestión de Ocupación de Bancas</h2>
|
||
|
|
<p>Asigne a cada banca un partido político y, opcionalmente, los datos de la persona que la ocupa.</p>
|
||
|
|
|
||
|
|
<div className="chamber-tabs">
|
||
|
|
{camaras.map(camara => (
|
||
|
|
<button
|
||
|
|
key={camara}
|
||
|
|
className={activeTab === camara ? 'active' : ''}
|
||
|
|
onClick={() => setActiveTab(camara)}
|
||
|
|
>
|
||
|
|
{camara === 'diputados' ? 'Cámara de Diputados' : 'Cámara de Senadores'}
|
||
|
|
</button>
|
||
|
|
))}
|
||
|
|
</div>
|
||
|
|
|
||
|
|
{isLoading ? <p>Cargando bancas...</p> : (
|
||
|
|
<table>
|
||
|
|
<thead>
|
||
|
|
<tr>
|
||
|
|
<th>Banca #</th>
|
||
|
|
<th>Partido Asignado</th>
|
||
|
|
<th>Ocupante Actual</th>
|
||
|
|
<th>Acciones</th>
|
||
|
|
</tr>
|
||
|
|
</thead>
|
||
|
|
<tbody>
|
||
|
|
{bancadas.map((bancada, index) => (
|
||
|
|
<tr key={bancada.id}>
|
||
|
|
<td>{`${activeTab.charAt(0).toUpperCase()}-${index + 1}`}</td>
|
||
|
|
<td>
|
||
|
|
<select
|
||
|
|
value={bancada.agrupacionPoliticaId || ''}
|
||
|
|
onChange={(e) => handleAgrupacionChange(bancada.id, e.target.value || null)}
|
||
|
|
>
|
||
|
|
<option value="">-- Vacante --</option>
|
||
|
|
{agrupaciones.map(a => <option key={a.id} value={a.id}>{a.nombre}</option>)}
|
||
|
|
</select>
|
||
|
|
</td>
|
||
|
|
<td>{bancada.ocupante?.nombreOcupante || 'Sin asignar'}</td>
|
||
|
|
<td>
|
||
|
|
<button
|
||
|
|
disabled={!bancada.agrupacionPoliticaId}
|
||
|
|
onClick={() => handleOpenModal(bancada)}
|
||
|
|
>
|
||
|
|
Editar Ocupante
|
||
|
|
</button>
|
||
|
|
</td>
|
||
|
|
</tr>
|
||
|
|
))}
|
||
|
|
</tbody>
|
||
|
|
</table>
|
||
|
|
)}
|
||
|
|
|
||
|
|
{modalVisible && bancadaSeleccionada && (
|
||
|
|
<OcupantesModal
|
||
|
|
bancada={bancadaSeleccionada}
|
||
|
|
onClose={() => setModalVisible(false)}
|
||
|
|
activeTab={activeTab}
|
||
|
|
/>
|
||
|
|
)}
|
||
|
|
</div>
|
||
|
|
);
|
||
|
|
};
|