From ed9067169336878fee61d2dbe4e112822d92f57b Mon Sep 17 00:00:00 2001 From: T'JAMPENS QUENTIN p2406187 Date: Wed, 11 Feb 2026 15:35:05 +0100 Subject: [PATCH 1/9] Create component for searchBar + btn --- src/components/SearchBar/SearchBar.jsx | 100 --------------- src/components/SearchBar/SearchBar.module.css | 4 +- src/components/SearchBar/SearchBar.tsx | 120 ++++++++++++++++++ .../components/searchBtn/SearchBtn.tsx | 38 ++++++ 4 files changed, 161 insertions(+), 101 deletions(-) delete mode 100644 src/components/SearchBar/SearchBar.jsx create mode 100644 src/components/SearchBar/SearchBar.tsx create mode 100644 src/components/ToolBar/components/searchBtn/SearchBtn.tsx diff --git a/src/components/SearchBar/SearchBar.jsx b/src/components/SearchBar/SearchBar.jsx deleted file mode 100644 index a1dded2..0000000 --- a/src/components/SearchBar/SearchBar.jsx +++ /dev/null @@ -1,100 +0,0 @@ -import styles from "./SearchBar.module.css" -import {Link} from "react-router"; -import {useEffect, useState} from "react"; -import searchEvents from "../../utils/events/searchEvents.js"; -import searchUsers from "../../utils/users/searchUsers.js"; -import { useLocation } from "react-router"; - - -function SearchBar() { - const [searchQuery, setSearchQuery] = useState(''); - const [searchResults, setSearchResults] = useState([]); - const location = useLocation(); - - useEffect(() => { - const performSearch = async (query) => { - if (query.trim() === '') { - setSearchResults([]); - return; - } - - let data; - - if (location.pathname.includes("events")) { - data = await searchEvents(query); - } else if (location.pathname.includes("volunteers")) { - data = await searchUsers(query); - } - - - if (data) { - setSearchResults(data); - } else { - setSearchResults([]); - } - }; - - - const handler = setTimeout(() => { - performSearch(searchQuery); - }, 300); - - return () => { - clearTimeout(handler); - }; - }, [searchQuery]); - - return ( -
-
element.preventDefault()}> - Rechercher - setSearchQuery(element.target.value)} - /> -
- -
- {searchResults.length > 0 ? ( -
- ) : null} -
- -
- {searchResults.map((result, i) => ( - (location.pathname.includes("events")) ? ( - -
-
- {result.image == null ? ( - Pas de photo de l'événement - ) : ( - Photo de l'événement - )} -
-

{result.name}

-
- - ) : location.pathname.includes("volunteers") ? ( - -
-
- {result.image == null ? ( - Pas de photo de l'événement - ) : ( - Photo de l'événement - )} -
-

{result.name} {result.lastname}

-
- - ) : null - ))} -
-
- ); -} - -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 index d35c808..c6a093d 100644 --- a/src/components/SearchBar/SearchBar.module.css +++ b/src/components/SearchBar/SearchBar.module.css @@ -1,6 +1,8 @@ .searchBarContainer{ position: fixed; - top: 4rem; + top: 20vh; + left: 50%; + transform: translateX(-50%); z-index: 100; width: 60%; background: #fff; diff --git a/src/components/SearchBar/SearchBar.tsx b/src/components/SearchBar/SearchBar.tsx new file mode 100644 index 0000000..d1ef4c6 --- /dev/null +++ b/src/components/SearchBar/SearchBar.tsx @@ -0,0 +1,120 @@ +import styles from "./SearchBar.module.css"; +import { Link } from "react-router"; +import { useEffect, useState } from "react"; +import searchEvents from "../../utils/events/searchEvents.js"; +import searchUsers from "../../utils/users/searchUsers.js"; +import { useLocation } from "react-router"; + +function SearchBar(): any { + const [searchQuery, setSearchQuery] = useState(""); + const [searchResults, setSearchResults] = useState([]); + const location: any = useLocation(); + + useEffect(() => { + const performSearch = async (query: string): Promise => { + if (query.trim() === "") { + setSearchResults([]); + return; + } + + let data: any; + + if (location.pathname.includes("events")) { + data = await searchEvents(query); + } else if (location.pathname.includes("volunteers")) { + data = await searchUsers(query); + } + + if (data) { + setSearchResults(data); + } else { + setSearchResults([]); + } + }; + + const handler: ReturnType = setTimeout(() => { + performSearch(searchQuery); + }, 300); + + return () => { + clearTimeout(handler); + }; + }, [searchQuery, location.pathname]); + + return ( +
+
) => + element.preventDefault() + } + > + Rechercher + ) => + setSearchQuery(element.target.value) + } + /> +
+ +
+ {searchResults.length > 0 ? ( +
+ ) : null} +
+ +
+ {searchResults.map((result: any, i: number) => + location.pathname.includes("events") ? ( + +
+
+ {result.image == null ? ( + Pas de photo de l'événement + ) : ( + Photo de l'événement + )} +
+

{result.name}

+
+ + ) : location.pathname.includes("volunteers") ? ( + +
+
+ {result.image == null ? ( + Pas de photo de l'événement + ) : ( + Photo de l'événement + )} +
+

+ {result.name} {result.lastname} +

+
+ + ) : null + )} +
+
+ ); +} + +export default SearchBar; diff --git a/src/components/ToolBar/components/searchBtn/SearchBtn.tsx b/src/components/ToolBar/components/searchBtn/SearchBtn.tsx new file mode 100644 index 0000000..c93e24a --- /dev/null +++ b/src/components/ToolBar/components/searchBtn/SearchBtn.tsx @@ -0,0 +1,38 @@ +import styles from "../../ToolBar.module.css" +import Button from "../../../ui/button/button"; +import { useEffect, useState } from "react"; +import SearchBar from "../../../SearchBar/SearchBar"; + +export default function SearchBtn() { + + const [isSearchVisible, setIsSearchVisible] = useState(false); + + useEffect(() => { + if (isSearchVisible) { + document.documentElement.style.overflow = 'hidden'; + } else { + document.documentElement.style.overflow = ''; + } + + return () => { + document.documentElement.style.overflow = ''; + }; + }, [isSearchVisible]); + + return <> + + {isSearchVisible ? ( +
+
setIsSearchVisible(false)}>
+ +
+ ) : null} + +
+ +
+ + +} \ No newline at end of file From 171a202859c96f5cfab10befe18a306b06fccf1a Mon Sep 17 00:00:00 2001 From: T'JAMPENS QUENTIN p2406187 Date: Wed, 11 Feb 2026 15:35:18 +0100 Subject: [PATCH 2/9] Use searchBarBtn component --- src/components/ToolBar/ToolBar.jsx | 29 +++-------------------------- 1 file changed, 3 insertions(+), 26 deletions(-) diff --git a/src/components/ToolBar/ToolBar.jsx b/src/components/ToolBar/ToolBar.jsx index 874fa70..a4590a3 100644 --- a/src/components/ToolBar/ToolBar.jsx +++ b/src/components/ToolBar/ToolBar.jsx @@ -1,50 +1,27 @@ import styles from "./ToolBar.module.css" import Filter from "../Filter/Filter.jsx"; import {useContext, useEffect, useState} from "react"; -import SearchBar from "../SearchBar/SearchBar.jsx"; +use import SearchBar from "../SearchBar/SearchBar.tsx"; import CreateEventBtn from "../createEventBtn/CreateEventBtn.jsx"; import Button from "../ui/button/button.tsx"; import {AuthContext} from "../../contexts/auth/AuthContext.js"; +import SearchBtn from "./components/searchBtn/SearchBtn.tsx"; function ToolBar({setFilters, filters, showCreate = true}) { const { user } = useContext(AuthContext); 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}
{showCreate && user.isAdmin ? ( ) : null} - +
-
- -
-
+
); diff --git a/src/components/ToolBar/tools/FilterBtn.tsx b/src/components/ToolBar/tools/FilterBtn.tsx new file mode 100644 index 0000000..1a5d89b --- /dev/null +++ b/src/components/ToolBar/tools/FilterBtn.tsx @@ -0,0 +1,29 @@ +import styles from "../ToolBar.module.css" +import Button from "../../ui/button/button"; +import { useEffect, useState } from "react"; +import SearchBar from "../../SearchBar/SearchBar"; +import Filter from "../../Filter/Filter.jsx"; + + +interface FilterBtnProps { + setFilters: (filter: string) => void; + filters: string; +} + +export default function FilterBtn({ setFilters, filters }: FilterBtnProps) { + + const [isFilterVisible, setIsFilterVisible] = useState(false); + + const toggleFilters = () => { + setIsFilterVisible(prev => !prev); + }; + + return
+ +
+ +
+
+} \ No newline at end of file From 87c0cc02e7488b7017ed837afa846462b2a81cdd Mon Sep 17 00:00:00 2001 From: T'JAMPENS QUENTIN p2406187 Date: Wed, 11 Feb 2026 16:47:15 +0100 Subject: [PATCH 6/9] Remove useless imports --- src/components/ToolBar/tools/FilterBtn.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/components/ToolBar/tools/FilterBtn.tsx b/src/components/ToolBar/tools/FilterBtn.tsx index 1a5d89b..672a3f3 100644 --- a/src/components/ToolBar/tools/FilterBtn.tsx +++ b/src/components/ToolBar/tools/FilterBtn.tsx @@ -1,7 +1,6 @@ import styles from "../ToolBar.module.css" import Button from "../../ui/button/button"; -import { useEffect, useState } from "react"; -import SearchBar from "../../SearchBar/SearchBar"; +import { useState } from "react"; import Filter from "../../Filter/Filter.jsx"; From 451da54fc33fec41aa44ae96e4bb6625efbd1673 Mon Sep 17 00:00:00 2001 From: T'JAMPENS QUENTIN p2406187 Date: Wed, 11 Feb 2026 17:08:52 +0100 Subject: [PATCH 7/9] Fix errors --- src/components/Filter/Filter.jsx | 56 ---------------- src/components/Filter/Filter.tsx | 78 ++++++++++++++++++++++ src/components/ToolBar/tools/FilterBtn.tsx | 10 ++- 3 files changed, 85 insertions(+), 59 deletions(-) delete mode 100644 src/components/Filter/Filter.jsx create mode 100644 src/components/Filter/Filter.tsx diff --git a/src/components/Filter/Filter.jsx b/src/components/Filter/Filter.jsx deleted file mode 100644 index eb0bf87..0000000 --- a/src/components/Filter/Filter.jsx +++ /dev/null @@ -1,56 +0,0 @@ -import styles from "./Filter.module.css"; -import Button from "../ui/button/button.tsx" - -function Filter({isFilterVisible, filters, setFilters}){ - const setAlphabeticalOrder = (order) => { - setFilters(prev => ({ - ...prev, - alphabetical : prev.alphabetical === order ? null : order - })); - }; - - const setYearOrder = (order) => { - setFilters(prev => ({ - ...prev, - yearOrder: prev.yearOrder === order ? null : order - })); - }; - - return ( -
- - - - - - - - - - - - - - - -
- ) -} - -export default Filter; \ No newline at end of file diff --git a/src/components/Filter/Filter.tsx b/src/components/Filter/Filter.tsx new file mode 100644 index 0000000..d917928 --- /dev/null +++ b/src/components/Filter/Filter.tsx @@ -0,0 +1,78 @@ +import styles from "./Filter.module.css"; +import Button from "../ui/button/button"; +import React from "react"; + +type FiltersType = { + alphabetical: "asc" | "desc" | null; + yearOrder: "asc" | "desc" | null; + [key: string]: any; +}; + +type FilterProps = { + isFilterVisible: boolean; + filters: FiltersType; + setFilters: React.Dispatch>; +}; + +function Filter({ isFilterVisible, filters, setFilters }: FilterProps): any { + + const setAlphabeticalOrder = (order: "asc" | "desc"): void => { + setFilters((prev) => ({ + ...prev, + alphabetical: prev.alphabetical === order ? null : order + })); + }; + + const setYearOrder = (order: "asc" | "desc"): void => { + setFilters((prev) => ({ + ...prev, + yearOrder: prev.yearOrder === order ? null : order + })); + }; + + return ( +
+ + + + + + + + + + + + + + + +
+ ); +} + +export default Filter; diff --git a/src/components/ToolBar/tools/FilterBtn.tsx b/src/components/ToolBar/tools/FilterBtn.tsx index 672a3f3..0f87ae9 100644 --- a/src/components/ToolBar/tools/FilterBtn.tsx +++ b/src/components/ToolBar/tools/FilterBtn.tsx @@ -1,12 +1,16 @@ import styles from "../ToolBar.module.css" import Button from "../../ui/button/button"; import { useState } from "react"; -import Filter from "../../Filter/Filter.jsx"; +import Filter from "../../Filter/Filter"; +interface Filters { + alphabetical: "asc" | "desc"; + yearOrder: "asc" | "desc"; +} interface FilterBtnProps { - setFilters: (filter: string) => void; - filters: string; + setFilters: any + filters: Filters } export default function FilterBtn({ setFilters, filters }: FilterBtnProps) { From fa6336fffcaa6e863fc8d0823d1c37ef6b4ade9f Mon Sep 17 00:00:00 2001 From: T'JAMPENS QUENTIN p2406187 Date: Wed, 11 Feb 2026 17:17:50 +0100 Subject: [PATCH 8/9] Move createEventBtn --- src/components/ToolBar/ToolBar.jsx | 3 +-- .../{ => ToolBar/tools}/createEventBtn/CreateEventBtn.jsx | 8 ++++---- .../tools}/createEventBtn/createEventBtn.module.css | 0 3 files changed, 5 insertions(+), 6 deletions(-) rename src/components/{ => ToolBar/tools}/createEventBtn/CreateEventBtn.jsx (91%) rename src/components/{ => ToolBar/tools}/createEventBtn/createEventBtn.module.css (100%) diff --git a/src/components/ToolBar/ToolBar.jsx b/src/components/ToolBar/ToolBar.jsx index 351ceab..8bfb46b 100644 --- a/src/components/ToolBar/ToolBar.jsx +++ b/src/components/ToolBar/ToolBar.jsx @@ -1,6 +1,6 @@ import styles from "./ToolBar.module.css" import { useContext } from "react"; -import CreateEventBtn from "../createEventBtn/CreateEventBtn.jsx"; +import CreateEventBtn from "./tools/createEventBtn/CreateEventBtn.jsx"; import { AuthContext } from "../../contexts/auth/AuthContext.js"; import SearchBtn from "./tools/SearchBtn.tsx"; import FilterBtn from "./tools/FilterBtn.tsx"; @@ -14,7 +14,6 @@ function ToolBar({setFilters, filters, showCreate = true}) { {showCreate && user.isAdmin ? ( ) : null} - diff --git a/src/components/createEventBtn/CreateEventBtn.jsx b/src/components/ToolBar/tools/createEventBtn/CreateEventBtn.jsx similarity index 91% rename from src/components/createEventBtn/CreateEventBtn.jsx rename to src/components/ToolBar/tools/createEventBtn/CreateEventBtn.jsx index 019b836..e7e886f 100644 --- a/src/components/createEventBtn/CreateEventBtn.jsx +++ b/src/components/ToolBar/tools/createEventBtn/CreateEventBtn.jsx @@ -1,9 +1,9 @@ import styles from "./createEventBtn.module.css" import { useState, useContext } from "react"; -import Modal from "../ui/modal/modal.tsx"; -import Button from "../ui/button/button.tsx"; -import TextInput from "../ui/input/input.tsx"; -import { EventContext } from "../../contexts/events/EventContext.js"; +import Modal from "../../../ui/modal/modal.tsx"; +import Button from "../../../ui/button/button.tsx"; +import TextInput from "../../../ui/input/input.tsx"; +import { EventContext } from "../../../../contexts/events/EventContext.js"; export default function CreateEventBtn() { diff --git a/src/components/createEventBtn/createEventBtn.module.css b/src/components/ToolBar/tools/createEventBtn/createEventBtn.module.css similarity index 100% rename from src/components/createEventBtn/createEventBtn.module.css rename to src/components/ToolBar/tools/createEventBtn/createEventBtn.module.css From eb9a0f58eff19d3eff296f67f51d33d2c81eeb6b Mon Sep 17 00:00:00 2001 From: T'JAMPENS QUENTIN p2406187 Date: Fri, 13 Feb 2026 14:20:07 +0100 Subject: [PATCH 9/9] Move isAdmin condition --- src/components/ToolBar/ToolBar.jsx | 7 +------ .../ToolBar/tools/createEventBtn/CreateEventBtn.jsx | 4 ++++ 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/components/ToolBar/ToolBar.jsx b/src/components/ToolBar/ToolBar.jsx index 8bfb46b..4461da7 100644 --- a/src/components/ToolBar/ToolBar.jsx +++ b/src/components/ToolBar/ToolBar.jsx @@ -1,19 +1,14 @@ import styles from "./ToolBar.module.css" -import { useContext } from "react"; import CreateEventBtn from "./tools/createEventBtn/CreateEventBtn.jsx"; -import { AuthContext } from "../../contexts/auth/AuthContext.js"; import SearchBtn from "./tools/SearchBtn.tsx"; import FilterBtn from "./tools/FilterBtn.tsx"; function ToolBar({setFilters, filters, showCreate = true}) { - const { user } = useContext(AuthContext); return (
- {showCreate && user.isAdmin ? ( - - ) : null} + {showCreate && }
diff --git a/src/components/ToolBar/tools/createEventBtn/CreateEventBtn.jsx b/src/components/ToolBar/tools/createEventBtn/CreateEventBtn.jsx index e7e886f..11b96d6 100644 --- a/src/components/ToolBar/tools/createEventBtn/CreateEventBtn.jsx +++ b/src/components/ToolBar/tools/createEventBtn/CreateEventBtn.jsx @@ -4,11 +4,13 @@ import Modal from "../../../ui/modal/modal.tsx"; import Button from "../../../ui/button/button.tsx"; import TextInput from "../../../ui/input/input.tsx"; import { EventContext } from "../../../../contexts/events/EventContext.js"; +import {AuthContext} from "../../../../contexts/auth/AuthContext.ts"; export default function CreateEventBtn() { const { addEvent } = useContext(EventContext); + const { user } = useContext(AuthContext); const [isOpen, setIsOpen] = useState(false); const [name, setName] = useState(""); @@ -24,6 +26,8 @@ export default function CreateEventBtn() { setIsOpen(false); } + if(!user.isAdmin) return null; + return <>