diff --git a/src/assets/sortByAlpha.svg b/src/assets/sortByAlpha.svg new file mode 100644 index 0000000..28789ca --- /dev/null +++ b/src/assets/sortByAlpha.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/sortByAntiAlpha.svg b/src/assets/sortByAntiAlpha.svg new file mode 100644 index 0000000..f74e5d8 --- /dev/null +++ b/src/assets/sortByAntiAlpha.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/assets/timerArrowDown.svg b/src/assets/timerArrowDown.svg new file mode 100644 index 0000000..df66463 --- /dev/null +++ b/src/assets/timerArrowDown.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/timerArrowUp.svg b/src/assets/timerArrowUp.svg new file mode 100644 index 0000000..861ced2 --- /dev/null +++ b/src/assets/timerArrowUp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/components/Filter/Filter.jsx b/src/components/Filter/Filter.jsx new file mode 100644 index 0000000..e0f39e2 --- /dev/null +++ b/src/components/Filter/Filter.jsx @@ -0,0 +1,61 @@ +import styles from "./Filter.module.css"; + +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.module.css b/src/components/Filter/Filter.module.css new file mode 100644 index 0000000..60fef57 --- /dev/null +++ b/src/components/Filter/Filter.module.css @@ -0,0 +1,64 @@ +.filterContainer { + display: flex; + flex-direction: column; + gap: 0.4rem; + overflow: hidden; + max-height: 0; + opacity: 0; + transform: translateY(-10px); + transition: max-height 0.5s ease, opacity 0.8s ease, transform 0.5s ease; +} + +.filterOpen { + max-height: 200px; + opacity: 1; + transform: translateY(0); +} + +.filterClose{ + max-height: 200px; + opacity: 0; + transform: translateY(-10px); +} + + +.filterTag { + border: none; + background: none; + display: flex; + align-items: center; + justify-content: center; + border-radius: 50%; + width: 45px; + height: 45px; +} + + +.filterTag:focus { + outline: none; +} +.filterTag:focus-visible { + outline: 2px solid black; +} + +.filterTag:hover { + cursor: pointer; + svg{ + fill: #019AFF; + } +} + + +.filterTag svg { + transform: scale(1); +} + + +.active { + border: 1px solid #019AFF; +} + +.active svg { + fill: #019AFF; + transform: scale(1); +} \ No newline at end of file diff --git a/src/index.css b/src/index.css index b6c5ed6..1699f0d 100644 --- a/src/index.css +++ b/src/index.css @@ -25,7 +25,7 @@ .content { padding: 1.5rem; z-index: 1; - + min-height: 100vh; } @@ -49,9 +49,9 @@ body { .glassCard { width: 100%; - padding: 10px 20px 10px 20px; + padding: 10px 10px 10px 10px; height: fit-content; - background: rgba(255, 255, 255, 0.65); + background: rgba(184, 184, 184, 0.65); backdrop-filter: blur(3px); -webkit-backdrop-filter: blur(3px); border-radius: 20px; @@ -60,7 +60,7 @@ body { 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); + inset 0 0 30px 4px rgba(255, 255, 255, 0.4); position: relative; overflow: hidden; } diff --git a/src/pages/Events/EventsPage.jsx b/src/pages/Events/EventsPage.jsx index 16abc09..d2e0bf7 100644 --- a/src/pages/Events/EventsPage.jsx +++ b/src/pages/Events/EventsPage.jsx @@ -1,12 +1,23 @@ import {useState} from "react"; import Event from "../../components/Event/Event.jsx"; import {Link} from "react-router"; -import styles from "./EventsPage.module.css" +import styles from "./EventsPage.module.css"; +import Filter from "../../components/Filter/Filter.jsx"; function EventsPage(){ - const [events, setEvents] = useState([ + const [isFilterVisible, setIsFilterVisible] = useState(false); + const toggleFilters = () => { + setIsFilterVisible(prev => !prev); + }; + + const [filters, setFilters] = useState({ + alphabetical: "asc", + yearOrder: "asc", + }); + + const [events] = useState([ { id: 1, name: "Marathon de la Ville", @@ -15,16 +26,16 @@ function EventsPage(){ tasks: [ { name: "Inscription des participants", - start: "08:00", - end: "10:00", + 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: "09:00", - end: "11:00", + 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 @@ -39,16 +50,16 @@ function EventsPage(){ tasks: [ { name: "Montage de la scène", - start: "10:00", - end: "14:00", + start: "2018-09-24 22:21:20", + end: "2018-09-24 22:21:20", place: "Parc central", description: "Installer la scène, les éclairages et le son.", volunteers_count: 6 }, { name: "Accueil du public", - start: "14:00", - end: "20:00", + start: "2018-09-24 22:21:20", + end: "2018-09-24 22:21:20", place: "Entrée principale", description: "Vérifier les billets et orienter les visiteurs.", volunteers_count: 4 @@ -63,24 +74,24 @@ function EventsPage(){ tasks: [ { name: "Préparation des salles", - start: "07:00", - end: "09:00", + start: "2018-09-24 22:21:20", + end: "2018-09-24 22:21:20", place: "Campus Tech", description: "Installer les chaises, projecteurs et matériel pour les conférences.", volunteers_count: 4 }, { name: "Accueil des intervenants", - start: "08:30", - end: "10:00", + start: "2018-09-24 22:21:20", + end: "2018-09-24 22:21:20", place: "Hall principal", description: "Assister les speakers et orienter vers les salles.", volunteers_count: 2 }, { name: "Gestion du buffet", - start: "12:00", - end: "14:00", + start: "2018-09-24 22:21:20", + end: "2018-09-24 22:21:20", place: "Salle de restauration", description: "Distribuer boissons et repas aux participants.", volunteers_count: 3 @@ -95,16 +106,16 @@ function EventsPage(){ tasks: [ { name: "Installation du matériel", - start: "09:00", - end: "10:00", + start: "2018-09-24 22:21:20", + end: "2018-09-24 22:21:20", place: "Jardin partagé", description: "Préparer outils et terreaux pour les participants.", volunteers_count: 2 }, { name: "Encadrement des participants", - start: "10:00", - end: "12:00", + start: "2018-09-24 22:21:20", + end: "2018-09-24 22:21:20", place: "Jardin partagé", description: "Aider et conseiller sur la plantation et l’entretien.", volunteers_count: 3 @@ -119,48 +130,48 @@ function EventsPage(){ tasks: [ { name: "Accueil et enregistrement", - start: "08:00", - end: "12:00", + start: "2020-09-24 22:21:20", + end: "2020-09-24 22:21:20", place: "Salle municipale", description: "Enregistrer les donneurs et expliquer le processus.", volunteers_count: 4 }, { name: "Préparation des salles", - start: "07:30", - end: "08:00", + start: "2018-09-24 22:21:20", + end: "2018-09-24 22:21:20", place: "Salle municipale", description: "Installer les lits, tables et matériel médical.", volunteers_count: 3 }, { name: "Assistance post-don", - start: "12:00", - end: "16:00", + start: "2018-09-24 22:21:20", + end: "2018-09-24 22:21:20", place: "Salle municipale", description: "Accompagner les donneurs après le don et proposer des rafraîchissements.", volunteers_count: 2 }, { name: "Accueil et enregistrement", - start: "08:00", - end: "12:00", + start: "2020-09-24 22:21:20", + end: "2020-09-24 22:21:20", place: "Salle municipale", description: "Enregistrer les donneurs et expliquer le processus.", volunteers_count: 4 }, { name: "Préparation des salles", - start: "07:30", - end: "08:00", + start: "2018-09-24 22:21:20", + end: "2018-09-24 22:21:20", place: "Salle municipale", description: "Installer les lits, tables et matériel médical.", volunteers_count: 3 }, { name: "Assistance post-don", - start: "12:00", - end: "16:00", + start: "2018-09-24 22:21:20", + end: "2018-09-24 22:21:20", place: "Salle municipale", description: "Accompagner les donneurs après le don et proposer des rafraîchissements.", volunteers_count: 2 @@ -169,12 +180,50 @@ 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 (
- {events.map((event, index) => ( + {sortedEvents.map((event, index) => ( ))}
@@ -184,11 +233,16 @@ function EventsPage(){ className={`${styles.createButton} glassCard`}> + - +
+ +
+ +
+
) diff --git a/src/pages/Events/EventsPage.module.css b/src/pages/Events/EventsPage.module.css index 6e949d2..64a6dd2 100644 --- a/src/pages/Events/EventsPage.module.css +++ b/src/pages/Events/EventsPage.module.css @@ -23,6 +23,17 @@ } +.filterContainer{ + padding: 0; + border-radius: 30px; + overflow: visible; +} + +.filterMenu{ + padding: 5px 5px 5px 5px; +} + + .createButton, .sortButton { display: flex; align-items: center; @@ -44,9 +55,12 @@ fill: #019AFF; } -.createButton:hover, .sortButton:hover { - transform: translateY(-5px); +.sortButton:hover { + cursor: pointer; +} +.createButton:hover, .mobileFilter:hover { + transform: translateY(-5px); }