ajout front images gallery

This commit is contained in:
Eddi3_As 2025-03-02 20:52:08 -05:00
parent 16d594c61d
commit c9d65c0082
5 changed files with 136 additions and 5 deletions

View file

@ -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;
}

View file

@ -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<HTMLInputElement>(null);
const [dialogOpen, setDialogOpen] = useState(false);
const [galleryOpen, setGalleryOpen] = useState(false);
const [showScrollButton, setShowScrollButton] = useState(false);
const [images, setImages] = useState<Images[]>([]);
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 (
<div className='quizEditor'>
@ -290,6 +313,48 @@ const QuizForm: React.FC = () => {
</div>
<h4>Mes images :</h4>
<Button
variant="outlined"
aria-label='Téléverser'
onClick={() => setGalleryOpen(true)}>
Images <ImageSearch />
</Button>
<Dialog
open={galleryOpen}
onClose={() => setDialogOpen(false)} >
<DialogTitle>Images disponibles</DialogTitle>
<DialogContent>
<div className="grid grid-cols-3 gap-4 p-4">
{images.map((obj: Images, index) => (
<div key={obj.id}>
<img
key={index}
src={`data:${obj.mime_type};base64,${obj.file_content}`}
alt={`Image ${obj.file_name + 1}`}
className="w-full h-auto rounded-lg shadow-md"
/>
{`lien: ${obj.id}`}
</div>
))}
</div>
</DialogContent>
<DialogActions>
{
totalImg > 10 ?
<Button onClick={() => handleMoreImages()} color="primary">
Plus
</Button>
:
<Button onClick={() => setDialogOpen(false)} color="primary">
OK
</Button>
}
</DialogActions>
</Dialog>
<div>
<div>
<div style={{ display: "inline" }}>(Voir section </div>

View file

@ -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<ImagesResponse> {
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.`);
}
}
}

View file

@ -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);
}

View file

@ -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;
}
}