feat: add filters
This commit is contained in:
parent
cdc41c4a51
commit
b4b74155c2
2 changed files with 105 additions and 149 deletions
|
|
@ -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<string>(
|
||||
getSessionFilter("subject")
|
||||
rawSubject === "all" ? "" : rawSubject || ""
|
||||
);
|
||||
const setSubject = (subject: string) => {
|
||||
updateQuery("subject", subject);
|
||||
setSubjectFilter(subject);
|
||||
};
|
||||
const rawExaminer = query.get("examiner");
|
||||
const [examinerFilter, setExaminerFilter] = useState<string>(
|
||||
getSessionFilter("examiner")
|
||||
rawExaminer === "all" ? "" : rawExaminer || ""
|
||||
);
|
||||
// const [studentFilter, setStudentFilter] = useState<string>("all")
|
||||
const [isFilterOpen, setIsFilterOpen] = useState(
|
||||
getSessionFilter("subject") !== "all" ||
|
||||
getSessionFilter("examiner") !== "all"
|
||||
const setExaminer = (examiner: string) => {
|
||||
updateQuery("examiner", examiner);
|
||||
setExaminerFilter(examiner);
|
||||
};
|
||||
const [sorted, setSort] = useState<string>(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 (
|
||||
<div className="space-y-6 pb-20 md:pb-0">
|
||||
|
|
@ -164,118 +180,50 @@ export default function Home() {
|
|||
</div>
|
||||
|
||||
{/* TODO: Filter component */}
|
||||
<Collapsible open={isFilterOpen} onOpenChange={setIsFilterOpen}>
|
||||
<div className="flex justify-between">
|
||||
<div className="flex gap-2">
|
||||
{activeTab === "class" && (
|
||||
<>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
// TODO: Implement sorting
|
||||
onClick={() => {}}
|
||||
>
|
||||
<ArrowUpDown className="h-4 w-4" />
|
||||
</Button>
|
||||
<div className="flex mb-4">
|
||||
<CollapsibleTrigger asChild>
|
||||
<Button variant="outline" size="sm">
|
||||
{isFilterOpen ? (
|
||||
<>
|
||||
<X className="h-4 w-4 mr-2" />
|
||||
Fermer
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Filter className="h-4 w-4 mr-2" />
|
||||
Recherche
|
||||
</>
|
||||
)}
|
||||
</Button>
|
||||
</CollapsibleTrigger>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
{/* TODO: DEBUG */}
|
||||
{/* {activeTab === "all" &&
|
||||
(getWeekStart().getTime() != startDate.getTime() ? (
|
||||
<Button variant="outline" size="sm" onClick={resetWeek}>
|
||||
<CalendarArrowUp className="h-4 w-4 mr-2" />
|
||||
Cette semaine
|
||||
</Button>
|
||||
) : (
|
||||
<Button variant="outline" size="sm" onClick={goPastYear}>
|
||||
<CalendarArrowDown className="h-4 w-4 mr-2" />
|
||||
Colles des spés
|
||||
</Button>
|
||||
))} */}
|
||||
</div>
|
||||
<div className="flex gap-1 pb-0 pt-2">
|
||||
<Select value={subjectFilter} onValueChange={setSubject}>
|
||||
<SelectTrigger className="rounded-full data-[placeholder]:text-primary">
|
||||
<SelectValue placeholder="Matière" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="all">Toutes</SelectItem>
|
||||
{subjects.map((subject) => (
|
||||
<SelectItem key={subject} value={subject}>
|
||||
{subject}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
|
||||
<CollapsibleContent className="space-y-4">
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="subject-filter">Filtrer par matière</Label>
|
||||
<Select value={subjectFilter} onValueChange={setSubjectFilter}>
|
||||
<SelectTrigger id="subject-filter">
|
||||
<SelectValue placeholder="Toutes les matières" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="all">Toutes les matières</SelectItem>
|
||||
{/* TODO: */}
|
||||
{/* {uniqueTopics.map((subject) => (
|
||||
<SelectItem key={subject} value={subject}>
|
||||
{subject}
|
||||
</SelectItem>
|
||||
))} */}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<Select value={examinerFilter} onValueChange={setExaminer}>
|
||||
<SelectTrigger className="rounded-full data-[placeholder]:text-primary">
|
||||
<SelectValue placeholder="Colleur" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="all">Tous</SelectItem>
|
||||
{/* TODO: */}
|
||||
{examiners.map((examiner) => (
|
||||
<SelectItem key={examiner} value={examiner}>
|
||||
{examiner}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="examiner-filter">Filtrer par colleur</Label>
|
||||
<Select value={examinerFilter} onValueChange={setExaminerFilter}>
|
||||
<SelectTrigger id="examiner-filter">
|
||||
<SelectValue placeholder="Tous les colleurs" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="all">Tous les colleurs</SelectItem>
|
||||
{/* TODO: */}
|
||||
{/* {uniqueExaminers.map((examiner) => (
|
||||
<SelectItem key={examiner} value={examiner}>
|
||||
{examiner}
|
||||
</SelectItem>
|
||||
))} */}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
|
||||
{/* <div className="space-y-2">
|
||||
<Label htmlFor="student-filter">Filtrer par élève</Label>
|
||||
<Select value={studentFilter} onValueChange={setStudentFilter}>
|
||||
<SelectTrigger id="student-filter">
|
||||
<SelectValue placeholder="Tous les élèves" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="all">Tous les élèves</SelectItem>
|
||||
{uniqueStudents.map((student) => (
|
||||
<SelectItem key={student} value={student}>
|
||||
{student}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div> */}
|
||||
</div>
|
||||
|
||||
<div className="flex justify-end">
|
||||
<Button variant="outline" size="sm">
|
||||
{/* //TODO: onClick={resetFilters} */}
|
||||
Réinitialiser les filtres
|
||||
</Button>
|
||||
</div>
|
||||
</CollapsibleContent>
|
||||
</Collapsible>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className="rounded-full dark:bg-input/30 text-primary font-normal"
|
||||
onClick={toggleSort}
|
||||
>
|
||||
{sorted == "asc" ? (
|
||||
<SortAsc className="h-5 w-5" />
|
||||
) : (
|
||||
<SortDesc className="h-5 w-5" />
|
||||
)}
|
||||
Trier
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
{/* Tab Content */}
|
||||
<div>
|
||||
|
|
@ -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)}
|
||||
/>
|
||||
)}
|
||||
|
||||
|
|
|
|||
|
|
@ -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<string, Colle[]> = {};
|
||||
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 (
|
||||
<>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue