- {section.items.length > 0 ? (
- section.items.map((item, itemIndex) => {
+
+ {section.items.map((item, itemIndex) => {
const status = item.isLive ? "live" : "soon";
const relative = item.isLive
? formatTimeLeft(item.endsAt.getTime() - nowMs)
@@ -102,41 +105,37 @@ const startTimeFmt = new Intl.DateTimeFormat("en-US", {
>
- {item.isLive ? (
- <>
-
- {section.label}
- >
- ) : (
- <>
-
- {section.label}
- >
- )}
+
+
+ {section.label}
);
- })
- ) : (
- {section.empty}
- )}
+ })}
+ 0}>
+ {section.empty}
+
))}
@@ -457,6 +456,96 @@ const startTimeFmt = new Intl.DateTimeFormat("en-US", {
});
}
+ function getLocalDateKey(date: Date): string {
+ return new Intl.DateTimeFormat("en-CA", {
+ year: "numeric",
+ month: "2-digit",
+ day: "2-digit",
+ }).format(date);
+ }
+
+ function setStatus(card: HTMLElement, mode: "live" | "soon", label: string) {
+ card.classList.toggle("now-card--live", mode === "live");
+ card.classList.toggle("now-card--soon", mode === "soon");
+
+ const liveIcon = card.querySelector
("[data-status-live-icon]");
+ const soonIcon = card.querySelector("[data-status-soon-icon]");
+ const labelEl = card.querySelector("[data-status-label]");
+ const rel = card.querySelector("[data-relative]");
+
+ liveIcon?.toggleAttribute("hidden", mode !== "live");
+ soonIcon?.toggleAttribute("hidden", mode === "live");
+ if (labelEl) labelEl.textContent = label;
+ if (rel) rel.dataset.relativeMode = mode;
+ }
+
+ function regroupNowStrip() {
+ const now = Date.now();
+ const todayKey = getLocalDateKey(new Date(now));
+ const weekEndsAt = now + 7 * 24 * 60 * 60 * 1000;
+ const sections = new Map(
+ Array.from(document.querySelectorAll("[data-now-section]")).map(
+ (section) => [section.dataset.nowSection, section],
+ ),
+ );
+ const buckets = {
+ now: [] as HTMLElement[],
+ today: [] as HTMLElement[],
+ week: [] as HTMLElement[],
+ };
+
+ document.querySelectorAll(".now-card").forEach((card) => {
+ const startsAt = card.dataset.eventStartsAt;
+ const endsAt = card.dataset.eventEndsAt;
+ if (!startsAt || !endsAt) return;
+
+ const start = new Date(startsAt).getTime();
+ const end = new Date(endsAt).getTime();
+ if (end <= now) return;
+
+ if (start <= now) {
+ buckets.now.push(card);
+ setStatus(card, "live", "Live");
+ } else if (getLocalDateKey(new Date(start)) === todayKey) {
+ buckets.today.push(card);
+ setStatus(card, "soon", "Today");
+ } else if (start < weekEndsAt) {
+ buckets.week.push(card);
+ setStatus(card, "soon", "This week");
+ }
+ });
+
+ buckets.now.sort(
+ (a, b) =>
+ new Date(a.dataset.eventEndsAt ?? 0).getTime() -
+ new Date(b.dataset.eventEndsAt ?? 0).getTime(),
+ );
+ buckets.today.sort(
+ (a, b) =>
+ new Date(a.dataset.eventStartsAt ?? 0).getTime() -
+ new Date(b.dataset.eventStartsAt ?? 0).getTime(),
+ );
+ buckets.week.sort(
+ (a, b) =>
+ new Date(a.dataset.eventStartsAt ?? 0).getTime() -
+ new Date(b.dataset.eventStartsAt ?? 0).getTime(),
+ );
+
+ for (const [id, section] of sections) {
+ if (!id) continue;
+ const cards = section.querySelector("[data-now-cards]");
+ const empty = section.querySelector("[data-now-empty]");
+ const items = buckets[id as keyof typeof buckets] ?? [];
+ if (!cards || !empty) continue;
+
+ items.forEach((card) => cards.insertBefore(card, empty));
+ empty.toggleAttribute("hidden", items.length > 0);
+ }
+ }
+
localizeTimes();
+ regroupNowStrip();
+ tickNowStrip();
setInterval(tickNowStrip, 30000);
+ setInterval(regroupNowStrip, 30000);