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);
}