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 {
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';
import React from "react";
import ImageGallery from "../../components/ImageGallery/ImageGallery";
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) => {
setLoading(true);
const data = await ApiService.getImages(page, limit);
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);
const handleCopy = (id: string) => {
if (navigator.clipboard) {
navigator.clipboard.writeText(id);
}
};
return (
<Box p={3}>
{loading ? (
<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 }}
<ImageGallery
handleCopy={handleCopy}
/>
</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 { 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 { AdminTableType } from "../../Types/AdminTableType";
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 [quizzes, setQuizzes] = useState<AdminTableType[]>([]);
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 = {
_id: "ID",
email: "Enseignant",
@ -58,37 +70,31 @@ const Users: React.FC = () => {
};
return (
<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>
<Paper className="p-4" sx={{ boxShadow: 'none', padding: 3 }}>
<Grid container spacing={3} justifyContent="center">
{stats.map((stat, index) => (
<Grid item xs={12} sm={3} key={index}>
<Card
sx={{
textAlign: "center",
padding: 2,
backgroundColor: styles.cardBg,
color: "white",
transition: "background-color 0.3s ease",
"&:hover": { backgroundColor: styles.cardHover },
}}>
<CardContent>
<Typography variant="h6" sx={{ color: "white" }}>{stat.label}</Typography>
<Typography variant="h4" sx={{ color: "white" }}>
{stat.value}
</Typography>
</CardContent>
</Card>
</Grid>
))}
</Grid>
<AdminTable
data={quizzes}
onDelete={handleQuizDelete}

View file

@ -5,7 +5,7 @@ import { ENV_VARIABLES } from '../constants';
import { FolderType } from 'src/Types/FolderType';
import { QuizType, QuizResponse } from 'src/Types/QuizType';
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';
type ApiResponse = boolean | string;