▍ humdrum codex / soft

Paper: bucket scores into Final + Today sections

845a465f1f3261694620f200524dc94e262d5eb5
humdrum <me@humdrum.me> · 2026-07-08 16:08

parent 2d5ec4c8

Paper: bucket scores into Final + Today sections

Replace the sports case block to split games into Final (completed)
and Today (in-progress + same-day starts) sections, removing the
Upcoming section since the paper only shows yesterday..today games.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

1 files changed

app/print/page.tsx +39 −13
@@ -286,21 +286,47 @@     }
     case "sports": {
       const p = payload as SportsPayload;
       if (p.games.length === 0) return null;
-      const groups: Record<string, SportsPayload["games"]> = {};
-      for (const g of p.games) (groups[g.league] ||= []).push(g);
+      type G = SportsPayload["games"][number];
+      const sameDay = (iso: string | null) =>
+        iso ? new Date(iso).toDateString() === new Date().toDateString() : true;
+      const bucketOf = (g: G): "final" | "today" | "upcoming" => {
+        if (g.state === "post") return "final";
+        if (g.state === "in") return "today";
+        return sameDay(g.startTime) ? "today" : "upcoming";
+      };
+      const line = (g: G) =>
+        g.state === "pre"
+          ? `${g.away} @ ${g.home}`
+          : `${g.away} ${g.awayScore ?? ""} @ ${g.home} ${g.homeScore ?? ""}`.replace(/\s+/g, " ").trim();
+      // Paper = last results + today's slate only; no future games.
+      const sections = ([
+        { key: "final", label: "Final" },
+        { key: "today", label: "Today" },
+      ] as const)
+        .map((s) => ({ ...s, games: p.games.filter((g) => bucketOf(g) === s.key) }))
+        .filter((s) => s.games.length > 0);
+      if (sections.length === 0) return null;
       return (
         <>
-          {Object.entries(groups).map(([league, games]) => (
-            <div key={league}>
-              <h3>{leagueName(league)}</h3>
-              {games.map((g, i) => (
-                <p className="paper-item" key={i}>
-                  {g.away} {g.awayScore ?? ""} @ {g.home} {g.homeScore ?? ""}{" "}
-                  <span className="src">— {g.status}</span>
-                </p>
-              ))}
-            </div>
-          ))}
+          {sections.map((s) => {
+            const groups: Record<string, G[]> = {};
+            for (const g of s.games) (groups[g.league] ||= []).push(g);
+            return (
+              <div key={s.key}>
+                <h3>{s.label}</h3>
+                {Object.entries(groups).map(([league, games]) => (
+                  <div key={league}>
+                    <p className="paper-item"><strong>{leagueName(league)}</strong></p>
+                    {games.map((g, i) => (
+                      <p className="paper-item" key={i}>
+                        {line(g)} <span className="src">— {g.status}</span>
+                      </p>
+                    ))}
+                  </div>
+                ))}
+              </div>
+            );
+          })}
         </>
       );
     }