FIX cards au lieu de gauge

This commit is contained in:
Eddi3_As 2025-03-28 20:55:14 -04:00
parent 4c1db84d78
commit 8daef780d3
3 changed files with 45 additions and 133 deletions

View file

@ -1,112 +1,18 @@
import React, { useState, useEffect } from "react"; import React from "react";
import { import ImageGallery from "../../components/ImageGallery/ImageGallery";
Table,
TableBody,
TableCell,
TableContainer,
TableRow,
TableHead,
IconButton,
Paper,
Box,
CircularProgress,
Button
} from "@mui/material";
import DeleteIcon from "@mui/icons-material/Delete";
import { ImageType } from "../../Types/ImageType";
import ApiService from '../../services/ApiService';
const Images: React.FC = () => { const Images: React.FC = () => {
const [images, setImages] = useState<ImageType[]>([]);
const [totalImg, setTotalImg] = useState(0);
const [imgPage, setImgPage] = useState(1);
const [imgLimit] = useState(10);
const [loading, setLoading] = useState(false);
const fetchImages = async (page: number, limit: number) => { const handleCopy = (id: string) => {
setLoading(true); if (navigator.clipboard) {
const data = await ApiService.getImages(page, limit); navigator.clipboard.writeText(id);
setImages(data.images);
setTotalImg(data.total);
setLoading(false);
};
useEffect(() => {
fetchImages(imgPage, imgLimit);
}, [imgPage]);
const handleDelete = async (id: string) => {
setLoading(true);
const isDeleted = await ApiService.deleteImage(id);
setLoading(false);
if (isDeleted) {
setImages(images.filter(image => image.id !== id));
}
};
const handleNextPage = () => {
if ((imgPage * imgLimit) < totalImg) {
setImgPage(prev => prev + 1);
}
};
const handlePrevPage = () => {
if (imgPage > 1) {
setImgPage(prev => prev - 1);
} }
}; };
return ( return (
<Box p={3}> <ImageGallery
{loading ? ( handleCopy={handleCopy}
<Box display="flex" justifyContent="center" alignItems="center" height={200}>
<CircularProgress />
</Box>
) : (
<TableContainer component={Paper}>
<Table>
<TableHead>
<TableRow>
<TableCell></TableCell>
<TableCell>Nom</TableCell>
<TableCell>Image ID</TableCell>
</TableRow>
</TableHead>
<TableBody>
{images.map((obj: ImageType) => (
<TableRow key={obj.id}>
<TableCell>
<img
src={`data:${obj.mime_type};base64,${obj.file_content}`}
alt={`Image ${obj.file_name}`}
style={{ width: 350, height: "auto", borderRadius: 8 }}
/> />
</TableCell>
<TableCell>{obj.file_name}</TableCell>
<TableCell style={{ minWidth: 150 }}>
{obj.id}
</TableCell>
<TableCell>
<IconButton onClick={() => handleDelete(obj.id)} color="error">
<DeleteIcon fontSize="small" />
</IconButton>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
)}
<Box display="flex" justifyContent="center" mt={2}>
<Button onClick={handlePrevPage} disabled={imgPage === 1} color="primary">
Précédent
</Button>
<Button onClick={handleNextPage} disabled={(imgPage * imgLimit) >= totalImg} color="primary">
Suivant
</Button>
</Box>
</Box>
); );
}; };

View file

@ -1,10 +1,15 @@
import React, { useState, useEffect } from "react"; import React, { useState, useEffect } from "react";
import { Paper, Grid, Typography, CircularProgress, Box } from "@mui/material"; import { Paper, Grid, Typography, CircularProgress, Box, Card, CardContent} from "@mui/material";
import ApiService from '../../services/ApiService'; import ApiService from '../../services/ApiService';
import { AdminTableType } from "../../Types/AdminTableType"; import { AdminTableType } from "../../Types/AdminTableType";
import AdminTable from "../../components/AdminTable/AdminTable"; import AdminTable from "../../components/AdminTable/AdminTable";
const styles = {
cardBg: 'rgba(82, 113, 255, 1)',
cardHover: 'rgba(65, 105, 225, 0.7)',
};
const Users: React.FC = () => { const Users: React.FC = () => {
const [quizzes, setQuizzes] = useState<AdminTableType[]>([]); const [quizzes, setQuizzes] = useState<AdminTableType[]>([]);
const [monthlyQuizzes, setMonthlyQuizzes] = useState(0); const [monthlyQuizzes, setMonthlyQuizzes] = useState(0);
@ -49,6 +54,13 @@ const Users: React.FC = () => {
); );
} }
const stats = [
{ label: "Quiz du Mois", value: monthlyQuizzes },
{ label: "Quiz total", value: totalQuizzes },
{ label: "Enseignants", value: totalUsers },
{ label: "Enseignants du Mois", value: totalUsers },
];
const labelMap = { const labelMap = {
_id: "ID", _id: "ID",
email: "Enseignant", email: "Enseignant",
@ -58,37 +70,31 @@ const Users: React.FC = () => {
}; };
return ( return (
<Paper className="p-4" sx={{ boxShadow: 'none' }}> <Paper className="p-4" sx={{ boxShadow: 'none', padding: 3 }}>
<Grid container spacing={8} justifyContent="center"> <Grid container spacing={3} justifyContent="center">
<Grid item> {stats.map((stat, index) => (
<Typography variant="h6" align="center">Quiz du Mois</Typography> <Grid item xs={12} sm={3} key={index}>
<Box position="relative" display="inline-flex"> <Card
<CircularProgress variant="determinate" value={monthlyQuizzes === 0 ? 0 : monthlyQuizzes} size={80} thickness={5} /> sx={{
<Box position="absolute" top={0} left={0} bottom={0} right={0} display="flex" alignItems="center" justifyContent="center"> textAlign: "center",
<Typography variant="h6">{monthlyQuizzes}</Typography> padding: 2,
</Box> backgroundColor: styles.cardBg,
</Box> color: "white",
</Grid> transition: "background-color 0.3s ease",
<Grid item> "&:hover": { backgroundColor: styles.cardHover },
<Typography variant="h6" align="center">Quiz total</Typography> }}>
<Box position="relative" display="inline-flex"> <CardContent>
<CircularProgress variant="determinate" value={totalQuizzes} size={80} thickness={5} /> <Typography variant="h6" sx={{ color: "white" }}>{stat.label}</Typography>
<Box position="absolute" top={0} left={0} bottom={0} right={0} display="flex" alignItems="center" justifyContent="center"> <Typography variant="h4" sx={{ color: "white" }}>
<Typography variant="h6">{totalQuizzes}</Typography> {stat.value}
</Box> </Typography>
</Box> </CardContent>
</Grid> </Card>
<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>
))}
</Grid> </Grid>
<AdminTable <AdminTable
data={quizzes} data={quizzes}
onDelete={handleQuizDelete} onDelete={handleQuizDelete}

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 { AdminTableType } from 'src/Types/LabelMap'; import { AdminTableType } from 'src/Types/AdminTableType';
import { ImagesResponse, ImagesParams } from 'src/Types/ImageType'; import { ImagesResponse, ImagesParams } from 'src/Types/ImageType';
type ApiResponse = boolean | string; type ApiResponse = boolean | string;