From e125215f5c39c26b30b88653c5549e3ba5d1187e Mon Sep 17 00:00:00 2001 From: ordonneau antoine Date: Thu, 20 Nov 2025 09:50:24 +0100 Subject: [PATCH 01/20] premier commit !!!! --- src/pages/Home/HomePage.jsx | 121 ++++++++++++++++++++++++++++- src/pages/Home/HomePage.module.css | 120 +++++++++++++++++++++++++++- 2 files changed, 235 insertions(+), 6 deletions(-) diff --git a/src/pages/Home/HomePage.jsx b/src/pages/Home/HomePage.jsx index fc12601..13b06b7 100644 --- a/src/pages/Home/HomePage.jsx +++ b/src/pages/Home/HomePage.jsx @@ -1,11 +1,124 @@ +import { useState } from "react"; +import styles from "./HomePage.module.css"; -function HomePage(){ +function HomePage() { + const today = new Date(); + const [currentMonth, setCurrentMonth] = useState(today.getMonth()); + const [currentYear, setCurrentYear] = useState(today.getFullYear()); + const [selectedDay, setSelectedDay] = useState(null); + + // Exemple d'événements : tu pourras ensuite les charger d'une base de données ou d'un fichier JSON + const events = { + "2025-11-07": ["Réunion de projet", "Anniversaire de Marie"], + "2025-11-10": ["Cours de React", "Rendez-vous médecin"], + "2025-11-14": ["Sortie cinéma"], + }; + + const monthNames = [ + "Janvier", "Février", "Mars", "Avril", "Mai", "Juin", + "Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre" + ]; + + // Calcul des jours + const daysInMonth = new Date(currentYear, currentMonth + 1, 0).getDate(); + const firstDay = new Date(currentYear, currentMonth, 1).getDay(); + const startDay = (firstDay + 6) % 7; + + const days = []; + for (let i = 0; i < startDay; i++) days.push(null); + for (let i = 1; i <= daysInMonth; i++) days.push(i); + + const handlePrevMonth = () => { + if (currentMonth === 0) { + setCurrentMonth(11); + setCurrentYear(currentYear - 1); + } else { + setCurrentMonth(currentMonth - 1); + } + setSelectedDay(null); + }; + + const handleNextMonth = () => { + if (currentMonth === 11) { + setCurrentMonth(0); + setCurrentYear(currentYear + 1); + } else { + setCurrentMonth(currentMonth + 1); + } + setSelectedDay(null); + }; + + const handleDayClick = (day) => { + if (!day) return; + const key = `${currentYear}-${String(currentMonth + 1).padStart(2, "0")}-${String(day).padStart(2, "0")}`; + setSelectedDay({ date: key, events: events[key] || [] }); + }; return ( -
+
+
+
+ +

{monthNames[currentMonth]} {currentYear}

+ +
+ + + + + + + + + + + + + + + {Array.from({ length: Math.ceil(days.length / 7) }).map((_, weekIndex) => ( + + {days.slice(weekIndex * 7, weekIndex * 7 + 7).map((day, index) => { + const key = `${currentYear}-${String(currentMonth + 1).padStart(2, "0")}-${String(day).padStart(2, "0")}`; + const hasEvent = events[key]; + return ( + + ); + })} + + ))} + +
LunMarMerJeuVenSamDim
handleDayClick(day)} + > + {day || ""} +
+ + {/* Box d’événements */} + {selectedDay && ( +
+

Événements du {selectedDay.date}

+ {selectedDay.events.length > 0 ? ( +
    + {selectedDay.events.map((ev, i) => ( +
  • {ev}
  • + ))} +
+ ) : ( +

Aucun événement ce jour-là.

+ )} +
+ )} +
- ) + ); } -export default HomePage; \ No newline at end of file +export default HomePage; diff --git a/src/pages/Home/HomePage.module.css b/src/pages/Home/HomePage.module.css index e83a063..69586fb 100644 --- a/src/pages/Home/HomePage.module.css +++ b/src/pages/Home/HomePage.module.css @@ -1,3 +1,119 @@ -.title { - color: red; +.calendarcontainer { + width: 50%; + padding: 20px; + font-family: Arial, sans-serif; + text-align: center; + justify-content: center; +} + +.calendarheader { + display: flex; + flex-direction: row; + align-items: center; + gap: 10px; +} + +.glass{ + background: rgba(255, 255, 255, 0.075); + border-radius: 20px; + border: 1px solid rgba(255, 255, 255, 0.3); + backdrop-filter: blur(10px); + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.5); + transition: transform 0.5s ease; +} + +.calendarheader p{ + width: auto; + text-align: center; + font-weight: bold; + font-size: 40px; +} + +.calendarheader button { + width: 40px; + height: 40px; + font-size: 15px; + color: #019AFF; + border: none; + border-radius: 50%; + cursor: pointer; + background-color: transparent; +} + +.glass{ + width:50px; + height:50px; + border-radius:50%; + background:rgba(255,255,255,.08); + box-shadow:0 0 0 2px rgba(255,255,255,.6),0 16px 32px rgba(0,0,0,.12); + place-items:center; + cursor:pointer; + outline:0; +} + +.calendar { + border-collapse: collapse; + width: 80%; + max-width: 500px; +} + +.calendar th, .calendar td { + border: 1px solid #ddd; + padding: 10px; + width: 14.2%; + text-align: center; + cursor: pointer; +} + +.calendar th { + background-color: #f2f2f2; +} + +.today { + background-color: #007bff; + color: white; + border-radius: 50%; +} + +.hasevent { + background-color: #e7f3ff; + font-weight: bold; +} + +.selected { + outline: 3px solid #007bff; +} + +.eventbox { + background-color: #f9f9f9; + border-radius: 10px; + padding: 15px; + margin-top: 20px; + box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1); + width: 80%; + max-width: 500px; + text-align: left; +} + +.eventbox ul { + list-style-type: disc; + margin-left: 20px; +} + +.glassCard { + width: 100%; + padding: 10px 20px 10px 20px; + height: fit-content; + background: rgba(255, 255, 255, 0.65); + backdrop-filter: blur(3px); + -webkit-backdrop-filter: blur(3px); + border-radius: 20px; + border: 1px solid rgba(255, 255, 255, 0.3); + box-shadow: + 0 8px 32px rgba(0, 0, 0, 0.1), + inset 0 1px 0 rgba(255, 255, 255, 0.5), + inset 0 -1px 0 rgba(255, 255, 255, 0.1), + inset 0 0 8px 4px rgba(255, 255, 255, 0.4); + position: relative; + overflow: hidden; } \ No newline at end of file From 7f4a74446e511cb3b8e48bea6ebbad5ee20fb3e1 Mon Sep 17 00:00:00 2001 From: ordonneau antoine Date: Mon, 24 Nov 2025 14:28:00 +0100 Subject: [PATCH 02/20] =?UTF-8?q?manque=20la=20deuxi=C3=A8me=20moiti=C3=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/Home/HomePage.jsx | 84 ++++++++++++-------- src/pages/Home/HomePage.module.css | 123 ++++++++++++++++------------- 2 files changed, 122 insertions(+), 85 deletions(-) diff --git a/src/pages/Home/HomePage.jsx b/src/pages/Home/HomePage.jsx index 13b06b7..0035c76 100644 --- a/src/pages/Home/HomePage.jsx +++ b/src/pages/Home/HomePage.jsx @@ -1,14 +1,7 @@ import { useState } from "react"; import styles from "./HomePage.module.css"; - function HomePage() { - const today = new Date(); - const [currentMonth, setCurrentMonth] = useState(today.getMonth()); - const [currentYear, setCurrentYear] = useState(today.getFullYear()); - const [selectedDay, setSelectedDay] = useState(null); - - // Exemple d'événements : tu pourras ensuite les charger d'une base de données ou d'un fichier JSON const events = { "2025-11-07": ["Réunion de projet", "Anniversaire de Marie"], "2025-11-10": ["Cours de React", "Rendez-vous médecin"], @@ -20,7 +13,17 @@ function HomePage() { "Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre" ]; - // Calcul des jours + const today = new Date(); + const [currentMonth, setCurrentMonth] = useState(today.getMonth()); + const [currentYear, setCurrentYear] = useState(today.getFullYear()); + const [selectedDay, setSelectedDay] = useState(() => { + const year = today.getFullYear(); + const month = String(today.getMonth() + 1).padStart(2, "0"); + const day = String(today.getDate()).padStart(2, "0"); + const key = `${year}-${month}-${day}`; + return { date: key, events: events[key] || [] }; + }); + const daysInMonth = new Date(currentYear, currentMonth + 1, 0).getDate(); const firstDay = new Date(currentYear, currentMonth, 1).getDay(); const startDay = (firstDay + 6) % 7; @@ -30,23 +33,35 @@ function HomePage() { for (let i = 1; i <= daysInMonth; i++) days.push(i); const handlePrevMonth = () => { - if (currentMonth === 0) { - setCurrentMonth(11); - setCurrentYear(currentYear - 1); - } else { - setCurrentMonth(currentMonth - 1); + let newMonth = currentMonth - 1; + let newYear = currentYear; + + if (newMonth < 0) { + newMonth = 11; + newYear--; } - setSelectedDay(null); + + setCurrentMonth(newMonth); + setCurrentYear(newYear); + + const key = `${newYear}-${String(newMonth + 1).padStart(2, "0")}-01`; + setSelectedDay({ date: key, events: events[key] || [] }); }; const handleNextMonth = () => { - if (currentMonth === 11) { - setCurrentMonth(0); - setCurrentYear(currentYear + 1); - } else { - setCurrentMonth(currentMonth + 1); + let newMonth = currentMonth + 1; + let newYear = currentYear; + + if (newMonth > 11) { + newMonth = 0; + newYear++; } - setSelectedDay(null); + + setCurrentMonth(newMonth); + setCurrentYear(newYear); + + const key = `${newYear}-${String(newMonth + 1).padStart(2, "0")}-01`; + setSelectedDay({ date: key, events: events[key] || [] }); }; const handleDayClick = (day) => { @@ -57,12 +72,12 @@ function HomePage() { return (
-
-
- -

{monthNames[currentMonth]} {currentYear}

- -
+
+
+ +

{monthNames[currentMonth]} {currentYear}

+ +
@@ -76,19 +91,24 @@ function HomePage() { + {Array.from({ length: Math.ceil(days.length / 7) }).map((_, weekIndex) => ( {days.slice(weekIndex * 7, weekIndex * 7 + 7).map((day, index) => { const key = `${currentYear}-${String(currentMonth + 1).padStart(2, "0")}-${String(day).padStart(2, "0")}`; const hasEvent = events[key]; + return (
Dim
handleDayClick(day)} > @@ -101,10 +121,10 @@ function HomePage() {
- {/* Box d’événements */} {selectedDay && ( -
+

Événements du {selectedDay.date}

+ {selectedDay.events.length > 0 ? (
    {selectedDay.events.map((ev, i) => ( @@ -121,4 +141,4 @@ function HomePage() { ); } -export default HomePage; +export default HomePage; \ No newline at end of file diff --git a/src/pages/Home/HomePage.module.css b/src/pages/Home/HomePage.module.css index 69586fb..da80286 100644 --- a/src/pages/Home/HomePage.module.css +++ b/src/pages/Home/HomePage.module.css @@ -1,54 +1,41 @@ -.calendarcontainer { - width: 50%; +.calendarContainer { padding: 20px; font-family: Arial, sans-serif; - text-align: center; - justify-content: center; + display: flex; + flex-direction: column; + align-items: center; } -.calendarheader { +.calendarHeader { display: flex; + width: 100%; flex-direction: row; + justify-content: space-between; align-items: center; gap: 10px; } -.glass{ - background: rgba(255, 255, 255, 0.075); - border-radius: 20px; - border: 1px solid rgba(255, 255, 255, 0.3); - backdrop-filter: blur(10px); - box-shadow: 0 4px 20px rgba(0, 0, 0, 0.5); - transition: transform 0.5s ease; -} - -.calendarheader p{ +.calendarHeader p { width: auto; text-align: center; font-weight: bold; font-size: 40px; } -.calendarheader button { +.calendarHeader button { + top: 50%; + left: 50%; width: 40px; height: 40px; + border-radius: 50%; + border: none; + background: transparent; + box-shadow: + inset 1.25px 1.25px 1px rgba(255, 255, 255, 1), + inset -1.25px -1.25px 1px rgba(255, 255, 255, 1); font-size: 15px; color: #019AFF; - border: none; - border-radius: 50%; cursor: pointer; - background-color: transparent; -} - -.glass{ - width:50px; - height:50px; - border-radius:50%; - background:rgba(255,255,255,.08); - box-shadow:0 0 0 2px rgba(255,255,255,.6),0 16px 32px rgba(0,0,0,.12); - place-items:center; - cursor:pointer; - outline:0; } .calendar { @@ -58,50 +45,80 @@ } .calendar th, .calendar td { - border: 1px solid #ddd; + border: none; padding: 10px; width: 14.2%; + line-height: 130%; text-align: center; cursor: pointer; } -.calendar th { - background-color: #f2f2f2; -} - .today { - background-color: #007bff; - color: white; - border-radius: 50%; + color: #007bff; } -.hasevent { - background-color: #e7f3ff; - font-weight: bold; +.hasEvent { + position: relative; +} + +.hasEvent::before { + content: ""; + position: absolute; + left: 50%; + bottom: 10px; + width: 20px; + height: 2px; + background-color: #007bff; + transform: translateX(-50%); + border-radius: 10px; +} + +.hasEvent.selected::before { + width: 25px; + height: 2px; + bottom: 10px; } .selected { - outline: 3px solid #007bff; + position: relative; + font-size: 18px; + font-weight: 600; } -.eventbox { - background-color: #f9f9f9; - border-radius: 10px; +.selected::after { + content: ""; + position: absolute; + top: 50%; + left: 50%; + width: 40px; + height: 40px; + transform: translate(-50%, -50%); + border-radius: 38%; + pointer-events: none; + background: transparent; + box-shadow: + inset 1.25px 1.25px 1px rgba(255, 255, 255, 1), + inset -1.25px -1.25px 1px rgba(255, 255, 255, 1); +} + +.eventBox { + border-radius: 20px; padding: 15px; - margin-top: 20px; - box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1); - width: 80%; - max-width: 500px; - text-align: left; + margin-top: 16px; + border: none; + background: rgb(255, 255, 255, 0.25); + box-shadow: + inset 1.25px 1.25px 1px rgba(255, 255, 255, 1), + inset -1.25px -1.25px 1px rgba(255, 255, 255, 1); } -.eventbox ul { +.eventBox ul { list-style-type: disc; - margin-left: 20px; } .glassCard { - width: 100%; + width: 45%; + margin: 16px; padding: 10px 20px 10px 20px; height: fit-content; background: rgba(255, 255, 255, 0.65); From a4f9be81dcb916445b4ddb8f87f295554ae2d6f9 Mon Sep 17 00:00:00 2001 From: Antoine Ordonneau Date: Thu, 4 Dec 2025 11:49:47 +0100 Subject: [PATCH 03/20] autre moitiay --- src/index.css | 13 +++ src/pages/Home/HomePage.jsx | 165 ++++++++++++++++++----------- src/pages/Home/HomePage.module.css | 49 +++++++-- 3 files changed, 154 insertions(+), 73 deletions(-) diff --git a/src/index.css b/src/index.css index 1d2d1c2..dc9cfef 100644 --- a/src/index.css +++ b/src/index.css @@ -61,6 +61,19 @@ body { overflow: hidden; } +.glassBorder{ + border-radius: 20px; + padding: 15px; + margin-top: 16px; + border: none; + background: rgb(255, 255, 255, 0.25); + box-shadow: + inset 1.25px 1.25px 1px rgba(255, 255, 255, 1), + inset -1.25px -1.25px 1px rgba(255, 255, 255, 1), + inset -0.25px 0.25px 1px rgba(0, 0, 0, 0.2), + inset 0.25px -0.25px 1px rgba(0, 0, 0, 0.2); +} + h1 { font-size: 3.2em; line-height: 1.1; diff --git a/src/pages/Home/HomePage.jsx b/src/pages/Home/HomePage.jsx index 0035c76..ae603b2 100644 --- a/src/pages/Home/HomePage.jsx +++ b/src/pages/Home/HomePage.jsx @@ -1,4 +1,5 @@ import { useState } from "react"; +import { useMemo } from "react"; import styles from "./HomePage.module.css"; function HomePage() { @@ -70,72 +71,108 @@ function HomePage() { setSelectedDay({ date: key, events: events[key] || [] }); }; + const sortedEvents = useMemo(() => { + return Object.entries(events) + .map(([dateKey, eventList]) => ({ date: dateKey, events: eventList })) + .sort((a, b) => new Date(a.date) - new Date(b.date)); + }, [events]); + + const formatDate = (dateString) => { + const [year, month, day] = dateString.split('-'); + return `${day} ${monthNames[parseInt(month) - 1]} ${year}`; + }; + return ( -
    -
    -
    - -

    {monthNames[currentMonth]} {currentYear}

    - -
    - - - - - - - - - - - - - - - - {Array.from({ length: Math.ceil(days.length / 7) }).map((_, weekIndex) => ( - - {days.slice(weekIndex * 7, weekIndex * 7 + 7).map((day, index) => { - const key = `${currentYear}-${String(currentMonth + 1).padStart(2, "0")}-${String(day).padStart(2, "0")}`; - const hasEvent = events[key]; - - return ( - - ); - })} - - ))} - -
    LunMarMerJeuVenSamDim
    handleDayClick(day)} - > - {day || ""} -
    - - {selectedDay && ( -
    -

    Événements du {selectedDay.date}

    - - {selectedDay.events.length > 0 ? ( -
      - {selectedDay.events.map((ev, i) => ( -
    • {ev}
    • - ))} -
    - ) : ( -

    Aucun événement ce jour-là.

    - )} +
    +
    +
    +
    + +

    {monthNames[currentMonth]} {currentYear}

    +
    - )} + + + + + + + + + + + + + + + + {Array.from({ length: Math.ceil(days.length / 7) }).map((_, weekIndex) => ( + + {days.slice(weekIndex * 7, weekIndex * 7 + 7).map((day, index) => { + const key = `${currentYear}-${String(currentMonth + 1).padStart(2, "0")}-${String(day).padStart(2, "0")}`; + const hasEvent = events[key]; + + return ( + + ); + })} + + ))} + +
    LunMarMerJeuVenSamDim
    handleDayClick(day)} + > + {day || ""} +
    + + {selectedDay && ( +
    +

    Événements du {formatDate(selectedDay.date)}

    + + {selectedDay.events.length > 0 ? ( +
      + {selectedDay.events.map((ev, i) => ( +
    • {ev}
    • + ))} +
    + ) : ( +

    Aucun événement ce jour-là.

    + )} +
    + )} +
    +
    +
    +
    +

    Liste des Événements à Venir

    + {sortedEvents.length > 0 ? ( +
      + {sortedEvents.map((eventGroup) => ( +
    • +
      + {formatDate(eventGroup.date)} +
      +
        + {eventGroup.events.map((event, i) => ( +
      • - {event}
      • + ))} +
      +
    • + ))} +
    + ) : ( +

    Aucun événement planifié pour l'instant.

    + )} +
    ); diff --git a/src/pages/Home/HomePage.module.css b/src/pages/Home/HomePage.module.css index da80286..a0f3426 100644 --- a/src/pages/Home/HomePage.module.css +++ b/src/pages/Home/HomePage.module.css @@ -32,7 +32,9 @@ background: transparent; box-shadow: inset 1.25px 1.25px 1px rgba(255, 255, 255, 1), - inset -1.25px -1.25px 1px rgba(255, 255, 255, 1); + inset -1.25px -1.25px 1px rgba(255, 255, 255, 1), + inset -0.25px 0.25px 1px rgba(0, 0, 0, 0.2), + inset 0.25px -0.25px 1px rgba(0, 0, 0, 0.2); font-size: 15px; color: #019AFF; cursor: pointer; @@ -98,7 +100,9 @@ background: transparent; box-shadow: inset 1.25px 1.25px 1px rgba(255, 255, 255, 1), - inset -1.25px -1.25px 1px rgba(255, 255, 255, 1); + inset -1.25px -1.25px 1px rgba(255, 255, 255, 1), + inset -0.25px 0.25px 1px rgba(0, 0, 0, 0.2), + inset 0.25px -0.25px 1px rgba(0, 0, 0, 0.2); } .eventBox { @@ -109,13 +113,28 @@ background: rgb(255, 255, 255, 0.25); box-shadow: inset 1.25px 1.25px 1px rgba(255, 255, 255, 1), - inset -1.25px -1.25px 1px rgba(255, 255, 255, 1); + inset -1.25px -1.25px 1px rgba(255, 255, 255, 1), + inset -0.25px 0.25px 1px rgba(0, 0, 0, 0.2), + inset 0.25px -0.25px 1px rgba(0, 0, 0, 0.2); } .eventBox ul { list-style-type: disc; } +.eventGroup{ + border-radius: 20px; + padding: 15px; + margin-top: 16px; + border: none; + background: rgb(255, 255, 255, 0.25); + box-shadow: + inset 1.25px 1.25px 1px rgba(255, 255, 255, 1), + inset -1.25px -1.25px 1px rgba(255, 255, 255, 1), + inset -0.25px 0.25px 1px rgba(0, 0, 0, 0.2), + inset 0.25px -0.25px 1px rgba(0, 0, 0, 0.2); +} + .glassCard { width: 45%; margin: 16px; @@ -126,11 +145,23 @@ -webkit-backdrop-filter: blur(3px); border-radius: 20px; border: 1px solid rgba(255, 255, 255, 0.3); - box-shadow: - 0 8px 32px rgba(0, 0, 0, 0.1), - inset 0 1px 0 rgba(255, 255, 255, 0.5), - inset 0 -1px 0 rgba(255, 255, 255, 0.1), - inset 0 0 8px 4px rgba(255, 255, 255, 0.4); - position: relative; + box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1), + inset 0 1px 0 rgba(255, 255, 255, 0.5), + inset 0 -1px 0 rgba(255, 255, 255, 0.1), + inset 0 0 8px 4px rgba(255, 255, 255, 0.4); overflow: hidden; +} +.allContent{ + display: flex; + flex-direction: row; +} + +@media (max-width: 768px) { + .glassCard { + width: 100%; + margin: 0px; + margin-top: 16px; + margin-bottom: 16px; + display: flex; + } } \ No newline at end of file From 6d8899c7deeb7d1e6ae1ccbc63ff33fa72fb6ab3 Mon Sep 17 00:00:00 2001 From: T'JAMPENS QUENTIN p2406187 Date: Tue, 9 Dec 2025 09:40:20 +0100 Subject: [PATCH 04/20] Create settings modal --- public/icons/settings-wheel.svg | 4 ++ .../SettingsModal/SettingsModal.jsx | 41 +++++++++++++++++++ .../SettingsModal/SettingsModal.module.css | 18 ++++++++ src/components/ui/modal/modal.module.css | 2 +- src/pages/Profile/ProfilePage.jsx | 19 ++------- src/pages/Profile/ProfilePage.module.css | 14 +++---- 6 files changed, 72 insertions(+), 26 deletions(-) create mode 100644 public/icons/settings-wheel.svg create mode 100644 src/components/SettingsModal/SettingsModal.jsx create mode 100644 src/components/SettingsModal/SettingsModal.module.css diff --git a/public/icons/settings-wheel.svg b/public/icons/settings-wheel.svg new file mode 100644 index 0000000..9a4e19b --- /dev/null +++ b/public/icons/settings-wheel.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/src/components/SettingsModal/SettingsModal.jsx b/src/components/SettingsModal/SettingsModal.jsx new file mode 100644 index 0000000..8b78d86 --- /dev/null +++ b/src/components/SettingsModal/SettingsModal.jsx @@ -0,0 +1,41 @@ +import Modal from "../ui/modal/modal.jsx"; +import Button from "../ui/button/button.jsx"; +import styles from "./SettingsModal.module.css" +import { useContext, useState } from "react"; +import ThemeSwitcher from "../ui/themeSwitcher/ThemeSwitcher.jsx"; +import { AuthContext } from "../../contexts/auth/AuthContext.js"; + + +export default function SettingsModal() { + + const [open, setOpen] = useState(false); + + const { logout } = useContext(AuthContext); + + const handleLogout = () => { + logout(); + } + + return ( + <> + + + setOpen(false)}> +
    + +
    +

    Compte

    + +
    + +
    +

    Apparence

    + +
    +
    +
    + + ) +} \ No newline at end of file diff --git a/src/components/SettingsModal/SettingsModal.module.css b/src/components/SettingsModal/SettingsModal.module.css new file mode 100644 index 0000000..d9d27ff --- /dev/null +++ b/src/components/SettingsModal/SettingsModal.module.css @@ -0,0 +1,18 @@ +.content { + width: 100%; + padding: 20px; + display: flex; + flex-direction: column; +} + +.modifyIcon { + height: 30px; + width: 30px; +} + +.section { + display: flex; + flex-direction: column; + gap: 10px; + margin-bottom: 30px; +} \ No newline at end of file diff --git a/src/components/ui/modal/modal.module.css b/src/components/ui/modal/modal.module.css index 76b108a..faf857f 100644 --- a/src/components/ui/modal/modal.module.css +++ b/src/components/ui/modal/modal.module.css @@ -18,7 +18,7 @@ max-width: 70%; position: relative; box-shadow: 0 4px 15px rgba(0,0,0,0.2); - width: fit-content; + width: clamp(300px, 50vw, 600px); border: 1px solid rgba(200, 200, 200, 0.3); background: rgba(255, 255, 255, 0.5); backdrop-filter: blur(10px); diff --git a/src/pages/Profile/ProfilePage.jsx b/src/pages/Profile/ProfilePage.jsx index 0271d42..aaa1338 100644 --- a/src/pages/Profile/ProfilePage.jsx +++ b/src/pages/Profile/ProfilePage.jsx @@ -3,18 +3,11 @@ import styles from "./ProfilePage.module.css"; import { AuthContext } from "../../contexts/auth/AuthContext.js"; import formatDate from "../../utils/date/formatDate.js"; import Task from "../../components/Task/Task"; -import Button from "../../components/ui/button/button.jsx"; -import { useNavigate } from "react-router"; -import ThemeSwitcher from "../../components/ui/themeSwitcher/ThemeSwitcher.jsx"; +import SettingsModal from "../../components/SettingsModal/SettingsModal.jsx"; function ProfilePage() { - const { user, logout } = useContext(AuthContext); - const navigate = useNavigate(); - - const handleLogout = () => { - logout(); - } + const { user } = useContext(AuthContext); return (
    @@ -30,10 +23,6 @@ function ProfilePage() {

    {user.name} {user.lastname}

    -
    - - -
    @@ -44,9 +33,7 @@ function ProfilePage() {

    Mail : {user.email}

    Téléphone : {user.phone}

    - +

    Vos Événements :

    diff --git a/src/pages/Profile/ProfilePage.module.css b/src/pages/Profile/ProfilePage.module.css index e4e467b..1e7913f 100644 --- a/src/pages/Profile/ProfilePage.module.css +++ b/src/pages/Profile/ProfilePage.module.css @@ -38,10 +38,11 @@ } .topDescription { - display: flex; - flex-direction: column; - gap: 10px; - margin-bottom: 15px; + display: flex; + flex-direction: column; + align-items: center; + gap: 10px; + margin-bottom: 15px; } .infoBlock { @@ -122,11 +123,6 @@ } -.modifyIcon { - height:50px; - width:50px; -} - .headerProfile { display: flex; flex-direction: row; From b9553aedf4d6c18b1ba17f17e8631f8464b55162 Mon Sep 17 00:00:00 2001 From: T'JAMPENS QUENTIN p2406187 Date: Tue, 9 Dec 2025 09:46:03 +0100 Subject: [PATCH 05/20] Remove sort --- src/pages/Events/EventsPage.jsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/pages/Events/EventsPage.jsx b/src/pages/Events/EventsPage.jsx index 2b458f4..ebfbe07 100644 --- a/src/pages/Events/EventsPage.jsx +++ b/src/pages/Events/EventsPage.jsx @@ -2,7 +2,6 @@ import { useEffect, useState } from "react"; import Event from "../../components/Event/Event.jsx"; import styles from "./EventsPage.module.css"; import ToolBar from "../../components/ToolBar/ToolBar.jsx"; -import filter from "../../utils/filter.js"; import getAllEvents from "../../utils/event/getAllEvents.js"; @@ -29,7 +28,7 @@ function EventsPage(){
    - {filter(events, filters).map((event, index) => ( + {events.map((event, index) => ( ))}
    From eebb405e4a78e21b8ca85cdfb98bb371f8d7c5dd Mon Sep 17 00:00:00 2001 From: T'JAMPENS QUENTIN p2406187 Date: Tue, 9 Dec 2025 10:01:27 +0100 Subject: [PATCH 06/20] fix modal height --- src/components/ui/modal/modal.jsx | 34 ++++++++++++------------ src/components/ui/modal/modal.module.css | 5 +++- 2 files changed, 21 insertions(+), 18 deletions(-) diff --git a/src/components/ui/modal/modal.jsx b/src/components/ui/modal/modal.jsx index 66ae46b..6ddf2a8 100644 --- a/src/components/ui/modal/modal.jsx +++ b/src/components/ui/modal/modal.jsx @@ -1,23 +1,23 @@ -import styles from "./modal.module.css" +import { createPortal } from "react-dom"; +import styles from "./modal.module.css"; import Button from "../button/button.jsx"; const Modal = ({ open, onClose, children, title }) => { - if(!open) return null; + if (!open) return null; - return
    + return createPortal( +
    +
    + {title &&

    {title}

    } + {children} +
    + +
    +
    +
    , + document.body + ); +}; -
    - - {title &&

    {title}

    } - - {children} - -
    - -
    - -
    -} - -export default Modal; \ No newline at end of file +export default Modal; diff --git a/src/components/ui/modal/modal.module.css b/src/components/ui/modal/modal.module.css index faf857f..fa3566f 100644 --- a/src/components/ui/modal/modal.module.css +++ b/src/components/ui/modal/modal.module.css @@ -7,8 +7,10 @@ background-color: rgba(0, 0, 0, 0.25); display: flex; justify-content: center; - align-items: center; z-index: 1000; + align-items: flex-start; + overflow-y: auto; + padding: 40px 0; } .modal { @@ -16,6 +18,7 @@ border-radius: 8px; min-width: 300px; max-width: 70%; + max-height: none; position: relative; box-shadow: 0 4px 15px rgba(0,0,0,0.2); width: clamp(300px, 50vw, 600px); From dd4dda2957b127ab44b4857c4e3ef6c481468374 Mon Sep 17 00:00:00 2001 From: T'JAMPENS QUENTIN p2406187 Date: Tue, 9 Dec 2025 11:15:26 +0100 Subject: [PATCH 07/20] Add update function --- src/contexts/auth/authProvider.jsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/contexts/auth/authProvider.jsx b/src/contexts/auth/authProvider.jsx index 009ec58..850c3a2 100644 --- a/src/contexts/auth/authProvider.jsx +++ b/src/contexts/auth/authProvider.jsx @@ -30,8 +30,13 @@ export function AuthProvider({ children }) { setUser(null); }; + const update = async () => { + const u = await getUser(); + setUser(u); + } + return ( - + {children} ); From 255880d40d03f93a857454564fdff5c7f08116ed Mon Sep 17 00:00:00 2001 From: T'JAMPENS QUENTIN p2406187 Date: Tue, 9 Dec 2025 11:15:40 +0100 Subject: [PATCH 08/20] Update user info --- .../SettingsModal/SettingsModal.jsx | 31 +++++++++++++++++- .../SettingsModal/SettingsModal.module.css | 7 +++- src/utils/users/updateUser.js | 32 +++++++++++++++++++ 3 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 src/utils/users/updateUser.js diff --git a/src/components/SettingsModal/SettingsModal.jsx b/src/components/SettingsModal/SettingsModal.jsx index 8b78d86..e39c64d 100644 --- a/src/components/SettingsModal/SettingsModal.jsx +++ b/src/components/SettingsModal/SettingsModal.jsx @@ -4,18 +4,29 @@ import styles from "./SettingsModal.module.css" import { useContext, useState } from "react"; import ThemeSwitcher from "../ui/themeSwitcher/ThemeSwitcher.jsx"; import { AuthContext } from "../../contexts/auth/AuthContext.js"; +import TextInput from "../ui/input/input.jsx"; +import updateUser from "../../utils/users/updateUser.js"; export default function SettingsModal() { + const { user, logout, update } = useContext(AuthContext); + const [open, setOpen] = useState(false); - const { logout } = useContext(AuthContext); + const [name, setName] = useState(user.name); + const [lastname, setLastName] = useState(user.lastname); + const [phone, setPhone] = useState(user.phone); const handleLogout = () => { logout(); } + const handleSubmit = async () => { + await updateUser(name, lastname, phone); + update(); + } + return ( <> + +
    +

    Changer de Prénom

    + setName(e.target.value)} type={"text"} /> +
    + +
    +

    Changer de nom

    + setLastName(e.target.value)} type={"text"} /> +
    + +
    +

    Changer de numéro de téléphone

    + setPhone(e.target.value)} type={"text"} /> +
    + + +
    diff --git a/src/components/SettingsModal/SettingsModal.module.css b/src/components/SettingsModal/SettingsModal.module.css index d9d27ff..80b9d81 100644 --- a/src/components/SettingsModal/SettingsModal.module.css +++ b/src/components/SettingsModal/SettingsModal.module.css @@ -14,5 +14,10 @@ display: flex; flex-direction: column; gap: 10px; - margin-bottom: 30px; + margin-top: 15px; + margin-bottom: 15px; +} + +.submitBtn { + align-self: center; } \ No newline at end of file diff --git a/src/utils/users/updateUser.js b/src/utils/users/updateUser.js new file mode 100644 index 0000000..dd2042e --- /dev/null +++ b/src/utils/users/updateUser.js @@ -0,0 +1,32 @@ +import getXSRFToken from "../getXSRF.js"; + +export default async function updateUser(name, lastname, phone) { + + const csrfToken = await getXSRFToken(); + + try { + const res = await fetch(`http://${import.meta.env.VITE_API_URL}/api/users/update`, { + method: 'POST', + credentials: 'include', + headers: { + 'Accept': 'application/json', + 'X-XSRF-TOKEN': csrfToken, + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + name: name, + phone: phone, + lastname: lastname, + }) + }); + + if (!res.ok) { + throw new Error(`Erreur serveur : ${res.status}`); + } + + return await res.json(); + } catch (err) { + console.error('Erreur :', err); + return null; + } +} \ No newline at end of file From 1c80e61329d34ac0b5112390e229d7fde5a8b88c Mon Sep 17 00:00:00 2001 From: T'JAMPENS QUENTIN p2406187 Date: Tue, 9 Dec 2025 11:20:00 +0100 Subject: [PATCH 09/20] Close modal on click --- src/components/ui/modal/modal.jsx | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/components/ui/modal/modal.jsx b/src/components/ui/modal/modal.jsx index 6ddf2a8..822398c 100644 --- a/src/components/ui/modal/modal.jsx +++ b/src/components/ui/modal/modal.jsx @@ -6,9 +6,17 @@ const Modal = ({ open, onClose, children, title }) => { if (!open) return null; + const handleOverlayClick = () => { + onClose(); + }; + + const handleModalClick = (e) => { + e.stopPropagation(); + }; + return createPortal( -
    -
    +
    +
    {title &&

    {title}

    } {children}
    From 16e91eed9f688f248a7a11a56c5f87f85e3e89c9 Mon Sep 17 00:00:00 2001 From: T'JAMPENS QUENTIN p2406187 Date: Tue, 9 Dec 2025 11:43:57 +0100 Subject: [PATCH 10/20] Add icon to ThemeSwitcher.jsx --- public/icons/theme/dark.svg | 33 +++++++++++++++++++ public/icons/theme/light.svg | 29 ++++++++++++++++ .../ui/themeSwitcher/ThemeSwitcher.jsx | 21 +++++++++--- .../ui/themeSwitcher/ThemeSwitcher.module.css | 12 +++++++ 4 files changed, 90 insertions(+), 5 deletions(-) create mode 100644 public/icons/theme/dark.svg create mode 100644 public/icons/theme/light.svg create mode 100644 src/components/ui/themeSwitcher/ThemeSwitcher.module.css diff --git a/public/icons/theme/dark.svg b/public/icons/theme/dark.svg new file mode 100644 index 0000000..7a1ccf1 --- /dev/null +++ b/public/icons/theme/dark.svg @@ -0,0 +1,33 @@ + + + + + + + + + + + + diff --git a/public/icons/theme/light.svg b/public/icons/theme/light.svg new file mode 100644 index 0000000..bc68130 --- /dev/null +++ b/public/icons/theme/light.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/components/ui/themeSwitcher/ThemeSwitcher.jsx b/src/components/ui/themeSwitcher/ThemeSwitcher.jsx index 1b9a84f..b0a5ef7 100644 --- a/src/components/ui/themeSwitcher/ThemeSwitcher.jsx +++ b/src/components/ui/themeSwitcher/ThemeSwitcher.jsx @@ -1,19 +1,30 @@ import Button from "../button/button.jsx"; -import React from "react"; +import { useState, useEffect } from "react"; +import styles from "./ThemeSwitcher.module.css"; + export default function ThemeSwitcher() { + const [theme, setTheme] = useState(""); + + useEffect(() => { + setTheme(localStorage.getItem("theme")); + }, []); + const switchTheme = () => { - const currentTheme = localStorage.getItem("theme"); - let newTheme = currentTheme === "light" ? "dark" : "light"; + let newTheme = theme === "light" ? "dark" : "light"; - if(currentTheme === null) newTheme = "dark"; + if(theme === null || theme === "") newTheme = "dark"; localStorage.setItem("theme", newTheme); + setTheme(newTheme); window.dispatchEvent(new Event("theme-changed")); }; - return + return } \ No newline at end of file diff --git a/src/components/ui/themeSwitcher/ThemeSwitcher.module.css b/src/components/ui/themeSwitcher/ThemeSwitcher.module.css new file mode 100644 index 0000000..93b6fc6 --- /dev/null +++ b/src/components/ui/themeSwitcher/ThemeSwitcher.module.css @@ -0,0 +1,12 @@ +.themeBtn { + display: flex; + flex-direction: row; + align-items: center; + justify-content: center; + gap: 5px; +} + +.themeIcon { + height: 20px; + width: 20px; +} \ No newline at end of file From 417b9856ad6832c58976de75fb2d7a8ea470c57d Mon Sep 17 00:00:00 2001 From: T'JAMPENS QUENTIN p2406187 Date: Tue, 9 Dec 2025 11:52:57 +0100 Subject: [PATCH 11/20] fix default theme icon --- src/components/ui/themeSwitcher/ThemeSwitcher.jsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/components/ui/themeSwitcher/ThemeSwitcher.jsx b/src/components/ui/themeSwitcher/ThemeSwitcher.jsx index b0a5ef7..a3aa96f 100644 --- a/src/components/ui/themeSwitcher/ThemeSwitcher.jsx +++ b/src/components/ui/themeSwitcher/ThemeSwitcher.jsx @@ -8,7 +8,9 @@ export default function ThemeSwitcher() { const [theme, setTheme] = useState(""); useEffect(() => { - setTheme(localStorage.getItem("theme")); + const t = localStorage.getItem("theme"); + if(t) setTheme(t); + else setTheme("light"); }, []); const switchTheme = () => { From 2021220cfeb0597958b3720aa8c4e37d845b9072 Mon Sep 17 00:00:00 2001 From: Antoine Ordonneau Date: Tue, 9 Dec 2025 12:04:11 +0100 Subject: [PATCH 12/20] fin de la page --- src/pages/Home/HomePage.module.css | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/pages/Home/HomePage.module.css b/src/pages/Home/HomePage.module.css index a0f3426..7d6a67a 100644 --- a/src/pages/Home/HomePage.module.css +++ b/src/pages/Home/HomePage.module.css @@ -164,4 +164,10 @@ margin-bottom: 16px; display: flex; } + + + .allContent{ + display: flex; + flex-direction: column; + } } \ No newline at end of file From 5c48f1918ee025e134818c52ae5cba44975bb453 Mon Sep 17 00:00:00 2001 From: T'JAMPENS QUENTIN p2406187 Date: Wed, 10 Dec 2025 09:01:53 +0100 Subject: [PATCH 13/20] fix searchEvent route --- src/utils/searchEvents.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/searchEvents.js b/src/utils/searchEvents.js index db4a67f..a9974d0 100644 --- a/src/utils/searchEvents.js +++ b/src/utils/searchEvents.js @@ -2,7 +2,7 @@ export default async function searchEvents(query) { try { const encodedQuery = encodeURIComponent(query); const response = await fetch( - `http://localhost:80/api/events/search?query=${encodedQuery}`, + `http://${import.meta.env.VITE_API_URL}/api/events/search?query=${encodedQuery}`, { method: 'GET', credentials: 'include', From 6c1d434a009b2f7fcb42b85fc633717cd26c6d60 Mon Sep 17 00:00:00 2001 From: T'JAMPENS QUENTIN p2406187 Date: Wed, 10 Dec 2025 09:25:03 +0100 Subject: [PATCH 14/20] Change admin route --- src/router.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/router.js b/src/router.js index bd0c986..f3fdef6 100644 --- a/src/router.js +++ b/src/router.js @@ -26,7 +26,7 @@ const router = createBrowserRouter([ Component: HomePage, }, { - path: "/stat", + path: "/admin", Component:StatPage, }, { From 01457c4328e1af8e5f291f1f22bcd7a229af5ca9 Mon Sep 17 00:00:00 2001 From: T'JAMPENS QUENTIN p2406187 Date: Wed, 10 Dec 2025 09:25:20 +0100 Subject: [PATCH 15/20] Add phone and password confirmation --- src/pages/Register/RegisterPage.jsx | 40 ++++++++++++++++++++++++----- src/utils/register.js | 4 +-- 2 files changed, 35 insertions(+), 9 deletions(-) diff --git a/src/pages/Register/RegisterPage.jsx b/src/pages/Register/RegisterPage.jsx index cac9e4d..b287e0d 100644 --- a/src/pages/Register/RegisterPage.jsx +++ b/src/pages/Register/RegisterPage.jsx @@ -5,6 +5,7 @@ import Button from "../../components/ui/button/button.jsx"; import { useState } from "react"; import register from "../../utils/register.js"; import { useNavigate } from "react-router"; +import {isNumber} from "chart.js/helpers"; function RegisterPage() { @@ -12,20 +13,31 @@ function RegisterPage() { const navigate = useNavigate(); const [email, setEmail] = useState(""); + const [phone, setPhone] = useState(""); const [password, setPassword] = useState(""); + const [confirmPassword, setConfirmPassword] = useState(""); const [name, setName] = useState(""); const [lastName, setLastName] = useState(""); - const [showPassword, setShowPassword] = useState(false); - - async function handleSubmit(e) { e.preventDefault(); - const res = await register(email, password, name, lastName); - if (!res || res.status !== 200) throw new Error("Register error"); - navigate("/login"); + + if(password === confirmPassword && password.length >= 8) { + const res = await register(email, password, name, lastName, phone); + if (!res || res.status !== 200) throw new Error("Register error"); + navigate("/login"); + } + } + const handlePhone = (e) => { + const value = e.target.value; + if (value === "" || /^[0-9 +]+$/.test(value)) { + setPhone(value); + } + }; + + return
    @@ -61,8 +73,22 @@ function RegisterPage() { style={{ width: '100%' }} />
    +
    - setPassword(e.target.value)} value={password} /> + +
    + +
    + setPassword(e.target.value)} value={password} placeholder={"Mot de passe"}/> +
    + +
    + setConfirmPassword(e.target.value)} value={confirmPassword} placeholder={"Confirmer le mot de passe"} />
    diff --git a/src/utils/register.js b/src/utils/register.js index 313df77..b2d6fac 100644 --- a/src/utils/register.js +++ b/src/utils/register.js @@ -1,6 +1,6 @@ import getXSRFToken from "./getXSRF.js"; -export default async function register(email, password, name, lastname) { +export default async function register(email, password, name, lastname, phone) { const csrfToken = await getXSRFToken(); try { @@ -12,7 +12,7 @@ export default async function register(email, password, name, lastname) { 'X-XSRF-TOKEN': csrfToken, 'Accept': 'application/json' }, - body: JSON.stringify({ email, password, name, lastname }), + body: JSON.stringify({ email, password, name, lastname, phone }), }); console.log('Code HTTP :', response.status); From 5f8333e3f666ef9e895f5876f63796479139429d Mon Sep 17 00:00:00 2001 From: T'JAMPENS QUENTIN p2406187 Date: Wed, 10 Dec 2025 09:25:31 +0100 Subject: [PATCH 16/20] Update placeholder --- src/components/loginform/loginForm.jsx | 2 +- src/components/ui/input/input.jsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/loginform/loginForm.jsx b/src/components/loginform/loginForm.jsx index cd22971..7562cba 100644 --- a/src/components/loginform/loginForm.jsx +++ b/src/components/loginform/loginForm.jsx @@ -30,7 +30,7 @@ function LoginForm({ className }) { />
    - setPassword(e.target.value)} value={password} /> + setPassword(e.target.value)} value={password} placeholder={"Mot de passe"} />
    diff --git a/src/components/ui/input/input.jsx b/src/components/ui/input/input.jsx index 0218b3e..7713b27 100644 --- a/src/components/ui/input/input.jsx +++ b/src/components/ui/input/input.jsx @@ -18,7 +18,7 @@ const TextInput = ({ placeholder, onChange, value, borderStyle, password, classN From 0749bed223615a443e1e364ab1af9d8b84c2367c Mon Sep 17 00:00:00 2001 From: T'JAMPENS QUENTIN p2406187 Date: Wed, 10 Dec 2025 09:40:09 +0100 Subject: [PATCH 17/20] Redirect to / if connected --- src/pages/Login/LoginPage.jsx | 13 +++++++++++++ src/pages/Register/RegisterPage.jsx | 12 ++++++++++-- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/pages/Login/LoginPage.jsx b/src/pages/Login/LoginPage.jsx index 93154f4..79af77a 100644 --- a/src/pages/Login/LoginPage.jsx +++ b/src/pages/Login/LoginPage.jsx @@ -1,8 +1,21 @@ import styles from "./LoginPage.module.css"; import LoginForm from "../../components/loginform/loginForm.jsx"; import Background from "../../components/background/background.jsx"; +import { useEffect, useContext } from "react"; +import { AuthContext } from "../../contexts/auth/AuthContext.js"; +import { useNavigate } from "react-router"; function LoginPage() { + + const { user, loading } = useContext(AuthContext) + const navigate = useNavigate(); + + useEffect(() => { + if (!loading && user) { + navigate("/"); + } + }, [loading, user]); + return (
    diff --git a/src/pages/Register/RegisterPage.jsx b/src/pages/Register/RegisterPage.jsx index b287e0d..ae5375b 100644 --- a/src/pages/Register/RegisterPage.jsx +++ b/src/pages/Register/RegisterPage.jsx @@ -2,10 +2,10 @@ import styles from "./RegisterPage.module.css"; import Background from "../../components/background/background.jsx"; import Input from "../../components/ui/input/input.jsx"; import Button from "../../components/ui/button/button.jsx"; -import { useState } from "react"; +import {useContext, useEffect, useState} from "react"; import register from "../../utils/register.js"; import { useNavigate } from "react-router"; -import {isNumber} from "chart.js/helpers"; +import { AuthContext } from "../../contexts/auth/AuthContext.js"; function RegisterPage() { @@ -19,6 +19,14 @@ function RegisterPage() { const [name, setName] = useState(""); const [lastName, setLastName] = useState(""); + const { user, loading } = useContext(AuthContext) + + useEffect(() => { + if (!loading && user) { + navigate("/"); + } + }, [loading, user]); + async function handleSubmit(e) { e.preventDefault(); From 6bab503447eff99761208dd57e099309ccb61582 Mon Sep 17 00:00:00 2001 From: T'JAMPENS QUENTIN p2406187 Date: Wed, 10 Dec 2025 10:02:16 +0100 Subject: [PATCH 18/20] Add feedback error --- src/pages/Register/RegisterPage.jsx | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/pages/Register/RegisterPage.jsx b/src/pages/Register/RegisterPage.jsx index ae5375b..66e0d52 100644 --- a/src/pages/Register/RegisterPage.jsx +++ b/src/pages/Register/RegisterPage.jsx @@ -6,6 +6,7 @@ import {useContext, useEffect, useState} from "react"; import register from "../../utils/register.js"; import { useNavigate } from "react-router"; import { AuthContext } from "../../contexts/auth/AuthContext.js"; +import Modal from "../../components/ui/modal/modal.jsx"; function RegisterPage() { @@ -18,6 +19,9 @@ function RegisterPage() { const [confirmPassword, setConfirmPassword] = useState(""); const [name, setName] = useState(""); const [lastName, setLastName] = useState(""); + const [open, setOpen] = useState(false); + const [title, setTitle] = useState(""); + const [message, setMessage] = useState(""); const { user, loading } = useContext(AuthContext) @@ -30,12 +34,25 @@ function RegisterPage() { async function handleSubmit(e) { e.preventDefault(); - if(password === confirmPassword && password.length >= 8) { + if(!(password === confirmPassword)) { + + setTitle("Mot de passe invalide") + setMessage("Les mots de passes ne conrrespondent pas") + setOpen(true); + + } else if(password.length < 8) { + + setTitle("Mot de passe invalide") + setMessage("Le mot de passe doit faire plus de 8 charactères") + setOpen(true); + + } else { + const res = await register(email, password, name, lastName, phone); if (!res || res.status !== 200) throw new Error("Register error"); navigate("/login"); - } + } } const handlePhone = (e) => { @@ -106,6 +123,10 @@ function RegisterPage() {
    + setOpen(false)} title={title}> +

    {message}

    +
    +
    } From 174d4f364cf45d7c6ac6602405dffa6476904022 Mon Sep 17 00:00:00 2001 From: T'JAMPENS QUENTIN p2406187 Date: Wed, 10 Dec 2025 10:19:18 +0100 Subject: [PATCH 19/20] Show error modal --- src/pages/Register/RegisterPage.jsx | 29 ++++++++++++++--------------- src/utils/register.js | 14 ++++++++++---- 2 files changed, 24 insertions(+), 19 deletions(-) diff --git a/src/pages/Register/RegisterPage.jsx b/src/pages/Register/RegisterPage.jsx index 66e0d52..2046c9a 100644 --- a/src/pages/Register/RegisterPage.jsx +++ b/src/pages/Register/RegisterPage.jsx @@ -31,26 +31,25 @@ function RegisterPage() { } }, [loading, user]); + const handleModal = (t, m) => { + setTitle(t) + setMessage(m) + setOpen(true); + } + async function handleSubmit(e) { e.preventDefault(); - if(!(password === confirmPassword)) { - - setTitle("Mot de passe invalide") - setMessage("Les mots de passes ne conrrespondent pas") - setOpen(true); - - } else if(password.length < 8) { - - setTitle("Mot de passe invalide") - setMessage("Le mot de passe doit faire plus de 8 charactères") - setOpen(true); - - } else { + if(!(password === confirmPassword)) handleModal("Mot de passe invalide", "Les mots de passes ne conrrespondent pas"); + else if(password.length < 8) handleModal("Mot de passe invalide", "Le mot de passe doit faire plus de 8 charactères"); + else { const res = await register(email, password, name, lastName, phone); - if (!res || res.status !== 200) throw new Error("Register error"); - navigate("/login"); + + if (res.status === 422) { + if (res.errors.email) handleModal("Adresse Email invalide", "Le formet de votre adresse Email n'est pas valide"); + if (res.errors.phone) handleModal("Numéro de téléphone invalide", "Le formet de votre numéro de téléphone n'est pas valide"); + } else navigate("/login"); } } diff --git a/src/utils/register.js b/src/utils/register.js index b2d6fac..43a8c1d 100644 --- a/src/utils/register.js +++ b/src/utils/register.js @@ -15,16 +15,22 @@ export default async function register(email, password, name, lastname, phone) { body: JSON.stringify({ email, password, name, lastname, phone }), }); - console.log('Code HTTP :', response.status); + const data = await response.json(); if (!response.ok) { + if (response.status === 422) { + return { + status: 422, + errors: data.errors + }; + } + throw new Error(`Erreur HTTP ${response.status}`); } - const data = await response.json(); - return { status: response.status, data }; + } catch (error) { - return error; + return { status: "error", error }; } } From c1a7db12e38aa256e45d9577dd6d734c102336e9 Mon Sep 17 00:00:00 2001 From: T'JAMPENS QUENTIN p2406187 Date: Wed, 10 Dec 2025 11:52:23 +0100 Subject: [PATCH 20/20] Change btn type --- src/pages/Volunteers/VolunteerCard.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/Volunteers/VolunteerCard.jsx b/src/pages/Volunteers/VolunteerCard.jsx index a2a3f84..42f18cd 100644 --- a/src/pages/Volunteers/VolunteerCard.jsx +++ b/src/pages/Volunteers/VolunteerCard.jsx @@ -68,7 +68,7 @@ export default function VolunteerCard({ id }) {