chore: add data to gridview
This commit is contained in:
parent
1f11c47484
commit
55cb3fb34f
@ -5,38 +5,65 @@ import { Typography, Button, Dialog, DialogTitle, DialogContent, IconButton, Box
|
||||
import EditRoundedIcon from '@mui/icons-material/EditRounded';
|
||||
import DeleteRoundedIcon from '@mui/icons-material/DeleteRounded';
|
||||
import AddOrEditUserForm from './AddOrEditUserForm';
|
||||
import { getExternalData, deleteExternalData } from '../../api/mongo/actions';
|
||||
import UserApi from '../../api/userApi';
|
||||
import { useAuth } from '../../context/AuthContext';
|
||||
import { deleteExternalData } from '../../api/mongo/actions';
|
||||
import useApiToast from '../../hooks/useApiToast';
|
||||
|
||||
const columnsBase = [
|
||||
{ field: 'username', headerName: 'Username', flex: 1 },
|
||||
{ field: 'fullName', headerName: 'Full Name', flex: 2 },
|
||||
{ field: 'email', headerName: 'Email', flex: 2 },
|
||||
{ field: 'role', headerName: 'Role', flex: 1 },
|
||||
{ field: 'email', headerName: 'Email', width: 260 },
|
||||
{ field: 'name', headerName: 'Name', width: 140 },
|
||||
{ field: 'middleName', headerName: 'Middle Name', width: 140 },
|
||||
{ field: 'lastName', headerName: 'Last Name', width: 160 },
|
||||
{ field: 'displayName', headerName: 'Display Name', width: 180, valueGetter: (params) => params?.row?.displayName ?? '—' },
|
||||
{ field: 'tenantId', headerName: 'Tenant Id', width: 240, valueGetter: (params) => params?.row?.tenantId ?? '—' },
|
||||
{ field: 'roleId', headerName: 'Role Id', width: 240, valueGetter: (params) => params?.row?.roleId ?? '—' },
|
||||
{
|
||||
field: 'lastLogIn',
|
||||
headerName: 'Last Login',
|
||||
width: 180,
|
||||
valueFormatter: (params) => {
|
||||
const date = params?.value;
|
||||
return date ? new Date(date).toLocaleString() : '—';
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'lastLogOut',
|
||||
headerName: 'Last Logout',
|
||||
width: 180,
|
||||
valueFormatter: (params) => {
|
||||
const date = params?.value;
|
||||
return date ? new Date(date).toLocaleString() : '—';
|
||||
}
|
||||
},
|
||||
{ field: 'status', headerName: 'Status', width: 120 },
|
||||
{
|
||||
field: 'createdAt',
|
||||
headerName: 'Created At',
|
||||
width: 160,
|
||||
width: 180,
|
||||
valueFormatter: (params) => {
|
||||
const date = params?.value;
|
||||
return date ? new Date(date).toLocaleString() : '—';
|
||||
}
|
||||
},
|
||||
{ field: 'createdBy', headerName: 'Created By', flex: 1 },
|
||||
{ field: 'createdBy', headerName: 'Created By', width: 160, valueGetter: (p) => p?.row?.createdBy ?? '—' },
|
||||
{
|
||||
field: 'updatedAt',
|
||||
headerName: 'Updated At',
|
||||
width: 160,
|
||||
width: 180,
|
||||
valueFormatter: (params) => {
|
||||
const date = params?.value;
|
||||
return date ? new Date(date).toLocaleString() : '—';
|
||||
}
|
||||
},
|
||||
{ field: 'updatedBy', headerName: 'Updated By', flex: 1 },
|
||||
{ field: 'updatedBy', headerName: 'Updated By', width: 160, valueGetter: (p) => p?.row?.updatedBy ?? '—' },
|
||||
];
|
||||
|
||||
export default function UserManagement() {
|
||||
const { user } = useAuth();
|
||||
const thalosToken = user?.thalosToken || localStorage.getItem('thalosToken');
|
||||
const apiRef = useRef(null);
|
||||
|
||||
const [rows, setRows] = useState([]);
|
||||
const [open, setOpen] = useState(false);
|
||||
const [editingData, setEditingData] = useState(null);
|
||||
@ -46,6 +73,12 @@ export default function UserManagement() {
|
||||
|
||||
const hasLoaded = useRef(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (thalosToken) {
|
||||
apiRef.current = new UserApi(thalosToken);
|
||||
}
|
||||
}, [thalosToken]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!hasLoaded.current) {
|
||||
loadData();
|
||||
@ -54,18 +87,20 @@ export default function UserManagement() {
|
||||
}, []);
|
||||
|
||||
const handleEditClick = (params) => {
|
||||
if (!params || !params.row) return;
|
||||
setEditingData(params.row);
|
||||
setOpen(true);
|
||||
};
|
||||
|
||||
const handleDeleteClick = (row) => {
|
||||
if (!row) return;
|
||||
setRowToDelete(row);
|
||||
setConfirmOpen(true);
|
||||
};
|
||||
|
||||
const handleConfirmDelete = async () => {
|
||||
try {
|
||||
await deleteExternalData(rowToDelete._Id);
|
||||
await deleteExternalData(rowToDelete?._id);
|
||||
await loadData();
|
||||
} catch (error) {
|
||||
console.error('Delete failed:', error);
|
||||
@ -77,24 +112,24 @@ export default function UserManagement() {
|
||||
|
||||
const loadData = async () => {
|
||||
try {
|
||||
const data = await getExternalData();
|
||||
if (!apiRef.current) throw new Error('Missing Thalos token or API not initialized');
|
||||
const data = await apiRef.current.getAllUsers();
|
||||
const safeData = Array.isArray(data) ? data : [];
|
||||
setRows(safeData);
|
||||
} catch (error) {
|
||||
console.error('Error loading data:', error);
|
||||
handleError(error, 'Failed to load data');
|
||||
handleError(error, 'Failed to load users');
|
||||
setRows([]);
|
||||
}
|
||||
};
|
||||
|
||||
const columns = [
|
||||
...columnsBase,
|
||||
{
|
||||
field: 'actions',
|
||||
headerName: '',
|
||||
width: 130,
|
||||
renderCell: (params) => (
|
||||
<Box display="flex" alignItems="center" justifyContent="flex-end" height="100%" gap={2}>
|
||||
<Box display="flex" alignItems="center" justifyContent="flex-start" height="100%" gap={1}>
|
||||
<IconButton
|
||||
size="small"
|
||||
sx={{
|
||||
@ -117,13 +152,14 @@ export default function UserManagement() {
|
||||
borderRadius: 2,
|
||||
p: 1,
|
||||
}}
|
||||
onClick={() => handleDeleteClick(params.row)}
|
||||
onClick={() => handleDeleteClick(params?.row)}
|
||||
>
|
||||
<DeleteRoundedIcon fontSize="small" />
|
||||
</IconButton>
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
},
|
||||
...columnsBase,
|
||||
];
|
||||
|
||||
return (
|
||||
@ -152,7 +188,7 @@ export default function UserManagement() {
|
||||
<DialogTitle>Confirm Delete</DialogTitle>
|
||||
<DialogContent>
|
||||
<Typography>
|
||||
Are you sure you want to delete <strong>{rowToDelete?.username}</strong>?
|
||||
Are you sure you want to delete <strong>{rowToDelete?.email || rowToDelete?.name}</strong>?
|
||||
</Typography>
|
||||
<Box mt={2} display="flex" justifyContent="flex-end" gap={1}>
|
||||
<Button onClick={() => setConfirmOpen(false)} className='button-transparent'>Cancel</Button>
|
||||
@ -161,14 +197,30 @@ export default function UserManagement() {
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
<Box mt={2}>
|
||||
<DataGrid
|
||||
rows={rows}
|
||||
columns={columns}
|
||||
pageSize={5}
|
||||
rowsPerPageOptions={[5]}
|
||||
getRowSpacing={() => ({ top: 4, bottom: 4 })}
|
||||
/>
|
||||
<Box mt={2} sx={{ width: '100%', overflowX: 'auto' }}>
|
||||
<Box sx={{ width: '100%', overflowX: 'auto' }}>
|
||||
<DataGrid
|
||||
rows={rows}
|
||||
columns={columns}
|
||||
pageSize={5}
|
||||
rowsPerPageOptions={[5]}
|
||||
getRowSpacing={() => ({ top: 4, bottom: 4 })}
|
||||
getRowId={(row) => row._id || row.id || row.email}
|
||||
autoHeight
|
||||
disableColumnMenu
|
||||
getRowHeight={() => 'auto'}
|
||||
sx={{
|
||||
'& .MuiDataGrid-cell': {
|
||||
display: 'flex',
|
||||
alignItems: 'center', // vertical centering
|
||||
},
|
||||
'& .MuiDataGrid-columnHeader': {
|
||||
display: 'flex',
|
||||
alignItems: 'center', // vertical centering headers too
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
|
||||
<Box display="flex" justifyContent="flex-end" mt={2}>
|
||||
<Button variant="contained" onClick={() => setOpen(true)} className="button-gold">
|
||||
|
||||
Loading…
Reference in New Issue
Block a user