// frontend/src/components/TablaTitulares.tsx
import { useState } from 'react';
import { Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Paper, Chip, IconButton, Typography, Link, TextField } from '@mui/material';
import DeleteIcon from '@mui/icons-material/Delete';
import DragHandleIcon from '@mui/icons-material/DragHandle';
import EditIcon from '@mui/icons-material/Edit';
import { DndContext, closestCenter, PointerSensor, useSensor, useSensors, type DragEndEvent } from '@dnd-kit/core';
import { arrayMove, SortableContext, useSortable, verticalListSortingStrategy } from '@dnd-kit/sortable';
import { CSS } from '@dnd-kit/utilities';
import type { Titular } from '../types';
import type { ActualizarTitularPayload } from '../services/apiService';
interface SortableRowProps {
titular: Titular;
onDelete: (id: number) => void;
onSave: (id: number, payload: ActualizarTitularPayload) => void;
onEdit: (titular: Titular) => void;
}
const SortableRow = ({ titular, onDelete, onSave, onEdit }: SortableRowProps) => {
const { attributes, listeners, setNodeRef, transform, transition } = useSortable({ id: titular.id });
const [isEditing, setIsEditing] = useState(false);
const [editText, setEditText] = useState(titular.texto);
const style = { transform: CSS.Transform.toString(transform), transition };
const handleSave = () => {
if (editText.trim() && editText.trim() !== titular.texto) {
onSave(titular.id, { texto: editText.trim(), viñeta: titular.viñeta });
}
setIsEditing(false);
};
const getChipColor = (tipo: Titular['tipo']): "success" | "warning" | "info" => {
if (tipo === 'Edited') return 'warning';
if (tipo === 'Manual') return 'info';
return 'success';
};
const formatFuente = (fuente: string | null) => {
if (!fuente) return 'N/A';
try {
const url = new URL(fuente);
return url.hostname.replace('www.', '');
} catch {
return fuente;
}
}
return (
setIsEditing(true)}>
{isEditing ? (
setEditText(e.target.value)}
onBlur={handleSave}
onKeyDown={(e) => { if (e.key === 'Enter') handleSave(); }}
onClick={(e) => e.stopPropagation()}
/>
) : (
{titular.texto}
)}
{titular.urlFuente ? (
{formatFuente(titular.fuente)}
) : (
formatFuente(titular.fuente)
)}
{ e.stopPropagation(); onEdit(titular); }}>
{ e.stopPropagation(); onDelete(titular.id); }} sx={{ color: '#ef4444' }}>
);
};
interface TablaTitularesProps {
titulares: Titular[];
onReorder: (titulares: Titular[]) => void;
onDelete: (id: number) => void;
onEdit: (titular: Titular) => void;
onSave: (id: number, payload: ActualizarTitularPayload) => void;
}
const TablaTitulares = ({ titulares, onReorder, onDelete, onEdit, onSave }: TablaTitularesProps) => {
const sensors = useSensors(useSensor(PointerSensor, { activationConstraint: { distance: 8 } }));
const handleDragEnd = (event: DragEndEvent) => {
const { active, over } = event;
if (over && active.id !== over.id) {
const oldIndex = titulares.findIndex((item) => item.id === active.id);
const newIndex = titulares.findIndex((item) => item.id === over.id);
onReorder(arrayMove(titulares, oldIndex, newIndex));
}
};
if (titulares.length === 0) {
return (
No hay titulares para mostrar.
);
}
return (
t.id)} strategy={verticalListSortingStrategy}>
Texto del Titular
Tipo
Fuente
Acciones
{titulares.map((titular) => (
))}
);
};
export default TablaTitulares;