SPB Git forge

spb/qc26

Public
10commits 1branches 0releases
2.8 MBsize
maindefault branch
17 days agolast push
Python 51.6% TypeScript 46.7% CSS 1.7%
2.7 KB · 27 lines tsx
Raw Blame History
1import type { Metadata } from "next";2import Link from "next/link";3import { apiSafe, type Forecast, type LiveState, type Meta } from "@/lib/api";4import { LiveHome } from "@/components/live";5import { Card, Empty } from "@/components/ui";6import { dateFr } from "@/lib/format";78export const metadata: Metadata = { title: "Soirée électorale — résultats en direct", description: "Le 5 octobre 2026 : résultats officiels en direct, forecast vs live, nowcast, probabilité de majorité, carte et ticker." };9export const revalidate = 0;1011export default async function Page() {12  const [meta, f, st] = await Promise.all([apiSafe<Meta>("/api/meta", { revalidate: 0 }), apiSafe<Forecast>("/api/forecast/latest"), apiSafe<LiveState>("/api/live/state", { revalidate: 0 })]);13  if (!meta || !f) return <Empty title="Indisponible" />;14  if (meta.mode === "forecast" && !st?.simulation) {15    return (16      <div className="space-y-8 max-w-3xl">17        <div><div className="eyebrow eyebrow-accent">QC26 Live · prêt</div><h1 className="display text-[40px] md:text-[56px] mt-3">Soirée électorale du {dateFr(meta.electionDate)}</h1><p className="text-ink-2 mt-3 text-[15px] leading-relaxed">À la fermeture des bureaux (20 h), QC26 bascule automatiquement en mode DIRECT : résultats officiels d&apos;Élections Québec toutes les 2 à 5 minutes, carte qui se colore bureau par bureau, ticker, nowcast et probabilité de majorité en temps réel, comparaison prévision–réalité. Même produit, même adresse.</p></div>18        <div className="grid sm:grid-cols-2 gap-3">19          {[["Flux officiel", "donnees.electionsquebec.qc.ca — JSON officiel, validé, archivé à chaque changement, mis en quarantaine en cas d'anomalie."], ["Forecast vs Live", "La dernière projection publiée avant 20 h est figée et comparée aux résultats, siège par siège."], ["Nowcast", "Prior QC26 + résultats partiels → probabilité de majorité mise à jour à chaque snapshot."], ["Replay", "Chaque snapshot est conservé : la soirée pourra être rejouée seconde par seconde."]].map(([t, d]) => <Card key={t}><div className="font-semibold">{t}</div><div className="text-[13.5px] text-ink-2 mt-1">{d}</div></Card>)}20        </div>21        <div className="text-[13px] text-ink-3">Dans {meta.daysToElection} jours. En attendant : <Link href="/prevision" className="link">la prévision</Link>, <Link href="/circonscriptions?tri=serre" className="link">les circonscriptions à surveiller</Link>, <Link href="/live/model-vs-reality" className="link">la page Modèle vs réalité</Link> (active le soir du vote).</div>22      </div>23    );24  }25  return <LiveHome meta={{ ...meta, mode: st?.simulation ? "live" : meta.mode }} forecast={f} initial={st} />;26}27