import { useEffect, useMemo, useRef, useState } from 'react'; import { Box, Button, Dialog, DialogContent, DialogTitle, IconButton, Typography, ToggleButton, ToggleButtonGroup } from '@mui/material'; import { DataGrid } from '@mui/x-data-grid'; import EditRoundedIcon from '@mui/icons-material/EditRounded'; import DeleteRoundedIcon from '@mui/icons-material/DeleteRounded'; import AddOrEditCategoryForm from './AddOrEditCategoryForm'; import CategoriesApi from '../../api/CategoriesApi'; import { useAuth } from '../../context/AuthContext'; export default function Categories() { const { user } = useAuth(); const token = user?.thalosToken || localStorage.getItem('thalosToken'); const api = useMemo(() => new CategoriesApi(token), [token]); const [rows, setRows] = useState([]); const [statusFilter, setStatusFilter] = useState('All'); // <- por defecto All const [open, setOpen] = useState(false); const [editingCategory, setEditingCategory] = useState(null); const [confirmOpen, setConfirmOpen] = useState(false); const [rowToDelete, setRowToDelete] = useState(null); const hasLoaded = useRef(false); const pageSize = 100; // Número de filas por página useEffect(() => { if (!hasLoaded.current) { loadData(); hasLoaded.current = true; } }, []); const loadData = async () => { try { const data = await api.getAll(); const list = Array.isArray(data) ? data : []; // Build a map of parentId -> array of child tagNames const parentToChildren = {}; for (const item of list) { const parents = Array.isArray(item?.parentTagId) ? item.parentTagId : []; for (const pid of parents) { if (!parentToChildren[pid]) parentToChildren[pid] = []; if (item?.tagName) parentToChildren[pid].push(item.tagName); } } // Enrich each row with `material` (children whose parentTagId includes this _id) const enriched = list.map((r) => ({ ...r, material: Array.isArray(parentToChildren[r?._id]) ? parentToChildren[r._id].join(', ') : '', })); setRows(enriched); } catch (e) { console.error('Failed to load categories:', e); setRows([]); } }; const handleAddClick = () => { setEditingCategory(null); setOpen(true); }; const handleEditClick = (params) => { const r = params?.row; if (!r) return; setEditingCategory({ _Id: r._id || r._Id || '', id: r.id || r.Id || '', tagName: r.tagName || r.name || '', typeId: r.typeId || '', parentTagId: Array.isArray(r.parentTagId) ? r.parentTagId : [], slug: r.slug || '', displayOrder: Number(r.displayOrder ?? 0), icon: r.icon || '', status: r.status ?? 'Active', }); setOpen(true); }; const handleDeleteClick = (row) => { if (!row) return; setRowToDelete(row); setConfirmOpen(true); }; const pickHexId = (r) => [r?._id, r?._Id, r?.id, r?.Id] .filter(Boolean) .find((x) => typeof x === 'string' && /^[0-9a-f]{24}$/i.test(x)) || null; const confirmDelete = async () => { try { if (!rowToDelete) return; const hexId = pickHexId(rowToDelete); if (!hexId) { alert('No se encontró _id (24-hex) para ChangeStatus en esta fila.'); return; } await api.changeStatus({ id: hexId, status: 'Inactive' }); await loadData(); } catch (e) { console.error('Delete failed:', e); alert('Delete failed. Revisa la consola para más detalles.'); } finally { setConfirmOpen(false); setRowToDelete(null); } }; const handleFormDone = async () => { await loadData(); setOpen(false); setEditingCategory(null); }; // --- FILTRO DE ESTADO --- const filteredRows = useMemo(() => { if (statusFilter === 'All') return rows; const want = String(statusFilter).toLowerCase(); return rows.filter((r) => String(r?.status ?? 'Active').toLowerCase() === want); }, [rows, statusFilter]); const columns = [ { field: 'actions', headerName: '', width: 130, sortable: false, filterable: false, disableExport: true, renderCell: (params) => ( handleEditClick(params)} > handleDeleteClick(params?.row)} > ), }, { field: 'tagName', headerName: 'Name', flex: 1.2, minWidth: 180 }, { field: 'slug', headerName: 'Slug', flex: 1.0, minWidth: 160 }, { field: 'icon', headerName: 'Icon', flex: 0.7, minWidth: 120 }, // New computed column { field: 'material', headerName: 'Material', flex: 1.2, minWidth: 200 }, // Hidden audit columns { field: 'createdAt', headerName: 'Created Date', flex: 1.0, minWidth: 180, hide: true, valueFormatter: (p) => { const v = p?.value; return v ? new Date(v).toLocaleString() : '—'; }, }, { field: 'createdBy', headerName: 'Created By', flex: 0.9, minWidth: 160, hide: true }, { field: 'updatedAt', headerName: 'Updated Date', flex: 1.0, minWidth: 180, hide: true, valueFormatter: (p) => { const v = p?.value; return v ? new Date(v).toLocaleString() : '—'; }, }, { field: 'updatedBy', headerName: 'Updated By', flex: 0.9, minWidth: 160, hide: true }, { field: 'status', headerName: 'Status', flex: 0.7, minWidth: 120 }, ]; return ( Categories v && setStatusFilter(v)} size="small" > Active All Inactive r?._id || r?.id} sx={{ height: '100%', '& .MuiDataGrid-cell, & .MuiDataGrid-columnHeader': { display: 'flex', alignItems: 'center', }, '& .MuiDataGrid-filler': { display: 'none', }, }} slots={{ noRowsOverlay: () => ( No categories found. Try switching the status filter to "All". ), }} /> { setOpen(false); setEditingCategory(null); }} fullWidth> {editingCategory ? 'Edit Category' : 'Add Category'} { setOpen(false); setEditingCategory(null); }} /> setConfirmOpen(false)}> Delete Category ); }