From de5f8fad6cb58074a78b921b4196b3f3d5220eb1 Mon Sep 17 00:00:00 2001 From: Eddi3_As Date: Tue, 11 Mar 2025 19:50:28 -0400 Subject: [PATCH] FIX - url DEV et PROD - images par prof --- client/src/Types/Images.tsx | 6 ++ .../components/ImageGallery/ImageGallery.tsx | 4 +- client/src/constants.tsx | 1 + client/src/services/ApiService.tsx | 56 +++++++++++++++++-- docker-compose.yaml | 1 + server/controllers/images.js | 25 +++++++-- server/models/images.js | 33 ++++++++++- server/routers/images.js | 1 + 8 files changed, 115 insertions(+), 12 deletions(-) diff --git a/client/src/Types/Images.tsx b/client/src/Types/Images.tsx index 84e1e5a..8cfe170 100644 --- a/client/src/Types/Images.tsx +++ b/client/src/Types/Images.tsx @@ -9,3 +9,9 @@ export interface ImagesResponse { images: Images[]; total: number; } + +export interface ImagesParams { + page: number; + limit: number; + uid?: string; +} \ No newline at end of file diff --git a/client/src/components/ImageGallery/ImageGallery.tsx b/client/src/components/ImageGallery/ImageGallery.tsx index 53b181b..7184cda 100644 --- a/client/src/components/ImageGallery/ImageGallery.tsx +++ b/client/src/components/ImageGallery/ImageGallery.tsx @@ -20,6 +20,7 @@ import CloseIcon from "@mui/icons-material/Close"; import EditIcon from "@mui/icons-material/Edit"; import { Images } from "../../Types/Images"; import ApiService from '../../services/ApiService'; +import { ENV_VARIABLES } from '../constants'; type Props = { galleryOpen: boolean; @@ -52,7 +53,8 @@ const ImageDialog: React.FC = ({ galleryOpen, admin, setDialogOpen, setIm }; const onCopy = (id: string) => { - const escLink = 'http://localhost:4400/api/image/get/'+id; + const escLink = `${ENV_VARIABLES.IMG_URL}/api/image/get/${id}`; + console.log(escLink); setCopiedId(id); setImageLinks(prevLinks => [...prevLinks, escLink]); }; diff --git a/client/src/constants.tsx b/client/src/constants.tsx index ad5b80b..fcdd278 100644 --- a/client/src/constants.tsx +++ b/client/src/constants.tsx @@ -2,6 +2,7 @@ const ENV_VARIABLES = { MODE: process.env.MODE || "production", VITE_BACKEND_URL: process.env.VITE_BACKEND_URL || "", + IMG_URL: process.env.MODE == "development" ? process.env.VITE_BACKEND_URL : process.env.IMG_URL, BACKEND_URL: process.env.SITE_URL != undefined ? `${process.env.SITE_URL}${process.env.USE_PORTS ? `:${process.env.BACKEND_PORT}`:''}` : process.env.VITE_BACKEND_URL || '', FRONTEND_URL: process.env.SITE_URL != undefined ? `${process.env.SITE_URL}${process.env.USE_PORTS ? `:${process.env.PORT}`:''}` : '' }; diff --git a/client/src/services/ApiService.tsx b/client/src/services/ApiService.tsx index fe573eb..0984652 100644 --- a/client/src/services/ApiService.tsx +++ b/client/src/services/ApiService.tsx @@ -3,7 +3,7 @@ import { jwtDecode } from 'jwt-decode'; import { ENV_VARIABLES } from '../constants'; import { FolderType } from 'src/Types/FolderType'; -import { ImagesResponse } from '../Types/Images'; +import { ImagesResponse, ImagesParams } from '../Types/Images'; import { QuizType } from 'src/Types/QuizType'; import { RoomType } from 'src/Types/RoomType'; @@ -143,6 +143,21 @@ class ApiService { return object.username; } + public getUserID(): string { + const objectStr = localStorage.getItem("jwt"); + + if (!objectStr) { + return ""; + } + + const jsonObj = JSON.parse(objectStr); + if (!jsonObj.userId) { + return ""; + } + + return jsonObj.userId; + } + // Route to know if rooms need authentication to join public async getRoomsRequireAuth(): Promise { const url: string = this.constructRequestUrl(`/auth/getRoomsRequireAuth`); @@ -1169,20 +1184,51 @@ public async login(email: string, password: string): Promise { } } - 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}; + let params : ImagesParams = { 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}`); + throw new Error(`L'affichage des images a échoué. Status: ${result.status}`); + } + 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}`); } - console.log(result.data); + throw new Error(`ERROR : Une erreur inattendue s'est produite.`); + } + } + + public async getUserImages(page: number, limit: number): Promise { + try { + const url: string = this.constructRequestUrl(`/image/getUserImages`); + const headers = this.constructRequestHeaders(); + let params : ImagesParams = { page: page, limit: limit }; + + const uid = this.getUserID(); + if(uid !== ''){ + params.uid = uid; + } + + const result: AxiosResponse = await axios.get(url, { params: params, headers: headers }); + + if (result.status !== 200) { + throw new Error(`L'affichage des images de l'utilisateur a échoué. Status: ${result.status}`); + } const images = result.data; return images; diff --git a/docker-compose.yaml b/docker-compose.yaml index 539c800..8db680e 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -10,6 +10,7 @@ services: - VITE_BACKEND_URL= # Define empty VITE_BACKEND_SOCKET_URL so it will default to window.location.host - VITE_BACKEND_SOCKET_URL= + - IMG_URL: https://evalsa.etsmtl.ca ports: - "5173:5173" restart: always diff --git a/server/controllers/images.js b/server/controllers/images.js index c5675d4..e0ac12c 100644 --- a/server/controllers/images.js +++ b/server/controllers/images.js @@ -54,15 +54,32 @@ class ImagesController { try { const page = parseInt(req.query.page) || 1; const limit = parseInt(req.query.limit) || 5; + const images = await this.images.getImages(page, limit); - const imagesBit = await this.images.getImages(page, limit); - - if (!imagesBit || imagesBit.length === 0) { + if (!images || images.length === 0) { throw new AppError(IMAGE_NOT_FOUND); } res.setHeader('Content-Type', 'application/json'); - return res.status(200).json(imagesBit); + return res.status(200).json(images); + } catch (error) { + return next(error); + } + }; + + getUserImages = async (req, res, next) => { + try { + const page = parseInt(req.query.page) || 1; + const limit = parseInt(req.query.limit) || 5; + const uid = req.query.uid; + const images = await this.images.getUserImages(page, limit, uid); + + if (!images || images.length === 0) { + throw new AppError(IMAGE_NOT_FOUND); + } + + res.setHeader('Content-Type', 'application/json'); + return res.status(200).json(images); } catch (error) { return next(error); } diff --git a/server/models/images.js b/server/models/images.js index 13d6ad0..036ce1e 100644 --- a/server/models/images.js +++ b/server/models/images.js @@ -49,11 +49,40 @@ class Images { const imagesCollection = conn.collection('images'); - const total = await imagesCollection.countDocuments(); // Efficient total count + const total = await imagesCollection.countDocuments(); if (!total || total === 0) return { images: [], total }; const result = await imagesCollection.find({}) - .sort({ created_at: 1 }) // Ensure 'created_at' is indexed + .sort({ created_at: 1 }) + .skip((page - 1) * limit) + .limit(limit) + .toArray(); + + const objImages = result.map(image => ({ + id: image._id, + user: image.userId, + file_name: image.file_name, + file_content: image.file_content.toString('base64'), + mime_type: image.mime_type + })); + + let respObj = { + images: objImages, + total: total + } + + return respObj; + } + + async getUserImages(page, limit, uid) { + await this.db.connect() + const conn = this.db.getConnection(); + const imagesCollection = conn.collection('images'); + const total = await imagesCollection.countDocuments({ userId: uid }); + if (!total || total === 0) return { images: [], total }; + + const result = await imagesCollection.find({ userId: uid }) + .sort({ created_at: 1 }) .skip((page - 1) * limit) .limit(limit) .toArray(); diff --git a/server/routers/images.js b/server/routers/images.js index 626e6e8..40aa481 100644 --- a/server/routers/images.js +++ b/server/routers/images.js @@ -13,5 +13,6 @@ const upload = multer({ storage: storage }); router.post("/upload", jwt.authenticate, upload.single('image'), asyncHandler(images.upload)); router.get("/get/:id", asyncHandler(images.get)); router.get("/getImages", asyncHandler(images.getImages)); +router.get("/getUserImages", asyncHandler(images.getUserImages)); module.exports = router;