Merge branch 'features/linkEventsPage' into 'dev'

Features/linkeventspage

See merge request sae-but2/2025-26/gestion-benevoles-association/Frontend!27
This commit is contained in:
T'JAMPENS QUENTIN p2406187
2025-12-07 00:30:22 +00:00
6 changed files with 75 additions and 185 deletions
+25 -23
View File
@@ -1,9 +1,12 @@
import styles from "./Event.module.css"; import styles from "./Event.module.css";
import {useState, useEffect} from "react"; import { useState, useEffect } from "react";
import {Link} from "react-router"; import { useNavigate } from "react-router";
import Button from "/src/components/ui/button/button.jsx" import Button from "/src/components/ui/button/button.jsx"
function Event({event}){ function Event({event}){
const navigate = useNavigate();
const [eventMenu, seteventMenu] = useState(false); const [eventMenu, seteventMenu] = useState(false);
const [windowSize, setWindowSize] = useState({ const [windowSize, setWindowSize] = useState({
width: null, width: null,
@@ -31,7 +34,7 @@ function Event({event}){
<div className={styles.eventContent}> <div className={styles.eventContent}>
<div className={`${styles.eventImageDiv}`}> <div className={`${styles.eventImageDiv}`}>
{event.image == null ? ( {event.image == null ? (
<img src="empty.png" className={styles.eventImage} alt="Pas de photo de l'événement" /> <img src="/empty.png" className={styles.eventImage} alt="Pas de photo de l'événement" />
) : ( ) : (
<img src={event.image + `.png`} alt="Photo de l'événement" /> <img src={event.image + `.png`} alt="Photo de l'événement" />
)} )}
@@ -39,37 +42,36 @@ function Event({event}){
<div className={styles.eventInfos}> <div className={styles.eventInfos}>
<p className={styles.eventTitle}>{event.name}</p> <p className={styles.eventTitle}>{event.name}</p>
<p>{event.description}</p> <p>{event.description}</p>
<div className={eventMenu ? styles.eventMenuOpen : styles.eventMenuClose}> <ul className={eventMenu ? styles.eventMenuOpen : styles.eventMenuClose}>
<ul> {event.tasks.length > 0 && (
{event.tasks <>
.slice(0,5) {event.tasks.slice(0, 5).map((task, index) => (
.map((task, index) => ( <li key={index}> {task.name} </li>
<li key={index}> - {task.name}</li> ))}
))}
{event.tasks.length > 5 ? ( {event.tasks.length > 5 && <li>...</li>}
<li>...</li> </>
) : null} )}
</ul> </ul>
</div>
</div> </div>
</div> </div>
{windowSize.width > 768 ? ( {windowSize.width > 768 ? (
<div className={styles.eventButtons}> <div className={styles.eventButtons}>
<button <Button
className={`${styles.moreButton} ${eventMenu ? styles.moreButtonClicked : ""}`} variant={"transparent"}
onClick={()=>{seteventMenu(!eventMenu)}}> onClick={()=>{seteventMenu(!eventMenu)}}
className={`${eventMenu ? styles.moreButtonClicked : ""}`}
>
{">"} {">"}
</button> </Button>
</div> </div>
) : null} ) : null}
</div> </div>
<div className={styles.eventContainerBottom}> <div className={styles.eventContainerBottom}>
{(windowSize.width <= 768 || eventMenu) ? ( {(windowSize.width <= 768 || eventMenu) ? (
<Link
to={`/event/` + event.id} <Button onClick={() => navigate(`/event/` + event.id)}>Voir plus</Button>
className={styles.moreLink}>
<Button>En savoir plus </Button>
</Link>
) : null} ) : null}
</div> </div>
</div> </div>
+3 -13
View File
@@ -3,6 +3,7 @@
flex-direction: column; flex-direction: column;
margin: 1rem 0; margin: 1rem 0;
width: 80%; width: 80%;
padding: 1rem 0.5rem;
} }
.eventContainerTop { .eventContainerTop {
@@ -45,11 +46,6 @@
font-size: 2rem; font-size: 2rem;
} }
.eventButtons { .eventButtons {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@@ -63,9 +59,6 @@
white-space: nowrap; white-space: nowrap;
} }
.moreButton { .moreButton {
background: none; background: none;
border: none; border: none;
@@ -94,19 +87,16 @@
rotate: 90deg; rotate: 90deg;
} }
.eventMenuOpen { .eventMenuOpen {
display: flex; display: flex;
flex-direction: column;
margin-left: 1.5em;
} }
.eventMenuClose { .eventMenuClose {
display: none; display: none;
} }
@media screen and (max-width: 768px) { @media screen and (max-width: 768px) {
.eventImage { .eventImage {
width: 100%; width: 100%;
+2 -2
View File
@@ -1,6 +1,6 @@
import styles from "./button.module.css"; import styles from "./button.module.css";
const Button = ({ children, variant = "primary", onClick }) => { const Button = ({ children, variant = "primary", onClick, className }) => {
let btnStyle; let btnStyle;
if (variant === "primary") btnStyle = styles.primary; if (variant === "primary") btnStyle = styles.primary;
@@ -8,7 +8,7 @@ const Button = ({ children, variant = "primary", onClick }) => {
else if(variant === "transparent") btnStyle = styles.transparent; else if(variant === "transparent") btnStyle = styles.transparent;
else btnStyle = styles.default; else btnStyle = styles.default;
return <div className={`${styles.btn} ${btnStyle}`} onClick={onClick}> return <div className={`${styles.btn} ${btnStyle} ${className}`} onClick={onClick}>
{children} {children}
</div>; </div>;
}; };
+22 -143
View File
@@ -1,8 +1,9 @@
import {useState} from "react"; import { useEffect, useState } from "react";
import Event from "../../components/Event/Event.jsx"; import Event from "../../components/Event/Event.jsx";
import {Link} from "react-router"; import { Link } from "react-router";
import styles from "./EventsPage.module.css"; import styles from "./EventsPage.module.css";
import Filter from "../../components/Filter/Filter.jsx"; import Filter from "../../components/Filter/Filter.jsx";
import getAllEvents from "../../utils/event/getAllEvents.js";
@@ -17,8 +18,11 @@ function EventsPage(){
yearOrder: "asc", yearOrder: "asc",
}); });
const [events] = useState([ const [events, setEvents] = useState([]);
{
/*
{
id: 1, id: 1,
name: "Marathon de la Ville", name: "Marathon de la Ville",
description: "Participez au marathon annuel et soutenez les associations locales.", description: "Participez au marathon annuel et soutenez les associations locales.",
@@ -41,144 +45,15 @@ function EventsPage(){
volunteers_count: 3 volunteers_count: 3
}, },
] ]
}, }
{ */
id: 2,
name: "Festival de Musique d’Été", useEffect(() => {
description: "Un week-end de concerts en plein air avec des artistes locaux et internationaux.", (async () => {
image: null, const data = await getAllEvents();
tasks: [ setEvents(data.data);
{ }) ()
name: "Montage de la scène", }, []);
start: "2018-09-24 22:21:20",
end: "2018-09-24 22:21:20",
place: "Parc central",
description: "Installer la scène, les éclairages et le son.",
volunteers_count: 6
},
{
name: "Accueil du public",
start: "2018-09-24 22:21:20",
end: "2018-09-24 22:21:20",
place: "Entrée principale",
description: "Vérifier les billets et orienter les visiteurs.",
volunteers_count: 4
},
]
},
{
id: 3,
name: "Conférence Tech Innovante",
description: "Journée de conférences et workshops autour des nouvelles technologies.",
image: null,
tasks: [
{
name: "Préparation des salles",
start: "2018-09-24 22:21:20",
end: "2018-09-24 22:21:20",
place: "Campus Tech",
description: "Installer les chaises, projecteurs et matériel pour les conférences.",
volunteers_count: 4
},
{
name: "Accueil des intervenants",
start: "2018-09-24 22:21:20",
end: "2018-09-24 22:21:20",
place: "Hall principal",
description: "Assister les speakers et orienter vers les salles.",
volunteers_count: 2
},
{
name: "Gestion du buffet",
start: "2018-09-24 22:21:20",
end: "2018-09-24 22:21:20",
place: "Salle de restauration",
description: "Distribuer boissons et repas aux participants.",
volunteers_count: 3
},
]
},
{
id: 4,
name: "Atelier de Jardinage Urbain",
description: "Apprenez à cultiver vos plantes en ville et participez à la création de jardins partagés.",
image: null,
tasks: [
{
name: "Installation du matériel",
start: "2018-09-24 22:21:20",
end: "2018-09-24 22:21:20",
place: "Jardin partagé",
description: "Préparer outils et terreaux pour les participants.",
volunteers_count: 2
},
{
name: "Encadrement des participants",
start: "2018-09-24 22:21:20",
end: "2018-09-24 22:21:20",
place: "Jardin partagé",
description: "Aider et conseiller sur la plantation et lentretien.",
volunteers_count: 3
},
]
},
{
id: 5,
name: "Collecte de Sang",
description: "Aidez à sauver des vies en participant à notre collecte de sang annuelle.",
image: null,
tasks: [
{
name: "Accueil et enregistrement",
start: "2020-09-24 22:21:20",
end: "2020-09-24 22:21:20",
place: "Salle municipale",
description: "Enregistrer les donneurs et expliquer le processus.",
volunteers_count: 4
},
{
name: "Préparation des salles",
start: "2018-09-24 22:21:20",
end: "2018-09-24 22:21:20",
place: "Salle municipale",
description: "Installer les lits, tables et matériel médical.",
volunteers_count: 3
},
{
name: "Assistance post-don",
start: "2018-09-24 22:21:20",
end: "2018-09-24 22:21:20",
place: "Salle municipale",
description: "Accompagner les donneurs après le don et proposer des rafraîchissements.",
volunteers_count: 2
},
{
name: "Accueil et enregistrement",
start: "2020-09-24 22:21:20",
end: "2020-09-24 22:21:20",
place: "Salle municipale",
description: "Enregistrer les donneurs et expliquer le processus.",
volunteers_count: 4
},
{
name: "Préparation des salles",
start: "2018-09-24 22:21:20",
end: "2018-09-24 22:21:20",
place: "Salle municipale",
description: "Installer les lits, tables et matériel médical.",
volunteers_count: 3
},
{
name: "Assistance post-don",
start: "2018-09-24 22:21:20",
end: "2018-09-24 22:21:20",
place: "Salle municipale",
description: "Accompagner les donneurs après le don et proposer des rafraîchissements.",
volunteers_count: 2
},
]
},
]);
const compareDate = (dateA, dateB) => { const compareDate = (dateA, dateB) => {
const dA = new Date(dateA); const dA = new Date(dateA);
@@ -191,6 +66,8 @@ function EventsPage(){
} }
}; };
/*
const sortedEvents = [...events].sort((a, b) => { const sortedEvents = [...events].sort((a, b) => {
const sortedATasks = a.tasks.sort((taskA, taskB) => const sortedATasks = a.tasks.sort((taskA, taskB) =>
compareDate(taskA.start, taskB.start) compareDate(taskA.start, taskB.start)
@@ -217,6 +94,8 @@ function EventsPage(){
return 0; return 0;
}); });
*/
@@ -240,7 +119,7 @@ function EventsPage(){
</div> </div>
</div> </div>
<div className={styles.eventsList}> <div className={styles.eventsList}>
{sortedEvents.map((event, index) => ( {events.map((event, index) => (
<Event key={index} event={event} /> <Event key={index} event={event} />
))} ))}
</div> </div>
-4
View File
@@ -25,10 +25,6 @@ const router = createBrowserRouter([
path: "/", path: "/",
Component: HomePage, Component: HomePage,
}, },
{
path: "/login",
Component: LoginPage,
},
{ {
path: "/stat", path: "/stat",
Component:StatPage, Component:StatPage,
+23
View File
@@ -0,0 +1,23 @@
export default async function getAllEvents() {
try {
const res = await fetch(`http://${import.meta.env.VITE_API_URL}/api/events/`, {
method: 'GET',
credentials: 'include',
headers: {
'Accept': 'application/json'
}
});
if (!res.ok) {
throw new Error(`Erreur serveur : ${res.status}`);
}
const data = await res.json();
return data;
} catch (err) {
console.error('Erreur :', err);
return null;
}
}