diff --git a/src/private/users/UserManagement.jsx b/src/private/users/UserManagement.jsx index 5cfe86c..7e3a992 100644 --- a/src/private/users/UserManagement.jsx +++ b/src/private/users/UserManagement.jsx @@ -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) => ( - + handleDeleteClick(params.row)} + onClick={() => handleDeleteClick(params?.row)} > ) - } + }, + ...columnsBase, ]; return ( @@ -152,7 +188,7 @@ export default function UserManagement() { Confirm Delete - Are you sure you want to delete {rowToDelete?.username}? + Are you sure you want to delete {rowToDelete?.email || rowToDelete?.name}? @@ -161,14 +197,30 @@ export default function UserManagement() { - - ({ top: 4, bottom: 4 })} - /> + + + ({ 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 + } + }} + /> +