import { useState, useEffect } from 'react'; import toast from 'react-hot-toast'; import styles from './SimpleTable.module.css'; const BASE_URL = 'http://localhost:5198/api'; // Interfaces para los diferentes tipos de datos interface TextValue { valor: string; conteo: number; } interface RamValue { id: number; fabricante?: string; tamano: number; velocidad?: number; partNumber?: string; conteo: number; } const GestionComponentes = () => { const [componentType, setComponentType] = useState('os'); const [valores, setValores] = useState<(TextValue | RamValue)[]>([]); // Estado que acepta ambos tipos const [isLoading, setIsLoading] = useState(false); const [isModalOpen, setIsModalOpen] = useState(false); const [valorAntiguo, setValorAntiguo] = useState(''); const [valorNuevo, setValorNuevo] = useState(''); useEffect(() => { setIsLoading(true); const endpoint = componentType === 'ram' ? `${BASE_URL}/admin/componentes/ram` : `${BASE_URL}/admin/componentes/${componentType}`; fetch(endpoint) .then(res => res.json()) .then(data => { setValores(data); }) .catch(_err => { toast.error(`No se pudieron cargar los datos de ${componentType}.`); }) .finally(() => setIsLoading(false)); }, [componentType]); const handleOpenModal = (valor: string) => { setValorAntiguo(valor); setValorNuevo(valor); setIsModalOpen(true); }; const handleUnificar = async () => { const toastId = toast.loading('Unificando valores...'); try { const response = await fetch(`${BASE_URL}/admin/componentes/${componentType}/unificar`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ valorAntiguo, valorNuevo }), }); if (!response.ok) { const error = await response.json(); throw new Error(error.message || 'La unificación falló.'); } // Refrescar la lista para ver el resultado const refreshedData = await (await fetch(`${BASE_URL}/admin/componentes/${componentType}`)).json(); setValores(refreshedData); toast.success('Valores unificados correctamente.', { id: toastId }); setIsModalOpen(false); } catch (error) { if (error instanceof Error) toast.error(error.message, { id: toastId }); } }; const handleDeleteRam = async (ramId: number) => { if (!window.confirm("¿Estás seguro de eliminar este módulo de RAM de la base de datos maestra? Esta acción es irreversible.")) { return; } const toastId = toast.loading('Eliminando módulo...'); try { const response = await fetch(`${BASE_URL}/admin/componentes/ram/${ramId}`, { method: 'DELETE' }); if (!response.ok) { const error = await response.json(); throw new Error(error.message || 'No se pudo eliminar.'); } setValores(prev => prev.filter(v => (v as RamValue).id !== ramId)); toast.success("Módulo de RAM eliminado.", { id: toastId }); } catch (error) { if (error instanceof Error) toast.error(error.message, { id: toastId }); } }; const handleDeleteTexto = async (valor: string) => { if (!window.confirm(`Este valor ya no está en uso. ¿Quieres intentar eliminarlo de la base de datos maestra? (Si no existe una tabla maestra, esta acción solo confirmará que no hay usos)`)) { return; } const toastId = toast.loading('Eliminando valor...'); try { // La API necesita el valor codificado para manejar caracteres especiales como '/' const encodedValue = encodeURIComponent(valor); const response = await fetch(`${BASE_URL}/admin/componentes/${componentType}/${encodedValue}`, { method: 'DELETE' }); if (!response.ok) { const error = await response.json(); throw new Error(error.message || 'No se pudo eliminar.'); } setValores(prev => prev.filter(v => (v as TextValue).valor !== valor)); toast.success("Valor eliminado/confirmado como no existente.", { id: toastId }); } catch (error) { if (error instanceof Error) toast.error(error.message, { id: toastId }); } }; const renderValor = (item: TextValue | RamValue) => { if (componentType === 'ram') { const ram = item as RamValue; return `${ram.fabricante || ''} ${ram.tamano}GB ${ram.velocidad ? ram.velocidad + 'MHz' : ''} (${ram.partNumber || 'N/P'})`; } return (item as TextValue).valor; }; return (
Unifica valores inconsistentes y elimina registros no utilizados.
Cargando...
) : (| Valor Registrado | Nº de Equipos | Acciones | 
|---|---|---|
| {renderValor(item)} | {item.conteo} | 
                                        {componentType === 'ram' ? (
                                            // Lógica solo para RAM (no tiene sentido "unificar" un objeto complejo)
                                            
                                        ) : (
                                            // Lógica para todos los demás tipos de componentes (texto)
                                            <>
                                                
                                                
                                            >
                                        )}
                                     | 
Se reemplazarán todas las instancias de:
{valorAntiguo} setValorNuevo(e.target.value)} className={styles.modalInput} />