diff --git a/CLAUDE.md b/CLAUDE.md index d1b0fe9..76376dc 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -136,13 +136,13 @@ Ce pattern (RLS pour l'accès à la ligne + trigger `BEFORE UPDATE` pour l'accè | `/` | Redirige vers `/leaderboard` si connecté, sinon `/login` | | `/login` | Email + mot de passe | | `/signup` | Email + mot de passe + pseudo + photo (recadrée) ; gère l'attente de confirmation email | -| `/leaderboard` | « L'Agora » — podium top 3 + liste, Realtime, contrôles de points pour les juges | +| `/leaderboard` | « L'Agora » — podium top 3 + liste, Realtime, contrôles de points pour les juges, date/décompte du Tribunal en en-tête (`src/lib/tribunal-date.ts`, partagé avec `/calendrier`) | | `/icare` | « Le Vol d'Icare » — Flappy Bird grec, record personnel all-time, scores figés au Tribunal, points attribués automatiquement | | `/char` | « Le Jeu de l'Agora » — format paysage (projeté) : Le Char (2 colonnes de 3, boutons de duel), Le Gardien du Silence (tirage aléatoire, minuteur discret) et La Roulette (tirage au sort animé) | | `/char/questions` | Banque de questions du Char (ajout/édition/réordonnancement/afficher-masquer) + modération des suggestions des Citoyens (ajouter à la banque/rejeter) — juges uniquement, pilotée depuis un téléphone pendant que `/char` est projetée | | `/mur` | « Le Mur de la Honte » — une note anonyme par Citoyen par jour (dix places, remis à zéro chaque jour) ; les Archontes y voient en plus l'historique complet avec l'auteur de chaque note | | `/urne` | « L'Urne de l'Agora » — un jeton par Citoyen par jour sur une autre personne, classement cumulatif public identique pour tous, Archontes compris (aucune vision privilégiée ici) | -| `/calendrier` | « Le Calendrier des Dieux » — agenda de la semaine, panthéon, date du Tribunal, édition réservée aux juges | +| `/calendrier` | « Le Calendrier des Dieux » — agenda de la semaine, panthéon, date du Tribunal, édition réservée aux juges. Retirée du menu de navigation (la date du Tribunal, seule info largement utile au quotidien, est reprise sur `/leaderboard`) mais la route reste fonctionnelle — les juges y accèdent directement par l'URL pour gérer le calendrier et changer la date | | `/journal` | « Le Crieur » — fil live des décrets (attributions de points), lecture pour tous | | `/profile` | Pseudo (verrouillable), photo, déconnexion, et pour les Citoyens : proposition d'une question pour Le Char (modifiable jusqu'au Tribunal) | | `/admin` | « Admin » — juges uniquement, **vérifié côté serveur** (Server Component), habillée d'une police monospace (rupture volontaire avec le thème grec) — gestion des membres, reset du repère de classement | diff --git a/src/app/calendrier/calendrier-view.tsx b/src/app/calendrier/calendrier-view.tsx index e2b64b6..63652f5 100644 --- a/src/app/calendrier/calendrier-view.tsx +++ b/src/app/calendrier/calendrier-view.tsx @@ -5,20 +5,7 @@ import { createClient, waitForRealtimeAuth } from "@/lib/supabase/client"; import { DayCard, type DayRow } from "./day-card"; import { PANTHEON_PRESETS, getGodPreset } from "@/lib/pantheon"; import { IconPlus } from "@/components/icons"; - -function formatCountdown(tribunalDate: string | null): string { - if (!tribunalDate) return "Aucune date n'a encore été fixée par les Archontes."; - - const target = new Date(tribunalDate); - const now = new Date(); - const diffMs = target.getTime() - now.getTime(); - const diffDays = Math.ceil(diffMs / (1000 * 60 * 60 * 24)); - - if (diffMs < 0) return "Le Tribunal a rendu son verdict."; - if (diffDays === 0) return "Le Tribunal siège aujourd'hui !"; - if (diffDays === 1) return "Le Tribunal siège demain."; - return `Le Tribunal siège dans ${diffDays} jours.`; -} +import { formatCountdown } from "@/lib/tribunal-date"; export function CalendrierView({ isJudge, diff --git a/src/app/leaderboard/page.tsx b/src/app/leaderboard/page.tsx index f6d4c39..c54edf5 100644 --- a/src/app/leaderboard/page.tsx +++ b/src/app/leaderboard/page.tsx @@ -2,6 +2,7 @@ import { redirect } from "next/navigation"; import { createClient } from "@/lib/supabase/server"; import { LeaderboardView } from "./leaderboard-view"; import { AgoraLogo } from "@/components/agora-logo"; +import { formatCountdown, formatTribunalDateTime } from "@/lib/tribunal-date"; export default async function LeaderboardPage() { const supabase = await createClient(); @@ -13,18 +14,26 @@ export default async function LeaderboardPage() { redirect("/login"); } - const { data: profiles, error } = await supabase - .from("profiles") - .select("id, pseudo, avatar_url, points, previous_rank, role") - .order("points", { ascending: false }); + const [{ data: profiles, error }, { data: settings }] = await Promise.all([ + supabase + .from("profiles") + .select("id, pseudo, avatar_url, points, previous_rank, role") + .order("points", { ascending: false }), + supabase.from("settings").select("tribunal_date").eq("id", true).single(), + ]); const isJudge = profiles?.find((p) => p.id === user.id)?.role === "judge"; + const tribunalDate = settings?.tribunal_date ?? null; return (
Le classement des Citoyens
++ {formatCountdown(tribunalDate)} +
+ {tribunalDate &&{formatTribunalDateTime(tribunalDate)}
}- Tu as voté pour {myVoteTarget?.pseudo ?? "quelqu'un"} aujourd'hui. + Tu as voté pour {myVoteTarget?.pseudo ?? "quelqu'un"}{" "} + aujourd'hui.
Reviens demain pour déposer un nouveau jeton.