317 lines
10 KiB
TypeScript
317 lines
10 KiB
TypeScript
import { DateTime } from "luxon";
|
|
import { useState, useEffect } from "react";
|
|
import { Button } from "~/components/ui/button";
|
|
import {
|
|
ChevronLeft,
|
|
ChevronRight,
|
|
Star,
|
|
Filter,
|
|
X,
|
|
Users,
|
|
User,
|
|
ArrowUpDown,
|
|
} from "lucide-react";
|
|
import {
|
|
Select,
|
|
SelectContent,
|
|
SelectItem,
|
|
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";
|
|
import { useSearchParams } from "react-router";
|
|
import { useColles } from "~/lib/api";
|
|
import TabContent from "~/components/home/tab-content";
|
|
|
|
const tabsStyle =
|
|
"rounded-none bg-background data-[state=active]:bg-background! h-full data-[state=active]:shadow-none border-b-2 border-transparent border-t-0 border-r-0 border-l-0 data-[state=active]:border-primary!";
|
|
|
|
export default function Home() {
|
|
// Handle query parameters
|
|
const [query, setQuery] = useSearchParams();
|
|
const updateQuery = (key: string, value: string) => {
|
|
if (query.get(key) !== value) {
|
|
setQuery((prev) => {
|
|
const newQuery = new URLSearchParams(prev);
|
|
newQuery.set(key, value);
|
|
return newQuery;
|
|
});
|
|
}
|
|
};
|
|
|
|
// Tabs
|
|
const activeTab = query.get("view") || "you";
|
|
const setActiveTab = (tab: string) => updateQuery("view", tab);
|
|
|
|
// Date
|
|
const rawStartDate = query.get("start");
|
|
const startDate = rawStartDate
|
|
? DateTime.fromISO(rawStartDate, { zone: "local" })
|
|
: DateTime.now().startOf("week");
|
|
|
|
const setStartDate = (date: DateTime) =>
|
|
updateQuery("start", date.startOf("week").toISODate()!);
|
|
|
|
const handlePreviousWeek = () => {
|
|
const previousWeek = startDate.minus({ weeks: 1 });
|
|
setStartDate(previousWeek);
|
|
};
|
|
|
|
const handleNextWeek = () => {
|
|
const nextWeek = startDate.plus({ weeks: 1 });
|
|
setStartDate(nextWeek);
|
|
};
|
|
|
|
// 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)
|
|
return (
|
|
<Error
|
|
title="Impossible de charger les colles"
|
|
message={error?.toString()}
|
|
code={500}
|
|
description="Une erreur s'est produite lors du chargement de la liste des colles."
|
|
/>
|
|
);
|
|
|
|
// TODO: FAVORITES
|
|
const useToggleStar = (auth: any) => {};
|
|
// TODO: FILTERS
|
|
const getSessionFilter = (key: string) => {
|
|
const filter = sessionStorage.getItem(key);
|
|
if (filter) {
|
|
return filter;
|
|
}
|
|
return "all";
|
|
};
|
|
const [subjectFilter, setSubjectFilter] = useState<string>(
|
|
getSessionFilter("subject")
|
|
);
|
|
const [examinerFilter, setExaminerFilter] = useState<string>(
|
|
getSessionFilter("examiner")
|
|
);
|
|
// const [studentFilter, setStudentFilter] = useState<string>("all")
|
|
const [isFilterOpen, setIsFilterOpen] = useState(
|
|
getSessionFilter("subject") !== "all" ||
|
|
getSessionFilter("examiner") !== "all"
|
|
);
|
|
useEffect(() => {
|
|
sessionStorage.setItem("subject", subjectFilter);
|
|
sessionStorage.setItem("examiner", examinerFilter);
|
|
// sessionStorage.setItem('student', studentFilter)
|
|
}, [subjectFilter, examinerFilter]);
|
|
|
|
return (
|
|
<div className="space-y-6 pb-20 md:pb-0">
|
|
{/* Tabs */}
|
|
<Tabs
|
|
defaultValue="all"
|
|
value={activeTab}
|
|
onValueChange={setActiveTab}
|
|
className="max-w-md w-full"
|
|
>
|
|
<TabsList className="w-full p-0 bg-background justify-start border-b rounded-none">
|
|
<TabsTrigger value="you" className={tabsStyle}>
|
|
<User className="h-4 w-4" />
|
|
Vous
|
|
</TabsTrigger>
|
|
<TabsTrigger value="favorites" className={tabsStyle}>
|
|
<Star className="h-4 w-4" />
|
|
Favoris
|
|
</TabsTrigger>
|
|
<TabsTrigger value="class" className={tabsStyle}>
|
|
<Users className="h-4 w-4" />
|
|
Classe
|
|
</TabsTrigger>
|
|
</TabsList>
|
|
</Tabs>
|
|
|
|
{/* Week Navigation */}
|
|
<div className="mb-0">
|
|
<div className="flex flex-row items-center justify-between gap-2">
|
|
<Button variant="outline" size="sm" onClick={handlePreviousWeek}>
|
|
<ChevronLeft className="h-10 w-10" />
|
|
</Button>
|
|
<div className="flex-1">
|
|
<DatePickerWithRange
|
|
startDate={startDate}
|
|
setStartDate={setStartDate}
|
|
/>
|
|
</div>
|
|
<Button variant="outline" size="sm" onClick={handleNextWeek}>
|
|
<ChevronRight className="h-10 w-10" />
|
|
</Button>
|
|
</div>
|
|
</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>
|
|
|
|
<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>
|
|
|
|
<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>
|
|
|
|
{/* Tab Content */}
|
|
<div>
|
|
{/* Your Colles Tab */}
|
|
{activeTab === "you" && (
|
|
<TabContent
|
|
tabTitle="Vos colles"
|
|
emptyCollesText="Vous n'avez pas encore de colle cette semaine."
|
|
isLoading={isLoading}
|
|
colles={studentColles}
|
|
/>
|
|
)}
|
|
|
|
{/* Favorites Tab */}
|
|
{activeTab === "favorites" && (
|
|
<TabContent
|
|
tabTitle="Vos favoris"
|
|
emptyCollesText="Vous n'avez pas encore de colle favorite, cliquez sur l'étoile pour ajouter une colle à vos favoris."
|
|
isLoading={isLoading}
|
|
colles={favoriteColles}
|
|
/>
|
|
)}
|
|
</div>
|
|
|
|
{/* Class Colles Tab */}
|
|
{activeTab === "class" && (
|
|
<TabContent
|
|
tabTitle="Les colles de la classe"
|
|
emptyCollesText="Aucune colle trouvée."
|
|
isLoading={isLoading}
|
|
colles={classColles}
|
|
/>
|
|
)}
|
|
|
|
{/* Bottom Navigation for Mobile */}
|
|
<BottomNavigation activeId="colles" />
|
|
</div>
|
|
);
|
|
}
|