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:
@@ -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,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%;
|
||||||
|
|||||||
@@ -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
@@ -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 l’entretien.",
|
|
||||||
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>
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user