@sensiblestats/widget-react 0.21.0 → 0.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +24 -0
- package/dist/index.cjs +373 -296
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +374 -297
- package/dist/index.js.map +1 -1
- package/dist/styles.css +111 -55
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -55,12 +55,6 @@ var STRINGS = {
|
|
|
55
55
|
const drift = direction ? `, ${direction}` : "";
|
|
56
56
|
return `Price movement over the last ${span}: opened at ${opening}, currently ${current}${drift}.`;
|
|
57
57
|
},
|
|
58
|
-
clubMatchPreviewHeading: "Match preview",
|
|
59
|
-
clubTeamDnaHeading: "How they play",
|
|
60
|
-
clubFormHeading: "Recent form",
|
|
61
|
-
clubCountdownLabel: "Countdown to kick-off",
|
|
62
|
-
clubKickoff: (ms) => new Intl.DateTimeFormat("en-GB", { weekday: "short", day: "numeric", month: "short", hour: "2-digit", minute: "2-digit" }).format(new Date(ms)),
|
|
63
|
-
clubKickoffAria: (ms) => `Kick-off ${new Intl.DateTimeFormat("en-GB", { weekday: "long", day: "numeric", month: "long", hour: "2-digit", minute: "2-digit" }).format(new Date(ms))}`,
|
|
64
58
|
inSlip: "In slip",
|
|
65
59
|
slipAdded: (n) => n === void 0 ? "Added to slip" : `Added to slip (${n} selection${n === 1 ? "" : "s"})`,
|
|
66
60
|
slipDuplicate: "Already in your slip",
|
|
@@ -112,12 +106,6 @@ var STRINGS = {
|
|
|
112
106
|
const drift = direction ? `, ${direction}` : "";
|
|
113
107
|
return `Son ${span} i\xE7indeki oran hareketi: ${opening} ile a\xE7\u0131ld\u0131, \u015Fu anda ${current}${drift}.`;
|
|
114
108
|
},
|
|
115
|
-
clubMatchPreviewHeading: "Ma\xE7 \xF6nizlemesi",
|
|
116
|
-
clubTeamDnaHeading: "Nas\u0131l oynuyorlar",
|
|
117
|
-
clubFormHeading: "Son form",
|
|
118
|
-
clubCountdownLabel: "Ba\u015Flama vuru\u015Funa kalan",
|
|
119
|
-
clubKickoff: (ms) => new Intl.DateTimeFormat("tr-TR", { weekday: "short", day: "numeric", month: "short", hour: "2-digit", minute: "2-digit" }).format(new Date(ms)),
|
|
120
|
-
clubKickoffAria: (ms) => `Ba\u015Flama vuru\u015Fu ${new Intl.DateTimeFormat("tr-TR", { weekday: "long", day: "numeric", month: "long", hour: "2-digit", minute: "2-digit" }).format(new Date(ms))}`,
|
|
121
109
|
inSlip: "Kuponda",
|
|
122
110
|
slipAdded: (n) => n === void 0 ? "Kupona eklendi" : `Kupona eklendi (${n} se\xE7im)`,
|
|
123
111
|
slipDuplicate: "Bu se\xE7im kuponunuzda zaten var",
|
|
@@ -181,12 +169,6 @@ function normalizeUi(cfg) {
|
|
|
181
169
|
excludedSuspended: strings.excludedSuspended,
|
|
182
170
|
chartTimeLabel: strings.chartTimeLabel,
|
|
183
171
|
chartAria: strings.chartAria,
|
|
184
|
-
clubMatchPreviewHeading: strings.clubMatchPreviewHeading,
|
|
185
|
-
clubTeamDnaHeading: strings.clubTeamDnaHeading,
|
|
186
|
-
clubFormHeading: strings.clubFormHeading,
|
|
187
|
-
clubCountdownLabel: strings.clubCountdownLabel,
|
|
188
|
-
clubKickoff: strings.clubKickoff,
|
|
189
|
-
clubKickoffAria: strings.clubKickoffAria,
|
|
190
172
|
addToSlip: strings.addToSlip,
|
|
191
173
|
inSlip: strings.inSlip,
|
|
192
174
|
slipAdded: strings.slipAdded,
|
|
@@ -537,8 +519,8 @@ function applyEvent(state, event) {
|
|
|
537
519
|
return { ...state, actionsLoading: true, status: event.data.message };
|
|
538
520
|
case "turn_complete": {
|
|
539
521
|
const active = activeTurn(state);
|
|
540
|
-
const
|
|
541
|
-
const popupText = active?.isGreeting && !state.isOpen &&
|
|
522
|
+
const greetingLine = event.data.clubFanDashboard?.greeting?.trim() || (active?.text.trim() ?? "");
|
|
523
|
+
const popupText = active?.isGreeting && !state.isOpen && greetingLine ? greetingLine.slice(0, POPUP_MAX) : state.popupText;
|
|
542
524
|
return {
|
|
543
525
|
...state,
|
|
544
526
|
isStreaming: false,
|
|
@@ -550,7 +532,7 @@ function applyEvent(state, event) {
|
|
|
550
532
|
...t,
|
|
551
533
|
done: true,
|
|
552
534
|
greetingDashboard: event.data.dashboard ?? void 0,
|
|
553
|
-
|
|
535
|
+
clubFanDashboard: event.data.clubFanDashboard ?? void 0
|
|
554
536
|
}))
|
|
555
537
|
};
|
|
556
538
|
}
|
|
@@ -747,7 +729,7 @@ function ChatFab({ label, greeting, popupText, onOpen, onDismissPopup, dismissLa
|
|
|
747
729
|
}
|
|
748
730
|
|
|
749
731
|
// src/components/ChatPanel.tsx
|
|
750
|
-
import { useEffect as useEffect5, useState as
|
|
732
|
+
import { useEffect as useEffect5, useState as useState8 } from "react";
|
|
751
733
|
|
|
752
734
|
// src/components/ChatHeader.tsx
|
|
753
735
|
import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
@@ -1306,246 +1288,286 @@ function GreetingDashboard({ dashboard, onTap }) {
|
|
|
1306
1288
|
] });
|
|
1307
1289
|
}
|
|
1308
1290
|
|
|
1309
|
-
// src/components/
|
|
1310
|
-
import { jsx as jsx17, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
1311
|
-
function
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1291
|
+
// src/components/dashboard/FixtureCard.tsx
|
|
1292
|
+
import { Fragment as Fragment5, jsx as jsx17, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
1293
|
+
function resultClass(result) {
|
|
1294
|
+
const upper = result.toUpperCase();
|
|
1295
|
+
if (upper === "W") return "ss-w-fandash-form-pill--win";
|
|
1296
|
+
if (upper === "L") return "ss-w-fandash-form-pill--loss";
|
|
1297
|
+
return "ss-w-fandash-form-pill--draw";
|
|
1316
1298
|
}
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
import { useState as useState6 } from "react";
|
|
1320
|
-
import { jsx as jsx18, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
1321
|
-
function initials3(name) {
|
|
1322
|
-
return name.split(/\s+/).filter(Boolean).slice(0, 2).map((w) => w[0].toUpperCase()).join("");
|
|
1299
|
+
function FormStrip({ form }) {
|
|
1300
|
+
return /* @__PURE__ */ jsx17("span", { className: "ss-w-fandash-form", children: form.map((r, i) => /* @__PURE__ */ jsx17("span", { className: `ss-w-fandash-form-pill ${resultClass(r)}`, children: r }, `${r}-${i}`)) });
|
|
1323
1301
|
}
|
|
1324
|
-
function
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
}
|
|
1329
|
-
return /* @__PURE__ */ jsx18("img", { className: "ss-w-cdash-crest", src: url, alt: "", "aria-hidden": "true", onError: () => setBroken(true) });
|
|
1302
|
+
function FormRow({ name, form }) {
|
|
1303
|
+
return /* @__PURE__ */ jsxs13("div", { className: "ss-w-fandash-formrow", children: [
|
|
1304
|
+
/* @__PURE__ */ jsx17("span", { className: "ss-w-fandash-formrow-name", children: name }),
|
|
1305
|
+
/* @__PURE__ */ jsx17(FormStrip, { form })
|
|
1306
|
+
] });
|
|
1330
1307
|
}
|
|
1331
|
-
function
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
/* @__PURE__ */
|
|
1342
|
-
|
|
1308
|
+
function FixtureCard({ card, onTap }) {
|
|
1309
|
+
const { data } = card;
|
|
1310
|
+
const h2h = data.h2H;
|
|
1311
|
+
return /* @__PURE__ */ jsxs13(Fragment5, { children: [
|
|
1312
|
+
/* @__PURE__ */ jsxs13("button", { type: "button", className: "ss-w-fandash-card ss-w-fandash-card--tap ss-w-fandash-fixture", onClick: () => onTap(card), children: [
|
|
1313
|
+
/* @__PURE__ */ jsxs13("span", { className: "ss-w-fandash-eyebrow", children: [
|
|
1314
|
+
card.title,
|
|
1315
|
+
" \xB7 ",
|
|
1316
|
+
data.competition
|
|
1317
|
+
] }),
|
|
1318
|
+
/* @__PURE__ */ jsxs13("div", { className: "ss-w-fandash-fixture-teams", children: [
|
|
1319
|
+
/* @__PURE__ */ jsxs13("span", { className: "ss-w-fandash-fixture-team", children: [
|
|
1320
|
+
/* @__PURE__ */ jsx17(Crest2, { url: data.homeCrestUrl ?? void 0, name: data.homeName, kind: "team" }),
|
|
1321
|
+
/* @__PURE__ */ jsx17("span", { className: "ss-w-fandash-fixture-name", children: data.homeName })
|
|
1322
|
+
] }),
|
|
1323
|
+
/* @__PURE__ */ jsx17("span", { className: "ss-w-fandash-fixture-vs", children: "v" }),
|
|
1324
|
+
/* @__PURE__ */ jsxs13("span", { className: "ss-w-fandash-fixture-team ss-w-fandash-fixture-team--away", children: [
|
|
1325
|
+
/* @__PURE__ */ jsx17("span", { className: "ss-w-fandash-fixture-name", children: data.awayName }),
|
|
1326
|
+
/* @__PURE__ */ jsx17(Crest2, { url: data.awayCrestUrl ?? void 0, name: data.awayName, kind: "team" })
|
|
1327
|
+
] })
|
|
1328
|
+
] }),
|
|
1329
|
+
/* @__PURE__ */ jsxs13("div", { className: "ss-w-fandash-fixture-meta", children: [
|
|
1330
|
+
/* @__PURE__ */ jsxs13("div", { className: "ss-w-fandash-fixture-metarow", children: [
|
|
1331
|
+
/* @__PURE__ */ jsx17("span", { className: "ss-w-fandash-fixture-metakey", children: data.dateLabel }),
|
|
1332
|
+
/* @__PURE__ */ jsx17("span", { className: "ss-w-fandash-fixture-metaval", children: data.kickoffLabel })
|
|
1333
|
+
] }),
|
|
1334
|
+
data.venue ? /* @__PURE__ */ jsxs13("div", { className: "ss-w-fandash-fixture-metarow", children: [
|
|
1335
|
+
/* @__PURE__ */ jsx17("span", { className: "ss-w-fandash-fixture-metakey", children: data.venueLabel }),
|
|
1336
|
+
/* @__PURE__ */ jsx17("span", { className: "ss-w-fandash-fixture-metaval", children: data.venue })
|
|
1337
|
+
] }) : null
|
|
1338
|
+
] }),
|
|
1339
|
+
/* @__PURE__ */ jsx17("span", { className: "ss-w-fandash-card-cta", children: card.actionLabel })
|
|
1343
1340
|
] }),
|
|
1344
|
-
/* @__PURE__ */
|
|
1345
|
-
/* @__PURE__ */
|
|
1346
|
-
|
|
1347
|
-
|
|
1341
|
+
/* @__PURE__ */ jsxs13("div", { className: "ss-w-fandash-card ss-w-fandash-lastfive", children: [
|
|
1342
|
+
/* @__PURE__ */ jsx17("span", { className: "ss-w-fandash-eyebrow", children: data.formLabel }),
|
|
1343
|
+
/* @__PURE__ */ jsxs13("div", { className: "ss-w-fandash-fixture-form", children: [
|
|
1344
|
+
/* @__PURE__ */ jsx17(FormRow, { name: data.homeName, form: data.homeForm }),
|
|
1345
|
+
/* @__PURE__ */ jsx17(FormRow, { name: data.awayName, form: data.awayForm })
|
|
1346
|
+
] })
|
|
1348
1347
|
] }),
|
|
1349
|
-
/* @__PURE__ */
|
|
1348
|
+
h2h || data.fact ? /* @__PURE__ */ jsxs13("div", { className: "ss-w-fandash-card ss-w-fandash-h2h", children: [
|
|
1349
|
+
h2h ? /* @__PURE__ */ jsxs13(Fragment5, { children: [
|
|
1350
|
+
/* @__PURE__ */ jsx17("span", { className: "ss-w-fandash-eyebrow", children: h2h.label }),
|
|
1351
|
+
/* @__PURE__ */ jsxs13("div", { className: "ss-w-fandash-split", children: [
|
|
1352
|
+
/* @__PURE__ */ jsxs13("span", { className: "ss-w-fandash-split-cell", children: [
|
|
1353
|
+
/* @__PURE__ */ jsx17("span", { className: "ss-w-fandash-split-value", children: h2h.wins }),
|
|
1354
|
+
/* @__PURE__ */ jsx17("span", { className: "ss-w-fandash-split-label", children: h2h.homeWinsLabel })
|
|
1355
|
+
] }),
|
|
1356
|
+
/* @__PURE__ */ jsxs13("span", { className: "ss-w-fandash-split-cell", children: [
|
|
1357
|
+
/* @__PURE__ */ jsx17("span", { className: "ss-w-fandash-split-value", children: h2h.draws }),
|
|
1358
|
+
/* @__PURE__ */ jsx17("span", { className: "ss-w-fandash-split-label", children: h2h.drawsLabel })
|
|
1359
|
+
] }),
|
|
1360
|
+
/* @__PURE__ */ jsxs13("span", { className: "ss-w-fandash-split-cell", children: [
|
|
1361
|
+
/* @__PURE__ */ jsx17("span", { className: "ss-w-fandash-split-value", children: h2h.losses }),
|
|
1362
|
+
/* @__PURE__ */ jsx17("span", { className: "ss-w-fandash-split-label", children: h2h.awayWinsLabel })
|
|
1363
|
+
] })
|
|
1364
|
+
] })
|
|
1365
|
+
] }) : null,
|
|
1366
|
+
data.fact ? /* @__PURE__ */ jsx17("span", { className: "ss-w-fandash-fact", children: data.fact }) : null
|
|
1367
|
+
] }) : null
|
|
1350
1368
|
] });
|
|
1351
1369
|
}
|
|
1352
1370
|
|
|
1353
|
-
// src/components/
|
|
1354
|
-
import { Fragment as
|
|
1355
|
-
|
|
1356
|
-
|
|
1371
|
+
// src/components/dashboard/CountdownCard.tsx
|
|
1372
|
+
import { Fragment as Fragment6, useEffect as useEffect3, useState as useState6 } from "react";
|
|
1373
|
+
import { jsx as jsx18, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
1374
|
+
var DAY_MS = 864e5;
|
|
1375
|
+
function remainingSegments(kickoffUnix, nowMs, withSeconds) {
|
|
1376
|
+
const totalSeconds = Math.floor((kickoffUnix * 1e3 - nowMs) / 1e3);
|
|
1377
|
+
if (totalSeconds <= 0) return null;
|
|
1378
|
+
const days = Math.floor(totalSeconds / 86400);
|
|
1379
|
+
const hours = Math.floor(totalSeconds % 86400 / 3600);
|
|
1380
|
+
const minutes = Math.floor(totalSeconds % 3600 / 60);
|
|
1381
|
+
const seconds = totalSeconds % 60;
|
|
1382
|
+
const pad = (n) => String(n).padStart(2, "0");
|
|
1383
|
+
if (days > 0) return [{ value: pad(days), unit: "d" }, { value: pad(hours), unit: "h" }];
|
|
1384
|
+
const segs = [{ value: pad(hours), unit: "h" }, { value: pad(minutes), unit: "m" }];
|
|
1385
|
+
if (withSeconds) segs.push({ value: pad(seconds), unit: "s" });
|
|
1386
|
+
return segs;
|
|
1387
|
+
}
|
|
1388
|
+
function CountdownCard({ card }) {
|
|
1389
|
+
const { data } = card;
|
|
1390
|
+
const unitLabel = { d: data.daysUnit, h: data.hoursUnit, m: data.minutesUnit, s: data.secondsUnit };
|
|
1391
|
+
const [nowMs, setNowMs] = useState6(() => Date.now());
|
|
1392
|
+
const [reduced] = useState6(
|
|
1393
|
+
() => typeof window !== "undefined" && window.matchMedia("(prefers-reduced-motion: reduce)").matches
|
|
1394
|
+
);
|
|
1395
|
+
const withinDay = data.kickoffUnix * 1e3 - nowMs < DAY_MS;
|
|
1396
|
+
useEffect3(() => {
|
|
1397
|
+
if (reduced) return;
|
|
1398
|
+
const id = window.setInterval(() => setNowMs(Date.now()), withinDay ? 1e3 : 6e4);
|
|
1399
|
+
return () => window.clearInterval(id);
|
|
1400
|
+
}, [reduced, withinDay]);
|
|
1401
|
+
const segments = remainingSegments(data.kickoffUnix, nowMs, withinDay && !reduced);
|
|
1402
|
+
return /* @__PURE__ */ jsx18("div", { className: "ss-w-fandash-card ss-w-fandash-countdown", children: /* @__PURE__ */ jsxs14("div", { className: "ss-w-fandash-countdown-top", children: [
|
|
1403
|
+
/* @__PURE__ */ jsx18("span", { className: "ss-w-fandash-eyebrow", children: card.title ?? "Kick-off in" }),
|
|
1404
|
+
segments ? /* @__PURE__ */ jsx18("span", { className: "ss-w-fandash-countdown-clock", children: segments.map((s, i) => /* @__PURE__ */ jsxs14(Fragment6, { children: [
|
|
1405
|
+
i > 0 ? /* @__PURE__ */ jsx18("span", { className: "ss-w-fandash-countdown-colon", children: ":" }) : null,
|
|
1406
|
+
/* @__PURE__ */ jsxs14("span", { className: "ss-w-fandash-countdown-seg", children: [
|
|
1407
|
+
/* @__PURE__ */ jsx18("span", { className: "ss-w-fandash-countdown-value", children: s.value }),
|
|
1408
|
+
/* @__PURE__ */ jsx18("span", { className: "ss-w-fandash-countdown-unit", children: unitLabel[s.unit] })
|
|
1409
|
+
] })
|
|
1410
|
+
] }, s.unit)) }) : null
|
|
1411
|
+
] }) });
|
|
1357
1412
|
}
|
|
1358
1413
|
|
|
1359
|
-
// src/components/
|
|
1360
|
-
import { jsx as
|
|
1361
|
-
function
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
/* @__PURE__ */
|
|
1365
|
-
|
|
1366
|
-
row.position != null ? ` #${row.position}` : ""
|
|
1367
|
-
] }),
|
|
1368
|
-
/* @__PURE__ */ jsx20("span", { className: "ss-w-cdash-form-pills", children: /* @__PURE__ */ jsx20(ResultPills, { results: row.last5 }) })
|
|
1369
|
-
] }, row.name)) });
|
|
1414
|
+
// src/components/dashboard/InjuriesCard.tsx
|
|
1415
|
+
import { jsx as jsx19, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
1416
|
+
function ColHead({ name, crestUrl }) {
|
|
1417
|
+
return /* @__PURE__ */ jsxs15("span", { className: "ss-w-fandash-injuries-col-head", children: [
|
|
1418
|
+
/* @__PURE__ */ jsx19(Crest2, { url: crestUrl ?? void 0, name, kind: "team" }),
|
|
1419
|
+
/* @__PURE__ */ jsx19("span", { className: "ss-w-fandash-injuries-col-head-name", children: name })
|
|
1420
|
+
] });
|
|
1370
1421
|
}
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
})
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
},
|
|
1398
|
-
i
|
|
1399
|
-
) : /* @__PURE__ */ jsx21("p", { children: f.sentence }, i)
|
|
1400
|
-
)
|
|
1422
|
+
function InjuryList({ rows, emptyLabel }) {
|
|
1423
|
+
if (rows.length === 0) return /* @__PURE__ */ jsx19("span", { className: "ss-w-fandash-injuries-empty", children: emptyLabel });
|
|
1424
|
+
return /* @__PURE__ */ jsx19("ul", { className: "ss-w-fandash-injury-list", children: rows.map((r, i) => /* @__PURE__ */ jsxs15("li", { className: "ss-w-fandash-injury-row", children: [
|
|
1425
|
+
/* @__PURE__ */ jsx19("span", { className: "ss-w-fandash-injury-name", children: r.playerName }),
|
|
1426
|
+
/* @__PURE__ */ jsxs15("span", { className: "ss-w-fandash-injury-meta", children: [
|
|
1427
|
+
/* @__PURE__ */ jsx19("span", { className: "ss-w-fandash-injury-status", children: r.status }),
|
|
1428
|
+
r.injuryType ? /* @__PURE__ */ jsx19("span", { className: "ss-w-fandash-injury-type", children: r.injuryType }) : null,
|
|
1429
|
+
r.expectedReturnLabel ? /* @__PURE__ */ jsx19("span", { className: "ss-w-fandash-injury-return", children: r.expectedReturnLabel }) : null
|
|
1430
|
+
] })
|
|
1431
|
+
] }, `${r.playerName}-${i}`)) });
|
|
1432
|
+
}
|
|
1433
|
+
function InjuriesCard({ card }) {
|
|
1434
|
+
const { data } = card;
|
|
1435
|
+
return /* @__PURE__ */ jsxs15("div", { className: "ss-w-fandash-card ss-w-fandash-injuries", children: [
|
|
1436
|
+
card.title ? /* @__PURE__ */ jsx19("span", { className: "ss-w-fandash-eyebrow", children: card.title }) : null,
|
|
1437
|
+
/* @__PURE__ */ jsxs15("div", { className: "ss-w-fandash-injuries-cols", children: [
|
|
1438
|
+
/* @__PURE__ */ jsxs15("div", { className: "ss-w-fandash-injuries-col", children: [
|
|
1439
|
+
/* @__PURE__ */ jsx19(ColHead, { name: data.oursName, crestUrl: data.oursCrestUrl }),
|
|
1440
|
+
/* @__PURE__ */ jsx19(InjuryList, { rows: data.ours, emptyLabel: data.emptyLabel })
|
|
1441
|
+
] }),
|
|
1442
|
+
/* @__PURE__ */ jsx19("div", { className: "ss-w-fandash-injuries-divider" }),
|
|
1443
|
+
/* @__PURE__ */ jsxs15("div", { className: "ss-w-fandash-injuries-col", children: [
|
|
1444
|
+
/* @__PURE__ */ jsx19(ColHead, { name: data.theirsName, crestUrl: data.theirsCrestUrl }),
|
|
1445
|
+
/* @__PURE__ */ jsx19(InjuryList, { rows: data.theirs, emptyLabel: data.emptyLabel })
|
|
1446
|
+
] })
|
|
1447
|
+
] })
|
|
1401
1448
|
] });
|
|
1402
1449
|
}
|
|
1403
1450
|
|
|
1404
|
-
// src/components/
|
|
1405
|
-
import { jsx as
|
|
1406
|
-
function
|
|
1407
|
-
return
|
|
1408
|
-
}
|
|
1409
|
-
|
|
1410
|
-
return /* @__PURE__ */ jsxs17("div", { className: "ss-w-cdash-preview", children: [
|
|
1411
|
-
/* @__PURE__ */ jsxs17("div", { className: "ss-w-cdash-preview-header", children: [
|
|
1412
|
-
/* @__PURE__ */ jsx22("span", { className: "ss-w-cdash-team", children: block.homeName }),
|
|
1413
|
-
/* @__PURE__ */ jsx22("span", { className: "ss-w-cdash-vs", children: "v" }),
|
|
1414
|
-
/* @__PURE__ */ jsx22("span", { className: "ss-w-cdash-team", children: block.awayName })
|
|
1415
|
-
] }),
|
|
1416
|
-
/* @__PURE__ */ jsxs17("div", { className: "ss-w-cdash-preview-row", children: [
|
|
1417
|
-
/* @__PURE__ */ jsx22("span", { className: "ss-w-cdash-preview-value", children: position(block.homePosition) }),
|
|
1418
|
-
/* @__PURE__ */ jsx22("span", { className: "ss-w-cdash-preview-label", children: block.tableLabel }),
|
|
1419
|
-
/* @__PURE__ */ jsx22("span", { className: "ss-w-cdash-preview-value", children: position(block.awayPosition) })
|
|
1420
|
-
] }),
|
|
1421
|
-
/* @__PURE__ */ jsxs17("div", { className: "ss-w-cdash-preview-row", children: [
|
|
1422
|
-
/* @__PURE__ */ jsx22("span", { className: "ss-w-cdash-preview-pills", children: /* @__PURE__ */ jsx22(ResultPills, { results: block.homeLast5 }) }),
|
|
1423
|
-
/* @__PURE__ */ jsx22("span", { className: "ss-w-cdash-preview-label", children: block.last5Label }),
|
|
1424
|
-
/* @__PURE__ */ jsx22("span", { className: "ss-w-cdash-preview-pills", children: /* @__PURE__ */ jsx22(ResultPills, { results: block.awayLast5 }) })
|
|
1425
|
-
] }),
|
|
1426
|
-
block.edgeTeamName ? /* @__PURE__ */ jsxs17("div", { className: "ss-w-cdash-preview-edge", children: [
|
|
1427
|
-
/* @__PURE__ */ jsx22("span", { "aria-hidden": "true", children: "\u25B8" }),
|
|
1428
|
-
/* @__PURE__ */ jsx22("strong", { children: block.edgeTeamName }),
|
|
1429
|
-
block.edgeReason ? /* @__PURE__ */ jsxs17("span", { children: [
|
|
1430
|
-
" \u2014 ",
|
|
1431
|
-
block.edgeReason
|
|
1432
|
-
] }) : null
|
|
1433
|
-
] }) : null,
|
|
1434
|
-
block.h2HLines.length > 0 ? /* @__PURE__ */ jsx22("div", { className: "ss-w-cdash-preview-h2h", children: block.h2HLines.map((line, i) => /* @__PURE__ */ jsx22("p", { children: line }, i)) }) : null
|
|
1451
|
+
// src/components/dashboard/ReasonToBetCard.tsx
|
|
1452
|
+
import { jsx as jsx20, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
1453
|
+
function ReasonToBetCard({ card }) {
|
|
1454
|
+
return /* @__PURE__ */ jsxs16("div", { className: "ss-w-fandash-card ss-w-fandash-reasons", children: [
|
|
1455
|
+
card.title ? /* @__PURE__ */ jsx20("span", { className: "ss-w-fandash-eyebrow", children: card.title }) : null,
|
|
1456
|
+
/* @__PURE__ */ jsx20("ul", { className: "ss-w-fandash-reason-list", children: card.data.angles.map((angle, i) => /* @__PURE__ */ jsx20("li", { className: "ss-w-fandash-reason-item", children: angle }, `${angle}-${i}`)) })
|
|
1435
1457
|
] });
|
|
1436
1458
|
}
|
|
1437
1459
|
|
|
1438
|
-
// src/components/
|
|
1439
|
-
import { jsx as
|
|
1440
|
-
function
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
}) {
|
|
1445
|
-
if (block.facts.length === 0) return null;
|
|
1446
|
-
const heading = ui.clubTeamDnaHeading;
|
|
1447
|
-
return /* @__PURE__ */ jsxs18("div", { className: "ss-w-cdash-lines", children: [
|
|
1448
|
-
/* @__PURE__ */ jsx23("span", { className: "ss-w-cdash-lines-heading", children: heading }),
|
|
1449
|
-
block.facts.map(
|
|
1450
|
-
(f, i) => f.actionRef ? /* @__PURE__ */ jsxs18(
|
|
1451
|
-
"button",
|
|
1452
|
-
{
|
|
1453
|
-
type: "button",
|
|
1454
|
-
className: "ss-w-cdash-fact",
|
|
1455
|
-
onClick: () => onAction(f.label ?? f.sentence, { actionRef: f.actionRef }),
|
|
1456
|
-
children: [
|
|
1457
|
-
f.sentence,
|
|
1458
|
-
f.label ? /* @__PURE__ */ jsxs18("span", { className: "ss-w-cdash-fact-label", children: [
|
|
1459
|
-
" ",
|
|
1460
|
-
f.label
|
|
1461
|
-
] }) : null
|
|
1462
|
-
]
|
|
1463
|
-
},
|
|
1464
|
-
i
|
|
1465
|
-
) : /* @__PURE__ */ jsx23("p", { children: f.sentence }, i)
|
|
1466
|
-
)
|
|
1460
|
+
// src/components/dashboard/WhereToWatchCard.tsx
|
|
1461
|
+
import { jsx as jsx21, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
1462
|
+
function WhereToWatchCard({ card }) {
|
|
1463
|
+
return /* @__PURE__ */ jsxs17("div", { className: "ss-w-fandash-card ss-w-fandash-watch", children: [
|
|
1464
|
+
card.title ? /* @__PURE__ */ jsx21("span", { className: "ss-w-fandash-eyebrow", children: card.title }) : null,
|
|
1465
|
+
/* @__PURE__ */ jsx21("span", { className: "ss-w-fandash-stations", children: card.data.stations.map((station, i) => /* @__PURE__ */ jsx21("span", { className: "ss-w-fandash-station-chip", children: station }, `${station}-${i}`)) })
|
|
1467
1466
|
] });
|
|
1468
1467
|
}
|
|
1469
1468
|
|
|
1470
|
-
// src/components/
|
|
1471
|
-
import {
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1469
|
+
// src/components/dashboard/CongestedWeekCard.tsx
|
|
1470
|
+
import { jsx as jsx22, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
1471
|
+
function CongestedWeekCard({ card, onTap }) {
|
|
1472
|
+
return /* @__PURE__ */ jsxs18("button", { type: "button", className: "ss-w-fandash-card ss-w-fandash-card--tap ss-w-fandash-congested", onClick: () => onTap(card), children: [
|
|
1473
|
+
card.title ? /* @__PURE__ */ jsx22("span", { className: "ss-w-fandash-eyebrow", children: card.title }) : null,
|
|
1474
|
+
/* @__PURE__ */ jsx22("div", { className: "ss-w-fandash-congested-grid", children: card.data.entries.map((entry, i) => /* @__PURE__ */ jsxs18("span", { className: "ss-w-fandash-congested-cell", children: [
|
|
1475
|
+
/* @__PURE__ */ jsx22("span", { className: "ss-w-fandash-congested-day", children: entry.dayLabel }),
|
|
1476
|
+
/* @__PURE__ */ jsx22("span", { className: "ss-w-fandash-congested-opponent", children: entry.opponent }),
|
|
1477
|
+
/* @__PURE__ */ jsx22("span", { className: "ss-w-fandash-congested-comp", children: entry.competition }),
|
|
1478
|
+
/* @__PURE__ */ jsx22("span", { className: "ss-w-fandash-congested-time", children: entry.timeLabel })
|
|
1479
|
+
] }, `${entry.opponent}-${i}`)) }),
|
|
1480
|
+
/* @__PURE__ */ jsx22("span", { className: "ss-w-fandash-card-cta", children: card.actionLabel })
|
|
1481
|
+
] });
|
|
1476
1482
|
}
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
return {
|
|
1483
|
+
|
|
1484
|
+
// src/components/dashboard/TransfersCard.tsx
|
|
1485
|
+
import { jsx as jsx23, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
1486
|
+
function TransferList({ rows }) {
|
|
1487
|
+
if (rows.length === 0) return /* @__PURE__ */ jsx23("span", { className: "ss-w-fandash-transfers-empty", children: "None" });
|
|
1488
|
+
return /* @__PURE__ */ jsx23("ul", { className: "ss-w-fandash-transfer-list", children: rows.map((r, i) => /* @__PURE__ */ jsxs19("li", { className: "ss-w-fandash-transfer-row", children: [
|
|
1489
|
+
/* @__PURE__ */ jsx23("span", { className: "ss-w-fandash-transfer-name", children: r.playerName }),
|
|
1490
|
+
/* @__PURE__ */ jsx23("span", { className: "ss-w-fandash-transfer-club", children: r.otherClub }),
|
|
1491
|
+
r.type ? /* @__PURE__ */ jsx23("span", { className: "ss-w-fandash-transfer-type", children: r.type }) : null
|
|
1492
|
+
] }, `${r.playerName}-${i}`)) });
|
|
1493
|
+
}
|
|
1494
|
+
function TransfersCard({ card }) {
|
|
1495
|
+
const { data } = card;
|
|
1496
|
+
return /* @__PURE__ */ jsxs19("div", { className: "ss-w-fandash-card ss-w-fandash-transfers", children: [
|
|
1497
|
+
card.title ? /* @__PURE__ */ jsx23("span", { className: "ss-w-fandash-eyebrow", children: card.title }) : null,
|
|
1498
|
+
/* @__PURE__ */ jsxs19("div", { className: "ss-w-fandash-transfers-cols", children: [
|
|
1499
|
+
/* @__PURE__ */ jsxs19("div", { className: "ss-w-fandash-transfers-col", children: [
|
|
1500
|
+
/* @__PURE__ */ jsx23("span", { className: "ss-w-fandash-transfers-col-head", children: "In" }),
|
|
1501
|
+
/* @__PURE__ */ jsx23(TransferList, { rows: data.in })
|
|
1502
|
+
] }),
|
|
1503
|
+
/* @__PURE__ */ jsxs19("div", { className: "ss-w-fandash-transfers-col", children: [
|
|
1504
|
+
/* @__PURE__ */ jsx23("span", { className: "ss-w-fandash-transfers-col-head", children: "Out" }),
|
|
1505
|
+
/* @__PURE__ */ jsx23(TransferList, { rows: data.out })
|
|
1506
|
+
] })
|
|
1507
|
+
] })
|
|
1508
|
+
] });
|
|
1483
1509
|
}
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
if (remainingMs <= 0) return null;
|
|
1495
|
-
if (remainingMs > DAY_MS) return null;
|
|
1496
|
-
const { h, m, s } = splitRemaining(remainingMs);
|
|
1497
|
-
return /* @__PURE__ */ jsxs19("div", { className: "ss-w-cdash-cd", "aria-label": ui.clubKickoffAria(block.kickoffUnix * 1e3), children: [
|
|
1498
|
-
/* @__PURE__ */ jsxs19("div", { className: "ss-w-cdash-cd-clock", "aria-hidden": "true", children: [
|
|
1499
|
-
/* @__PURE__ */ jsx24("span", { className: "ss-w-cdash-cd-h", children: h }),
|
|
1500
|
-
"h",
|
|
1501
|
-
" ",
|
|
1502
|
-
/* @__PURE__ */ jsx24("span", { className: "ss-w-cdash-cd-m", children: m }),
|
|
1503
|
-
"m",
|
|
1504
|
-
" ",
|
|
1505
|
-
/* @__PURE__ */ jsx24("span", { className: "ss-w-cdash-cd-s", children: s }),
|
|
1506
|
-
"s"
|
|
1507
|
-
] }),
|
|
1508
|
-
/* @__PURE__ */ jsx24("div", { className: "ss-w-cdash-cd-label", children: ui.clubCountdownLabel })
|
|
1510
|
+
|
|
1511
|
+
// src/components/dashboard/LinksCard.tsx
|
|
1512
|
+
import { jsx as jsx24, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
1513
|
+
function LinksCard({ card }) {
|
|
1514
|
+
return /* @__PURE__ */ jsxs20("div", { className: "ss-w-fandash-card ss-w-fandash-links", children: [
|
|
1515
|
+
card.title ? /* @__PURE__ */ jsx24("span", { className: "ss-w-fandash-eyebrow", children: card.title }) : null,
|
|
1516
|
+
/* @__PURE__ */ jsx24("div", { className: "ss-w-fandash-link-grid", children: card.data.links.map((link, i) => /* @__PURE__ */ jsxs20("a", { className: "ss-w-fandash-link-tile", href: link.url, target: "_blank", rel: "noopener noreferrer", children: [
|
|
1517
|
+
/* @__PURE__ */ jsx24("span", { className: "ss-w-fandash-link-label", children: link.label }),
|
|
1518
|
+
/* @__PURE__ */ jsx24("span", { className: "ss-w-fandash-link-chevron", children: /* @__PURE__ */ jsx24(ChevronIcon, {}) })
|
|
1519
|
+
] }, `${link.url}-${i}`)) })
|
|
1509
1520
|
] });
|
|
1510
1521
|
}
|
|
1511
1522
|
|
|
1512
|
-
// src/components/
|
|
1513
|
-
import { jsx as jsx25 } from "react/jsx-runtime";
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
};
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
})
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1523
|
+
// src/components/dashboard/ClubFanDashboard.tsx
|
|
1524
|
+
import { jsx as jsx25, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
1525
|
+
function ClubFanDashboard({ dashboard, onTap, ui }) {
|
|
1526
|
+
const orderedCards = [
|
|
1527
|
+
...dashboard.cards.filter((c) => c.cardType === "countdown"),
|
|
1528
|
+
...dashboard.cards.filter((c) => c.cardType !== "countdown")
|
|
1529
|
+
];
|
|
1530
|
+
return /* @__PURE__ */ jsxs21("div", { className: "ss-w-fandash", children: [
|
|
1531
|
+
dashboard.greeting ? /* @__PURE__ */ jsx25("span", { className: "ss-w-fandash-greeting", children: dashboard.greeting }) : null,
|
|
1532
|
+
/* @__PURE__ */ jsx25("div", { className: "ss-w-fandash-cards", children: orderedCards.map((card, i) => /* @__PURE__ */ jsx25(FanDashboardCard, { card, onTap, ui }, `${card.cardType}-${i}`)) })
|
|
1533
|
+
] });
|
|
1534
|
+
}
|
|
1535
|
+
function FanDashboardCard({ card, onTap, ui }) {
|
|
1536
|
+
switch (card.cardType) {
|
|
1537
|
+
case "fixture":
|
|
1538
|
+
return /* @__PURE__ */ jsx25(FixtureCard, { card, onTap });
|
|
1539
|
+
case "countdown":
|
|
1540
|
+
return /* @__PURE__ */ jsx25(CountdownCard, { card });
|
|
1541
|
+
case "injuries":
|
|
1542
|
+
return /* @__PURE__ */ jsx25(InjuriesCard, { card });
|
|
1543
|
+
case "reasonToBet":
|
|
1544
|
+
return /* @__PURE__ */ jsx25(ReasonToBetCard, { card });
|
|
1545
|
+
case "whereToWatch":
|
|
1546
|
+
return /* @__PURE__ */ jsx25(WhereToWatchCard, { card });
|
|
1547
|
+
case "congestedWeek":
|
|
1548
|
+
return /* @__PURE__ */ jsx25(CongestedWeekCard, { card, onTap });
|
|
1549
|
+
case "transfers":
|
|
1550
|
+
return /* @__PURE__ */ jsx25(TransfersCard, { card });
|
|
1551
|
+
case "links":
|
|
1552
|
+
return /* @__PURE__ */ jsx25(LinksCard, { card });
|
|
1553
|
+
default:
|
|
1533
1554
|
return null;
|
|
1534
|
-
|
|
1535
|
-
return /* @__PURE__ */ jsx25("div", { className: "ss-w-cdash-block", children: /* @__PURE__ */ jsx25(Comp, { block, ui, onAction }) }, i);
|
|
1536
|
-
}) });
|
|
1555
|
+
}
|
|
1537
1556
|
}
|
|
1538
1557
|
|
|
1539
1558
|
// src/components/ChatMessage.tsx
|
|
1540
|
-
import { jsx as jsx26, jsxs as
|
|
1541
|
-
function ChatMessage({ message, disabled, onAct, onTap,
|
|
1559
|
+
import { jsx as jsx26, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
1560
|
+
function ChatMessage({ message, disabled, onAct, onTap, ui, slip }) {
|
|
1542
1561
|
if (message.role === "user") {
|
|
1543
1562
|
return /* @__PURE__ */ jsx26("div", { className: "ss-w-msg ss-w-user", children: /* @__PURE__ */ jsx26("div", { className: "ss-w-bubble", children: message.text }) });
|
|
1544
1563
|
}
|
|
1545
|
-
|
|
1546
|
-
message.
|
|
1547
|
-
|
|
1548
|
-
|
|
1564
|
+
const onFanDashboardTap = (card) => {
|
|
1565
|
+
onAct({ message: card.actionValue, label: card.actionLabel || card.title || "" });
|
|
1566
|
+
};
|
|
1567
|
+
return /* @__PURE__ */ jsxs22("div", { className: "ss-w-msg ss-w-bot", children: [
|
|
1568
|
+
message.text && !message.greetingDashboard && !message.clubFanDashboard ? /* @__PURE__ */ jsx26(Markdown, { text: message.text }) : null,
|
|
1569
|
+
message.greetingDashboard && !message.clubFanDashboard ? /* @__PURE__ */ jsx26(GreetingDashboard, { dashboard: message.greetingDashboard, onTap }) : null,
|
|
1570
|
+
message.clubFanDashboard ? /* @__PURE__ */ jsx26(ClubFanDashboard, { dashboard: message.clubFanDashboard, onTap: onFanDashboardTap, ui }) : null,
|
|
1549
1571
|
/* @__PURE__ */ jsx26(EntityCardList, { cards: message.cards, disabled, showLessLabel: ui?.showLess, showMoreLabel: ui?.showMore }),
|
|
1550
1572
|
/* @__PURE__ */ jsx26(BettingInsightList, { insights: message.insights, ui, slip }),
|
|
1551
1573
|
/* @__PURE__ */ jsx26(MarketOddsCardList, { cards: message.marketOdds, ui, slip }),
|
|
@@ -1568,7 +1590,7 @@ function isPinnedToBottom(el, threshold = PIN_THRESHOLD) {
|
|
|
1568
1590
|
}
|
|
1569
1591
|
|
|
1570
1592
|
// src/components/MessageList.tsx
|
|
1571
|
-
import { jsx as jsx28, jsxs as
|
|
1593
|
+
import { jsx as jsx28, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
1572
1594
|
function MessageList({ controller, ui, slip, onDashboardTap }) {
|
|
1573
1595
|
const { state, send } = controller;
|
|
1574
1596
|
const listRef = useRef2(null);
|
|
@@ -1578,8 +1600,8 @@ function MessageList({ controller, ui, slip, onDashboardTap }) {
|
|
|
1578
1600
|
if (pinnedRef.current) endRef.current?.scrollIntoView({ block: "end" });
|
|
1579
1601
|
}, [state.messages, state.status]);
|
|
1580
1602
|
const hasUserMessage = state.messages.some((m) => m.role === "user");
|
|
1581
|
-
const hasDashboard = state.messages.some((m) => m.role === "assistant" && m.greetingDashboard);
|
|
1582
|
-
return /* @__PURE__ */
|
|
1603
|
+
const hasDashboard = state.messages.some((m) => m.role === "assistant" && (m.greetingDashboard || m.clubFanDashboard));
|
|
1604
|
+
return /* @__PURE__ */ jsxs23(
|
|
1583
1605
|
"div",
|
|
1584
1606
|
{
|
|
1585
1607
|
className: "ss-w-list",
|
|
@@ -1599,7 +1621,6 @@ function MessageList({ controller, ui, slip, onDashboardTap }) {
|
|
|
1599
1621
|
send(tile.actionValue, { displayText: tile.title });
|
|
1600
1622
|
if (m.role === "assistant" && m.greetingDashboard) onDashboardTap?.(tile, index, m.greetingDashboard.layout);
|
|
1601
1623
|
},
|
|
1602
|
-
onClubAction: (label, opts) => send(label, { actionRef: opts.actionRef }),
|
|
1603
1624
|
ui,
|
|
1604
1625
|
slip
|
|
1605
1626
|
},
|
|
@@ -1608,7 +1629,7 @@ function MessageList({ controller, ui, slip, onDashboardTap }) {
|
|
|
1608
1629
|
state.isStreaming && state.actionsLoading ? /* @__PURE__ */ jsx28(ActionButtons, { actions: [], loading: true, onAct: () => {
|
|
1609
1630
|
} }) : null,
|
|
1610
1631
|
state.status ? /* @__PURE__ */ jsx28("div", { className: "ss-w-status", children: state.status }) : null,
|
|
1611
|
-
state.error ? /* @__PURE__ */
|
|
1632
|
+
state.error ? /* @__PURE__ */ jsxs23("div", { className: "ss-w-error", role: "alert", children: [
|
|
1612
1633
|
/* @__PURE__ */ jsx28("span", { children: "message" in state.error ? state.error.message : ui.somethingWentWrong }),
|
|
1613
1634
|
/* @__PURE__ */ jsx28("button", { type: "button", className: "ss-w-retry", onClick: () => controller.retry(), children: ui.retry })
|
|
1614
1635
|
] }) : null,
|
|
@@ -1620,10 +1641,10 @@ function MessageList({ controller, ui, slip, onDashboardTap }) {
|
|
|
1620
1641
|
}
|
|
1621
1642
|
|
|
1622
1643
|
// src/components/ChatInput.tsx
|
|
1623
|
-
import { useState as
|
|
1624
|
-
import { jsx as jsx29, jsxs as
|
|
1644
|
+
import { useState as useState7 } from "react";
|
|
1645
|
+
import { jsx as jsx29, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
1625
1646
|
function ChatInput({ placeholder, streaming, onSend, onStop, stopLabel = "Stop response", sendLabel = "Send message" }) {
|
|
1626
|
-
const [value, setValue] =
|
|
1647
|
+
const [value, setValue] = useState7("");
|
|
1627
1648
|
const submit = () => {
|
|
1628
1649
|
const t = value.trim();
|
|
1629
1650
|
if (!t) return;
|
|
@@ -1636,17 +1657,17 @@ function ChatInput({ placeholder, streaming, onSend, onStop, stopLabel = "Stop r
|
|
|
1636
1657
|
submit();
|
|
1637
1658
|
}
|
|
1638
1659
|
};
|
|
1639
|
-
return /* @__PURE__ */
|
|
1660
|
+
return /* @__PURE__ */ jsxs24("div", { className: "ss-w-input", children: [
|
|
1640
1661
|
/* @__PURE__ */ jsx29("textarea", { className: "ss-w-textarea", rows: 1, placeholder, value, disabled: streaming, onChange: (e) => setValue(e.target.value), onKeyDown }),
|
|
1641
1662
|
streaming ? /* @__PURE__ */ jsx29("button", { type: "button", className: "ss-w-send ss-w-stop", "aria-label": stopLabel, onClick: onStop, children: /* @__PURE__ */ jsx29("span", { className: "ss-w-stop-glyph" }) }) : /* @__PURE__ */ jsx29("button", { type: "button", className: "ss-w-send", "aria-label": sendLabel, onClick: submit, children: /* @__PURE__ */ jsx29(SendIcon, {}) })
|
|
1642
1663
|
] });
|
|
1643
1664
|
}
|
|
1644
1665
|
|
|
1645
1666
|
// src/components/ChatPanel.tsx
|
|
1646
|
-
import { jsx as jsx30, jsxs as
|
|
1667
|
+
import { jsx as jsx30, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
1647
1668
|
var FULLSCREEN_QUERY = "(max-width: 639px)";
|
|
1648
1669
|
function useIsModal() {
|
|
1649
|
-
const [modal, setModal] =
|
|
1670
|
+
const [modal, setModal] = useState8(false);
|
|
1650
1671
|
useEffect5(() => {
|
|
1651
1672
|
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
|
|
1652
1673
|
const mql = window.matchMedia(FULLSCREEN_QUERY);
|
|
@@ -1667,7 +1688,7 @@ function ChatPanel({ controller, ui, slip, onDashboardTap }) {
|
|
|
1667
1688
|
window.addEventListener("keydown", onKey);
|
|
1668
1689
|
return () => window.removeEventListener("keydown", onKey);
|
|
1669
1690
|
}, [close]);
|
|
1670
|
-
return /* @__PURE__ */
|
|
1691
|
+
return /* @__PURE__ */ jsxs25("div", { className: "ss-w-panel", role: "dialog", "aria-modal": isModal, "aria-label": ui.chatDialogLabel, children: [
|
|
1671
1692
|
/* @__PURE__ */ jsx30(ChatHeader, { onClose: close, closeLabel: ui.closeChat }),
|
|
1672
1693
|
/* @__PURE__ */ jsx30(MessageList, { controller, ui, slip, onDashboardTap }),
|
|
1673
1694
|
/* @__PURE__ */ jsx30(ChatInput, { placeholder: ui.placeholder, streaming: state.isStreaming, onSend: (t) => send(t), onStop: stop, stopLabel: ui.stopResponse, sendLabel: ui.sendMessage })
|
|
@@ -2024,61 +2045,117 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
|
|
|
2024
2045
|
.ss-w-dash--discovery .ss-w-dash-tile:nth-child(3) { background: #fdf6ec; }
|
|
2025
2046
|
.ss-w-dash--discovery .ss-w-dash-tile:nth-child(4) { background: #f5eefb; }
|
|
2026
2047
|
|
|
2027
|
-
/* club match
|
|
2028
|
-
.ss-w-
|
|
2029
|
-
.ss-w-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
.ss-w-
|
|
2041
|
-
.ss-w-
|
|
2042
|
-
.ss-w-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
.ss-w-
|
|
2047
|
-
.ss-w-
|
|
2048
|
-
.ss-w-
|
|
2049
|
-
.ss-w-
|
|
2050
|
-
.ss-w-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
.ss-w-
|
|
2055
|
-
.ss-w-
|
|
2056
|
-
.ss-w-
|
|
2057
|
-
.ss-w-
|
|
2058
|
-
.ss-w-
|
|
2059
|
-
.ss-w-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
.ss-w-
|
|
2063
|
-
.ss-w-
|
|
2064
|
-
.ss-w-
|
|
2065
|
-
|
|
2066
|
-
.ss-w-
|
|
2067
|
-
|
|
2068
|
-
.ss-w-
|
|
2069
|
-
|
|
2070
|
-
.ss-w-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
.ss-w-
|
|
2074
|
-
.ss-w-
|
|
2075
|
-
.ss-w-
|
|
2076
|
-
.ss-w-
|
|
2077
|
-
.ss-w-
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
.ss-w-
|
|
2048
|
+
/* club fan pre-match dashboard */
|
|
2049
|
+
.ss-w-fandash { display: flex; flex-direction: column; gap: 10px; padding: 4px 0; }
|
|
2050
|
+
.ss-w-fandash-greeting { font-size: 14px; font-weight: 600; line-height: 1.3; color: var(--ss-w-ink); }
|
|
2051
|
+
.ss-w-fandash-cards { display: flex; flex-direction: column; gap: 8px; }
|
|
2052
|
+
|
|
2053
|
+
/* Shared card chrome -- a plain <div> for [data] cards, a <button> for [prefill] cards. Both
|
|
2054
|
+
share the same box so the two families read as one system, not two ad hoc layouts. */
|
|
2055
|
+
.ss-w-fandash-card {
|
|
2056
|
+
display: flex; flex-direction: column; gap: 8px;
|
|
2057
|
+
padding: 12px; border-radius: 14px; border: 1px solid var(--ss-w-line);
|
|
2058
|
+
background: var(--ss-w-panel); text-align: left;
|
|
2059
|
+
color: inherit; font: inherit; width: 100%; min-width: 0;
|
|
2060
|
+
}
|
|
2061
|
+
.ss-w-fandash-card--tap { cursor: pointer; border-left: 3px solid var(--ss-w-accent); }
|
|
2062
|
+
.ss-w-fandash-card--tap:hover { background: var(--ss-w-bubble); }
|
|
2063
|
+
.ss-w-fandash-card-cta { align-self: flex-start; font-size: 11.5px; font-weight: 700; color: var(--ss-w-accent); }
|
|
2064
|
+
|
|
2065
|
+
/* Shared alignment primitives: a small letterspaced section eyebrow, and a 3-column value/label
|
|
2066
|
+
split reused by the fixture head-to-head (and any future stat-row card). */
|
|
2067
|
+
.ss-w-fandash-eyebrow { font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; color: var(--ss-w-faint); }
|
|
2068
|
+
.ss-w-fandash-split { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
|
|
2069
|
+
.ss-w-fandash-split-cell { display: flex; flex-direction: column; align-items: center; gap: 2px; text-align: center; min-width: 0; }
|
|
2070
|
+
.ss-w-fandash-split-value { font-size: 20px; font-weight: 750; font-variant-numeric: tabular-nums; color: var(--ss-w-ink); line-height: 1; }
|
|
2071
|
+
.ss-w-fandash-split-label { font-size: 9px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: var(--ss-w-faint); overflow-wrap: anywhere; }
|
|
2072
|
+
|
|
2073
|
+
/* fixture card */
|
|
2074
|
+
.ss-w-fandash-fixture-teams { display: flex; align-items: center; gap: 10px; }
|
|
2075
|
+
.ss-w-fandash-fixture-team { display: flex; align-items: center; gap: 8px; min-width: 0; flex: 1; }
|
|
2076
|
+
.ss-w-fandash-fixture-team--away { justify-content: flex-end; }
|
|
2077
|
+
.ss-w-fandash-fixture-team .ss-w-bi-crest { width: 30px; height: 30px; }
|
|
2078
|
+
.ss-w-fandash-fixture-team .ss-w-bi-crest-mono { font-size: 12px; }
|
|
2079
|
+
.ss-w-fandash-fixture-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 13px; font-weight: 650; }
|
|
2080
|
+
.ss-w-fandash-fixture-team--away .ss-w-fandash-fixture-name { text-align: right; }
|
|
2081
|
+
.ss-w-fandash-fixture-vs { flex: none; font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: var(--ss-w-faint); }
|
|
2082
|
+
/* date + venue as labelled rows, so a long stadium name gets its own line to ellipsis in */
|
|
2083
|
+
.ss-w-fandash-fixture-meta { display: flex; flex-direction: column; gap: 1px; border-top: 1px solid var(--ss-w-line); padding-top: 8px; }
|
|
2084
|
+
.ss-w-fandash-fixture-metarow { display: flex; align-items: baseline; gap: 9px; }
|
|
2085
|
+
.ss-w-fandash-fixture-metakey { flex: none; width: 44px; font-size: 8.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; color: var(--ss-w-faint); }
|
|
2086
|
+
.ss-w-fandash-fixture-metaval { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 12.5px; font-weight: 600; color: var(--ss-w-ink); }
|
|
2087
|
+
.ss-w-fandash-fact { font-size: 12px; color: var(--ss-w-ink); background: var(--ss-w-bubble); border-radius: 8px; padding: 6px 8px; }
|
|
2088
|
+
/* each head-to-head figure sits on its own shaded tile, so the grid gap separates wins/draws/losses */
|
|
2089
|
+
.ss-w-fandash-h2h .ss-w-fandash-split-cell { background: var(--ss-w-bubble); border-radius: 10px; padding: 12px 6px; }
|
|
2090
|
+
/* extra breathing room between the tally row and the fact beyond the card's own gap */
|
|
2091
|
+
.ss-w-fandash-h2h .ss-w-fandash-fact { margin-top: 4px; }
|
|
2092
|
+
|
|
2093
|
+
/* last-five: one row per side, team name left, form pills right */
|
|
2094
|
+
.ss-w-fandash-fixture-form { display: flex; flex-direction: column; gap: 5px; }
|
|
2095
|
+
.ss-w-fandash-formrow { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
|
|
2096
|
+
.ss-w-fandash-formrow-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 12px; font-weight: 600; }
|
|
2097
|
+
.ss-w-fandash-form { display: inline-flex; gap: 3px; flex: none; }
|
|
2098
|
+
.ss-w-fandash-form-pill {
|
|
2099
|
+
display: inline-grid; place-items: center; width: 16px; height: 16px;
|
|
2100
|
+
border-radius: 4px; font-size: 9.5px; font-weight: 700; color: #fff;
|
|
2101
|
+
}
|
|
2102
|
+
.ss-w-fandash-form-pill--win { background: var(--ss-w-pos); }
|
|
2103
|
+
.ss-w-fandash-form-pill--loss { background: var(--ss-w-neg); }
|
|
2104
|
+
.ss-w-fandash-form-pill--draw { background: var(--ss-w-faint); }
|
|
2105
|
+
|
|
2106
|
+
/* countdown card: a compact top card -- section eyebrow left, colon-separated clock right. Each
|
|
2107
|
+
segment stacks its figure over a small unit label (d/h/m/s). The exact kickoff date is not
|
|
2108
|
+
repeated here; the fixture card below carries it. */
|
|
2109
|
+
.ss-w-fandash-countdown-top { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
|
|
2110
|
+
.ss-w-fandash-countdown-clock { display: inline-flex; align-items: flex-start; gap: 6px; color: var(--ss-w-accent); }
|
|
2111
|
+
.ss-w-fandash-countdown-seg { display: inline-flex; flex-direction: column; align-items: center; }
|
|
2112
|
+
.ss-w-fandash-countdown-value { font-size: 26px; font-weight: 750; font-variant-numeric: tabular-nums; line-height: 1; letter-spacing: -.01em; }
|
|
2113
|
+
.ss-w-fandash-countdown-unit { font-size: 8px; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; color: var(--ss-w-faint); margin-top: 3px; }
|
|
2114
|
+
.ss-w-fandash-countdown-colon { font-size: 22px; font-weight: 750; line-height: 1; color: var(--ss-w-faint); }
|
|
2115
|
+
|
|
2116
|
+
/* injuries + transfers: two-column ours/theirs, in/out */
|
|
2117
|
+
.ss-w-fandash-transfers-cols { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
|
|
2118
|
+
/* injuries: a 1px divider column sits between the two team sections, each headed by crest + name */
|
|
2119
|
+
.ss-w-fandash-injuries-cols { display: grid; grid-template-columns: minmax(0, 1fr) 1px minmax(0, 1fr); gap: 12px; }
|
|
2120
|
+
.ss-w-fandash-injuries-divider { background: var(--ss-w-line); }
|
|
2121
|
+
.ss-w-fandash-injuries-col, .ss-w-fandash-transfers-col { min-width: 0; display: flex; flex-direction: column; gap: 4px; }
|
|
2122
|
+
.ss-w-fandash-transfers-col-head { font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .03em; color: var(--ss-w-faint); }
|
|
2123
|
+
.ss-w-fandash-injuries-col-head { display: flex; align-items: center; gap: 6px; font-size: 11px; font-weight: 700; color: var(--ss-w-ink); }
|
|
2124
|
+
.ss-w-fandash-injuries-col-head .ss-w-bi-crest { width: 18px; height: 18px; }
|
|
2125
|
+
.ss-w-fandash-injuries-col-head .ss-w-bi-crest-mono { font-size: 9px; }
|
|
2126
|
+
.ss-w-fandash-injuries-col-head-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
2127
|
+
.ss-w-fandash-injuries-empty, .ss-w-fandash-transfers-empty { font-size: 11.5px; color: var(--ss-w-faint); }
|
|
2128
|
+
.ss-w-fandash-injury-list, .ss-w-fandash-transfer-list { list-style: none; display: flex; flex-direction: column; gap: 5px; }
|
|
2129
|
+
.ss-w-fandash-injury-row, .ss-w-fandash-transfer-row { display: flex; flex-direction: column; gap: 1px; }
|
|
2130
|
+
.ss-w-fandash-injury-name, .ss-w-fandash-transfer-name { font-size: 12px; font-weight: 600; overflow-wrap: anywhere; }
|
|
2131
|
+
.ss-w-fandash-injury-meta { display: flex; flex-wrap: wrap; gap: 4px; font-size: 10.5px; color: var(--ss-w-faint); }
|
|
2132
|
+
.ss-w-fandash-injury-status { font-weight: 700; color: var(--ss-w-neg); }
|
|
2133
|
+
.ss-w-fandash-transfer-club { font-size: 11px; color: var(--ss-w-faint); }
|
|
2134
|
+
.ss-w-fandash-transfer-type { align-self: flex-start; font-size: 9.5px; font-weight: 700; text-transform: uppercase; color: var(--ss-w-accent); background: color-mix(in srgb, var(--ss-w-accent) 13%, var(--ss-w-panel)); border-radius: 999px; padding: 1px 7px; margin-top: 2px; }
|
|
2135
|
+
|
|
2136
|
+
/* reason-to-bet */
|
|
2137
|
+
.ss-w-fandash-reason-list { list-style: none; display: flex; flex-direction: column; gap: 6px; }
|
|
2138
|
+
.ss-w-fandash-reason-item { font-size: 12.5px; padding-left: 14px; position: relative; }
|
|
2139
|
+
.ss-w-fandash-reason-item::before { content: "\u2022"; position: absolute; left: 0; color: var(--ss-w-accent); font-weight: 700; }
|
|
2140
|
+
|
|
2141
|
+
/* where-to-watch */
|
|
2142
|
+
.ss-w-fandash-stations { display: flex; flex-wrap: wrap; gap: 6px; }
|
|
2143
|
+
.ss-w-fandash-station-chip { font-size: 11.5px; font-weight: 600; color: var(--ss-w-ink); background: var(--ss-w-bubble); border-radius: 999px; padding: 4px 10px; }
|
|
2144
|
+
|
|
2145
|
+
/* congested week: a fixed 3-column grid of upcoming fixtures (day / opponent / comp / time) */
|
|
2146
|
+
.ss-w-fandash-congested-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
|
|
2147
|
+
.ss-w-fandash-congested-cell { display: flex; flex-direction: column; gap: 2px; min-width: 0; padding: 8px; border-radius: 10px; background: var(--ss-w-bubble); }
|
|
2148
|
+
.ss-w-fandash-congested-day { font-size: 9.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: var(--ss-w-faint); }
|
|
2149
|
+
.ss-w-fandash-congested-opponent { font-size: 12.5px; font-weight: 650; overflow-wrap: anywhere; }
|
|
2150
|
+
.ss-w-fandash-congested-comp { font-size: 10px; color: var(--ss-w-faint); overflow-wrap: anywhere; }
|
|
2151
|
+
.ss-w-fandash-congested-time { font-size: 10.5px; color: var(--ss-w-faint); font-variant-numeric: tabular-nums; }
|
|
2152
|
+
|
|
2153
|
+
/* links: 2-column grid of tappable tiles */
|
|
2154
|
+
.ss-w-fandash-link-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
|
|
2155
|
+
.ss-w-fandash-link-tile { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 11px 13px; border-radius: 10px; border: 1px solid transparent; text-decoration: none; color: inherit; background: color-mix(in srgb, var(--ss-w-accent) 10%, var(--ss-w-panel)); }
|
|
2156
|
+
.ss-w-fandash-link-tile:hover { background: color-mix(in srgb, var(--ss-w-accent) 16%, var(--ss-w-panel)); }
|
|
2157
|
+
.ss-w-fandash-link-label { font-size: 12.5px; font-weight: 650; overflow-wrap: anywhere; }
|
|
2158
|
+
.ss-w-fandash-link-chevron { flex: none; width: 12px; height: 12px; color: var(--ss-w-accent); }
|
|
2082
2159
|
`;
|
|
2083
2160
|
|
|
2084
2161
|
// src/StatsWidget.tsx
|