From b4b74155c27abd2a68b47a125dc86f0d67f95171 Mon Sep 17 00:00:00 2001 From: Nathan Lamy Date: Tue, 19 Aug 2025 14:32:55 +0200 Subject: [PATCH] feat: add filters --- app/components/home/index.tsx | 246 +++++++++++----------------- app/components/home/tab-content.tsx | 8 +- 2 files changed, 105 insertions(+), 149 deletions(-) diff --git a/app/components/home/index.tsx b/app/components/home/index.tsx index 389d128..a975e5b 100644 --- a/app/components/home/index.tsx +++ b/app/components/home/index.tsx @@ -1,15 +1,14 @@ import { DateTime } from "luxon"; -import { useState, useEffect } from "react"; +import { useState } from "react"; import { Button } from "~/components/ui/button"; import { ChevronLeft, ChevronRight, Star, - Filter, - X, Users, User, - ArrowUpDown, + SortAsc, + SortDesc, } from "lucide-react"; import { Select, @@ -18,13 +17,7 @@ import { SelectTrigger, SelectValue, } from "~/components/ui/select"; -import { Label } from "~/components/ui/label"; import { Tabs, TabsList, TabsTrigger } from "~/components/ui/tabs"; -import { - Collapsible, - CollapsibleContent, - CollapsibleTrigger, -} from "~/components/ui/collapsible"; import DatePickerWithRange from "~/components/home/date-picker"; import BottomNavigation from "~/components/home/bottom-nav"; import Error from "~/components/error"; @@ -74,13 +67,6 @@ export default function Home() { // Fetch colles from API const { studentColles, classColles, favoriteColles, error, isLoading } = useColles(startDate); - console.log("Colles loaded:", { - studentColles, - classColles, - favoriteColles, - error, - isLoading, - }); // Error handling (after all hooks) if (error) @@ -95,30 +81,60 @@ export default function Home() { // TODO: FAVORITES const useToggleStar = (auth: any) => {}; - // TODO: FILTERS - const getSessionFilter = (key: string) => { - const filter = sessionStorage.getItem(key); - if (filter) { - return filter; - } - return "all"; - }; + + // Filter state + const rawSubject = query.get("subject"); const [subjectFilter, setSubjectFilter] = useState( - getSessionFilter("subject") + rawSubject === "all" ? "" : rawSubject || "" ); + const setSubject = (subject: string) => { + updateQuery("subject", subject); + setSubjectFilter(subject); + }; + const rawExaminer = query.get("examiner"); const [examinerFilter, setExaminerFilter] = useState( - getSessionFilter("examiner") + rawExaminer === "all" ? "" : rawExaminer || "" ); - // const [studentFilter, setStudentFilter] = useState("all") - const [isFilterOpen, setIsFilterOpen] = useState( - getSessionFilter("subject") !== "all" || - getSessionFilter("examiner") !== "all" + const setExaminer = (examiner: string) => { + updateQuery("examiner", examiner); + setExaminerFilter(examiner); + }; + const [sorted, setSort] = useState(query.get("sort") || "desc"); + const toggleSort = () => { + const newSort = sorted === "asc" ? "desc" : "asc"; + updateQuery("sort", newSort); + setSort(newSort); + }; + + const keepUnique = (arr: any[]) => { + return [...new Set(arr)]; + }; + const subjects = keepUnique(classColles.map((colle) => colle.subject?.name)); + const examiners = keepUnique( + classColles.map((colle) => colle.examiner?.name) ); - useEffect(() => { - sessionStorage.setItem("subject", subjectFilter); - sessionStorage.setItem("examiner", examinerFilter); - // sessionStorage.setItem('student', studentFilter) - }, [subjectFilter, examinerFilter]); + + const applyFilters = (colles: any[]) => { + return colles + .filter((colle) => { + const subjectMatch = + subjectFilter === "all" || !subjectFilter + ? true + : colle.subject?.name === subjectFilter; + const examinerMatch = + examinerFilter === "all" || !examinerFilter + ? true + : colle.examiner?.name === examinerFilter; + return subjectMatch && examinerMatch; + }) + .sort((a, b) => { + if (sorted === "asc") { + return a.date.localeCompare(b.date); + } else { + return b.date.localeCompare(a.date); + } + }); + }; return (
@@ -164,118 +180,50 @@ export default function Home() {
{/* TODO: Filter component */} - -
-
- {activeTab === "class" && ( - <> - -
- - - -
- - )} -
- {/* TODO: DEBUG */} - {/* {activeTab === "all" && - (getWeekStart().getTime() != startDate.getTime() ? ( - - ) : ( - - ))} */} -
+
+ - -
-
- - -
+ -
- - -
- - {/*
- - -
*/} -
- -
- -
-
- + +
{/* Tab Content */}
@@ -285,7 +233,8 @@ export default function Home() { tabTitle="Vos colles" emptyCollesText="Vous n'avez pas encore de colle cette semaine." isLoading={isLoading} - colles={studentColles} + isSorted={sorted === "desc"} + colles={applyFilters(studentColles)} /> )} @@ -306,7 +255,8 @@ export default function Home() { tabTitle="Les colles de la classe" emptyCollesText="Aucune colle trouvée." isLoading={isLoading} - colles={classColles} + isSorted={sorted === "desc"} + colles={applyFilters(classColles)} /> )} diff --git a/app/components/home/tab-content.tsx b/app/components/home/tab-content.tsx index 67bd80e..e61ec85 100644 --- a/app/components/home/tab-content.tsx +++ b/app/components/home/tab-content.tsx @@ -9,7 +9,8 @@ type TabContentProps = { emptyCollesText: string; isLoading: boolean; colles: Colle[]; -}; + isSorted?: boolean; +} const WEEK_DAYS = [ "Lundi", @@ -26,6 +27,7 @@ export default function TabContent({ emptyCollesText, isLoading, colles, + isSorted }: TabContentProps) { const collesByDay: Record = {}; colles.forEach((colle) => { @@ -40,6 +42,10 @@ export default function TabContent({ const days = WEEK_DAYS.filter( (day) => collesByDay[day] && collesByDay[day].length > 0 ); + // If not sorted, reverse the order of days + if (!isSorted) { + days.reverse(); + } return ( <>