EvalueTonSavoir/client/src/components/AdminTable/AdminTable.tsx

170 lines
5 KiB
TypeScript
Raw Normal View History

2025-03-18 18:33:40 -04:00
import React, { useState } from "react";
import {
Table,
TableBody,
TableCell,
TableContainer,
TableHead,
TableRow,
TablePagination,
Paper,
Input,
IconButton,
Dialog,
DialogActions,
DialogContent,
DialogContentText,
DialogTitle,
Button,
InputAdornment,
Box,
} from "@mui/material";
import DeleteIcon from "@mui/icons-material/Delete";
import SearchIcon from "@mui/icons-material/Search";
2025-03-18 20:03:54 -04:00
import { AdminTableType } from "../../Types/AdminTableType";
import { LabelMap } from "../../Types/LabelMap";
2025-03-18 18:33:40 -04:00
interface AdminTableProps {
2025-03-18 19:31:44 -04:00
data: AdminTableType[];
onDelete: (row: AdminTableType) => void;
2025-03-18 18:33:40 -04:00
filterKeys?: string[];
labelMap?: LabelMap;
}
const AdminTable: React.FC<AdminTableProps> = ({
data,
onDelete,
filterKeys = [],
labelMap = {},
}) => {
const [page, setPage] = useState<number>(0);
const [rowsPerPage, setRowsPerPage] = useState<number>(10);
const [searchQuery, setSearchQuery] = useState<string>("");
const [openDialog, setOpenDialog] = useState<boolean>(false);
2025-03-18 19:31:44 -04:00
const [deleteRow, setDeleteRow] = useState<AdminTableType | null>(null);
2025-03-18 18:33:40 -04:00
const handleChangePage = (_event: unknown, newPage: number) => {
setPage(newPage);
};
const handleChangeRowsPerPage = (event: React.ChangeEvent<HTMLTextAreaElement | HTMLInputElement>) => {
setRowsPerPage(parseInt(event.target.value, 10));
setPage(0);
};
const handleSearchChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setSearchQuery(event.target.value);
setPage(0);
};
2025-03-18 19:31:44 -04:00
const handleOpenDialog = (row: AdminTableType) => {
2025-03-18 18:33:40 -04:00
setDeleteRow(row);
setOpenDialog(true);
};
const handleCloseDialog = () => {
setOpenDialog(false);
setDeleteRow(null);
};
const handleConfirmDelete = () => {
if (deleteRow) {
onDelete(deleteRow);
}
handleCloseDialog();
};
const filteredData = data.filter((row) => {
return Object.values(row).some((value) =>
value.toString().toLowerCase().includes(searchQuery.toLowerCase())
);
});
const headers = Object.keys(labelMap).filter((key) => !filterKeys.includes(key));
return (
<Paper sx={{ width: "100%", overflow: "hidden", padding: "16px" }}>
<Box display="flex" justifyContent="flex-start" marginBottom={2}>
<Input
2025-03-18 20:03:54 -04:00
placeholder="Recherche: Enseignant, Courriel..."
2025-03-18 18:33:40 -04:00
value={searchQuery}
onChange={handleSearchChange}
startAdornment={
<InputAdornment position="start">
<SearchIcon />
</InputAdornment>
}
sx={{ width: "30%" }}
/>
</Box>
<TableContainer>
<Table>
<TableHead>
<TableRow>
{headers.map((key) => (
<TableCell key={key} sx={{ fontWeight: "bold", fontSize: "1.1rem" }}>
{labelMap[key] || key} {/* Use custom label from map or fallback to key */}
</TableCell>
))}
<TableCell />
</TableRow>
</TableHead>
<TableBody>
{filteredData
.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)
.map((row, index) => (
<TableRow key={row._id} sx={{ backgroundColor: index % 2 === 0 ? "#f9f9f9" : "inherit" }}>
{headers.map((key) => {
2025-03-18 19:31:44 -04:00
const value = row[key as keyof AdminTableType];
2025-03-18 18:33:40 -04:00
let displayValue;
if (value instanceof Date) {
2025-03-18 19:31:44 -04:00
displayValue = value.toLocaleDateString();
2025-03-18 18:33:40 -04:00
} else if (value && typeof value === "string" && !isNaN(Date.parse(value))) {
2025-03-18 19:31:44 -04:00
displayValue = new Date(value).toLocaleDateString();
2025-03-18 18:33:40 -04:00
} else {
displayValue = value;
}
return <TableCell key={key}>{displayValue}</TableCell>;
})}
<TableCell>
<IconButton color="error" onClick={() => handleOpenDialog(row)}>
<DeleteIcon />
</IconButton>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
<TablePagination
rowsPerPageOptions={[5, 10, 25]}
component="div"
count={filteredData.length}
rowsPerPage={rowsPerPage}
page={page}
onPageChange={handleChangePage}
onRowsPerPageChange={handleChangeRowsPerPage}
/>
<Dialog open={openDialog} onClose={handleCloseDialog}>
<DialogTitle>Confirm Deletion</DialogTitle>
<DialogContent>
<DialogContentText>
Are you sure you want to delete this record?
</DialogContentText>
</DialogContent>
<DialogActions>
<Button onClick={handleCloseDialog}>Cancel</Button>
<Button onClick={handleConfirmDelete} color="error">
Delete
</Button>
</DialogActions>
</Dialog>
</Paper>
);
};
export default AdminTable;