EvalueTonSavoir/client/src/pages/Admin/Stats.tsx

172 lines
6.3 KiB
TypeScript
Raw Normal View History

2025-03-16 00:52:22 -04:00
import React, { useState, useEffect } from "react";
2025-03-17 20:47:07 -04:00
import {
Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Paper,
IconButton, Grid, Typography, CircularProgress, Box, TextField, Accordion, AccordionSummary, AccordionDetails
} from "@mui/material";
2025-03-16 00:52:22 -04:00
import DeleteIcon from "@mui/icons-material/Delete";
import ApiService from '../../services/ApiService';
2025-03-17 20:47:07 -04:00
import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
2025-03-16 00:52:22 -04:00
import { QuizTypeShort } from "../../Types/QuizType";
const Users: React.FC = () => {
const [quizzes, setQuizzes] = useState<QuizTypeShort[]>([]);
2025-03-17 20:47:07 -04:00
const [filteredQuizzes, setFilteredQuizzes] = useState<QuizTypeShort[]>([]);
2025-03-16 20:26:55 -04:00
const [monthlyQuizzes, setMonthlyQuizzes] = useState(0);
const [totalUsers, setTotalUsers] = useState(0);
const [loading, setLoading] = useState(true);
2025-03-17 20:47:07 -04:00
const [emailFilter, setEmailFilter] = useState("");
const [dateFilter, setDateFilter] = useState("");
const [expanded, setExpanded] = useState(false);
2025-03-16 00:52:22 -04:00
useEffect(() => {
2025-03-16 20:26:55 -04:00
const fetchStats = async () => {
2025-03-16 00:52:22 -04:00
try {
2025-03-16 20:26:55 -04:00
const data = await ApiService.getStats();
setQuizzes(data.quizzes);
2025-03-17 20:47:07 -04:00
setFilteredQuizzes(data.quizzes);
2025-03-16 20:26:55 -04:00
setTotalUsers(data.total);
const currentMonth = new Date().getMonth();
const currentYear = new Date().getFullYear();
2025-03-17 20:47:07 -04:00
const filteredMonthlyQuizzes = data.quizzes.filter((quiz: QuizTypeShort) => {
2025-03-16 20:26:55 -04:00
const quizDate = new Date(quiz.created_at);
return quizDate.getMonth() === currentMonth && quizDate.getFullYear() === currentYear;
});
2025-03-17 20:47:07 -04:00
setMonthlyQuizzes(filteredMonthlyQuizzes.length === 0 ? 10 : 0);
2025-03-16 00:52:22 -04:00
} catch (error) {
console.error("Error fetching quizzes:", error);
2025-03-16 20:26:55 -04:00
} finally {
setLoading(false);
2025-03-16 00:52:22 -04:00
}
};
2025-03-16 20:26:55 -04:00
fetchStats();
2025-03-16 00:52:22 -04:00
}, []);
2025-03-17 20:47:07 -04:00
useEffect(() => {
const filtered = quizzes.filter(quiz =>
quiz.email.toLowerCase().includes(emailFilter.toLowerCase()) &&
((new Date(quiz.created_at).toLocaleDateString().includes(dateFilter) ||
new Date(quiz.updated_at).toLocaleDateString().includes(dateFilter)))
);
setFilteredQuizzes(filtered);
}, [emailFilter, dateFilter, quizzes]);
2025-03-16 00:52:22 -04:00
const handleDelete = (id: string) => {
setQuizzes(quizzes.filter(quiz => quiz._id !== id));
};
2025-03-16 20:26:55 -04:00
const totalQuizzes = quizzes.length;
if (loading) {
return (
<Box display="flex" justifyContent="center" alignItems="center" height="100vh">
<CircularProgress size={80} thickness={5} />
</Box>
);
}
2025-03-16 00:52:22 -04:00
return (
2025-03-16 20:26:55 -04:00
<Paper className="p-4" sx={{ boxShadow: 'none' }}>
<Grid container spacing={8} justifyContent="center">
<Grid item>
<Typography variant="h6" align="center">Quiz du Mois</Typography>
<Box position="relative" display="inline-flex">
<CircularProgress variant="determinate" value={monthlyQuizzes === 0 ? 0 : monthlyQuizzes} size={80} thickness={5} />
<Box position="absolute" top={0} left={0} bottom={0} right={0} display="flex" alignItems="center" justifyContent="center">
<Typography variant="h6">{monthlyQuizzes}</Typography>
</Box>
</Box>
</Grid>
<Grid item>
<Typography variant="h6" align="center">Quiz total</Typography>
<Box position="relative" display="inline-flex">
<CircularProgress variant="determinate" value={totalQuizzes} size={80} thickness={5} />
<Box position="absolute" top={0} left={0} bottom={0} right={0} display="flex" alignItems="center" justifyContent="center">
<Typography variant="h6">{totalQuizzes}</Typography>
</Box>
</Box>
</Grid>
<Grid item>
<Typography variant="h6" align="center">Enseignants</Typography>
<Box position="relative" display="inline-flex">
<CircularProgress variant="determinate" value={totalUsers} size={80} thickness={5} />
<Box position="absolute" top={0} left={0} bottom={0} right={0} display="flex" alignItems="center" justifyContent="center">
<Typography variant="h6">{totalUsers}</Typography>
</Box>
</Box>
</Grid>
</Grid>
2025-03-17 20:47:07 -04:00
<Accordion expanded={expanded} onChange={() => setExpanded(!expanded)}>
<AccordionSummary
expandIcon={<ExpandMoreIcon />}
aria-controls="filter-content"
id="filter-header"
>
<Typography variant="h6">Filtres</Typography>
</AccordionSummary>
<AccordionDetails>
<Grid container spacing={3}>
<Grid item xs={12} sm={3}>
<TextField
fullWidth
variant="outlined"
size="small"
placeholder="Filtrer par email"
value={emailFilter}
onChange={(e) => setEmailFilter(e.target.value)}
/>
</Grid>
<Grid item xs={12} sm={3}>
<TextField
fullWidth
variant="outlined"
size="small"
placeholder="Filtrer par date"
value={dateFilter}
onChange={(e) => setDateFilter(e.target.value)}
/>
</Grid>
</Grid>
</AccordionDetails>
</Accordion>
2025-03-16 20:26:55 -04:00
{/* Table */}
<TableContainer component={Paper} className="mt-4">
<Table>
<TableHead>
<TableRow>
2025-03-17 20:47:07 -04:00
<TableCell>
Enseignant
</TableCell>
2025-03-16 20:26:55 -04:00
<TableCell>Titre</TableCell>
<TableCell>Crée</TableCell>
<TableCell>Modifié</TableCell>
2025-03-16 00:52:22 -04:00
</TableRow>
2025-03-16 20:26:55 -04:00
</TableHead>
<TableBody>
2025-03-17 20:47:07 -04:00
{filteredQuizzes.map((quiz) => (
2025-03-16 20:26:55 -04:00
<TableRow key={quiz._id}>
2025-03-17 19:06:25 -04:00
<TableCell>{quiz.email}</TableCell>
2025-03-16 20:26:55 -04:00
<TableCell>{quiz.title}</TableCell>
<TableCell>{new Date(quiz.created_at).toLocaleDateString()}</TableCell>
<TableCell>{new Date(quiz.updated_at).toLocaleDateString()}</TableCell>
<TableCell>
<IconButton onClick={() => handleDelete(quiz._id)} color="error">
<DeleteIcon />
</IconButton>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
</Paper>
2025-03-16 00:52:22 -04:00
);
};
export default Users;