chore: edit existing item

This commit is contained in:
Rodolfo Ruiz
2025-09-01 20:53:04 -06:00
parent 24f82889e1
commit 304d5a6e59
2 changed files with 158 additions and 57 deletions

View File

@@ -2,8 +2,8 @@ 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 EditIcon from '@mui/icons-material/Edit';
import DeleteIcon from '@mui/icons-material/Delete';
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';
@@ -14,7 +14,7 @@ export default function Categories() {
const api = useMemo(() => new CategoriesApi(token), [token]);
const [rows, setRows] = useState([]);
const [statusFilter, setStatusFilter] = useState('Active'); // <- por defecto Active
const [statusFilter, setStatusFilter] = useState('All'); // <- por defecto All
const [open, setOpen] = useState(false);
const [editingCategory, setEditingCategory] = useState(null);
const [confirmOpen, setConfirmOpen] = useState(false);
@@ -31,13 +31,8 @@ export default function Categories() {
const loadData = async () => {
try {
const data = await api.getAll();
const safeRows = (Array.isArray(data) ? data : [])
.filter(Boolean)
.map((r, idx) => ({
...r,
__rid: r?._id || r?._Id || r?.id || r?.Id || `tmp-${idx}`,
}));
setRows(safeRows);
const list = Array.isArray(data) ? data : [];
setRows(list);
} catch (e) {
console.error('Failed to load categories:', e);
setRows([]);
@@ -110,48 +105,79 @@ export default function Categories() {
}, [rows, statusFilter]);
const columns = [
{
field: 'tagName',
headerName: 'Name',
flex: 1,
minWidth: 200,
valueGetter: (p) => p?.row?.tagName ?? p?.row?.name ?? '',
},
{
field: 'slug',
headerName: 'Slug',
width: 180,
valueGetter: (p) => p?.row?.slug ?? '',
},
{
field: 'displayOrder',
headerName: 'Display',
width: 120,
valueGetter: (p) => Number(p?.row?.displayOrder ?? 0),
},
{
field: 'status',
headerName: 'Status',
width: 140,
valueGetter: (p) => p?.row?.status ?? 'Active',
},
{
field: 'actions',
headerName: '',
width: 120,
width: 130,
sortable: false,
filterable: false,
renderCell: (params) => {
const r = params?.row;
if (!r) return null;
return (
<Box sx={{ display: 'flex', gap: 1 }}>
<IconButton size="small" onClick={() => handleEditClick(params)}><EditIcon /></IconButton>
<IconButton size="small" color="error" onClick={() => handleDeleteClick(r)}><DeleteIcon /></IconButton>
</Box>
);
disableExport: true,
renderCell: (params) => (
<Box display="flex" alignItems="center" justifyContent="flex-start" height="100%" gap={1}>
<IconButton
size="small"
sx={{
backgroundColor: '#DFCCBC',
color: '#26201A',
'&:hover': { backgroundColor: '#C2B2A4' },
borderRadius: 2,
p: 1,
}}
onClick={() => handleEditClick(params)}
>
<EditRoundedIcon fontSize="small" />
</IconButton>
<IconButton
size="small"
sx={{
backgroundColor: '#FBE9E7',
color: '#C62828',
'&:hover': { backgroundColor: '#EF9A9A' },
borderRadius: 2,
p: 1,
}}
onClick={() => handleDeleteClick(params?.row)}
>
<DeleteRoundedIcon fontSize="small" />
</IconButton>
</Box>
),
},
{ field: 'tenantId', headerName: 'tenantId', width: 180 },
{ field: 'tagName', headerName: 'tagName', width: 200 },
{ field: 'typeId', headerName: 'typeId', width: 260 },
{
field: 'parentTagId',
headerName: 'parentTagId',
width: 220,
valueGetter: (params) => Array.isArray(params.value) ? params.value.join(', ') : (params.value ?? '—'),
},
{ field: 'slug', headerName: 'slug', width: 180 },
{ field: 'displayOrder', headerName: 'displayOrder', width: 140, type: 'number' },
{ field: 'icon', headerName: 'icon', width: 160 },
{ field: '_id', headerName: '_id', width: 260 },
{ field: 'id', headerName: 'id', width: 280 },
{
field: 'createdAt',
headerName: 'createdAt',
width: 200,
valueFormatter: (p) => {
const v = p?.value;
return v ? new Date(v).toLocaleString() : '—';
},
},
{ field: 'createdBy', headerName: 'createdBy', width: 180 },
{
field: 'updatedAt',
headerName: 'updatedAt',
width: 200,
valueFormatter: (p) => {
const v = p?.value;
return v ? new Date(v).toLocaleString() : '—';
},
},
{ field: 'updatedBy', headerName: 'updatedBy', width: 180 },
{ field: 'status', headerName: 'status', width: 140 },
];
return (
@@ -177,15 +203,29 @@ export default function Categories() {
</Box>
</Box>
<DataGrid
rows={filteredRows}
columns={columns}
pageSize={10}
rowsPerPageOptions={[10]}
autoHeight
disableColumnMenu
getRowId={(r) => r?.__rid}
/>
<Box sx={{ width: '100%', overflowX: 'auto' }}>
<DataGrid
rows={filteredRows}
columns={columns}
initialState={{ pagination: { paginationModel: { pageSize: 10 } } }}
pageSizeOptions={[10]}
autoHeight
disableColumnMenu
getRowId={(r) => r?._id || r?.id}
sx={{
minWidth: 1400,
'& .MuiDataGrid-cell, & .MuiDataGrid-columnHeader': {
display: 'flex',
alignItems: 'center',
},
}}
slots={{
noRowsOverlay: () => (
<Box sx={{ p: 2 }}>No categories found. Try switching the status filter to "All".</Box>
),
}}
/>
</Box>
<Dialog open={open} onClose={() => { setOpen(false); setEditingCategory(null); }} fullWidth>
<DialogTitle>{editingCategory ? 'Edit Category' : 'Add Category'}</DialogTitle>