Files
Elecciones-2025/Elecciones-Web/frontend-admin/src/components/OrdenDiputadosManager.tsx

114 lines
3.9 KiB
TypeScript
Raw Normal View History

// src/components/OrdenDiputadosManager.tsx
import { useState, useEffect } from 'react';
import {
DndContext,
closestCenter,
KeyboardSensor,
PointerSensor,
useSensor,
useSensors,
type DragEndEvent,
} from '@dnd-kit/core';
import {
arrayMove,
SortableContext,
sortableKeyboardCoordinates,
horizontalListSortingStrategy,
} from '@dnd-kit/sortable';
import { getAgrupaciones } from '../services/apiService';
import type { AgrupacionPolitica } from '../types';
import { SortableItem } from './SortableItem';
import './AgrupacionesManager.css'; // Reutilizamos los estilos
// Función para llamar al endpoint específico de diputados
const updateOrdenDiputadosApi = async (ids: string[]) => {
const token = localStorage.getItem('admin-jwt-token');
const response = await fetch('http://localhost:5217/api/admin/agrupaciones/orden-diputados', {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`
},
body: JSON.stringify(ids)
});
if (!response.ok) {
throw new Error("Failed to save Diputados order");
}
};
export const OrdenDiputadosManager = () => {
const [agrupaciones, setAgrupaciones] = useState<AgrupacionPolitica[]>([]);
const [loading, setLoading] = useState(true);
const sensors = useSensors(
useSensor(PointerSensor),
useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates })
);
useEffect(() => {
const fetchAndSortAgrupaciones = async () => {
setLoading(true);
try {
const data = await getAgrupaciones();
// Ordenar por el orden de Diputados. Los nulos van al final.
data.sort((a, b) => (a.ordenDiputados || 999) - (b.ordenDiputados || 999));
setAgrupaciones(data);
} catch (error) {
console.error("Failed to fetch agrupaciones for Diputados:", error);
} finally {
setLoading(false);
}
};
fetchAndSortAgrupaciones();
}, []);
const handleDragEnd = (event: DragEndEvent) => {
const { active, over } = event;
if (over && active.id !== over.id) {
setAgrupaciones((items) => {
const oldIndex = items.findIndex((item) => item.id === active.id);
const newIndex = items.findIndex((item) => item.id === over.id);
return arrayMove(items, oldIndex, newIndex);
});
}
};
const handleSaveOrder = async () => {
const idsOrdenados = agrupaciones.map(a => a.id);
try {
await updateOrdenDiputadosApi(idsOrdenados);
alert('Orden de Diputados guardado con éxito!');
} catch (error) {
alert('Error al guardar el orden de Diputados.');
}
};
if (loading) return <p>Cargando orden de Diputados...</p>;
return (
<div className="admin-module">
<h3>Ordenar Agrupaciones (Diputados)</h3>
<p>Arrastre para reordenar.</p>
<p>Ancla izquierda. Prioridad de izquierda a derecha y de arriba abajo.</p>
<DndContext
sensors={sensors}
collisionDetection={closestCenter}
onDragEnd={handleDragEnd}
>
<SortableContext
items={agrupaciones.map(a => a.id)}
strategy={horizontalListSortingStrategy}
>
<ul className="sortable-list-horizontal">
{agrupaciones.map(agrupacion => (
<SortableItem key={agrupacion.id} id={agrupacion.id}>
{agrupacion.nombreCorto || agrupacion.nombre}
</SortableItem>
))}
</ul>
</SortableContext>
</DndContext>
<button onClick={handleSaveOrder} style={{ marginTop: '1rem' }}>Guardar Orden Diputados</button>
</div>
);
};