114 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			114 lines
		
	
	
		
			3.6 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.id}) ${agrupacion.nombreCorto || agrupacion.nombre}`}
 | |
|               </SortableItem>
 | |
|             ))}
 | |
|           </ul>
 | |
|         </SortableContext>
 | |
|       </DndContext>
 | |
|       <button onClick={handleSaveOrder} style={{ marginTop: '1rem' }}>Guardar Orden Diputados</button>
 | |
|     </div>
 | |
|   );
 | |
| }; |