import SectionContainer from '../../components/SectionContainer'; import { useEffect, useRef, useState } from 'react'; import { DataGrid } from '@mui/x-data-grid'; import { Typography, Button, Dialog, DialogTitle, DialogContent, IconButton, Box } from '@mui/material'; import EditRoundedIcon from '@mui/icons-material/EditRounded'; import DeleteRoundedIcon from '@mui/icons-material/DeleteRounded'; import AddOrEditFurnitureVariantForm from './AddOrEditFurnitureVariantForm'; import FurnitureVariantApi from '../../api/furnitureVariantApi'; import { useAuth } from '../../context/AuthContext'; import useApiToast from '../../hooks/useApiToast'; const columnsBase = [ { field: 'modelId', headerName: 'Model Id', width: 260 }, { field: 'name', headerName: 'Name', width: 220 }, { field: 'color', headerName: 'Color', width: 160 }, { field: 'line', headerName: 'Line', width: 160 }, { field: 'stock', headerName: 'Stock', width: 100, type: 'number' }, { field: 'price', headerName: 'Price', width: 120, type: 'number', valueFormatter: (p) => p?.value != null ? Number(p.value).toFixed(2) : '—' }, { field: 'currency', headerName: 'Currency', width: 120 }, { field: 'categoryId', headerName: 'Category Id', width: 280 }, { field: 'providerId', headerName: 'Provider Id', width: 280 }, { field: 'attributes.material', headerName: 'Material', width: 160, valueGetter: (p) => p?.row?.attributes?.material ?? '—' }, { field: 'attributes.legs', headerName: 'Legs', width: 160, valueGetter: (p) => p?.row?.attributes?.legs ?? '—' }, { field: 'attributes.origin', headerName: 'Origin', width: 160, valueGetter: (p) => p?.row?.attributes?.origin ?? '—' }, { field: 'status', headerName: 'Status', width: 120 }, { field: 'createdAt', headerName: 'Created At', width: 180, valueFormatter: (p) => p?.value ? new Date(p.value).toLocaleString() : '—' }, { field: 'createdBy', headerName: 'Created By', width: 160, valueGetter: (p) => p?.row?.createdBy ?? '—' }, { field: 'updatedAt', headerName: 'Updated At', width: 180, valueFormatter: (p) => p?.value ? new Date(p.value).toLocaleString() : '—' }, { field: 'updatedBy', headerName: 'Updated By', width: 160, valueGetter: (p) => p?.row?.updatedBy ?? '—' }, ]; export default function FurnitureVariantManagement() { const { user } = useAuth(); const token = user?.thalosToken || localStorage.getItem('thalosToken'); const apiRef = useRef(null); const [rows, setRows] = useState([]); const [open, setOpen] = useState(false); const [editingData, setEditingData] = useState(null); const [confirmOpen, setConfirmOpen] = useState(false); const [rowToDelete, setRowToDelete] = useState(null); const { handleError } = useApiToast(); const hasLoaded = useRef(false); useEffect(() => { apiRef.current = new FurnitureVariantApi(token); }, [token]); useEffect(() => { if (!hasLoaded.current) { loadData(); hasLoaded.current = true; } }, []); const loadData = async () => { try { const data = await apiRef.current.getAllVariants(); setRows(Array.isArray(data) ? data : []); } catch (err) { console.error('Error loading variants:', err); handleError(err, 'Failed to load furniture variants'); setRows([]); } }; const handleEditClick = (params) => { if (!params?.row) return; const r = params.row; const normalized = { _id: r._id || r._Id || '', id: r.id || r.Id || '', modelId: r.modelId ?? '', name: r.name ?? '', color: r.color ?? '', line: r.line ?? '', stock: r.stock ?? 0, price: r.price ?? 0, currency: r.currency ?? 'USD', categoryId: r.categoryId ?? '', providerId: r.providerId ?? '', attributes: { material: r?.attributes?.material ?? '', legs: r?.attributes?.legs ?? '', origin: r?.attributes?.origin ?? '', }, status: r.status ?? 'Active', }; setEditingData(normalized); setOpen(true); }; const handleDeleteClick = (row) => { setRowToDelete(row); setConfirmOpen(true); }; const handleConfirmDelete = async () => { try { if (!apiRef.current || !rowToDelete?._id) throw new Error('Missing API or id'); // If your inventory BFF uses soft delete via Update (status=Inactive), do this: const payload = { _Id: rowToDelete._id || rowToDelete._Id, modelId: rowToDelete.modelId, name: rowToDelete.name, color: rowToDelete.color, line: rowToDelete.line, stock: rowToDelete.stock, price: rowToDelete.price, currency: rowToDelete.currency, categoryId: rowToDelete.categoryId, providerId: rowToDelete.providerId, attributes: { material: rowToDelete?.attributes?.material ?? '', legs: rowToDelete?.attributes?.legs ?? '', origin: rowToDelete?.attributes?.origin ?? '', }, status: 'Inactive', }; // Prefer update soft-delete; if you truly have DELETE, switch to apiRef.current.deleteVariant({ _Id: ... }) await apiRef.current.updateVariant(payload); await loadData(); } catch (e) { console.error('Delete failed:', e); } finally { setConfirmOpen(false); setRowToDelete(null); } }; const columns = [ { field: 'actions', headerName: '', width: 130, renderCell: (params) => ( handleEditClick(params)} > handleDeleteClick(params?.row)} > ) }, ...columnsBase, ]; return ( { setOpen(false); setEditingData(null); }} maxWidth="md" fullWidth> {editingData ? 'Edit Furniture Variant' : 'Add Furniture Variant'} { setOpen(false); setEditingData(null); }} onAdd={async () => { await loadData(); setOpen(false); setEditingData(null); }} /> setConfirmOpen(false)}> Confirm Delete Are you sure you want to delete {rowToDelete?.name}? ({ top: 4, bottom: 4 })} getRowId={(row) => row._id || row.id || row.modelId} autoHeight disableColumnMenu getRowHeight={() => 'auto'} sx={{ '& .MuiDataGrid-cell': { display: 'flex', alignItems: 'center' }, '& .MuiDataGrid-columnHeader': { display: 'flex', alignItems: 'center' }, }} /> ); }