| 
									
										
										
										
											2025-08-29 09:54:22 -03:00
										 |  |  | // 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', { | 
					
						
							| 
									
										
										
										
											2025-10-20 11:03:19 -03:00
										 |  |  |     method: 'PUT', | 
					
						
							|  |  |  |     headers: { | 
					
						
							|  |  |  |       'Content-Type': 'application/json', | 
					
						
							|  |  |  |       'Authorization': `Bearer ${token}` | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |     body: JSON.stringify(ids) | 
					
						
							| 
									
										
										
										
											2025-08-29 09:54:22 -03:00
										 |  |  |   }); | 
					
						
							|  |  |  |   if (!response.ok) { | 
					
						
							|  |  |  |     throw new Error("Failed to save Diputados order"); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export const OrdenDiputadosManager = () => { | 
					
						
							| 
									
										
										
										
											2025-10-20 11:03:19 -03:00
										 |  |  |   const [agrupaciones, setAgrupaciones] = useState<AgrupacionPolitica[]>([]); | 
					
						
							|  |  |  |   const [loading, setLoading] = useState(true); | 
					
						
							|  |  |  |   const sensors = useSensors( | 
					
						
							|  |  |  |     useSensor(PointerSensor), | 
					
						
							|  |  |  |     useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates }) | 
					
						
							|  |  |  |   ); | 
					
						
							| 
									
										
										
										
											2025-08-29 09:54:22 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-10-20 11:03:19 -03:00
										 |  |  |   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); | 
					
						
							| 
									
										
										
										
											2025-08-29 09:54:22 -03:00
										 |  |  |       } | 
					
						
							|  |  |  |     }; | 
					
						
							| 
									
										
										
										
											2025-10-20 11:03:19 -03:00
										 |  |  |     fetchAndSortAgrupaciones(); | 
					
						
							|  |  |  |   }, []); | 
					
						
							| 
									
										
										
										
											2025-08-29 09:54:22 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-10-20 11:03:19 -03:00
										 |  |  |   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.'); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   }; | 
					
						
							| 
									
										
										
										
											2025-08-29 09:54:22 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-10-20 11:03:19 -03:00
										 |  |  |   if (loading) return <p>Cargando orden de Diputados...</p>; | 
					
						
							| 
									
										
										
										
											2025-08-29 09:54:22 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-10-20 11:03:19 -03:00
										 |  |  |   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> | 
					
						
							|  |  |  |   ); | 
					
						
							| 
									
										
										
										
											2025-08-29 09:54:22 -03:00
										 |  |  | }; |