Fix - Users ajout admintable

This commit is contained in:
Eddi3_As 2025-03-18 19:31:44 -04:00
parent af2840e262
commit 4e33165d9b
5 changed files with 48 additions and 47 deletions

View file

@ -1,2 +1,12 @@
export type LabelMap = { [key: string]: string }; export type LabelMap = { [key: string]: string };
export interface AdminTableType {
_id: string;
email: string;
title: string;
created_at: Date;
updated_at: Date;
name: string;
roles: string[];
}

View file

@ -22,12 +22,12 @@ import {
import DeleteIcon from "@mui/icons-material/Delete"; import DeleteIcon from "@mui/icons-material/Delete";
import SearchIcon from "@mui/icons-material/Search"; import SearchIcon from "@mui/icons-material/Search";
import { QuizTypeShort } from "../../Types/QuizType"; import { QuizTypeShort } from "../../Types/QuizType";
import { LabelMap } from "../../Types/LabelMap"; import { LabelMap, AdminTableType } from "../../Types/LabelMap";
interface AdminTableProps { interface AdminTableProps {
data: QuizTypeShort[]; data: AdminTableType[];
onDelete: (row: QuizTypeShort) => void; onDelete: (row: AdminTableType) => void;
filterKeys?: string[]; filterKeys?: string[];
labelMap?: LabelMap; labelMap?: LabelMap;
} }
@ -42,7 +42,7 @@ const AdminTable: React.FC<AdminTableProps> = ({
const [rowsPerPage, setRowsPerPage] = useState<number>(10); const [rowsPerPage, setRowsPerPage] = useState<number>(10);
const [searchQuery, setSearchQuery] = useState<string>(""); const [searchQuery, setSearchQuery] = useState<string>("");
const [openDialog, setOpenDialog] = useState<boolean>(false); const [openDialog, setOpenDialog] = useState<boolean>(false);
const [deleteRow, setDeleteRow] = useState<QuizTypeShort | null>(null); const [deleteRow, setDeleteRow] = useState<AdminTableType | null>(null);
const handleChangePage = (_event: unknown, newPage: number) => { const handleChangePage = (_event: unknown, newPage: number) => {
setPage(newPage); setPage(newPage);
@ -58,7 +58,7 @@ const AdminTable: React.FC<AdminTableProps> = ({
setPage(0); setPage(0);
}; };
const handleOpenDialog = (row: QuizTypeShort) => { const handleOpenDialog = (row: AdminTableType) => {
setDeleteRow(row); setDeleteRow(row);
setOpenDialog(true); setOpenDialog(true);
}; };
@ -116,12 +116,12 @@ const AdminTable: React.FC<AdminTableProps> = ({
.map((row, index) => ( .map((row, index) => (
<TableRow key={row._id} sx={{ backgroundColor: index % 2 === 0 ? "#f9f9f9" : "inherit" }}> <TableRow key={row._id} sx={{ backgroundColor: index % 2 === 0 ? "#f9f9f9" : "inherit" }}>
{headers.map((key) => { {headers.map((key) => {
const value = row[key as keyof QuizTypeShort]; const value = row[key as keyof AdminTableType];
let displayValue; let displayValue;
if (value instanceof Date) { if (value instanceof Date) {
displayValue = value.toLocaleDateString("en-GB"); displayValue = value.toLocaleDateString();
} else if (value && typeof value === "string" && !isNaN(Date.parse(value))) { } else if (value && typeof value === "string" && !isNaN(Date.parse(value))) {
displayValue = new Date(value).toLocaleDateString("en-GB"); displayValue = new Date(value).toLocaleDateString();
} else { } else {
displayValue = value; displayValue = value;
} }

View file

@ -2,13 +2,13 @@ import React, { useState, useEffect } from "react";
import { Paper, Grid, Typography, CircularProgress, Box, TextField, Accordion, AccordionSummary, AccordionDetails} from "@mui/material"; import { Paper, Grid, Typography, CircularProgress, Box, TextField, Accordion, AccordionSummary, AccordionDetails} from "@mui/material";
import ApiService from '../../services/ApiService'; import ApiService from '../../services/ApiService';
import ExpandMoreIcon from "@mui/icons-material/ExpandMore"; import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
import { QuizTypeShort } from "../../Types/QuizType"; import { AdminTableType } from "../../Types/LabelMap/AdminTableType";
import AdminTable from "../../components/AdminTable/AdminTable"; import AdminTable from "../../components/AdminTable/AdminTable";
const Users: React.FC = () => { const Users: React.FC = () => {
const [quizzes, setQuizzes] = useState<QuizTypeShort[]>([]); const [quizzes, setQuizzes] = useState<AdminTableType[]>([]);
const [filteredQuizzes, setFilteredQuizzes] = useState<QuizTypeShort[]>([]); const [filteredQuizzes, setFilteredQuizzes] = useState<AdminTableType[]>([]);
const [monthlyQuizzes, setMonthlyQuizzes] = useState(0); const [monthlyQuizzes, setMonthlyQuizzes] = useState(0);
const [totalUsers, setTotalUsers] = useState(0); const [totalUsers, setTotalUsers] = useState(0);
const [loading, setLoading] = useState(true); const [loading, setLoading] = useState(true);
@ -26,7 +26,7 @@ const Users: React.FC = () => {
const currentMonth = new Date().getMonth(); const currentMonth = new Date().getMonth();
const currentYear = new Date().getFullYear(); const currentYear = new Date().getFullYear();
const filteredMonthlyQuizzes = data.quizzes.filter((quiz: QuizTypeShort) => { const filteredMonthlyQuizzes = data.quizzes.filter((quiz: AdminTableType) => {
const quizDate = new Date(quiz.created_at); const quizDate = new Date(quiz.created_at);
return quizDate.getMonth() === currentMonth && quizDate.getFullYear() === currentYear; return quizDate.getMonth() === currentMonth && quizDate.getFullYear() === currentYear;
}); });
@ -50,7 +50,7 @@ const Users: React.FC = () => {
setFilteredQuizzes(filtered); setFilteredQuizzes(filtered);
}, [emailFilter, dateFilter, quizzes]); }, [emailFilter, dateFilter, quizzes]);
const handleQuizDelete = (rowToDelete: QuizTypeShort) => { const handleQuizDelete = (rowToDelete: AdminTableType) => {
setQuizzes((prevData) => prevData.filter((row) => row._id !== rowToDelete._id)); setQuizzes((prevData) => prevData.filter((row) => row._id !== rowToDelete._id));
}; };

View file

@ -2,15 +2,17 @@ import React, { useState, useEffect } from "react";
import { Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Paper, IconButton } from "@mui/material"; import { Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Paper, IconButton } from "@mui/material";
import DeleteIcon from "@mui/icons-material/Delete"; import DeleteIcon from "@mui/icons-material/Delete";
import ApiService from '../../services/ApiService'; import ApiService from '../../services/ApiService';
import { UserType } from "../../Types/UserType"; import { LabelMap, AdminTableType } from "../../Types/LabelMap";
import AdminTable from "../../components/AdminTable/AdminTable";
const Users: React.FC = () => { const Users: React.FC = () => {
const [users, setUsers] = useState<UserType[]>([]); const [users, setUsers] = useState<AdminTableType[]>([]);
useEffect(() => { useEffect(() => {
const fetchUsers = async () => { const fetchUsers = async () => {
try { try {
const data = await ApiService.getUsers(); const data = await ApiService.getUsers();
console.log(data);
setUsers(data); setUsers(data);
} catch (error) { } catch (error) {
console.error("Error fetching users:", error); console.error("Error fetching users:", error);
@ -19,38 +21,27 @@ const Users: React.FC = () => {
fetchUsers(); fetchUsers();
}, []); }, []);
const handleDelete = (email: string) => { const handleDelete = (data: AdminTableType) => {
setUsers(users.filter(user => user.email !== email)); setUsers(users.filter(user => user.email !== data.email));
};
const labelMap = {
_id: "ID",
name: "Enseignant",
email: "Courriel",
created_at: "Création",
roles: "Rôles",
}; };
return ( return (
<TableContainer component={Paper} className="p-4"> <AdminTable
<Table> data={users}
<TableHead> onDelete={handleDelete}
<TableRow> filterKeys={["_id", "password"]}
<TableCell>Nom</TableCell> labelMap={labelMap}
<TableCell>Courriel</TableCell> />
<TableCell>Crée</TableCell>
<TableCell>Roles</TableCell>
</TableRow>
</TableHead>
<TableBody>
{users.map((user) => (
<TableRow key={user.email}>
<TableCell>{user.name}</TableCell>
<TableCell>{user.email}</TableCell>
<TableCell>{new Date(user.created_at).toLocaleDateString()}</TableCell>
<TableCell>{user.roles?.join(", ")}</TableCell>
<TableCell>
<IconButton onClick={() => handleDelete(user.email)} color="error">
<DeleteIcon />
</IconButton>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
); );
}; };

View file

@ -5,7 +5,7 @@ import { ENV_VARIABLES } from '../constants';
import { FolderType } from 'src/Types/FolderType'; import { FolderType } from 'src/Types/FolderType';
import { QuizType, QuizResponse } from 'src/Types/QuizType'; import { QuizType, QuizResponse } from 'src/Types/QuizType';
import { RoomType } from 'src/Types/RoomType'; import { RoomType } from 'src/Types/RoomType';
import { UserType } from 'src/Types/UserType'; import { AdminTableType } from 'src/Types/LabelMap';
import { ImagesResponse, ImagesParams } from 'src/Types/ImageType'; import { ImagesResponse, ImagesParams } from 'src/Types/ImageType';
type ApiResponse = boolean | string; type ApiResponse = boolean | string;
@ -1171,7 +1171,7 @@ public async login(email: string, password: string): Promise<any> {
} }
} }
public async getUsers(): Promise<UserType[]> { public async getUsers(): Promise<AdminTableType[]> {
try { try {
const url: string = this.constructRequestUrl(`/admin/getUsers`); const url: string = this.constructRequestUrl(`/admin/getUsers`);