114 lines
3.9 KiB
TypeScript
114 lines
3.9 KiB
TypeScript
|
|
// 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>
|
||
|
|
);
|
||
|
|
};
|