Compare commits
	
		
			2 Commits
		
	
	
		
			9cdb76273d
			...
			73699009fc
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 73699009fc | ||
|   | 55dc96085d | 
| @@ -3,7 +3,7 @@ import { useEffect, useMemo, useState } from 'react'; | |||||||
| import { DataGrid } from '@mui/x-data-grid'; | import { DataGrid } from '@mui/x-data-grid'; | ||||||
| import { | import { | ||||||
|   Typography, Button, Dialog, DialogTitle, DialogContent, |   Typography, Button, Dialog, DialogTitle, DialogContent, | ||||||
|   IconButton, Box, FormControlLabel, Switch, Tooltip |   IconButton, Box, ToggleButtonGroup, ToggleButton | ||||||
| } from '@mui/material'; | } from '@mui/material'; | ||||||
| import EditRoundedIcon from '@mui/icons-material/EditRounded'; | import EditRoundedIcon from '@mui/icons-material/EditRounded'; | ||||||
| import DeleteRoundedIcon from '@mui/icons-material/DeleteRounded'; | import DeleteRoundedIcon from '@mui/icons-material/DeleteRounded'; | ||||||
| @@ -48,9 +48,10 @@ export default function ProductCollections() { | |||||||
|   const [rawRows, setRawRows] = useState([]); |   const [rawRows, setRawRows] = useState([]); | ||||||
|   const [open, setOpen] = useState(false); |   const [open, setOpen] = useState(false); | ||||||
|   const [editRow, setEditRow] = useState(null); |   const [editRow, setEditRow] = useState(null); | ||||||
|   const [showInactive, setShowInactive] = useState(false); |  | ||||||
|   const [loading, setLoading] = useState(true); |   const [loading, setLoading] = useState(true); | ||||||
|  |  | ||||||
|  |   const [statusFilter, setStatusFilter] = useState('All'); | ||||||
|  |  | ||||||
|   // Tags |   // Tags | ||||||
|   const [loadingTags, setLoadingTags] = useState(true); |   const [loadingTags, setLoadingTags] = useState(true); | ||||||
|   const [typeMap, setTypeMap] = useState({}); |   const [typeMap, setTypeMap] = useState({}); | ||||||
| @@ -154,7 +155,6 @@ export default function ProductCollections() { | |||||||
|         createdBy: r.createdBy ?? null, |         createdBy: r.createdBy ?? null, | ||||||
|       })); |       })); | ||||||
|       setRawRows(normalized); |       setRawRows(normalized); | ||||||
|       setRows(normalized.filter(r => showInactive ? true : r.status !== 'Inactive')); |  | ||||||
|     } catch (err) { |     } catch (err) { | ||||||
|       console.error(err); |       console.error(err); | ||||||
|       toast.error(err?.message || 'Error loading variants'); |       toast.error(err?.message || 'Error loading variants'); | ||||||
| @@ -165,11 +165,55 @@ export default function ProductCollections() { | |||||||
|  |  | ||||||
|   useEffect(() => { load(); /* eslint-disable-next-line */ }, []); |   useEffect(() => { load(); /* eslint-disable-next-line */ }, []); | ||||||
|   useEffect(() => { |   useEffect(() => { | ||||||
|     setRows(rawRows.filter(r => showInactive ? true : r.status !== 'Inactive')); |     if (statusFilter === 'All') { | ||||||
|   }, [showInactive, rawRows]); |       setRows(rawRows); | ||||||
|  |     } else { | ||||||
|  |       const want = statusFilter.toLowerCase(); | ||||||
|  |       setRows(rawRows.filter(r => String(r.status ?? 'Active').toLowerCase() === want)); | ||||||
|  |     } | ||||||
|  |   }, [statusFilter, rawRows]); | ||||||
|  |  | ||||||
|   const columns = [ |   const columns = [ | ||||||
|     { field: 'modelId', headerName: 'Model Id', width: 220 }, |    { | ||||||
|  |       field: 'actions', | ||||||
|  |       headerName: '', | ||||||
|  |       width: 130, | ||||||
|  |       sortable: false, | ||||||
|  |       filterable: false, | ||||||
|  |       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: 'name', headerName: 'Name', width: 200 }, |     { field: 'name', headerName: 'Name', width: 200 }, | ||||||
|     { field: 'categoryId', headerName: 'Category', width: 170, valueGetter: (p) => labelCategory(p?.row?.categoryId) }, |     { field: 'categoryId', headerName: 'Category', width: 170, valueGetter: (p) => labelCategory(p?.row?.categoryId) }, | ||||||
|     { field: 'providerId', headerName: 'Provider', width: 170, valueGetter: (p) => labelProvider(p?.row?.providerId) }, |     { field: 'providerId', headerName: 'Provider', width: 170, valueGetter: (p) => labelProvider(p?.row?.providerId) }, | ||||||
| @@ -196,68 +240,47 @@ export default function ProductCollections() { | |||||||
|     { field: 'attributes.material', headerName: 'Material', width: 150, valueGetter: (p) => labelMaterial(p?.row?.attributes?.material) }, |     { field: 'attributes.material', headerName: 'Material', width: 150, valueGetter: (p) => labelMaterial(p?.row?.attributes?.material) }, | ||||||
|     { field: 'attributes.legs', headerName: 'Legs', width: 140, valueGetter: (p) => labelLegs(p?.row?.attributes?.legs) }, |     { field: 'attributes.legs', headerName: 'Legs', width: 140, valueGetter: (p) => labelLegs(p?.row?.attributes?.legs) }, | ||||||
|     { field: 'attributes.origin', headerName: 'Origin', width: 150, valueGetter: (p) => labelOrigin(p?.row?.attributes?.origin) }, |     { field: 'attributes.origin', headerName: 'Origin', width: 150, valueGetter: (p) => labelOrigin(p?.row?.attributes?.origin) }, | ||||||
|     { field: 'status', headerName: 'Status', width: 120 }, |     { field: 'status', headerName: 'Status', width: 120 } | ||||||
|     { |  | ||||||
|       field: 'actions', |  | ||||||
|       headerName: '', |  | ||||||
|       sortable: false, |  | ||||||
|       width: 110, |  | ||||||
|       renderCell: (p) => ( |  | ||||||
|         <Box display="flex" gap={1}> |  | ||||||
|           <Tooltip title="Edit"> |  | ||||||
|             <IconButton size="small" onClick={() => { setEditRow(p.row); setOpen(true); }}> |  | ||||||
|               <EditRoundedIcon fontSize="small" /> |  | ||||||
|             </IconButton> |  | ||||||
|           </Tooltip> |  | ||||||
|           <Tooltip title={p.row.status === 'Active' ? 'Deactivate' : 'Activate'}> |  | ||||||
|             <IconButton |  | ||||||
|               size="small" |  | ||||||
|               onClick={async () => { |  | ||||||
|                 try { |  | ||||||
|                   const updated = { ...p.row, status: p.row.status === 'Active' ? 'Inactive' : 'Active' }; |  | ||||||
|                   await api.updateVariant(updated); |  | ||||||
|                   setRawRows(prev => prev.map(r => r.id === p.row.id ? updated : r)); |  | ||||||
|                 } catch (err) { |  | ||||||
|                   console.error(err); |  | ||||||
|                   toast.error(err?.message || 'Error updating status'); |  | ||||||
|                 } |  | ||||||
|               }} |  | ||||||
|             > |  | ||||||
|               <DeleteRoundedIcon fontSize="small" /> |  | ||||||
|             </IconButton> |  | ||||||
|           </Tooltip> |  | ||||||
|         </Box> |  | ||||||
|       ) |  | ||||||
|     }, |  | ||||||
|   ]; |   ]; | ||||||
|  |  | ||||||
|   return ( |   return ( | ||||||
|  |     <Box sx={{ height: 'calc(100vh - 64px - 64px)', display: 'flex', flexDirection: 'column', gap: 2 }}> | ||||||
|       <SectionContainer> |       <SectionContainer> | ||||||
|       <Box display="flex" alignItems="center" justifyContent="space-between" mb={2}> |       <Box display="flex" alignItems="center" justifyContent="space-between" mb={2} flexWrap="wrap" gap={2}> | ||||||
|         <Typography variant="h6">Furniture Variants</Typography> |         <Typography variant="h6">Furniture Variants</Typography> | ||||||
|         <Box display="flex" alignItems="center" gap={2}> |         <Box display="flex" alignItems="center" gap={2}> | ||||||
|           <FormControlLabel control={<Switch checked={showInactive} onChange={(_, v) => setShowInactive(v)} />} label="Show Inactive" /> |           <ToggleButtonGroup | ||||||
|  |             value={statusFilter} | ||||||
|  |             exclusive | ||||||
|  |             onChange={(_, v) => v && setStatusFilter(v)} | ||||||
|  |             size="small" | ||||||
|  |           > | ||||||
|  |             <ToggleButton value="Active">Active</ToggleButton> | ||||||
|  |             <ToggleButton value="All">All</ToggleButton> | ||||||
|  |             <ToggleButton value="Inactive">Inactive</ToggleButton> | ||||||
|  |           </ToggleButtonGroup> | ||||||
|           <Button variant="contained" className="button-gold" startIcon={<AddRoundedIcon />} onClick={() => { setEditRow(null); setOpen(true); }}> |           <Button variant="contained" className="button-gold" startIcon={<AddRoundedIcon />} onClick={() => { setEditRow(null); setOpen(true); }}> | ||||||
|             Add Variant |             Add Variant | ||||||
|           </Button> |           </Button> | ||||||
|         </Box> |         </Box> | ||||||
|       </Box> |       </Box> | ||||||
|  |  | ||||||
|       <Box sx={{ width: '100%', height: 560 }}> |       <Box sx={{ flex: 1, minHeight: 0 }}> | ||||||
|         <DataGrid |         <DataGrid | ||||||
|           rows={rows} |           rows={rows} | ||||||
|           columns={columns} |           columns={columns} | ||||||
|           disableRowSelectionOnClick |           disableRowSelectionOnClick | ||||||
|           loading={loading || loadingTags} |           loading={loading || loadingTags} | ||||||
|           pageSizeOptions={[10, 25, 50]} |           pageSizeOptions={[50, 100, 200]} | ||||||
|           initialState={{ |           initialState={{ | ||||||
|             pagination: { paginationModel: { pageSize: 10 } }, |             pagination: { paginationModel: { pageSize: 50 } }, | ||||||
|             columns: { columnVisibilityModel: { id: false, _Id: false } }, |             columns: { columnVisibilityModel: { id: false, _Id: false } }, | ||||||
|           }} |           }} | ||||||
|           getRowHeight={() => 'auto'} |           getRowHeight={() => 'auto'} | ||||||
|           sx={{ |           sx={{ | ||||||
|             '& .MuiDataGrid-cell': { display: 'flex', alignItems: 'center' }, |             '& .MuiDataGrid-cell': { display: 'flex', alignItems: 'center' }, | ||||||
|             '& .MuiDataGrid-columnHeader': { display: 'flex', alignItems: 'center' }, |             '& .MuiDataGrid-columnHeader': { display: 'flex', alignItems: 'center' }, | ||||||
|  |             '& .MuiDataGrid-virtualScroller': { overflowX: 'hidden' }, | ||||||
|           }} |           }} | ||||||
|         /> |         /> | ||||||
|       </Box> |       </Box> | ||||||
| @@ -280,5 +303,6 @@ export default function ProductCollections() { | |||||||
|         </DialogContent> |         </DialogContent> | ||||||
|       </Dialog> |       </Dialog> | ||||||
|       </SectionContainer> |       </SectionContainer> | ||||||
|  |     </Box> | ||||||
|   ); |   ); | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user