import type { Metadata } from "next"; import { apiSafe, type Forecast, type Poll } from "@/lib/api"; import { Legend } from "@/components/charts"; import { TrendChartInteractive } from "@/components/trend-chart"; import { Card, Empty, PageTitle, SectionHeader } from "@/components/ui"; import { PollsTable } from "@/components/polls-table"; import { PARTY_IDS, partyVar, partyLabel } from "@/lib/parties"; import { dateShort } from "@/lib/format"; export const metadata: Metadata = { title: "Sondages Québec 2026 — Agrégateur et tendances", description: "Tous les sondages provinciaux depuis l'élection de 2022, avec documents originaux archivés, poids dans le modèle QC26, effets maison et sous-échantillons." }; export const revalidate = 60; interface Pollster { id: string; name: string; website: string | null; polls: number; lastPoll: string | null; houseEffects: Record | null; nUsed: number | null } export default async function Page() { const [data, f, ps] = await Promise.all([apiSafe<{ polls: Poll[]; trend: Forecast["trend"] }>("/api/polls?limit=600"), apiSafe("/api/forecast/latest"), apiSafe<{ pollsters: Pollster[] }>("/api/pollsters")]); if (!data) return ; const polls = data.polls; const pollPts = polls.filter((p) => !p.excluded).map((p) => ({ date: p.fieldworkEnd, values: p.results, pollster: p.pollster.name })); const primary = polls.filter((p) => p.sourceTier === "primary").length; return (
{f?.trend && }
Points = sondages bruts · ligne = moyenne QC26 corrigée des effets maison · bande 80 %
{ps && (
{ps.pollsters.sort((a, b) => b.polls - a.polls).map((p) => (
{p.name}{p.polls} sondages · dernier {dateShort(p.lastPoll)}
{PARTY_IDS.map((id) =>
{partyLabel(id)}
{p.houseEffects?.[id] !== undefined ? (p.houseEffects[id] > 0 ? "+" : "") + p.houseEffects[id].toFixed(1).replace(".", ",") : "—"}
)}
))}

— : moins de 2 sondages dans la fenêtre de 400 jours, aucun effet maison estimé.

{PARTY_IDS.map((id) => )}{ps.pollsters.sort((a, b) => b.polls - a.polls).map((p) => ( {PARTY_IDS.map((id) => )} ))}
FirmeSondagesDernier{partyLabel(id)}
{p.website ? {p.name} : p.name}{p.polls}{dateShort(p.lastPoll)}{p.houseEffects?.[id] !== undefined ? (p.houseEffects[id] > 0 ? "+" : "") + p.houseEffects[id].toFixed(1).replace(".", ",") : —}

— : moins de 2 sondages dans la fenêtre de 400 jours, aucun effet maison estimé (le sondage entre sans correction).

)}
); }