From c9d65c00820586a9480c0461108765a5d004742f Mon Sep 17 00:00:00 2001 From: Eddi3_As Date: Sun, 2 Mar 2025 20:52:08 -0500 Subject: [PATCH] ajout front images gallery --- client/src/Types/Images.tsx | 11 +++ .../pages/Teacher/EditorQuiz/EditorQuiz.tsx | 67 ++++++++++++++++++- client/src/services/ApiService.tsx | 47 ++++++++++++- server/controllers/users.js | 7 +- server/models/images.js | 9 ++- 5 files changed, 136 insertions(+), 5 deletions(-) create mode 100644 client/src/Types/Images.tsx diff --git a/client/src/Types/Images.tsx b/client/src/Types/Images.tsx new file mode 100644 index 0000000..84e1e5a --- /dev/null +++ b/client/src/Types/Images.tsx @@ -0,0 +1,11 @@ +export interface Images { + id: string; + file_content: string; + file_name: string; + mime_type: string; +} + +export interface ImagesResponse { + images: Images[]; + total: number; +} diff --git a/client/src/pages/Teacher/EditorQuiz/EditorQuiz.tsx b/client/src/pages/Teacher/EditorQuiz/EditorQuiz.tsx index f2c2d69..51ad681 100644 --- a/client/src/pages/Teacher/EditorQuiz/EditorQuiz.tsx +++ b/client/src/pages/Teacher/EditorQuiz/EditorQuiz.tsx @@ -16,7 +16,8 @@ import ReturnButton from 'src/components/ReturnButton/ReturnButton'; import ApiService from '../../../services/ApiService'; import { escapeForGIFT } from '../../../utils/giftUtils'; -import { Upload } from '@mui/icons-material'; +import { Upload, ImageSearch } from '@mui/icons-material'; +import { Images } from '../../../Types/Images'; interface EditQuizParams { id: string; @@ -40,7 +41,12 @@ const QuizForm: React.FC = () => { }; const fileInputRef = useRef(null); const [dialogOpen, setDialogOpen] = useState(false); + const [galleryOpen, setGalleryOpen] = useState(false); const [showScrollButton, setShowScrollButton] = useState(false); + const [images, setImages] = useState([]); + const [totalImg, setTotalImg] = useState(0); + const [imgPage, setImgPage] = useState(1); + const [imgLimit] = useState(5); const scrollToTop = () => { window.scrollTo({ top: 0, behavior: 'smooth' }); @@ -69,9 +75,19 @@ const QuizForm: React.FC = () => { } }; + const fetchImages = async (page: number , limit: number) => { + const data = await ApiService.getImages(page, limit); + const imgs = data.images; + const total = data.total; + + setImages(imgs as Images[]); + setTotalImg(total); + } + useEffect(() => { const fetchData = async () => { const userFolders = await ApiService.getUserFolders(); + fetchImages(1, imgLimit); setFolders(userFolders as FolderType[]); }; @@ -205,6 +221,13 @@ const QuizForm: React.FC = () => { navigator.clipboard.writeText(link); } + const handleMoreImages = async () => { + let page = imgPage; + page += 1; + setImgPage(page); + fetchImages(imgPage, imgLimit); + } + return (
@@ -290,6 +313,48 @@ const QuizForm: React.FC = () => {

Mes images :

+ + + + setDialogOpen(false)} > + Images disponibles + + +
+ {images.map((obj: Images, index) => ( +
+ {`Image + {`lien: ${obj.id}`} +
+ ))} +
+
+ + { + totalImg > 10 ? + + : + + + } + +
(Voir section
diff --git a/client/src/services/ApiService.tsx b/client/src/services/ApiService.tsx index ef124b4..22189e5 100644 --- a/client/src/services/ApiService.tsx +++ b/client/src/services/ApiService.tsx @@ -1,6 +1,7 @@ import axios, { AxiosError, AxiosResponse } from 'axios'; import { FolderType } from 'src/Types/FolderType'; +import { ImagesResponse } from '../Types/Images'; import { QuizType } from 'src/Types/QuizType'; import { ENV_VARIABLES } from 'src/constants'; @@ -65,6 +66,16 @@ class ApiService { return object.token; } + private getUserID(): string | null { + const objStr = localStorage.getItem("uid"); + + if (!objStr) { + return null; + } + + return objStr; + } + public isLoggedIn(): boolean { const token = this.getToken() @@ -141,7 +152,8 @@ class ApiService { throw new Error(`La connexion a échoué. Status: ${result.status}`); } - this.saveToken(result.data.token); + this.saveToken(result.data.result.token); + localStorage.setItem("uid", JSON.stringify(result.data.result.userId)); return true; @@ -886,7 +898,38 @@ class ApiService { return `ERROR : Une erreur inattendue s'est produite.` } } - // NOTE : Get Image pas necessaire + + + public async getImages(page: number, limit: number): Promise { + try { + const url: string = this.constructRequestUrl(`/image/getImages`); + const headers = this.constructRequestHeaders(); + const params = { page: page, limit: limit}; + + const result: AxiosResponse = await axios.get(url, { params: params, headers: headers }); + + if (result.status !== 200) { + throw new Error(`L'enregistrement a échoué. Status: ${result.status}`); + } + + console.log(result.data); + const images = result.data; + + return images; + + } catch (error) { + console.log("Error details: ", error); + + if (axios.isAxiosError(error)) { + const err = error as AxiosError; + const data = err.response?.data as { error: string } | undefined; + const msg = data?.error || 'Erreur serveur inconnue lors de la requête.'; + throw new Error(`L'enregistrement a échoué. Status: ${msg}`); + } + + throw new Error(`ERROR : Une erreur inattendue s'est produite.`); + } + } } diff --git a/server/controllers/users.js b/server/controllers/users.js index c6b5dab..57ebeeb 100644 --- a/server/controllers/users.js +++ b/server/controllers/users.js @@ -54,7 +54,12 @@ class UsersController { const token = jwt.create(user.email, user._id); - return res.status(200).json({ token }); + let result = { + token: token, + userId: user._id + } + + return res.status(200).json({ result }); } catch (error) { next(error); } diff --git a/server/models/images.js b/server/models/images.js index a9e8306..b631e0e 100644 --- a/server/models/images.js +++ b/server/models/images.js @@ -52,6 +52,8 @@ class Images { if (!result) return null; + const total = result.length; + const objImages = result.slice((page - 1) * limit, page * limit).map(image => ({ id: image._id, user: image.userId, @@ -60,7 +62,12 @@ class Images { mime_type: image.mime_type })); - return objImages; + let respObj = { + images: objImages, + total: total + } + + return respObj; } }