From 33a7f16be4ed6baf1bafff9210dd8ee4975b238a Mon Sep 17 00:00:00 2001 From: Giovanni-Josserand Date: Mon, 24 Nov 2025 08:37:04 +0100 Subject: [PATCH 1/9] initialize searchBar component --- public/search.svg | 1 + src/components/SearchBar/SearchBar.jsx | 23 ++++++++++++++++ src/components/SearchBar/SearchBar.module.css | 0 src/pages/Events/EventsPage.jsx | 16 +++++++++++- src/pages/Events/EventsPage.module.css | 26 +++++++++++-------- 5 files changed, 54 insertions(+), 12 deletions(-) create mode 100644 public/search.svg create mode 100644 src/components/SearchBar/SearchBar.jsx create mode 100644 src/components/SearchBar/SearchBar.module.css diff --git a/public/search.svg b/public/search.svg new file mode 100644 index 0000000..f0d166f --- /dev/null +++ b/public/search.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/components/SearchBar/SearchBar.jsx b/src/components/SearchBar/SearchBar.jsx new file mode 100644 index 0000000..b984cb9 --- /dev/null +++ b/src/components/SearchBar/SearchBar.jsx @@ -0,0 +1,23 @@ +import styles from "./SearchBar.module.css" + +function SearchBar({isSearchVisible, setIsSearchVisible}) { + + + return ( +
+
+
+ + + + +
+ + +
+
+ ); +} + +export default SearchBar; \ No newline at end of file diff --git a/src/components/SearchBar/SearchBar.module.css b/src/components/SearchBar/SearchBar.module.css new file mode 100644 index 0000000..e69de29 diff --git a/src/pages/Events/EventsPage.jsx b/src/pages/Events/EventsPage.jsx index f547b45..2d8e636 100644 --- a/src/pages/Events/EventsPage.jsx +++ b/src/pages/Events/EventsPage.jsx @@ -3,11 +3,12 @@ import Event from "../../components/Event/Event.jsx"; import {Link} from "react-router"; import styles from "./EventsPage.module.css"; import Filter from "../../components/Filter/Filter.jsx"; - +import SearchBar from "../../components/SearchBar/SearchBar.jsx"; function EventsPage(){ const [isFilterVisible, setIsFilterVisible] = useState(false); + const [isSearchVisible, setIsSearchVisible] = useState(false); const toggleFilters = () => { setIsFilterVisible(prev => !prev); }; @@ -222,12 +223,24 @@ function EventsPage(){ return (
+ + {isSearchVisible ? ( + + ) : null} +
+ + + +
+
) } diff --git a/src/pages/Events/EventsPage.module.css b/src/pages/Events/EventsPage.module.css index 9bff2ec..059e604 100644 --- a/src/pages/Events/EventsPage.module.css +++ b/src/pages/Events/EventsPage.module.css @@ -1,5 +1,6 @@ .eventsContainer { width: 100%; + position: relative; } @@ -34,7 +35,7 @@ } -.createButton, .sortButton { +.createButton, .searchButton, .sortButton { display: flex; align-items: center; justify-content: center; @@ -50,25 +51,28 @@ color: #019AFF; } -.sortButton svg { +.sortButton svg, .searchButton svg { transform: scale(0.8); fill: #019AFF; } -.sortButton:hover { +.createButton:hover, .searchButton:hover, .mobileFilter:hover { + transform: translateY(-5px); cursor: pointer; } -.createButton:hover, .mobileFilter:hover { - transform: translateY(-5px); -} - -.sortButton:focus { +.sortButton:focus, .searchButton:focus { outline: none; } -.sortButton:focus-visible { - outline: 2px solid black; + + + +.searchBar { + position: absolute; + top: 0; + right: 0; + left: 0; } @@ -92,7 +96,7 @@ width: fit-content; } - .createButton:hover, .mobileFilter:hover { + .createButton:hover, .searchButton:hover, .mobileFilter:hover { transform: none !important; } } From 7d83fa3092414e052f17ed2e9cd085127b03e187 Mon Sep 17 00:00:00 2001 From: Giovanni-Josserand Date: Fri, 28 Nov 2025 13:36:52 +0100 Subject: [PATCH 2/9] add of style for the searchBar --- src/components/SearchBar/SearchBar.jsx | 22 +++++++--------- src/components/SearchBar/SearchBar.module.css | 21 ++++++++++++++++ src/pages/Events/EventsPage.jsx | 19 ++++++++++++-- src/pages/Events/EventsPage.module.css | 25 ++++++++++++------- 4 files changed, 63 insertions(+), 24 deletions(-) diff --git a/src/components/SearchBar/SearchBar.jsx b/src/components/SearchBar/SearchBar.jsx index b984cb9..fb7da99 100644 --- a/src/components/SearchBar/SearchBar.jsx +++ b/src/components/SearchBar/SearchBar.jsx @@ -1,21 +1,17 @@ import styles from "./SearchBar.module.css" -function SearchBar({isSearchVisible, setIsSearchVisible}) { +function SearchBar() { return ( -
-
-
- - - - -
- - -
+
+
+ + + + +
); } diff --git a/src/components/SearchBar/SearchBar.module.css b/src/components/SearchBar/SearchBar.module.css index e69de29..5779207 100644 --- a/src/components/SearchBar/SearchBar.module.css +++ b/src/components/SearchBar/SearchBar.module.css @@ -0,0 +1,21 @@ +.searchBarContainer{ + position: fixed; + top: 10rem; + z-index: 100; + width: 60%; + background: #fff; +} + +.searchBarForm{ + display: flex; +} + +.searchBarForm input{ + background: none; + box-shadow: none; + height: 2em; +} + +.searchBarForm input:focus{ + outline: none; +} diff --git a/src/pages/Events/EventsPage.jsx b/src/pages/Events/EventsPage.jsx index 2d8e636..83f1e32 100644 --- a/src/pages/Events/EventsPage.jsx +++ b/src/pages/Events/EventsPage.jsx @@ -1,4 +1,4 @@ -import {useState} from "react"; +import {useState, useEffect} from "react"; import Event from "../../components/Event/Event.jsx"; import {Link} from "react-router"; import styles from "./EventsPage.module.css"; @@ -18,6 +18,18 @@ function EventsPage(){ yearOrder: "asc", }); + useEffect(() => { + if (isSearchVisible) { + document.getElementById("root").style.overflow = 'hidden'; + } else { + document.getElementById("root").style.overflow = ''; + } + + return () => { + document.getElementById("root").style.overflow = ''; + }; + }, [isSearchVisible]); + const [events] = useState([ { id: 1, @@ -225,7 +237,10 @@ function EventsPage(){
{isSearchVisible ? ( - +
+
setIsSearchVisible(false)}>
+ +
) : null}
diff --git a/src/pages/Events/EventsPage.module.css b/src/pages/Events/EventsPage.module.css index 059e604..bc8aa08 100644 --- a/src/pages/Events/EventsPage.module.css +++ b/src/pages/Events/EventsPage.module.css @@ -34,6 +34,22 @@ padding: 5px 5px 5px 5px; } +.searchBarOverlay { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: 100; + background-color: rgba(0, 0, 0, 0.3); + backdrop-filter: blur(4px); +} + + +.searchBarContainer{ + display: flex; + justify-content: center; +} .createButton, .searchButton, .sortButton { display: flex; @@ -67,15 +83,6 @@ } - -.searchBar { - position: absolute; - top: 0; - right: 0; - left: 0; -} - - @media screen and (max-width: 768px) { .eventsButtons { flex-direction: row; From b0d8eca5a3e509ce1dbc6ffb09ef52f1ba42280b Mon Sep 17 00:00:00 2001 From: Giovanni-Josserand Date: Sat, 29 Nov 2025 17:54:27 +0100 Subject: [PATCH 3/9] correction of API routes url --- src/utils/getUser.js | 2 +- src/utils/getUserNotifications.js | 2 +- src/utils/getXSRF.js | 2 +- src/utils/login.js | 2 +- src/utils/register.js | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/utils/getUser.js b/src/utils/getUser.js index 6826525..b5c817d 100644 --- a/src/utils/getUser.js +++ b/src/utils/getUser.js @@ -1,6 +1,6 @@ export default async function getUser() { try { - const res = await fetch('http://localhost:8000/api/me', { + const res = await fetch('http://localhost:80/api/users/me', { method: 'GET', credentials: 'include', headers: { diff --git a/src/utils/getUserNotifications.js b/src/utils/getUserNotifications.js index 69d2431..1b93395 100644 --- a/src/utils/getUserNotifications.js +++ b/src/utils/getUserNotifications.js @@ -1,7 +1,7 @@ export default async function getUserNotifications() { try { const response = await fetch( - 'http://localhost:8000/api/users/1/notifications', + 'http://localhost:80/api/users/1/notifications', { method: 'GET', credentials: 'include', diff --git a/src/utils/getXSRF.js b/src/utils/getXSRF.js index 1bed25f..46a9415 100644 --- a/src/utils/getXSRF.js +++ b/src/utils/getXSRF.js @@ -1,5 +1,5 @@ export default async function getXSRFToken() { - const response = await fetch('http://localhost:8000/sanctum/csrf-cookie', { + const response = await fetch('http://localhost:80/sanctum/csrf-cookie', { method: 'GET', credentials: 'include' }); diff --git a/src/utils/login.js b/src/utils/login.js index a08151b..6107185 100644 --- a/src/utils/login.js +++ b/src/utils/login.js @@ -4,7 +4,7 @@ export default async function login(email, password) { const csrfToken = await getXSRFToken(); try { - const response = await fetch('http://localhost:8000/api/users/login', { + const response = await fetch('http://localhost:80/api/users/login', { method: 'POST', credentials: 'include', headers: { diff --git a/src/utils/register.js b/src/utils/register.js index 1612bf8..2cdacf6 100644 --- a/src/utils/register.js +++ b/src/utils/register.js @@ -4,7 +4,7 @@ export default async function register(email, password, name, lastname) { const csrfToken = await getXSRFToken(); try { - const response = await fetch('http://localhost:8000/api/users/register', { + const response = await fetch('http://localhost:80/api/users/register', { method: 'POST', credentials: 'include', headers: { From adcd0933d20c2472442014484e759af48adfb9ed Mon Sep 17 00:00:00 2001 From: Giovanni-Josserand Date: Sun, 30 Nov 2025 16:16:44 +0100 Subject: [PATCH 4/9] add searchEvents utils function to call the events/search route --- src/utils/searchEvents.js | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 src/utils/searchEvents.js diff --git a/src/utils/searchEvents.js b/src/utils/searchEvents.js new file mode 100644 index 0000000..db4a67f --- /dev/null +++ b/src/utils/searchEvents.js @@ -0,0 +1,22 @@ +export default async function searchEvents(query) { + try { + const encodedQuery = encodeURIComponent(query); + const response = await fetch( + `http://localhost:80/api/events/search?query=${encodedQuery}`, + { + method: 'GET', + credentials: 'include', + headers: { + 'Content-Type': 'application/json', + 'Accept': 'application/json' + } + } + ); + const data = await response.json(); + return data.hits.map(hit => hit.document); + + } catch (err) { + console.error("Erreur :", err); + return null; + } +} From caf990f7007e0db528c01f7642a5e1fc2c07ab45 Mon Sep 17 00:00:00 2001 From: Giovanni-Josserand Date: Sun, 30 Nov 2025 16:17:21 +0100 Subject: [PATCH 5/9] add dedicated code to call work with the search of events --- src/components/Event/Event.jsx | 26 ++++++++-------- src/components/SearchBar/SearchBar.jsx | 13 +++++--- src/pages/Events/EventsPage.jsx | 42 +++++++++++++++++++++----- src/pages/Events/EventsPage.module.css | 2 -- 4 files changed, 56 insertions(+), 27 deletions(-) diff --git a/src/components/Event/Event.jsx b/src/components/Event/Event.jsx index deaec58..f3941b5 100644 --- a/src/components/Event/Event.jsx +++ b/src/components/Event/Event.jsx @@ -39,18 +39,20 @@ function Event({event}){

{event.name}

{event.description}

-
-
    - {event.tasks - .slice(0,5) - .map((task, index) => ( -
  • - {task.name}
  • - ))} - {event.tasks.length > 5 ? ( -
  • ...
  • - ) : null} -
-
+ {event.tasks != null ? ( +
+
    + {event.tasks + .slice(0,5) + .map((task, index) => ( +
  • - {task.name}
  • + ))} + {event.tasks.length > 5 ? ( +
  • ...
  • + ) : null} +
+
+ ) : null}
{windowSize.width > 768 ? ( diff --git a/src/components/SearchBar/SearchBar.jsx b/src/components/SearchBar/SearchBar.jsx index fb7da99..8df2beb 100644 --- a/src/components/SearchBar/SearchBar.jsx +++ b/src/components/SearchBar/SearchBar.jsx @@ -1,16 +1,19 @@ import styles from "./SearchBar.module.css" -function SearchBar() { - - +function SearchBar({ searchQuery, setSearchQuery}) { return (
-
+ event.preventDefault()}> - + setSearchQuery(event.target.value)} + />
); diff --git a/src/pages/Events/EventsPage.jsx b/src/pages/Events/EventsPage.jsx index 83f1e32..fba2bdf 100644 --- a/src/pages/Events/EventsPage.jsx +++ b/src/pages/Events/EventsPage.jsx @@ -4,11 +4,14 @@ import {Link} from "react-router"; import styles from "./EventsPage.module.css"; import Filter from "../../components/Filter/Filter.jsx"; import SearchBar from "../../components/SearchBar/SearchBar.jsx"; +import searchEvents from "../../utils/searchEvents.js" function EventsPage(){ const [isFilterVisible, setIsFilterVisible] = useState(false); const [isSearchVisible, setIsSearchVisible] = useState(false); + const [searchQuery, setSearchQuery] = useState(''); + const [searchResults, setSearchResults] = useState([]); const toggleFilters = () => { setIsFilterVisible(prev => !prev); }; @@ -18,17 +21,34 @@ function EventsPage(){ yearOrder: "asc", }); + + + useEffect(() => { - if (isSearchVisible) { - document.getElementById("root").style.overflow = 'hidden'; - } else { - document.getElementById("root").style.overflow = ''; - } + const performSearch = async (query) => { + if (query.trim() === '') { + setSearchResults([]); + return; + } + + const data = await searchEvents(query); + if (data) { + setSearchResults(data); + } else { + setSearchResults([]); + } + }; + + + const handler = setTimeout(() => { + performSearch(searchQuery); + }, 300); return () => { - document.getElementById("root").style.overflow = ''; + clearTimeout(handler); }; - }, [isSearchVisible]); + }, [searchQuery]); + const [events] = useState([ { @@ -239,7 +259,13 @@ function EventsPage(){ {isSearchVisible ? (
setIsSearchVisible(false)}>
- + + {searchResults.map((event, index) => ( + + ))}
) : null} diff --git a/src/pages/Events/EventsPage.module.css b/src/pages/Events/EventsPage.module.css index bc8aa08..6c7a2a5 100644 --- a/src/pages/Events/EventsPage.module.css +++ b/src/pages/Events/EventsPage.module.css @@ -41,8 +41,6 @@ width: 100%; height: 100%; z-index: 100; - background-color: rgba(0, 0, 0, 0.3); - backdrop-filter: blur(4px); } From 7adc58419902875fcb4e38876d50c7b9fcaedd80 Mon Sep 17 00:00:00 2001 From: Giovanni-Josserand Date: Sun, 7 Dec 2025 14:35:17 +0100 Subject: [PATCH 6/9] add scroll-y lock on search --- src/components/Event/Event.module.css | 1 + src/components/SearchBar/SearchBar.jsx | 55 ++++++++++++++++++- src/components/SearchBar/SearchBar.module.css | 52 ++++++++++++++++++ src/index.css | 8 ++- src/pages/Events/EventsPage.jsx | 44 ++++----------- src/pages/Events/EventsPage.module.css | 5 +- 6 files changed, 127 insertions(+), 38 deletions(-) diff --git a/src/components/Event/Event.module.css b/src/components/Event/Event.module.css index 142d004..04a40f6 100644 --- a/src/components/Event/Event.module.css +++ b/src/components/Event/Event.module.css @@ -7,6 +7,7 @@ .eventContainerTop { display: flex; + justify-content: space-between; } .eventContainerBottom{ diff --git a/src/components/SearchBar/SearchBar.jsx b/src/components/SearchBar/SearchBar.jsx index 8df2beb..3241c0c 100644 --- a/src/components/SearchBar/SearchBar.jsx +++ b/src/components/SearchBar/SearchBar.jsx @@ -1,6 +1,37 @@ import styles from "./SearchBar.module.css" +import {Link} from "react-router"; +import {useEffect, useState} from "react"; +import searchEvents from "../../utils/searchEvents.js"; + +function SearchBar() { + const [searchQuery, setSearchQuery] = useState(''); + const [searchResults, setSearchResults] = useState([]); + + useEffect(() => { + const performSearch = async (query) => { + if (query.trim() === '') { + setSearchResults([]); + return; + } + + const data = await searchEvents(query); + if (data) { + setSearchResults(data); + } else { + setSearchResults([]); + } + }; + + + const handler = setTimeout(() => { + performSearch(searchQuery); + }, 300); + + return () => { + clearTimeout(handler); + }; + }, [searchQuery]); -function SearchBar({ searchQuery, setSearchQuery}) { return (
event.preventDefault()}> @@ -15,6 +46,28 @@ function SearchBar({ searchQuery, setSearchQuery}) { onChange={(event) => setSearchQuery(event.target.value)} />
+ +
+ {searchResults.length > 0 ? ( +
+ ) : null} +
+ + + {searchResults.map((result, i) => ( + +
+
+ {result.image == null ? ( + Pas de photo de l'événement + ) : ( + Photo de l'événement + )} +
+

{result.name}

+
+ + ))}
); } diff --git a/src/components/SearchBar/SearchBar.module.css b/src/components/SearchBar/SearchBar.module.css index 5779207..ff2830e 100644 --- a/src/components/SearchBar/SearchBar.module.css +++ b/src/components/SearchBar/SearchBar.module.css @@ -10,6 +10,58 @@ display: flex; } + + +.eventImageDiv { + display: flex; + align-items: center; + justify-content: center; + margin-right: 1rem; + width: auto; + height: 2rem; + flex-shrink: 0; +} + +.searchedEvent{ + display: flex; + padding: 0.5rem; + border-radius: 15px; + align-items: center; +} + +.searchedEvent:hover { + background: #afafaf; + cursor: pointer; +} + +.searchedEvent p { + display: flex; + align-items: center; + text-decoration: none; + color: black; +} + + +.lineContainer{ + display: flex; + justify-content: center; + align-items: center; +} + +.line{ + height: 0; + width: 96%; + border: #606060 solid 1px; + margin: 0.5rem 0; +} + +.eventImage { + max-width: 100%; + max-height: 100%; + object-fit: contain; + border-radius: 20px; +} + .searchBarForm input{ background: none; box-shadow: none; diff --git a/src/index.css b/src/index.css index f7d7591..87c36d8 100644 --- a/src/index.css +++ b/src/index.css @@ -1,8 +1,10 @@ * { margin: 0; padding: 0; - width: 100%; box-sizing: border-box; +} + +html { overflow-x: hidden; } @@ -20,12 +22,14 @@ @media screen and (max-width: 768px) { .content{ padding: 0.7rem; - z-index:1; } } + + .content { padding: 1.5rem; z-index: 1; + width: 100%; } a { diff --git a/src/pages/Events/EventsPage.jsx b/src/pages/Events/EventsPage.jsx index fba2bdf..3728572 100644 --- a/src/pages/Events/EventsPage.jsx +++ b/src/pages/Events/EventsPage.jsx @@ -4,14 +4,12 @@ import {Link} from "react-router"; import styles from "./EventsPage.module.css"; import Filter from "../../components/Filter/Filter.jsx"; import SearchBar from "../../components/SearchBar/SearchBar.jsx"; -import searchEvents from "../../utils/searchEvents.js" function EventsPage(){ const [isFilterVisible, setIsFilterVisible] = useState(false); const [isSearchVisible, setIsSearchVisible] = useState(false); - const [searchQuery, setSearchQuery] = useState(''); - const [searchResults, setSearchResults] = useState([]); + const toggleFilters = () => { setIsFilterVisible(prev => !prev); }; @@ -21,33 +19,19 @@ function EventsPage(){ yearOrder: "asc", }); - - - useEffect(() => { - const performSearch = async (query) => { - if (query.trim() === '') { - setSearchResults([]); - return; - } - - const data = await searchEvents(query); - if (data) { - setSearchResults(data); - } else { - setSearchResults([]); - } - }; - - - const handler = setTimeout(() => { - performSearch(searchQuery); - }, 300); + if (isSearchVisible) { + document.documentElement.style.overflow = 'hidden'; + } else { + document.documentElement.style.overflow = ''; + } return () => { - clearTimeout(handler); + document.documentElement.style.overflow = ''; }; - }, [searchQuery]); + }, [isSearchVisible]); + + const [events] = useState([ @@ -259,13 +243,7 @@ function EventsPage(){ {isSearchVisible ? (
setIsSearchVisible(false)}>
- - {searchResults.map((event, index) => ( - - ))} +
) : null} diff --git a/src/pages/Events/EventsPage.module.css b/src/pages/Events/EventsPage.module.css index 6c7a2a5..321145b 100644 --- a/src/pages/Events/EventsPage.module.css +++ b/src/pages/Events/EventsPage.module.css @@ -34,6 +34,7 @@ padding: 5px 5px 5px 5px; } + .searchBarOverlay { position: fixed; top: 0; @@ -41,9 +42,9 @@ width: 100%; height: 100%; z-index: 100; + background-color: rgba(0, 0, 0, 0.3); + backdrop-filter: blur(4px); } - - .searchBarContainer{ display: flex; justify-content: center; From 22921f3da12f915981c585e3ebd33bfae7d889da Mon Sep 17 00:00:00 2001 From: Giovanni-Josserand Date: Sun, 7 Dec 2025 15:22:33 +0100 Subject: [PATCH 7/9] moving side buttons within a ToolBar component --- src/components/ToolBar/ToolBar.jsx | 66 ++++++++++++++ src/components/ToolBar/ToolBar.module.css | 97 +++++++++++++++++++++ src/pages/Events/EventsPage.jsx | 64 +------------- src/pages/Events/EventsPage.module.css | 100 +--------------------- 4 files changed, 167 insertions(+), 160 deletions(-) create mode 100644 src/components/ToolBar/ToolBar.jsx create mode 100644 src/components/ToolBar/ToolBar.module.css diff --git a/src/components/ToolBar/ToolBar.jsx b/src/components/ToolBar/ToolBar.jsx new file mode 100644 index 0000000..7788f59 --- /dev/null +++ b/src/components/ToolBar/ToolBar.jsx @@ -0,0 +1,66 @@ +import styles from "./ToolBar.module.css" +import {Link} from "react-router"; +import Filter from "../Filter/Filter.jsx"; +import {useEffect, useState} from "react"; +import SearchBar from "../SearchBar/SearchBar.jsx"; + + +function ToolBar({setFilters, filters}) { + const [isFilterVisible, setIsFilterVisible] = useState(false); + const [isSearchVisible, setIsSearchVisible] = useState(false); + const toggleFilters = () => { + setIsFilterVisible(prev => !prev); + }; + + + useEffect(() => { + if (isSearchVisible) { + document.documentElement.style.overflow = 'hidden'; + } else { + document.documentElement.style.overflow = ''; + } + + return () => { + document.documentElement.style.overflow = ''; + }; + }, [isSearchVisible]); + + + + return ( +
+ {isSearchVisible ? ( +
+
setIsSearchVisible(false)}>
+ +
+ ) : null} +
+ + + + + + + +
+ +
+ +
+
+
+
+ ); +} + +export default ToolBar; \ No newline at end of file diff --git a/src/components/ToolBar/ToolBar.module.css b/src/components/ToolBar/ToolBar.module.css new file mode 100644 index 0000000..d67cd44 --- /dev/null +++ b/src/components/ToolBar/ToolBar.module.css @@ -0,0 +1,97 @@ +.eventsButtons { + overflow: visible; + position: fixed; + top: 10rem; + right: 2rem; + display: flex; + flex-direction: column; + align-items: flex-end; + width: fit-content; + height: fit-content; + gap: 1rem; +} + + +.filterContainer{ + padding: 0; + border-radius: 30px; + overflow: visible; +} + +.filterMenu{ + padding: 5px 5px 5px 5px; +} + +.createButton, .searchButton, .sortButton { + display: flex; + align-items: center; + justify-content: center; + border: none; + border-radius: 50%; + width: 55px; + height: 55px; + transition: all 0.5s ease; +} + +.createButton { + font-size: 2rem; + color: #019AFF; +} + +.createButton:hover, .searchButton:hover, .mobileFilter:hover { + transform: translateY(-5px); + cursor: pointer; +} + + +.searchBarOverlay { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: 100; + background-color: rgba(0, 0, 0, 0.3); + backdrop-filter: blur(4px); +} +.searchBarContainer{ + display: flex; + justify-content: center; +} + +.sortButton svg, .searchButton svg { + transform: scale(0.8); + fill: #019AFF; +} + + +.sortButton:focus, .searchButton:focus { + outline: none; +} + + + +@media screen and (max-width: 768px) { + .eventsButtons { + flex-direction: row; + position: relative; + top: 0; + right: 0; + align-items: flex-start; + width: 100%; + margin-top: 16px; + } + + .filterContainer{ + display: flex; + width: fit-content; + } + + .filterMenu{ + width: fit-content; + } + + .createButton:hover, .searchButton:hover, .mobileFilter:hover { + transform: none !important; + } +} \ No newline at end of file diff --git a/src/pages/Events/EventsPage.jsx b/src/pages/Events/EventsPage.jsx index 3728572..84797be 100644 --- a/src/pages/Events/EventsPage.jsx +++ b/src/pages/Events/EventsPage.jsx @@ -1,39 +1,15 @@ -import {useState, useEffect} from "react"; +import {useState} from "react"; import Event from "../../components/Event/Event.jsx"; -import {Link} from "react-router"; import styles from "./EventsPage.module.css"; -import Filter from "../../components/Filter/Filter.jsx"; -import SearchBar from "../../components/SearchBar/SearchBar.jsx"; +import ToolBar from "../../components/ToolBar/ToolBar.jsx"; function EventsPage(){ - const [isFilterVisible, setIsFilterVisible] = useState(false); - const [isSearchVisible, setIsSearchVisible] = useState(false); - - const toggleFilters = () => { - setIsFilterVisible(prev => !prev); - }; - const [filters, setFilters] = useState({ alphabetical: "asc", yearOrder: "asc", }); - useEffect(() => { - if (isSearchVisible) { - document.documentElement.style.overflow = 'hidden'; - } else { - document.documentElement.style.overflow = ''; - } - - return () => { - document.documentElement.style.overflow = ''; - }; - }, [isSearchVisible]); - - - - const [events] = useState([ { id: 1, @@ -235,48 +211,14 @@ function EventsPage(){ }); - - return (
- - {isSearchVisible ? ( -
-
setIsSearchVisible(false)}>
- -
- ) : null} - -
- - + - - - - -
- -
- -
-
-
+
{sortedEvents.map((event, index) => ( ))}
-
) } diff --git a/src/pages/Events/EventsPage.module.css b/src/pages/Events/EventsPage.module.css index 321145b..7666a73 100644 --- a/src/pages/Events/EventsPage.module.css +++ b/src/pages/Events/EventsPage.module.css @@ -8,102 +8,4 @@ display: flex; align-items: center; flex-direction: column; -} - -.eventsButtons { - overflow: visible; - position: fixed; - top: 10rem; - right: 2rem; - display: flex; - flex-direction: column; - align-items: flex-end; - width: fit-content; - height: fit-content; - gap: 1rem; -} - - -.filterContainer{ - padding: 0; - border-radius: 30px; - overflow: visible; -} - -.filterMenu{ - padding: 5px 5px 5px 5px; -} - - -.searchBarOverlay { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - z-index: 100; - background-color: rgba(0, 0, 0, 0.3); - backdrop-filter: blur(4px); -} -.searchBarContainer{ - display: flex; - justify-content: center; -} - -.createButton, .searchButton, .sortButton { - display: flex; - align-items: center; - justify-content: center; - border: none; - border-radius: 50%; - width: 55px; - height: 55px; - transition: all 0.5s ease; -} - -.createButton { - font-size: 2rem; - color: #019AFF; -} - -.sortButton svg, .searchButton svg { - transform: scale(0.8); - fill: #019AFF; -} - -.createButton:hover, .searchButton:hover, .mobileFilter:hover { - transform: translateY(-5px); - cursor: pointer; -} - - -.sortButton:focus, .searchButton:focus { - outline: none; -} - - -@media screen and (max-width: 768px) { - .eventsButtons { - flex-direction: row; - position: relative; - top: 0; - right: 0; - align-items: flex-start; - width: 100%; - margin-top: 16px; - } - - .filterContainer{ - display: flex; - width: fit-content; - } - - .filterMenu{ - width: fit-content; - } - - .createButton:hover, .searchButton:hover, .mobileFilter:hover { - transform: none !important; - } -} - +} \ No newline at end of file From a3c62b693358d1362c6f49a89dfd2b6f1cea52e1 Mon Sep 17 00:00:00 2001 From: Giovanni-Josserand Date: Sun, 7 Dec 2025 15:49:03 +0100 Subject: [PATCH 8/9] moving filter function within a dedicated file --- src/pages/Events/EventsPage.jsx | 41 +++----------------------------- src/utils/filter.js | 42 +++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 38 deletions(-) create mode 100644 src/utils/filter.js diff --git a/src/pages/Events/EventsPage.jsx b/src/pages/Events/EventsPage.jsx index 84797be..70f2e9a 100644 --- a/src/pages/Events/EventsPage.jsx +++ b/src/pages/Events/EventsPage.jsx @@ -2,6 +2,7 @@ import {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"; function EventsPage(){ @@ -10,6 +11,7 @@ function EventsPage(){ yearOrder: "asc", }); + const [events] = useState([ { id: 1, @@ -173,49 +175,12 @@ function EventsPage(){ }, ]); - const compareDate = (dateA, dateB) => { - const dA = new Date(dateA); - const dB = new Date(dateB); - - if (filters.yearOrder === "asc") { - return dB - dA; - } else { - return dA - dB; - } - }; - - const sortedEvents = [...events].sort((a, b) => { - const sortedATasks = a.tasks.sort((taskA, taskB) => - compareDate(taskA.start, taskB.start) - ); - const sortedBTasks = b.tasks.sort((taskA, taskB) => - compareDate(taskA.start, taskB.start) - ); - - const timeComparison = compareDate( - sortedATasks[0].start, - sortedBTasks[0].start - ); - - if (timeComparison !== 0) { - return timeComparison; - } - - if (filters.alphabetical !== null) { - return filters.alphabetical === "asc" - ? a.name.localeCompare(b.name) - : b.name.localeCompare(a.name); - } - - return 0; - }); - return (
- {sortedEvents.map((event, index) => ( + {filter(events, filters).map((event, index) => ( ))}
diff --git a/src/utils/filter.js b/src/utils/filter.js new file mode 100644 index 0000000..93f126f --- /dev/null +++ b/src/utils/filter.js @@ -0,0 +1,42 @@ +function filter(elements, filters) { + const compareDate = (dateA, dateB) => { + const dA = new Date(dateA); + const dB = new Date(dateB); + + if (filters.yearOrder === "asc") { + return dB - dA; + } else { + return dA - dB; + } + }; + + + return [...elements].sort((a, b) => { + const sortedATasks = a.tasks.sort((taskA, taskB) => + compareDate(taskA.start, taskB.start) + ); + const sortedBTasks = b.tasks.sort((taskA, taskB) => + compareDate(taskA.start, taskB.start) + ); + + const timeComparison = compareDate( + sortedATasks[0].start, + sortedBTasks[0].start + ); + + if (timeComparison !== 0) { + return timeComparison; + } + + if (filters.alphabetical !== null) { + return filters.alphabetical === "asc" + ? a.name.localeCompare(b.name) + : b.name.localeCompare(a.name); + } + + return 0; + }); +} + + +export default filter; \ No newline at end of file From 8275bd164357a65dc1ffb63baf44195047aab268 Mon Sep 17 00:00:00 2001 From: Giovanni-Josserand Date: Sun, 7 Dec 2025 17:13:44 +0100 Subject: [PATCH 9/9] remove unecessary code --- package-lock.json | 28 ++++++++++++++++++++++++++++ src/pages/Events/EventsPage.jsx | 30 ++++-------------------------- 2 files changed, 32 insertions(+), 26 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4b8ff7e..8daf889 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1109,6 +1109,12 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@kurkle/color": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@kurkle/color/-/color-0.3.4.tgz", + "integrity": "sha512-M5UknZPHRu3DEDWoipU6sE8PdkZ6Z/S+v4dD+Ke8IaNlpdSQah50lz1KtcFBa2vsdOnwbbnxJwVM4wty6udA5w==", + "license": "MIT" + }, "node_modules/@mdx-js/react": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-3.1.1.tgz", @@ -2684,6 +2690,18 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/chart.js": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.5.1.tgz", + "integrity": "sha512-GIjfiT9dbmHRiYi6Nl2yFCq7kkwdkp1W/lp2J99rX0yo9tgJGn3lKQATztIjb5tVtevcBtIdICNWqlq5+E8/Pw==", + "license": "MIT", + "dependencies": { + "@kurkle/color": "^0.3.0" + }, + "engines": { + "pnpm": ">=8" + } + }, "node_modules/check-error": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", @@ -4421,6 +4439,16 @@ "node": ">=0.10.0" } }, + "node_modules/react-chartjs-2": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/react-chartjs-2/-/react-chartjs-2-5.3.1.tgz", + "integrity": "sha512-h5IPXKg9EXpjoBzUfyWJvllMjG2mQ4EiuHQFhms/AjUm0XSZHhyRy2xVmLXHKrtcdrPO4mnGqRtYoD0vp95A0A==", + "license": "MIT", + "peerDependencies": { + "chart.js": "^4.1.1", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, "node_modules/react-docgen": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/react-docgen/-/react-docgen-8.0.2.tgz", diff --git a/src/pages/Events/EventsPage.jsx b/src/pages/Events/EventsPage.jsx index 02c70bf..2b458f4 100644 --- a/src/pages/Events/EventsPage.jsx +++ b/src/pages/Events/EventsPage.jsx @@ -3,6 +3,7 @@ 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"; function EventsPage(){ @@ -12,32 +13,9 @@ function EventsPage(){ }); - const [events] = useState([ - { - id: 1, - name: "Marathon de la Ville", - description: "Participez au marathon annuel et soutenez les associations locales.", - image: null, - tasks: [ - { - name: "Inscription des participants", - start: "2018-09-24 22:21:20", - end: "2018-09-24 22:21:20", - place: "Centre sportif", - description: "Accueillir et enregistrer tous les coureurs.", - volunteers_count: 5 - }, - { - name: "Distribution des dossards", - start: "2018-09-24 22:21:20", - end: "2018-09-24 22:21:20", - place: "Salle principale", - description: "Remettre les dossards et goodies aux participants.", - volunteers_count: 3 - }, - ] - } - */ + const [events, setEvents] = useState([]); + + useEffect(() => { (async () => {