mirror of
https://github.com/ets-cfuhrman-pfe/EvalueTonSavoir.git
synced 2025-08-11 21:23:54 -04:00
FIX cards au lieu de gauge
This commit is contained in:
parent
4c1db84d78
commit
8daef780d3
3 changed files with 45 additions and 133 deletions
|
|
@ -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 }}
|
||||
/>
|
||||
</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>
|
||||
<ImageGallery
|
||||
handleCopy={handleCopy}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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,36 +70,30 @@ 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>
|
||||
<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 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>
|
||||
))}
|
||||
</Grid>
|
||||
|
||||
|
||||
<AdminTable
|
||||
data={quizzes}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in a new issue