ui: rework colle details
All checks were successful
Deploy to Netlify / Deploy to Netlify (push) Successful in 1m55s

This commit is contained in:
Nathan Lamy 2025-08-21 13:35:15 +02:00
parent 21cb6a8b9f
commit 70ed93e88c
2 changed files with 53 additions and 76 deletions

View file

@ -160,6 +160,7 @@ export const getColles = async (startDate: DateTime) => {
}; };
export interface Colle { export interface Colle {
relatives: Colle[];
id: number; id: number;
date: string; // ISO date string date: string; // ISO date string
subject: { subject: {

View file

@ -2,7 +2,7 @@ import "katex/dist/katex.min.css";
import { DomUtils, parseDocument } from "htmlparser2"; import { DomUtils, parseDocument } from "htmlparser2";
import Latex from "react-latex-next"; import Latex from "react-latex-next";
import { useState } from "react"; import { useState } from "react";
import { Navigate, useNavigate, useParams } from "react-router"; import { Link, Navigate, useNavigate, useParams } from "react-router";
import { Button } from "~/components/ui/button"; import { Button } from "~/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "~/components/ui/card"; import { Card, CardContent, CardHeader, CardTitle } from "~/components/ui/card";
import { import {
@ -19,6 +19,7 @@ import {
RefreshCw, RefreshCw,
Share2, Share2,
ExternalLink, ExternalLink,
Users,
} from "lucide-react"; } from "lucide-react";
import { Separator } from "~/components/ui/separator"; import { Separator } from "~/components/ui/separator";
import ColleDetailsSkeleton from "~/components/details/skeleton-details"; import ColleDetailsSkeleton from "~/components/details/skeleton-details";
@ -27,19 +28,17 @@ import Error from "~/components/error";
import { Badge } from "~/components/ui/badge"; import { Badge } from "~/components/ui/badge";
import { AUTH_ERROR, refreshColle, useColle, useUser } from "~/lib/api"; import { AUTH_ERROR, refreshColle, useColle, useUser } from "~/lib/api";
import { toast } from "sonner"; import { toast } from "sonner";
import { formatDate, formatGrade, formatTime, goBack } from "~/lib/utils"; import {
formatDate,
formatGrade,
formatTime,
getColorClass,
getSubjectColor,
getSubjectEmoji,
goBack,
} from "~/lib/utils";
import { useQueryClient } from "@tanstack/react-query"; import { useQueryClient } from "@tanstack/react-query";
// TODO: Preferences for subject colors
const getSubjectColor = (_: string) => {
// Mock placeholder function
return "bg-blue-100 text-blue-800"; // Default color
};
const getSubjectEmoji = (_: string) => {
// Mock placeholder function
return "📚"; // Default emoji
};
// TODO: Move all code to components // TODO: Move all code to components
export default function ColleDetailPage() { export default function ColleDetailPage() {
const { user, isLoading: isUserLoading, error: userError } = useUser(); const { user, isLoading: isUserLoading, error: userError } = useUser();
@ -143,8 +142,10 @@ export default function ColleDetailPage() {
}); });
}; };
const subjectColor = getSubjectColor(colle.subject.name); const subjectColor = getColorClass(
const subjectEmoji = getSubjectEmoji(colle.subject.name); getSubjectColor(colle.subject.name, user.preferences)
);
const subjectEmoji = getSubjectEmoji(colle.subject.name, user.preferences);
return ( return (
<div className="container mx-auto py-6 px-4 pb-20 md:pb-6 md:py-8"> <div className="container mx-auto py-6 px-4 pb-20 md:pb-6 md:py-8">
@ -154,18 +155,28 @@ export default function ColleDetailPage() {
Retour Retour
</Button> </Button>
<div className="flex md:hidden items-center gap-2"> <div className="flex md:hidden items-center gap-2">
<Button <div className="space-x-2">
variant="outline" <Button
size="icon" variant="outline"
className="h-10 w-10" size="icon"
onClick={handleReload} className="h-10 w-10"
disabled={isReloading} onClick={handleReload}
> disabled={isReloading}
<RefreshCw >
className={`h-5 w-5 ${isReloading ? "animate-spin" : ""}`} <RefreshCw
/> className={`h-5 w-5 ${isReloading ? "animate-spin" : ""}`}
<span className="sr-only">Recharger</span> />
</Button> <span className="sr-only">Recharger</span>
</Button>
<Button
variant="outline"
size="icon"
className="h-10 w-10"
onClick={handleShare}
>
<Share2 className="h-5 w-5" />
</Button>
</div>
</div> </div>
</div> </div>
@ -174,7 +185,9 @@ export default function ColleDetailPage() {
<div className="flex flex-col md:flex-row md:items-center md:justify-between gap-2"> <div className="flex flex-col md:flex-row md:items-center md:justify-between gap-2">
<div className="flex flex-col"> <div className="flex flex-col">
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<CardTitle className="text-2xl">Résumé de Colle</CardTitle> <CardTitle className="text-xl">
Colle de {colle.subject.name}
</CardTitle>
{colle.grade && ( {colle.grade && (
<div <div
className={`md:hidden px-3 py-1 rounded-md text-sm font-medium ${subjectColor}`} className={`md:hidden px-3 py-1 rounded-md text-sm font-medium ${subjectColor}`}
@ -217,7 +230,7 @@ export default function ColleDetailPage() {
<span className="sr-only">Recharger</span> <span className="sr-only">Recharger</span>
</Button> </Button>
<Button {/* <Button
variant="ghost" variant="ghost"
size="sm" size="sm"
className={`h-9 w-9 ${ className={`h-9 w-9 ${
@ -233,7 +246,7 @@ export default function ColleDetailPage() {
}`} }`}
/> />
<span className="sr-only">Ajouter aux favoris</span> <span className="sr-only">Ajouter aux favoris</span>
</Button> </Button> */}
{colle.grade && ( {colle.grade && (
<div <div
@ -246,9 +259,9 @@ export default function ColleDetailPage() {
</div> </div>
</CardHeader> </CardHeader>
<CardContent className="space-y-6"> <CardContent className="space-y-4">
<div className="grid grid-cols-1 md:grid-cols-2 gap-4"> <div className="grid grid-cols-1 md:grid-cols-2 gap-2">
<div className="space-y-4"> <div className="space-y-2">
<div> <div>
<h3 className="text-sm font-medium text-muted-foreground mb-1"> <h3 className="text-sm font-medium text-muted-foreground mb-1">
Date Date
@ -272,10 +285,10 @@ export default function ColleDetailPage() {
</div> </div>
</div> </div>
<div className="space-y-4"> <div className="space-y-2">
<div> <div>
<h3 className="text-sm font-medium text-muted-foreground mb-1"> <h3 className="text-sm font-medium text-muted-foreground mb-1">
Étudiant Élève
</h3> </h3>
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<User className="h-4 w-4" /> <User className="h-4 w-4" />
@ -283,29 +296,28 @@ export default function ColleDetailPage() {
</div> </div>
</div> </div>
{/* TODO: Colles groups - others students */} {colle.relatives?.length > 0 && (
{/* {colle.group?.length > 0 && (
<div> <div>
<h3 className="text-sm font-medium text-muted-foreground mb-1"> <h3 className="text-sm font-medium text-muted-foreground mb-1">
Autres élèves Autres élèves
</h3> </h3>
{colle.group.map((linkedColle) => ( {colle.relatives.map((linkedColle) => (
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<Users className="h-4 w-4" /> <Users className="h-4 w-4" />
<Link <Link
to={`/colles/${linkedColle.id}`} to={`/colles/${linkedColle.id}`}
key={linkedColle.id} key={linkedColle.id}
> >
{linkedColle.student} {linkedColle.student.fullName}
</Link> </Link>
</div> </div>
))} ))}
</div> </div>
)} */} )}
</div> </div>
{colle.room && ( {colle.room && (
<div className="space-y-4"> <div className="space-y-2">
<div> <div>
<h3 className="text-sm font-medium text-muted-foreground mb-1"> <h3 className="text-sm font-medium text-muted-foreground mb-1">
Salle Salle
@ -377,42 +389,6 @@ export default function ColleDetailPage() {
</div> </div>
</CardContent> </CardContent>
</Card> </Card>
{/* Mobile Action Bar - Fixed at Bottom */}
<div className="fixed bottom-0 left-0 right-0 bg-background border-t border-border md:hidden z-50">
<div className="container mx-auto px-4 py-2 flex items-center justify-around">
<Button
variant="ghost"
size="lg"
className={`flex-1 h-12 ${
// TODO: Use a proper favorite state
false ? "text-yellow-500" : "text-muted-foreground"
}`}
onClick={handleToggleFavorite}
>
<Star
className={`h-5 w-5 mr-2 ${
// TODO: Use a proper favorite state
false ? "fill-yellow-500" : ""
}`}
/>
{/* TODO: */}
{false ? "Favori" : "Ajouter"}
</Button>
<Separator orientation="vertical" className="h-8" />
<Button
variant="ghost"
size="lg"
className="flex-1 h-12"
onClick={handleShare}
>
<Share2 className="h-5 w-5 mr-2" />
Partager
</Button>
</div>
</div>
</div> </div>
); );
} }