Merge branch 'EventContext' into 'dev'

Eventcontext

See merge request sae-but2/2025-26/gestion-benevoles-association/Frontend!71
This commit is contained in:
T'JAMPENS QUENTIN p2406187
2026-01-27 13:24:31 +00:00
11 changed files with 101 additions and 95 deletions
+7 -4
View File
@@ -1,10 +1,6 @@
import { Link, NavLink } from "react-router";
import {useContext, useEffect, useRef, useState} from "react";
import {AuthContext} from "../../contexts/auth/AuthContext.js";
import styles from "./Header.module.css"
import getUserNotifications from "../../utils/notifications/getUserNotifications.js";
import deleteNotificationUser from "../../utils/notifications/deleteNotificationUser.js";
import initEcho from "../../utils/echo/initEcho.js"
@@ -12,9 +8,13 @@ import readNotifications from "../../utils/notifications/readNotifications.js";
import { userCreatedListener } from "../../utils/echo/listeners/userCreatedListener";
import { userNotificationsListener } from "../../utils/echo/listeners/userNotificationsListener.js";
import NotificationCard from "../NotificationCard/NotificationCard.jsx";
import { EventContext } from "../../contexts/events/EventContext.js";
import {AuthContext} from "../../contexts/auth/AuthContext.js";
function Header() {
const { update, user } = useContext(AuthContext);
const { updateEvent } = useContext(EventContext);
const [notificationMenu, setnotificationMenu] = useState(false);
const [unreadNotification, setunreadNotification] = useState(false);
const [mobileMenu, setMobileMenu] = useState(false);
@@ -22,6 +22,9 @@ function Header() {
const notificationRef = useRef(null);
useEffect(() => {
updateEvent();
let echoInstance = null;
let channelsToLeave = [];
@@ -1,13 +1,15 @@
import styles from "./createEventBtn.module.css"
import { useState } from "react";
import { useState, useContext } from "react";
import Modal from "../ui/modal/modal.jsx";
import Button from "../ui/button/button.jsx";
import TextInput from "../ui/input/input.jsx";
import createEvent from "../../utils/events/createEvent.js"
import { EventContext } from "../../contexts/events/EventContext.js";
export default function CreateEventBtn() {
const { addEvent } = useContext(EventContext);
const [isOpen, setIsOpen] = useState(false);
const [name, setName] = useState("");
const [description, setDescription] = useState("");
@@ -16,9 +18,8 @@ export default function CreateEventBtn() {
const handleCreateEvent = async () => {
if(name !== "" || description !== "" || start !== "" || end !== "") {
await createEvent(name, description, start, end);
console.log(start);
if (name !== "" && description !== "" && start !== "" && end !== "") {
await addEvent(name, description, start, end);
}
setIsOpen(false);
}
+3
View File
@@ -0,0 +1,3 @@
import { createContext } from "react";
export const EventContext = createContext(null);
+33
View File
@@ -0,0 +1,33 @@
import {useState} from 'react';
import {EventContext} from "./EventContext";
import getAllEvents from "../../utils/events/getAllEvents.js";
import createEvent from "../../utils/events/createEvent.js";
import deleteEvent from "../../utils/events/deleteEvent.js";
export function EventProvider({ children }) {
const [events, setEvents] = useState([]);
const updateEvent = async () => {
const data = await getAllEvents();
setEvents(data.data);
}
const addEvent = async (name, description, start, end) => {
await createEvent(name, description, start, end);
await updateEvent();
}
const removeEvent = async (eventId) => {
const result = await deleteEvent(eventId);
await updateEvent();
return result;
}
return (
<EventContext.Provider value={{ events, updateEvent, addEvent, removeEvent }}>
{children}
</EventContext.Provider>
);
}
+4 -3
View File
@@ -4,14 +4,15 @@ import './index.css'
import { RouterProvider } from "react-router";
import router from './router';
import { AuthProvider } from "./contexts/auth/authProvider.jsx";
import {EventProvider} from "./contexts/events/EventProvider.jsx";
createRoot(document.getElementById('root')).render(
<StrictMode>
{/* TODO: refaire l'arborescence du frontend */}
{/* TODO: refaire le docker du backend */}
<AuthProvider>
<RouterProvider router={router} />
<EventProvider>
<RouterProvider router={router} />
</EventProvider>
</AuthProvider>
</StrictMode>,
)
@@ -1,59 +1,37 @@
import React, { useState, useEffect } from "react";
import React, { useContext } from "react";
import styles from "./IncompleteEvent.module.css";
import getAllEvents from "../../../../utils/events/getAllEvents.js";
import { EventContext } from "../../../../contexts/events/EventContext.js";
function IncompleteEvent() {
const [events, setEvents] = useState([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
const fetchEvents = async () => {
const data = await getAllEvents();
setEvents(data?.data || data || []);
setLoading(false);
};
fetchEvents();
}, []);
const { events } = useContext(EventContext);
if (loading) {
return (
<div className={`${styles.rightBlock} glassCard`}>
<h2>Derniers événements</h2>
<div className={styles.eventsContainer}>
<div className={`${styles.emptyEvent} glassCard`}>
<p>Chargement des événements...</p>
</div>
<div className={`${styles.rightBlock} glassCard`}>
<h2>Derniers événements</h2>
<div className={styles.eventsContainer}>
{events.map((event) => (
<div key={event.id} className={`glassCard ${styles.eventCard}`}>
<h3>{event.name}</h3>
<p className={styles.eventDate}>
{new Date(event.start).toLocaleDateString("fr-FR")} - {new Date(event.end).toLocaleDateString("fr-FR")}
</p>
<p className={styles.eventDescription}>{event.description}</p>
<h4>Tâches associées :</h4>
<ul className={styles.tasksList}>
{event.tasks?.length ? (
event.tasks.map((task, taskIndex) => (
<li key={taskIndex}>{task.name}</li>
))
) : (
<li>Aucune tâche associée.</li>
)}
</ul>
</div>
))}
</div>
</div>
</div>
);
}
return (
<div className={`${styles.rightBlock} glassCard`}>
<h2>Derniers événements</h2>
<div className={styles.eventsContainer}>
{events.map((event) => (
<div key={event.id} className={`glassCard ${styles.eventCard}`}>
<h3>{event.name}</h3>
<p className={styles.eventDate}>
{new Date(event.start).toLocaleDateString("fr-FR")} - {new Date(event.end).toLocaleDateString("fr-FR")}
</p>
<p className={styles.eventDescription}>{event.description}</p>
<h4>Tâches associées :</h4>
<ul className={styles.tasksList}>
{event.tasks?.length ? (
event.tasks.map((task, taskIndex) => (
<li key={taskIndex}>{task.name}</li>
))
) : (
<li>Aucune tâche associée.</li>
)}
</ul>
</div>
))}
</div>
</div>
);
}
export default IncompleteEvent;
+7 -17
View File
@@ -1,33 +1,23 @@
import { useEffect, useState } from "react";
import { useState, useContext } from "react";
import Event from "./components/Event/Event.jsx";
import styles from "./EventsPage.module.css";
import ToolBar from "../../components/ToolBar/ToolBar.jsx";
import getAllEvents from "../../utils/events/getAllEvents.js";
import filter from "../../utils/filter.js";
import { EventContext } from "../../contexts/events/EventContext.js";
function EventsPage(){
const { events } = useContext(EventContext);
const [filters, setFilters] = useState({
alphabetical: "asc",
yearOrder: "desc",
});
const [events, setEvents] = useState([]);
useEffect(() => {
(async () => {
const data = await getAllEvents();
setEvents(data.data);
}) ()
}, []);
return (
<div className={styles.eventsContainer}>
<ToolBar setFilters={setFilters} filters={filters}/>
<ToolBar setFilters={setFilters} filters={filters} />
<div className={styles.eventsList}>
{filter(events, filters, "event").map((event, index) => (
<Event key={index} event={event} />
+2 -13
View File
@@ -1,24 +1,13 @@
import styles from "./HomePage.module.css";
import Calendar from "./components/Calendar/calendar.jsx";
import EventList from "./components/EventList/eventList.jsx";
import { useState, useEffect } from "react";
import getAllEvents from "../../utils/events/getAllEvents.js";
function HomePage() {
const [events, setEvents] = useState([]);
useEffect(() => {
(async () => {
const data = await getAllEvents();
setEvents(data.data);
}) ()
}, [])
return (
<div className={styles.allContent}>
<Calendar events={events} />
<EventList events={events} />
<Calendar />
<EventList />
</div>
);
}
@@ -1,8 +1,11 @@
import { useState, useMemo, useEffect } from "react";
import {useState, useMemo, useEffect, useContext} from "react";
import styles from "./calendar.module.css";
import { formatDateLetterJS } from "../../../../utils/date/formatDateLetter.js";
import {EventContext} from "../../../../contexts/events/EventContext.js";
function Calendar({ events = [] }) {
function Calendar() {
const { events } = useContext(EventContext);
const monthNames = [
"Janvier", "Février", "Mars", "Avril", "Mai", "Juin",
@@ -1,9 +1,13 @@
import { useMemo } from "react";
import styles from "./eventList.module.css";
import EventItem from "./eventItem.jsx";
import { EventContext } from "../../../../contexts/events/EventContext.js";
import { useContext } from "react";
function EventList({ events }) {
function EventList() {
const { events } = useContext(EventContext);
const sortedEvents = useMemo(() => {
return [...events].sort(
+3 -2
View File
@@ -7,7 +7,7 @@ import EventTask from "./components/EventTask/EventTask.jsx";
import Button from "../../components/ui/button/button.jsx";
import Modal from "../../components/ui/modal/modal.jsx";
import { AuthContext } from "../../contexts/auth/AuthContext.js";
import deleteEvent from "../../utils/events/deleteEvent.js";
import { EventContext } from "../../contexts/events/EventContext.js";
import { useNavigate } from "react-router";
import TextInput from "../../components/ui/input/input.jsx";
import createTaskApi from "../../utils/tasks/createTask.js";
@@ -18,6 +18,7 @@ function EventDetail() {
const params = useParams();
const id = params.id;
const { user } = useContext(AuthContext)
const { removeEvent } = useContext(EventContext)
const navigate = useNavigate();
const [open, setOpen] = useState(false);
@@ -44,7 +45,7 @@ function EventDetail() {
}
const delEvent = async () => {
const result = await deleteEvent(id);
const result = await removeEvent(id);
if (result.status === 200 || result.status === 204) {
setOpen(false);