@burdenoff/microfe-atheletebridge 2026.827.1 → 2026.829.2

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.
Files changed (46) hide show
  1. package/dist/atheletebridge/components/LoadingState.d.ts.map +1 -1
  2. package/dist/atheletebridge/components/LoadingState.js +39 -32
  3. package/dist/atheletebridge/components/LoadingState.js.map +1 -1
  4. package/dist/atheletebridge/components/TeamCard.d.ts.map +1 -1
  5. package/dist/atheletebridge/components/TeamCard.js +45 -49
  6. package/dist/atheletebridge/components/TeamCard.js.map +1 -1
  7. package/dist/atheletebridge/pages/DashboardPage.d.ts.map +1 -1
  8. package/dist/atheletebridge/pages/DashboardPage.js +56 -24
  9. package/dist/atheletebridge/pages/DashboardPage.js.map +1 -1
  10. package/dist/atheletebridge/pages/analytics/CoachAnalyticsPage.d.ts.map +1 -1
  11. package/dist/atheletebridge/pages/analytics/CoachAnalyticsPage.js +58 -56
  12. package/dist/atheletebridge/pages/analytics/CoachAnalyticsPage.js.map +1 -1
  13. package/dist/atheletebridge/pages/fixtures/FixtureDetailPage.d.ts.map +1 -1
  14. package/dist/atheletebridge/pages/fixtures/FixtureDetailPage.js +110 -106
  15. package/dist/atheletebridge/pages/fixtures/FixtureDetailPage.js.map +1 -1
  16. package/dist/atheletebridge/pages/fixtures/FixturesListPage.d.ts.map +1 -1
  17. package/dist/atheletebridge/pages/fixtures/FixturesListPage.js +80 -71
  18. package/dist/atheletebridge/pages/fixtures/FixturesListPage.js.map +1 -1
  19. package/dist/atheletebridge/pages/onboarding/OnboardingPage.d.ts.map +1 -1
  20. package/dist/atheletebridge/pages/onboarding/OnboardingPage.js +244 -210
  21. package/dist/atheletebridge/pages/onboarding/OnboardingPage.js.map +1 -1
  22. package/dist/atheletebridge/pages/performance/PerformancePage.d.ts.map +1 -1
  23. package/dist/atheletebridge/pages/performance/PerformancePage.js +197 -148
  24. package/dist/atheletebridge/pages/performance/PerformancePage.js.map +1 -1
  25. package/dist/atheletebridge/pages/programs/ProgramDetailPage.d.ts.map +1 -1
  26. package/dist/atheletebridge/pages/programs/ProgramDetailPage.js +169 -143
  27. package/dist/atheletebridge/pages/programs/ProgramDetailPage.js.map +1 -1
  28. package/dist/atheletebridge/pages/programs/ProgramsListPage.d.ts.map +1 -1
  29. package/dist/atheletebridge/pages/programs/ProgramsListPage.js +77 -72
  30. package/dist/atheletebridge/pages/programs/ProgramsListPage.js.map +1 -1
  31. package/dist/atheletebridge/pages/sessions/SessionDetailPage.d.ts.map +1 -1
  32. package/dist/atheletebridge/pages/sessions/SessionDetailPage.js +104 -86
  33. package/dist/atheletebridge/pages/sessions/SessionDetailPage.js.map +1 -1
  34. package/dist/atheletebridge/pages/sessions/SessionsListPage.d.ts.map +1 -1
  35. package/dist/atheletebridge/pages/sessions/SessionsListPage.js +54 -49
  36. package/dist/atheletebridge/pages/sessions/SessionsListPage.js.map +1 -1
  37. package/dist/atheletebridge/pages/teams/TeamDetailPage.d.ts.map +1 -1
  38. package/dist/atheletebridge/pages/teams/TeamDetailPage.js +286 -267
  39. package/dist/atheletebridge/pages/teams/TeamDetailPage.js.map +1 -1
  40. package/dist/atheletebridge/pages/teams/TeamFormPage.d.ts.map +1 -1
  41. package/dist/atheletebridge/pages/teams/TeamFormPage.js +185 -180
  42. package/dist/atheletebridge/pages/teams/TeamFormPage.js.map +1 -1
  43. package/dist/atheletebridge/pages/teams/TeamsListPage.d.ts.map +1 -1
  44. package/dist/atheletebridge/pages/teams/TeamsListPage.js +70 -74
  45. package/dist/atheletebridge/pages/teams/TeamsListPage.js.map +1 -1
  46. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"LoadingState.d.ts","sourceRoot":"","sources":["../../../src/atheletebridge/components/LoadingState.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAIhC,UAAU,iBAAiB;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,YAAY,EAAE,EAAE,CAAC,iBAAiB,CAS9C,CAAC;AAEF,UAAU,eAAe;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,UAAU,EAAE,EAAE,CAAC,eAAe,CAyB1C,CAAC"}
1
+ {"version":3,"file":"LoadingState.d.ts","sourceRoot":"","sources":["../../../src/atheletebridge/components/LoadingState.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAKhC,UAAU,iBAAiB;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,YAAY,EAAE,EAAE,CAAC,iBAAiB,CAY9C,CAAC;AAEF,UAAU,eAAe;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,UAAU,EAAE,EAAE,CAAC,eAAe,CA2B1C,CAAC"}
@@ -1,36 +1,43 @@
1
- import { cn as e } from "../utils/cn.js";
2
- import { AlertCircle as t, Loader2 as n } from "lucide-react";
3
- import { jsx as r, jsxs as i } from "react/jsx-runtime";
1
+ import { useAbTranslate as e } from "../i18n.js";
2
+ import { cn as t } from "../utils/cn.js";
3
+ import { AlertCircle as n, Loader2 as r } from "lucide-react";
4
+ import { jsx as i, jsxs as a } from "react/jsx-runtime";
4
5
  //#region src/atheletebridge/components/LoadingState.tsx
5
- var a = ({ label: t = "Loading…", className: a }) => /* @__PURE__ */ i("div", {
6
- className: e("flex min-h-[40vh] flex-col items-center justify-center gap-3", a),
7
- role: "status",
8
- "aria-live": "polite",
9
- children: [/* @__PURE__ */ r(n, { className: "h-8 w-8 animate-spin text-text-secondary" }), /* @__PURE__ */ r("p", {
10
- className: "text-sm text-text-secondary",
11
- children: t
12
- })]
13
- }), o = ({ title: n = "Something went wrong", message: a = "We could not load this data. Please try again.", onRetry: o, className: s }) => /* @__PURE__ */ i("div", {
14
- className: e("flex min-h-[40vh] flex-col items-center justify-center gap-3 text-center", s),
15
- children: [
16
- /* @__PURE__ */ r(t, { className: "h-10 w-10 text-status-error-text" }),
17
- /* @__PURE__ */ r("h3", {
18
- className: "text-lg font-semibold text-text-primary",
19
- children: n
20
- }),
21
- /* @__PURE__ */ r("p", {
22
- className: "max-w-sm text-sm text-text-secondary",
23
- children: a
24
- }),
25
- o && /* @__PURE__ */ r("button", {
26
- type: "button",
27
- onClick: o,
28
- className: "mt-2 rounded-lg border border-border-seam px-4 py-2 text-sm font-medium text-text-primary transition-colors hover:bg-bg-sunken",
29
- children: "Try again"
30
- })
31
- ]
32
- });
6
+ var o = ({ label: n, className: o }) => {
7
+ let s = e();
8
+ return /* @__PURE__ */ a("div", {
9
+ className: t("flex min-h-[40vh] flex-col items-center justify-center gap-3", o),
10
+ role: "status",
11
+ "aria-live": "polite",
12
+ children: [/* @__PURE__ */ i(r, { className: "h-8 w-8 animate-spin text-text-secondary" }), /* @__PURE__ */ i("p", {
13
+ className: "text-sm text-text-secondary",
14
+ children: n ?? s("common.loading", "Loading…")
15
+ })]
16
+ });
17
+ }, s = ({ title: r, message: o, onRetry: s, className: c }) => {
18
+ let l = e();
19
+ return /* @__PURE__ */ a("div", {
20
+ className: t("flex min-h-[40vh] flex-col items-center justify-center gap-3 text-center", c),
21
+ children: [
22
+ /* @__PURE__ */ i(n, { className: "h-10 w-10 text-status-error-text" }),
23
+ /* @__PURE__ */ i("h3", {
24
+ className: "text-lg font-semibold text-text-primary",
25
+ children: r ?? l("common.errorTitle", "Something went wrong")
26
+ }),
27
+ /* @__PURE__ */ i("p", {
28
+ className: "max-w-sm text-sm text-text-secondary",
29
+ children: o ?? l("common.errorMessage", "We could not load this data. Please try again.")
30
+ }),
31
+ s && /* @__PURE__ */ i("button", {
32
+ type: "button",
33
+ onClick: s,
34
+ className: "mt-2 rounded-lg border border-border-seam px-4 py-2 text-sm font-medium text-text-primary transition-colors hover:bg-bg-sunken",
35
+ children: l("common.tryAgain", "Try again")
36
+ })
37
+ ]
38
+ });
39
+ };
33
40
  //#endregion
34
- export { o as ErrorState, a as LoadingState };
41
+ export { s as ErrorState, o as LoadingState };
35
42
 
36
43
  //# sourceMappingURL=LoadingState.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"LoadingState.js","names":[],"sources":["../../../src/atheletebridge/components/LoadingState.tsx"],"sourcesContent":["/**\n * Loading / Error State Components\n * @module atheletebridge/components\n *\n * Small calm, centered states shared across list and detail pages.\n */\n\nimport type { FC } from 'react';\nimport { AlertCircle, Loader2 } from 'lucide-react';\nimport { cn } from '../utils/cn';\n\ninterface LoadingStateProps {\n label?: string;\n className?: string;\n}\n\nexport const LoadingState: FC<LoadingStateProps> = ({ label = 'Loading…', className }) => (\n <div\n className={cn('flex min-h-[40vh] flex-col items-center justify-center gap-3', className)}\n role=\"status\"\n aria-live=\"polite\"\n >\n <Loader2 className=\"h-8 w-8 animate-spin text-text-secondary\" />\n <p className=\"text-sm text-text-secondary\">{label}</p>\n </div>\n);\n\ninterface ErrorStateProps {\n title?: string;\n message?: string;\n onRetry?: () => void;\n className?: string;\n}\n\nexport const ErrorState: FC<ErrorStateProps> = ({\n title = 'Something went wrong',\n message = 'We could not load this data. Please try again.',\n onRetry,\n className,\n}) => (\n <div\n className={cn(\n 'flex min-h-[40vh] flex-col items-center justify-center gap-3 text-center',\n className\n )}\n >\n <AlertCircle className=\"h-10 w-10 text-status-error-text\" />\n <h3 className=\"text-lg font-semibold text-text-primary\">{title}</h3>\n <p className=\"max-w-sm text-sm text-text-secondary\">{message}</p>\n {onRetry && (\n <button\n type=\"button\"\n onClick={onRetry}\n className=\"mt-2 rounded-lg border border-border-seam px-4 py-2 text-sm font-medium text-text-primary transition-colors hover:bg-bg-sunken\"\n >\n Try again\n </button>\n )}\n </div>\n);\n"],"mappings":";;;;AAgBA,IAAa,KAAuC,EAAE,WAAQ,YAAY,mBACxE,kBAAC,OAAD;CACE,WAAW,EAAG,gEAAgE,CAAS;CACvF,MAAK;CACL,aAAU;WAHZ,CAKE,kBAAC,GAAD,EAAS,WAAU,2CAA4C,CAAA,GAC/D,kBAAC,KAAD;EAAG,WAAU;YAA+B;CAAS,CAAA,CAClD;IAUM,KAAmC,EAC9C,WAAQ,wBACR,aAAU,kDACV,YACA,mBAEA,kBAAC,OAAD;CACE,WAAW,EACT,4EACA,CACF;WAJF;EAME,kBAAC,GAAD,EAAa,WAAU,mCAAoC,CAAA;EAC3D,kBAAC,MAAD;GAAI,WAAU;aAA2C;EAAU,CAAA;EACnE,kBAAC,KAAD;GAAG,WAAU;aAAwC;EAAW,CAAA;EAC/D,KACC,kBAAC,UAAD;GACE,MAAK;GACL,SAAS;GACT,WAAU;aACX;EAEO,CAAA;CAEP"}
1
+ {"version":3,"file":"LoadingState.js","names":[],"sources":["../../../src/atheletebridge/components/LoadingState.tsx"],"sourcesContent":["/**\n * Loading / Error State Components\n * @module atheletebridge/components\n *\n * Small calm, centered states shared across list and detail pages.\n */\n\nimport type { FC } from 'react';\nimport { AlertCircle, Loader2 } from 'lucide-react';\nimport { cn } from '../utils/cn';\nimport { useAbTranslate } from '../i18n';\n\ninterface LoadingStateProps {\n label?: string;\n className?: string;\n}\n\nexport const LoadingState: FC<LoadingStateProps> = ({ label, className }) => {\n const tr = useAbTranslate();\n return (\n <div\n className={cn('flex min-h-[40vh] flex-col items-center justify-center gap-3', className)}\n role=\"status\"\n aria-live=\"polite\"\n >\n <Loader2 className=\"h-8 w-8 animate-spin text-text-secondary\" />\n <p className=\"text-sm text-text-secondary\">{label ?? tr('common.loading', 'Loading…')}</p>\n </div>\n );\n};\n\ninterface ErrorStateProps {\n title?: string;\n message?: string;\n onRetry?: () => void;\n className?: string;\n}\n\nexport const ErrorState: FC<ErrorStateProps> = ({ title, message, onRetry, className }) => {\n const tr = useAbTranslate();\n return (\n <div\n className={cn(\n 'flex min-h-[40vh] flex-col items-center justify-center gap-3 text-center',\n className\n )}\n >\n <AlertCircle className=\"h-10 w-10 text-status-error-text\" />\n <h3 className=\"text-lg font-semibold text-text-primary\">\n {title ?? tr('common.errorTitle', 'Something went wrong')}\n </h3>\n <p className=\"max-w-sm text-sm text-text-secondary\">\n {message ?? tr('common.errorMessage', 'We could not load this data. Please try again.')}\n </p>\n {onRetry && (\n <button\n type=\"button\"\n onClick={onRetry}\n className=\"mt-2 rounded-lg border border-border-seam px-4 py-2 text-sm font-medium text-text-primary transition-colors hover:bg-bg-sunken\"\n >\n {tr('common.tryAgain', 'Try again')}\n </button>\n )}\n </div>\n );\n};\n"],"mappings":";;;;;AAiBA,IAAa,KAAuC,EAAE,UAAO,mBAAgB;CAC3E,IAAM,IAAK,EAAe;CAC1B,OACE,kBAAC,OAAD;EACE,WAAW,EAAG,gEAAgE,CAAS;EACvF,MAAK;EACL,aAAU;YAHZ,CAKE,kBAAC,GAAD,EAAS,WAAU,2CAA4C,CAAA,GAC/D,kBAAC,KAAD;GAAG,WAAU;aAA+B,KAAS,EAAG,kBAAkB,UAAU;EAAK,CAAA,CACtF;;AAET,GASa,KAAmC,EAAE,UAAO,YAAS,YAAS,mBAAgB;CACzF,IAAM,IAAK,EAAe;CAC1B,OACE,kBAAC,OAAD;EACE,WAAW,EACT,4EACA,CACF;YAJF;GAME,kBAAC,GAAD,EAAa,WAAU,mCAAoC,CAAA;GAC3D,kBAAC,MAAD;IAAI,WAAU;cACX,KAAS,EAAG,qBAAqB,sBAAsB;GACtD,CAAA;GACJ,kBAAC,KAAD;IAAG,WAAU;cACV,KAAW,EAAG,uBAAuB,gDAAgD;GACrF,CAAA;GACF,KACC,kBAAC,UAAD;IACE,MAAK;IACL,SAAS;IACT,WAAU;cAET,EAAG,mBAAmB,WAAW;GAC5B,CAAA;EAEP;;AAET"}
@@ -1 +1 @@
1
- {"version":3,"file":"TeamCard.d.ts","sourceRoot":"","sources":["../../../src/atheletebridge/components/TeamCard.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAOhC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAExC,UAAU,aAAa;IACrB,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,eAAO,MAAM,QAAQ,EAAE,EAAE,CAAC,aAAa,CA2EtC,CAAC"}
1
+ {"version":3,"file":"TeamCard.d.ts","sourceRoot":"","sources":["../../../src/atheletebridge/components/TeamCard.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAQhC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAExC,UAAU,aAAa;IACrB,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,eAAO,MAAM,QAAQ,EAAE,EAAE,CAAC,aAAa,CAuFtC,CAAC"}
@@ -1,111 +1,107 @@
1
- import { cn as e } from "../utils/cn.js";
2
- import { StatusBadge as t } from "./StatusBadge.js";
3
- import { SPORT_ICONS as n, SPORT_LABELS as r } from "./domain.js";
4
- import { Crest as i } from "./Crest.js";
5
- import { CalendarDays as a, MapPin as o, Users as s } from "lucide-react";
6
- import { jsx as c, jsxs as l } from "react/jsx-runtime";
7
- import { Badge as u, GlassCard as d } from "@burdenoff/fe-libs/ui";
1
+ import { useAbTranslate as e } from "../i18n.js";
2
+ import { cn as t } from "../utils/cn.js";
3
+ import { StatusBadge as n } from "./StatusBadge.js";
4
+ import { SPORT_ICONS as r, SPORT_LABELS as i } from "./domain.js";
5
+ import { Crest as a } from "./Crest.js";
6
+ import { CalendarDays as o, MapPin as s, Users as c } from "lucide-react";
7
+ import { jsx as l, jsxs as u } from "react/jsx-runtime";
8
+ import { Badge as d, GlassCard as f } from "@burdenoff/fe-libs/ui";
8
9
  //#region src/atheletebridge/components/TeamCard.tsx
9
- var f = ({ team: f, onClick: p, memberCount: m }) => {
10
- let h = n[f.sport], g = m ?? f.members?.items.length;
11
- return /* @__PURE__ */ l(d, {
10
+ var p = ({ team: p, onClick: m, memberCount: h }) => {
11
+ let g = e(), _ = r[p.sport], v = h ?? p.members?.items.length, y = v === 1 ? g("atheletebridge.team.memberCount.one", "{{count}} member").replace("{{count}}", String(v)) : g("atheletebridge.team.memberCount.other", "{{count}} members").replace("{{count}}", String(v ?? 0));
12
+ return /* @__PURE__ */ u(f, {
12
13
  treatment: "metric",
13
14
  role: "button",
14
15
  tabIndex: 0,
15
- onClick: p,
16
+ onClick: m,
16
17
  onKeyDown: (e) => {
17
- (e.key === "Enter" || e.key === " ") && (e.preventDefault(), p?.());
18
+ (e.key === "Enter" || e.key === " ") && (e.preventDefault(), m?.());
18
19
  },
19
- className: e("cursor-pointer p-5 transition-transform duration-200 hover:-translate-y-0.5 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)]"),
20
+ className: t("cursor-pointer p-5 transition-transform duration-200 hover:-translate-y-0.5 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)]"),
20
21
  children: [
21
- /* @__PURE__ */ l("div", {
22
+ /* @__PURE__ */ u("div", {
22
23
  className: "flex items-start justify-between gap-3",
23
- children: [/* @__PURE__ */ l("div", {
24
+ children: [/* @__PURE__ */ u("div", {
24
25
  className: "flex min-w-0 items-center gap-3",
25
- children: [/* @__PURE__ */ c(i, {
26
- name: f.name,
27
- sport: f.sport,
26
+ children: [/* @__PURE__ */ l(a, {
27
+ name: p.name,
28
+ sport: p.sport,
28
29
  size: 44
29
- }), /* @__PURE__ */ l("div", {
30
+ }), /* @__PURE__ */ u("div", {
30
31
  className: "min-w-0",
31
- children: [/* @__PURE__ */ c("h3", {
32
+ children: [/* @__PURE__ */ l("h3", {
32
33
  className: "truncate text-base font-semibold text-text-primary",
33
- children: f.name
34
- }), /* @__PURE__ */ c("div", {
34
+ children: p.name
35
+ }), /* @__PURE__ */ l("div", {
35
36
  className: "mt-1",
36
- children: /* @__PURE__ */ l(u, {
37
+ children: /* @__PURE__ */ u(d, {
37
38
  variant: "secondary",
38
39
  className: "gap-1",
39
- children: [/* @__PURE__ */ c(h, {
40
+ children: [/* @__PURE__ */ l(_, {
40
41
  className: "h-3 w-3",
41
42
  "aria-hidden": "true"
42
- }), r[f.sport]]
43
+ }), i[p.sport]]
43
44
  })
44
45
  })]
45
46
  })]
46
- }), /* @__PURE__ */ c(t, { status: f.status })]
47
+ }), /* @__PURE__ */ l(n, { status: p.status })]
47
48
  }),
48
- /* @__PURE__ */ l("div", {
49
+ /* @__PURE__ */ u("div", {
49
50
  className: "mt-4 flex flex-wrap items-center gap-x-4 gap-y-1.5 text-xs text-text-secondary",
50
51
  children: [
51
- f.ageGroup && /* @__PURE__ */ l("span", {
52
+ p.ageGroup && /* @__PURE__ */ u("span", {
52
53
  className: "flex items-center gap-1",
53
54
  children: [
54
- /* @__PURE__ */ c(s, {
55
+ /* @__PURE__ */ l(c, {
55
56
  className: "h-3.5 w-3.5",
56
57
  "aria-hidden": "true"
57
58
  }),
58
59
  " ",
59
- f.ageGroup
60
+ p.ageGroup
60
61
  ]
61
62
  }),
62
- f.season && /* @__PURE__ */ l("span", {
63
+ p.season && /* @__PURE__ */ u("span", {
63
64
  className: "flex items-center gap-1",
64
65
  children: [
65
- /* @__PURE__ */ c(a, {
66
+ /* @__PURE__ */ l(o, {
66
67
  className: "h-3.5 w-3.5",
67
68
  "aria-hidden": "true"
68
69
  }),
69
70
  " ",
70
- f.season
71
+ p.season
71
72
  ]
72
73
  }),
73
- f.homeVenue && /* @__PURE__ */ l("span", {
74
+ p.homeVenue && /* @__PURE__ */ u("span", {
74
75
  className: "flex items-center gap-1 truncate",
75
76
  children: [
76
- /* @__PURE__ */ c(o, {
77
+ /* @__PURE__ */ l(s, {
77
78
  className: "h-3.5 w-3.5 shrink-0",
78
79
  "aria-hidden": "true"
79
80
  }),
80
81
  " ",
81
- f.homeVenue
82
+ p.homeVenue
82
83
  ]
83
84
  })
84
85
  ]
85
86
  }),
86
- f.tags.length > 0 && /* @__PURE__ */ c("div", {
87
+ p.tags.length > 0 && /* @__PURE__ */ l("div", {
87
88
  className: "mt-3 flex flex-wrap gap-1.5",
88
- children: f.tags.slice(0, 4).map((e) => /* @__PURE__ */ c("span", {
89
+ children: p.tags.slice(0, 4).map((e) => /* @__PURE__ */ l("span", {
89
90
  className: "inline-flex items-center rounded-full bg-bg-sunken px-2 py-0.5 text-xs text-text-secondary",
90
91
  children: e
91
92
  }, e))
92
93
  }),
93
- g !== void 0 && /* @__PURE__ */ l("div", {
94
+ v !== void 0 && /* @__PURE__ */ u("div", {
94
95
  className: "mt-4 flex items-center gap-1.5 border-t border-border-seam pt-3 text-xs font-medium text-text-secondary",
95
- children: [
96
- /* @__PURE__ */ c(s, {
97
- className: "h-3.5 w-3.5",
98
- "aria-hidden": "true"
99
- }),
100
- g,
101
- " ",
102
- g === 1 ? "member" : "members"
103
- ]
96
+ children: [/* @__PURE__ */ l(c, {
97
+ className: "h-3.5 w-3.5",
98
+ "aria-hidden": "true"
99
+ }), y]
104
100
  })
105
101
  ]
106
102
  });
107
103
  };
108
104
  //#endregion
109
- export { f as TeamCard };
105
+ export { p as TeamCard };
110
106
 
111
107
  //# sourceMappingURL=TeamCard.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"TeamCard.js","names":[],"sources":["../../../src/atheletebridge/components/TeamCard.tsx"],"sourcesContent":["/**\n * Team Card\n * @module atheletebridge/components\n *\n * A team tile fronted by a deterministic gradient monogram crest, with a sport\n * Badge, a StatusBadge (green Active / amber Forming / grey Inactive·Archived),\n * a member-count chip and a hover lift. Semantic tokens only.\n */\n\nimport type { FC } from 'react';\nimport { Users, MapPin, CalendarDays } from 'lucide-react';\nimport { GlassCard, Badge } from '@burdenoff/fe-libs/ui';\nimport { StatusBadge } from './StatusBadge';\nimport { Crest } from './Crest';\nimport { SPORT_ICONS, SPORT_LABELS } from './domain';\nimport { cn } from '../utils/cn';\nimport type { AthTeam } from '../types';\n\ninterface TeamCardProps {\n team: AthTeam;\n onClick?: () => void;\n /**\n * Member count for the footer chip. Falls back to `team.members?.length`\n * when the list query selected members; omit the chip entirely if neither is\n * available (never guess).\n */\n memberCount?: number;\n}\n\nexport const TeamCard: FC<TeamCardProps> = ({ team, onClick, memberCount }) => {\n const SportIcon = SPORT_ICONS[team.sport];\n const count = memberCount ?? team.members?.items.length;\n\n return (\n <GlassCard\n treatment=\"metric\"\n role=\"button\"\n tabIndex={0}\n onClick={onClick}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n onClick?.();\n }\n }}\n className={cn(\n 'cursor-pointer p-5 transition-transform duration-200 hover:-translate-y-0.5 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)]'\n )}\n >\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"flex min-w-0 items-center gap-3\">\n <Crest name={team.name} sport={team.sport} size={44} />\n <div className=\"min-w-0\">\n <h3 className=\"truncate text-base font-semibold text-text-primary\">{team.name}</h3>\n <div className=\"mt-1\">\n <Badge variant=\"secondary\" className=\"gap-1\">\n <SportIcon className=\"h-3 w-3\" aria-hidden=\"true\" />\n {SPORT_LABELS[team.sport]}\n </Badge>\n </div>\n </div>\n </div>\n <StatusBadge status={team.status} />\n </div>\n\n <div className=\"mt-4 flex flex-wrap items-center gap-x-4 gap-y-1.5 text-xs text-text-secondary\">\n {team.ageGroup && (\n <span className=\"flex items-center gap-1\">\n <Users className=\"h-3.5 w-3.5\" aria-hidden=\"true\" /> {team.ageGroup}\n </span>\n )}\n {team.season && (\n <span className=\"flex items-center gap-1\">\n <CalendarDays className=\"h-3.5 w-3.5\" aria-hidden=\"true\" /> {team.season}\n </span>\n )}\n {team.homeVenue && (\n <span className=\"flex items-center gap-1 truncate\">\n <MapPin className=\"h-3.5 w-3.5 shrink-0\" aria-hidden=\"true\" /> {team.homeVenue}\n </span>\n )}\n </div>\n\n {team.tags.length > 0 && (\n <div className=\"mt-3 flex flex-wrap gap-1.5\">\n {team.tags.slice(0, 4).map((tag) => (\n <span\n key={tag}\n className=\"inline-flex items-center rounded-full bg-bg-sunken px-2 py-0.5 text-xs text-text-secondary\"\n >\n {tag}\n </span>\n ))}\n </div>\n )}\n\n {count !== undefined && (\n <div className=\"mt-4 flex items-center gap-1.5 border-t border-border-seam pt-3 text-xs font-medium text-text-secondary\">\n <Users className=\"h-3.5 w-3.5\" aria-hidden=\"true\" />\n {count} {count === 1 ? 'member' : 'members'}\n </div>\n )}\n </GlassCard>\n );\n};\n"],"mappings":";;;;;;;;AA6BA,IAAa,KAA+B,EAAE,SAAM,YAAS,qBAAkB;CAC7E,IAAM,IAAY,EAAY,EAAK,QAC7B,IAAQ,KAAe,EAAK,SAAS,MAAM;CAEjD,OACE,kBAAC,GAAD;EACE,WAAU;EACV,MAAK;EACL,UAAU;EACD;EACT,YAAY,MAAM;GAChB,CAAI,EAAE,QAAQ,WAAW,EAAE,QAAQ,SACjC,EAAE,eAAe,GACjB,IAAU;EAEd;EACA,WAAW,EACT,0KACF;YAbF;GAeE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,GAAD;MAAO,MAAM,EAAK;MAAM,OAAO,EAAK;MAAO,MAAM;KAAK,CAAA,GACtD,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,MAAD;OAAI,WAAU;iBAAsD,EAAK;MAAS,CAAA,GAClF,kBAAC,OAAD;OAAK,WAAU;iBACb,kBAAC,GAAD;QAAO,SAAQ;QAAY,WAAU;kBAArC,CACE,kBAAC,GAAD;SAAW,WAAU;SAAU,eAAY;QAAQ,CAAA,GAClD,EAAa,EAAK,MACd;;MACJ,CAAA,CACF;OACF;QACL,kBAAC,GAAD,EAAa,QAAQ,EAAK,OAAS,CAAA,CAChC;;GAEL,kBAAC,OAAD;IAAK,WAAU;cAAf;KACG,EAAK,YACJ,kBAAC,QAAD;MAAM,WAAU;gBAAhB;OACE,kBAAC,GAAD;QAAO,WAAU;QAAc,eAAY;OAAQ,CAAA;OAAC;OAAE,EAAK;MACvD;;KAEP,EAAK,UACJ,kBAAC,QAAD;MAAM,WAAU;gBAAhB;OACE,kBAAC,GAAD;QAAc,WAAU;QAAc,eAAY;OAAQ,CAAA;OAAC;OAAE,EAAK;MAC9D;;KAEP,EAAK,aACJ,kBAAC,QAAD;MAAM,WAAU;gBAAhB;OACE,kBAAC,GAAD;QAAQ,WAAU;QAAuB,eAAY;OAAQ,CAAA;OAAC;OAAE,EAAK;MACjE;;IAEL;;GAEJ,EAAK,KAAK,SAAS,KAClB,kBAAC,OAAD;IAAK,WAAU;cACZ,EAAK,KAAK,MAAM,GAAG,CAAC,EAAE,KAAK,MAC1B,kBAAC,QAAD;KAEE,WAAU;eAET;IACG,GAJC,CAID,CACP;GACE,CAAA;GAGN,MAAU,KAAA,KACT,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,GAAD;MAAO,WAAU;MAAc,eAAY;KAAQ,CAAA;KAClD;KAAM;KAAE,MAAU,IAAI,WAAW;IAC/B;;EAEE;;AAEf"}
1
+ {"version":3,"file":"TeamCard.js","names":[],"sources":["../../../src/atheletebridge/components/TeamCard.tsx"],"sourcesContent":["/**\n * Team Card\n * @module atheletebridge/components\n *\n * A team tile fronted by a deterministic gradient monogram crest, with a sport\n * Badge, a StatusBadge (green Active / amber Forming / grey Inactive·Archived),\n * a member-count chip and a hover lift. Semantic tokens only.\n */\n\nimport type { FC } from 'react';\nimport { Users, MapPin, CalendarDays } from 'lucide-react';\nimport { GlassCard, Badge } from '@burdenoff/fe-libs/ui';\nimport { StatusBadge } from './StatusBadge';\nimport { Crest } from './Crest';\nimport { SPORT_ICONS, SPORT_LABELS } from './domain';\nimport { cn } from '../utils/cn';\nimport { useAbTranslate } from '../i18n';\nimport type { AthTeam } from '../types';\n\ninterface TeamCardProps {\n team: AthTeam;\n onClick?: () => void;\n /**\n * Member count for the footer chip. Falls back to `team.members?.length`\n * when the list query selected members; omit the chip entirely if neither is\n * available (never guess).\n */\n memberCount?: number;\n}\n\nexport const TeamCard: FC<TeamCardProps> = ({ team, onClick, memberCount }) => {\n const tr = useAbTranslate();\n const SportIcon = SPORT_ICONS[team.sport];\n const count = memberCount ?? team.members?.items.length;\n\n const memberLabel =\n count === 1\n ? tr('atheletebridge.team.memberCount.one', '{{count}} member').replace(\n '{{count}}',\n String(count)\n )\n : tr('atheletebridge.team.memberCount.other', '{{count}} members').replace(\n '{{count}}',\n String(count ?? 0)\n );\n\n return (\n <GlassCard\n treatment=\"metric\"\n role=\"button\"\n tabIndex={0}\n onClick={onClick}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n onClick?.();\n }\n }}\n className={cn(\n 'cursor-pointer p-5 transition-transform duration-200 hover:-translate-y-0.5 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)]'\n )}\n >\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"flex min-w-0 items-center gap-3\">\n <Crest name={team.name} sport={team.sport} size={44} />\n <div className=\"min-w-0\">\n <h3 className=\"truncate text-base font-semibold text-text-primary\">{team.name}</h3>\n <div className=\"mt-1\">\n <Badge variant=\"secondary\" className=\"gap-1\">\n <SportIcon className=\"h-3 w-3\" aria-hidden=\"true\" />\n {SPORT_LABELS[team.sport]}\n </Badge>\n </div>\n </div>\n </div>\n <StatusBadge status={team.status} />\n </div>\n\n <div className=\"mt-4 flex flex-wrap items-center gap-x-4 gap-y-1.5 text-xs text-text-secondary\">\n {team.ageGroup && (\n <span className=\"flex items-center gap-1\">\n <Users className=\"h-3.5 w-3.5\" aria-hidden=\"true\" /> {team.ageGroup}\n </span>\n )}\n {team.season && (\n <span className=\"flex items-center gap-1\">\n <CalendarDays className=\"h-3.5 w-3.5\" aria-hidden=\"true\" /> {team.season}\n </span>\n )}\n {team.homeVenue && (\n <span className=\"flex items-center gap-1 truncate\">\n <MapPin className=\"h-3.5 w-3.5 shrink-0\" aria-hidden=\"true\" /> {team.homeVenue}\n </span>\n )}\n </div>\n\n {team.tags.length > 0 && (\n <div className=\"mt-3 flex flex-wrap gap-1.5\">\n {team.tags.slice(0, 4).map((tag) => (\n <span\n key={tag}\n className=\"inline-flex items-center rounded-full bg-bg-sunken px-2 py-0.5 text-xs text-text-secondary\"\n >\n {tag}\n </span>\n ))}\n </div>\n )}\n\n {count !== undefined && (\n <div className=\"mt-4 flex items-center gap-1.5 border-t border-border-seam pt-3 text-xs font-medium text-text-secondary\">\n <Users className=\"h-3.5 w-3.5\" aria-hidden=\"true\" />\n {memberLabel}\n </div>\n )}\n </GlassCard>\n );\n};\n"],"mappings":";;;;;;;;;AA8BA,IAAa,KAA+B,EAAE,SAAM,YAAS,qBAAkB;CAC7E,IAAM,IAAK,EAAe,GACpB,IAAY,EAAY,EAAK,QAC7B,IAAQ,KAAe,EAAK,SAAS,MAAM,QAE3C,IACJ,MAAU,IACN,EAAG,uCAAuC,kBAAkB,EAAE,QAC5D,aACA,OAAO,CAAK,CACd,IACA,EAAG,yCAAyC,mBAAmB,EAAE,QAC/D,aACA,OAAO,KAAS,CAAC,CACnB;CAEN,OACE,kBAAC,GAAD;EACE,WAAU;EACV,MAAK;EACL,UAAU;EACD;EACT,YAAY,MAAM;GAChB,CAAI,EAAE,QAAQ,WAAW,EAAE,QAAQ,SACjC,EAAE,eAAe,GACjB,IAAU;EAEd;EACA,WAAW,EACT,0KACF;YAbF;GAeE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,GAAD;MAAO,MAAM,EAAK;MAAM,OAAO,EAAK;MAAO,MAAM;KAAK,CAAA,GACtD,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,MAAD;OAAI,WAAU;iBAAsD,EAAK;MAAS,CAAA,GAClF,kBAAC,OAAD;OAAK,WAAU;iBACb,kBAAC,GAAD;QAAO,SAAQ;QAAY,WAAU;kBAArC,CACE,kBAAC,GAAD;SAAW,WAAU;SAAU,eAAY;QAAQ,CAAA,GAClD,EAAa,EAAK,MACd;;MACJ,CAAA,CACF;OACF;QACL,kBAAC,GAAD,EAAa,QAAQ,EAAK,OAAS,CAAA,CAChC;;GAEL,kBAAC,OAAD;IAAK,WAAU;cAAf;KACG,EAAK,YACJ,kBAAC,QAAD;MAAM,WAAU;gBAAhB;OACE,kBAAC,GAAD;QAAO,WAAU;QAAc,eAAY;OAAQ,CAAA;OAAC;OAAE,EAAK;MACvD;;KAEP,EAAK,UACJ,kBAAC,QAAD;MAAM,WAAU;gBAAhB;OACE,kBAAC,GAAD;QAAc,WAAU;QAAc,eAAY;OAAQ,CAAA;OAAC;OAAE,EAAK;MAC9D;;KAEP,EAAK,aACJ,kBAAC,QAAD;MAAM,WAAU;gBAAhB;OACE,kBAAC,GAAD;QAAQ,WAAU;QAAuB,eAAY;OAAQ,CAAA;OAAC;OAAE,EAAK;MACjE;;IAEL;;GAEJ,EAAK,KAAK,SAAS,KAClB,kBAAC,OAAD;IAAK,WAAU;cACZ,EAAK,KAAK,MAAM,GAAG,CAAC,EAAE,KAAK,MAC1B,kBAAC,QAAD;KAEE,WAAU;eAET;IACG,GAJC,CAID,CACP;GACE,CAAA;GAGN,MAAU,KAAA,KACT,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,GAAD;KAAO,WAAU;KAAc,eAAY;IAAQ,CAAA,GAClD,CACE;;EAEE;;AAEf"}
@@ -1 +1 @@
1
- {"version":3,"file":"DashboardPage.d.ts","sourceRoot":"","sources":["../../../src/atheletebridge/pages/DashboardPage.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAsDH,wBAAgB,aAAa,gCAgS5B"}
1
+ {"version":3,"file":"DashboardPage.d.ts","sourceRoot":"","sources":["../../../src/atheletebridge/pages/DashboardPage.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAsDH,wBAAgB,aAAa,gCAyT5B"}
@@ -65,8 +65,8 @@ function P() {
65
65
  gradientTitle: !0,
66
66
  children: /* @__PURE__ */ O(l, { label: y("atheletebridge.pages.dashboard.loading", "Loading your sporting operation…") })
67
67
  }) : /* @__PURE__ */ k(n, {
68
- title: `Welcome back, ${z}`,
69
- description: "Your teams, fixtures, training and coaching — one connected record.",
68
+ title: `${y("atheletebridge.pages.dashboard.welcomeBack", "Welcome back")}, ${z}`,
69
+ description: y("atheletebridge.pages.dashboard.description", "Your teams, fixtures, training and coaching — one connected record."),
70
70
  hero: !0,
71
71
  gradientTitle: !0,
72
72
  actions: /* @__PURE__ */ k("div", {
@@ -75,18 +75,26 @@ function P() {
75
75
  type: "button",
76
76
  onClick: () => E("/teams/new"),
77
77
  className: M,
78
- children: [/* @__PURE__ */ O(S, { className: "h-4 w-4" }), " New team"]
78
+ children: [
79
+ /* @__PURE__ */ O(S, { className: "h-4 w-4" }),
80
+ " ",
81
+ y("atheletebridge.pages.dashboard.newTeam", "New team")
82
+ ]
79
83
  }), /* @__PURE__ */ k("button", {
80
84
  type: "button",
81
85
  onClick: () => E("/performance"),
82
86
  className: M,
83
- children: [/* @__PURE__ */ O(w, { className: "h-4 w-4" }), " Track performance"]
87
+ children: [
88
+ /* @__PURE__ */ O(w, { className: "h-4 w-4" }),
89
+ " ",
90
+ y("atheletebridge.pages.dashboard.trackPerformance", "Track performance")
91
+ ]
84
92
  })]
85
93
  }),
86
94
  children: [
87
95
  /* @__PURE__ */ O(j, {
88
96
  className: "mb-6",
89
- children: "AthleteBridge is the operating system for sports, coaching and training. From here you can assemble your roster, schedule fixtures, build training programs, run coaching sessions and track athlete performance — all reading and writing the same workspace-scoped source of truth."
97
+ children: y("atheletebridge.pages.dashboard.purpose", "AthleteBridge is the operating system for sports, coaching and training. From here you can assemble your roster, schedule fixtures, build training programs, run coaching sessions and track athlete performance — all reading and writing the same workspace-scoped source of truth.")
90
98
  }),
91
99
  /* @__PURE__ */ k("div", {
92
100
  "data-tour": "dashboard-kpis",
@@ -95,26 +103,26 @@ function P() {
95
103
  /* @__PURE__ */ O(i, {
96
104
  icon: /* @__PURE__ */ O(D, { className: "h-5 w-5" }),
97
105
  value: B.length,
98
- label: "Teams",
106
+ label: y("atheletebridge.pages.dashboard.kpi.teams", "Teams"),
99
107
  tone: "accent",
100
108
  featured: !0
101
109
  }),
102
110
  /* @__PURE__ */ O(i, {
103
111
  icon: /* @__PURE__ */ O(v, { className: "h-5 w-5" }),
104
112
  value: V.length,
105
- label: "Fixtures",
113
+ label: y("atheletebridge.pages.dashboard.kpi.fixtures", "Fixtures"),
106
114
  tone: "accent"
107
115
  }),
108
116
  /* @__PURE__ */ O(i, {
109
117
  icon: /* @__PURE__ */ O(x, { className: "h-5 w-5" }),
110
118
  value: `${q}/${H.length}`,
111
- label: "Programs published",
119
+ label: y("atheletebridge.pages.dashboard.kpi.programsPublished", "Programs published"),
112
120
  tone: "accent"
113
121
  }),
114
122
  /* @__PURE__ */ O(i, {
115
123
  icon: /* @__PURE__ */ O(b, { className: "h-5 w-5" }),
116
124
  value: U.length,
117
- label: "Sessions",
125
+ label: y("atheletebridge.pages.dashboard.kpi.sessions", "Sessions"),
118
126
  tone: "accent"
119
127
  })
120
128
  ]
@@ -148,7 +156,11 @@ function P() {
148
156
  type: "button",
149
157
  onClick: () => E("/fixtures/new"),
150
158
  className: M,
151
- children: [/* @__PURE__ */ O(S, { className: "h-4 w-4" }), " Schedule fixture"]
159
+ children: [
160
+ /* @__PURE__ */ O(S, { className: "h-4 w-4" }),
161
+ " ",
162
+ y("atheletebridge.pages.dashboard.scheduleFixture", "Schedule fixture")
163
+ ]
152
164
  })
153
165
  }) : /* @__PURE__ */ O(A, {
154
166
  treatment: "glass",
@@ -164,7 +176,7 @@ function P() {
164
176
  className: "mb-4 flex items-center min-h-[1.75rem]",
165
177
  children: /* @__PURE__ */ O("h2", {
166
178
  className: "text-lg font-semibold text-text-primary",
167
- children: "Recent activity"
179
+ children: y("atheletebridge.pages.dashboard.recentActivity", "Recent activity")
168
180
  })
169
181
  }), Y.length === 0 ? /* @__PURE__ */ O(A, {
170
182
  treatment: "metric",
@@ -172,8 +184,8 @@ function P() {
172
184
  children: /* @__PURE__ */ O(c, {
173
185
  illustration: "empty-data",
174
186
  icon: /* @__PURE__ */ O(w, { className: "h-10 w-10" }),
175
- title: "No recent activity",
176
- description: "Create teams, publish programs or record results — the latest moves land here."
187
+ title: y("atheletebridge.pages.dashboard.noRecentActivity", "No recent activity"),
188
+ description: y("atheletebridge.pages.dashboard.noRecentActivityHint", "Create teams, publish programs or record results — the latest moves land here.")
177
189
  })
178
190
  }) : /* @__PURE__ */ O(A, {
179
191
  treatment: "metric",
@@ -189,23 +201,31 @@ function P() {
189
201
  className: "mb-4 flex items-center justify-between",
190
202
  children: [/* @__PURE__ */ O("h2", {
191
203
  className: "text-lg font-semibold text-text-primary",
192
- children: "Upcoming sessions"
204
+ children: y("atheletebridge.pages.dashboard.upcomingSessions", "Upcoming sessions")
193
205
  }), /* @__PURE__ */ k("button", {
194
206
  type: "button",
195
207
  onClick: () => E("/sessions"),
196
208
  className: "flex items-center gap-1 text-sm font-medium text-text-link hover:underline",
197
- children: ["View all ", /* @__PURE__ */ O(_, { className: "h-3.5 w-3.5" })]
209
+ children: [
210
+ y("atheletebridge.pages.dashboard.viewAll", "View all"),
211
+ " ",
212
+ /* @__PURE__ */ O(_, { className: "h-3.5 w-3.5" })
213
+ ]
198
214
  })]
199
215
  }), G.length === 0 ? /* @__PURE__ */ O(c, {
200
216
  illustration: "empty-calendar",
201
217
  icon: /* @__PURE__ */ O(b, { className: "h-10 w-10" }),
202
- title: "No upcoming sessions",
203
- description: "Book a coaching session with an athlete to get started.",
218
+ title: y("atheletebridge.pages.dashboard.noSessions", "No upcoming sessions"),
219
+ description: y("atheletebridge.pages.dashboard.noSessionsHint", "Book a coaching session with an athlete to get started."),
204
220
  action: /* @__PURE__ */ k("button", {
205
221
  type: "button",
206
222
  onClick: () => E("/sessions/new"),
207
223
  className: M,
208
- children: [/* @__PURE__ */ O(S, { className: "h-4 w-4" }), " Book session"]
224
+ children: [
225
+ /* @__PURE__ */ O(S, { className: "h-4 w-4" }),
226
+ " ",
227
+ y("atheletebridge.pages.dashboard.bookSession", "Book session")
228
+ ]
209
229
  })
210
230
  }) : /* @__PURE__ */ O("div", {
211
231
  className: "grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3",
@@ -221,30 +241,42 @@ function P() {
221
241
  className: "mb-4 flex items-center justify-between",
222
242
  children: [/* @__PURE__ */ O("h2", {
223
243
  className: "text-lg font-semibold text-text-primary",
224
- children: "Your teams"
244
+ children: y("atheletebridge.pages.dashboard.yourTeams", "Your teams")
225
245
  }), /* @__PURE__ */ k("button", {
226
246
  type: "button",
227
247
  onClick: () => E("/teams"),
228
248
  className: "flex items-center gap-1 text-sm font-medium text-text-link hover:underline",
229
- children: ["View all ", /* @__PURE__ */ O(_, { className: "h-3.5 w-3.5" })]
249
+ children: [
250
+ y("atheletebridge.pages.dashboard.viewAll", "View all"),
251
+ " ",
252
+ /* @__PURE__ */ O(_, { className: "h-3.5 w-3.5" })
253
+ ]
230
254
  })]
231
255
  }), K.length === 0 ? /* @__PURE__ */ O(c, {
232
256
  illustration: "empty-data",
233
257
  icon: /* @__PURE__ */ O(T, { className: "h-10 w-10" }),
234
- title: "No teams yet",
235
- description: "Set up AthleteBridge in about a minute — pick your sport, create your first team and add yourself to the roster.",
258
+ title: y("atheletebridge.pages.dashboard.noTeams", "No teams yet"),
259
+ description: y("atheletebridge.pages.dashboard.noTeamsHint", "Set up AthleteBridge in about a minute — pick your sport, create your first team and add yourself to the roster."),
236
260
  action: /* @__PURE__ */ k("div", {
237
261
  className: "flex flex-wrap items-center justify-center gap-2",
238
262
  children: [/* @__PURE__ */ k("button", {
239
263
  type: "button",
240
264
  onClick: () => E("/onboarding"),
241
265
  className: M,
242
- children: [/* @__PURE__ */ O(C, { className: "h-4 w-4" }), " Get started"]
266
+ children: [
267
+ /* @__PURE__ */ O(C, { className: "h-4 w-4" }),
268
+ " ",
269
+ y("atheletebridge.pages.dashboard.getStarted", "Get started")
270
+ ]
243
271
  }), /* @__PURE__ */ k("button", {
244
272
  type: "button",
245
273
  onClick: () => E("/teams/new"),
246
274
  className: "inline-flex items-center gap-1.5 rounded-lg border border-border-seam px-4 py-2 text-sm font-medium text-text-primary transition-colors hover:bg-bg-sunken",
247
- children: [/* @__PURE__ */ O(S, { className: "h-4 w-4" }), " Create team"]
275
+ children: [
276
+ /* @__PURE__ */ O(S, { className: "h-4 w-4" }),
277
+ " ",
278
+ y("atheletebridge.pages.dashboard.createTeam", "Create team")
279
+ ]
248
280
  })]
249
281
  })
250
282
  }) : /* @__PURE__ */ O("div", {
@@ -1 +1 @@
1
- {"version":3,"file":"DashboardPage.js","names":[],"sources":["../../../src/atheletebridge/pages/DashboardPage.tsx"],"sourcesContent":["/**\n * Dashboard / Overview\n * @module atheletebridge/pages\n *\n * The AthleteBridge landing page: a coach command-center that reads live counts\n * and recent items across teams, fixtures, programs and sessions from the real\n * `ath*` API. Elevated to the concept bar: glass teal-stat KPI tiles, a\n * crest-vs-crest upcoming-fixtures rail, and a real (derived) recent-activity\n * timeline — every item mapped to a real record, nothing fabricated.\n */\n\nimport { useMemo } from 'react';\nimport {\n Users,\n CalendarDays,\n Dumbbell,\n ClipboardCheck,\n ArrowRight,\n Plus,\n Rocket,\n Trophy,\n TrendingUp,\n UserPlus,\n CheckCircle2,\n type LucideIcon,\n} from 'lucide-react';\nimport { GlassCard, PagePurpose } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../components/PageLayout';\nimport { MetricsCard } from '../components/MetricsCard';\nimport { TeamCard } from '../components/TeamCard';\nimport { MatchupRow } from '../components/MatchupRow';\nimport { SessionCard } from '../components/SessionCard';\nimport { EmptyState } from '../components/EmptyState';\nimport { LoadingState } from '../components/LoadingState';\nimport { Timeline, type TimelineItem, type TimelineTone } from '../components/viz';\nimport { useAthleteBridge } from '../context/AthleteBridgeContext';\nimport {\n useTeams,\n useFixtures,\n usePrograms,\n useSessions,\n useRecentActivity,\n type ActivityType,\n} from '../hooks/useAthleteBridgeApi';\nimport { timeAgo } from '../utils/timeAgo';\nimport { useAbTranslate } from '../i18n';\n\n/**\n * Brand gradient CTA — orange action-primary blended toward accent-purple, the\n * same brand gradient the hero title uses. Token-only (no raw colors).\n */\nconst GRADIENT_CTA =\n 'inline-flex items-center gap-1.5 rounded-lg px-4 py-2 text-sm font-semibold text-action-primary-text shadow-elevation-1 transition-[filter,box-shadow] hover:shadow-elevation-2 hover:brightness-110 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)] bg-[linear-gradient(120deg,var(--color-action-primary-bg),color-mix(in_oklab,var(--color-action-primary-bg)_62%,var(--color-accent-purple)),var(--color-action-primary-bg))]';\n\n/** Per-activity-type node styling for the recent-activity timeline. */\nconst ACTIVITY_VISUAL: Record<ActivityType, { tone: TimelineTone; Icon: LucideIcon }> = {\n 'program-published': { tone: 'success', Icon: ClipboardCheck },\n 'member-added': { tone: 'accent', Icon: UserPlus },\n 'fixture-updated': { tone: 'warning', Icon: CalendarDays },\n 'session-completed': { tone: 'info', Icon: CheckCircle2 },\n 'team-created': { tone: 'accent', Icon: Users },\n};\n\nexport function DashboardPage() {\n const tr = useAbTranslate();\n const { navigateTo, currentUser } = useAthleteBridge();\n\n const teams = useTeams({ pagination: { limit: 50 } });\n const fixtures = useFixtures({ pagination: { limit: 50 } });\n const programs = usePrograms({ pagination: { limit: 50 } });\n const sessions = useSessions({ pagination: { limit: 50 } });\n\n const firstName = currentUser?.firstName ?? currentUser?.name ?? 'coach';\n\n const teamItems = useMemo(() => teams.data?.items ?? [], [teams.data]);\n const fixtureItems = useMemo(() => fixtures.data?.items ?? [], [fixtures.data]);\n const programItems = useMemo(() => programs.data?.items ?? [], [programs.data]);\n const sessionItems = useMemo(() => sessions.data?.items ?? [], [sessions.data]);\n\n const upcomingFixtures = useMemo(\n () =>\n [...fixtureItems]\n .filter((f) => f.status === 'SCHEDULED' || f.status === 'LIVE')\n .sort((a, b) => new Date(a.scheduledAt).getTime() - new Date(b.scheduledAt).getTime())\n .slice(0, 5),\n [fixtureItems]\n );\n\n const upcomingSessions = useMemo(\n () =>\n [...sessionItems]\n .filter((s) => s.status === 'REQUESTED' || s.status === 'CONFIRMED')\n .sort((a, b) => new Date(a.scheduledAt).getTime() - new Date(b.scheduledAt).getTime())\n .slice(0, 3),\n [sessionItems]\n );\n\n const recentTeams = useMemo(() => teamItems.slice(0, 6), [teamItems]);\n\n const publishedPrograms = programItems.filter((p) => p.status === 'PUBLISHED').length;\n\n const activity = useRecentActivity({\n teams: teamItems,\n fixtures: fixtureItems,\n sessions: sessionItems,\n programs: programItems,\n limit: 6,\n });\n\n const activityTimeline = useMemo<TimelineItem[]>(\n () =>\n activity.map((item) => {\n const visual = ACTIVITY_VISUAL[item.type];\n const Icon = visual.Icon;\n return {\n id: item.id,\n tone: visual.tone,\n icon: <Icon className=\"h-3 w-3\" aria-hidden=\"true\" />,\n title: item.title,\n meta: item.subtitle,\n time: timeAgo(item.at),\n };\n }),\n [activity]\n );\n\n const isLoading =\n teams.isLoading || fixtures.isLoading || programs.isLoading || sessions.isLoading;\n\n if (isLoading) {\n return (\n <PageLayout title=\"AthleteBridge\" hero gradientTitle>\n <LoadingState\n label={tr('atheletebridge.pages.dashboard.loading', 'Loading your sporting operation…')}\n />\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title={`Welcome back, ${firstName}`}\n description=\"Your teams, fixtures, training and coaching — one connected record.\"\n hero\n gradientTitle\n actions={\n <div className=\"flex flex-wrap items-center gap-2\">\n <button type=\"button\" onClick={() => navigateTo('/teams/new')} className={GRADIENT_CTA}>\n <Plus className=\"h-4 w-4\" /> New team\n </button>\n <button type=\"button\" onClick={() => navigateTo('/performance')} className={GRADIENT_CTA}>\n <TrendingUp className=\"h-4 w-4\" /> Track performance\n </button>\n </div>\n }\n >\n <PagePurpose className=\"mb-6\">\n AthleteBridge is the operating system for sports, coaching and training. From here you can\n assemble your roster, schedule fixtures, build training programs, run coaching sessions and\n track athlete performance — all reading and writing the same workspace-scoped source of\n truth.\n </PagePurpose>\n\n {/* KPIs — glass tiles with teal stat values (2-col mobile → 4-col lg) */}\n <div data-tour=\"dashboard-kpis\" className=\"mb-8 grid grid-cols-2 gap-4 lg:grid-cols-4\">\n <MetricsCard\n icon={<Users className=\"h-5 w-5\" />}\n value={teamItems.length}\n label=\"Teams\"\n tone=\"accent\"\n featured\n />\n <MetricsCard\n icon={<CalendarDays className=\"h-5 w-5\" />}\n value={fixtureItems.length}\n label=\"Fixtures\"\n tone=\"accent\"\n />\n <MetricsCard\n icon={<Dumbbell className=\"h-5 w-5\" />}\n value={`${publishedPrograms}/${programItems.length}`}\n label=\"Programs published\"\n tone=\"accent\"\n />\n <MetricsCard\n icon={<ClipboardCheck className=\"h-5 w-5\" />}\n value={sessionItems.length}\n label=\"Sessions\"\n tone=\"accent\"\n />\n </div>\n\n {/* Upcoming fixtures (matchup rail) + Recent activity (timeline) */}\n <div className=\"mb-8 grid grid-cols-1 gap-6 lg:grid-cols-3\">\n {/* Fixtures — spans two columns on large screens */}\n <section data-tour=\"dashboard-fixtures\" className=\"lg:col-span-2\">\n <div className=\"mb-4 flex items-center justify-between\">\n <h2 className=\"text-lg font-semibold text-text-primary\">\n {tr('atheletebridge.pages.dashboard.upcomingFixtures', 'Upcoming fixtures')}\n </h2>\n <button\n type=\"button\"\n onClick={() => navigateTo('/fixtures')}\n className=\"flex items-center gap-1 text-sm font-medium text-text-link hover:underline\"\n >\n {tr('atheletebridge.pages.dashboard.viewAllFixtures', 'View all fixtures')}{' '}\n <ArrowRight className=\"h-3.5 w-3.5\" />\n </button>\n </div>\n {upcomingFixtures.length === 0 ? (\n <EmptyState\n illustration=\"empty-calendar\"\n icon={<CalendarDays className=\"h-10 w-10\" />}\n title={tr('atheletebridge.pages.dashboard.noFixtures', 'No upcoming fixtures')}\n description={tr(\n 'atheletebridge.pages.dashboard.noFixturesHint',\n 'Schedule a match to start tracking results and standings.'\n )}\n action={\n <button\n type=\"button\"\n onClick={() => navigateTo('/fixtures/new')}\n className={GRADIENT_CTA}\n >\n <Plus className=\"h-4 w-4\" /> Schedule fixture\n </button>\n }\n />\n ) : (\n <GlassCard treatment=\"glass\" className=\"divide-y divide-border-seam px-4 py-1 sm:px-5\">\n {upcomingFixtures.map((fixture) => (\n <MatchupRow\n key={fixture.id}\n fixture={fixture}\n onClick={() => navigateTo(`/fixtures/${fixture.id}`)}\n />\n ))}\n </GlassCard>\n )}\n </section>\n\n {/* Recent activity */}\n <section data-tour=\"dashboard-activity\">\n <div className=\"mb-4 flex items-center min-h-[1.75rem]\">\n <h2 className=\"text-lg font-semibold text-text-primary\">Recent activity</h2>\n </div>\n {activityTimeline.length === 0 ? (\n <GlassCard treatment=\"metric\" className=\"p-6\">\n <EmptyState\n illustration=\"empty-data\"\n icon={<TrendingUp className=\"h-10 w-10\" />}\n title=\"No recent activity\"\n description=\"Create teams, publish programs or record results — the latest moves land here.\"\n />\n </GlassCard>\n ) : (\n <GlassCard treatment=\"metric\" className=\"p-5\">\n <Timeline items={activityTimeline} />\n </GlassCard>\n )}\n </section>\n </div>\n\n {/* Upcoming sessions */}\n <section data-tour=\"dashboard-sessions\" className=\"mb-8\">\n <div className=\"mb-4 flex items-center justify-between\">\n <h2 className=\"text-lg font-semibold text-text-primary\">Upcoming sessions</h2>\n <button\n type=\"button\"\n onClick={() => navigateTo('/sessions')}\n className=\"flex items-center gap-1 text-sm font-medium text-text-link hover:underline\"\n >\n View all <ArrowRight className=\"h-3.5 w-3.5\" />\n </button>\n </div>\n {upcomingSessions.length === 0 ? (\n <EmptyState\n illustration=\"empty-calendar\"\n icon={<ClipboardCheck className=\"h-10 w-10\" />}\n title=\"No upcoming sessions\"\n description=\"Book a coaching session with an athlete to get started.\"\n action={\n <button\n type=\"button\"\n onClick={() => navigateTo('/sessions/new')}\n className={GRADIENT_CTA}\n >\n <Plus className=\"h-4 w-4\" /> Book session\n </button>\n }\n />\n ) : (\n <div className=\"grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3\">\n {upcomingSessions.map((session) => (\n <SessionCard\n key={session.id}\n session={session}\n onClick={() => navigateTo(`/sessions/${session.id}`)}\n />\n ))}\n </div>\n )}\n </section>\n\n {/* Teams */}\n <section data-tour=\"dashboard-teams\">\n <div className=\"mb-4 flex items-center justify-between\">\n <h2 className=\"text-lg font-semibold text-text-primary\">Your teams</h2>\n <button\n type=\"button\"\n onClick={() => navigateTo('/teams')}\n className=\"flex items-center gap-1 text-sm font-medium text-text-link hover:underline\"\n >\n View all <ArrowRight className=\"h-3.5 w-3.5\" />\n </button>\n </div>\n {recentTeams.length === 0 ? (\n <EmptyState\n illustration=\"empty-data\"\n icon={<Trophy className=\"h-10 w-10\" />}\n title=\"No teams yet\"\n description=\"Set up AthleteBridge in about a minute — pick your sport, create your first team and add yourself to the roster.\"\n action={\n <div className=\"flex flex-wrap items-center justify-center gap-2\">\n <button\n type=\"button\"\n onClick={() => navigateTo('/onboarding')}\n className={GRADIENT_CTA}\n >\n <Rocket className=\"h-4 w-4\" /> Get started\n </button>\n <button\n type=\"button\"\n onClick={() => navigateTo('/teams/new')}\n className=\"inline-flex items-center gap-1.5 rounded-lg border border-border-seam px-4 py-2 text-sm font-medium text-text-primary transition-colors hover:bg-bg-sunken\"\n >\n <Plus className=\"h-4 w-4\" /> Create team\n </button>\n </div>\n }\n />\n ) : (\n <div className=\"grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3\">\n {recentTeams.map((team) => (\n <TeamCard key={team.id} team={team} onClick={() => navigateTo(`/teams/${team.id}`)} />\n ))}\n </div>\n )}\n </section>\n </PageLayout>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAmDA,IAAM,IACJ,kdAGI,IAAkF;CACtF,qBAAqB;EAAE,MAAM;EAAW,MAAM;CAAe;CAC7D,gBAAgB;EAAE,MAAM;EAAU,MAAM;CAAS;CACjD,mBAAmB;EAAE,MAAM;EAAW,MAAM;CAAa;CACzD,qBAAqB;EAAE,MAAM;EAAQ,MAAM;CAAa;CACxD,gBAAgB;EAAE,MAAM;EAAU,MAAM;CAAM;AAChD;AAEA,SAAgB,IAAgB;CAC9B,IAAM,IAAK,EAAe,GACpB,EAAE,eAAY,mBAAgB,EAAiB,GAE/C,IAAQ,EAAS,EAAE,YAAY,EAAE,OAAO,GAAG,EAAE,CAAC,GAC9C,IAAW,EAAY,EAAE,YAAY,EAAE,OAAO,GAAG,EAAE,CAAC,GACpD,IAAW,EAAY,EAAE,YAAY,EAAE,OAAO,GAAG,EAAE,CAAC,GACpD,IAAW,EAAY,EAAE,YAAY,EAAE,OAAO,GAAG,EAAE,CAAC,GAEpD,IAAY,GAAa,aAAa,GAAa,QAAQ,SAE3D,IAAY,QAAc,EAAM,MAAM,SAAS,CAAC,GAAG,CAAC,EAAM,IAAI,CAAC,GAC/D,IAAe,QAAc,EAAS,MAAM,SAAS,CAAC,GAAG,CAAC,EAAS,IAAI,CAAC,GACxE,IAAe,QAAc,EAAS,MAAM,SAAS,CAAC,GAAG,CAAC,EAAS,IAAI,CAAC,GACxE,IAAe,QAAc,EAAS,MAAM,SAAS,CAAC,GAAG,CAAC,EAAS,IAAI,CAAC,GAExE,IAAmB,QAErB,CAAC,GAAG,CAAY,EACb,QAAQ,MAAM,EAAE,WAAW,eAAe,EAAE,WAAW,MAAM,EAC7D,MAAM,GAAG,MAAM,IAAI,KAAK,EAAE,WAAW,EAAE,QAAQ,IAAI,IAAI,KAAK,EAAE,WAAW,EAAE,QAAQ,CAAC,EACpF,MAAM,GAAG,CAAC,GACf,CAAC,CAAY,CACf,GAEM,IAAmB,QAErB,CAAC,GAAG,CAAY,EACb,QAAQ,MAAM,EAAE,WAAW,eAAe,EAAE,WAAW,WAAW,EAClE,MAAM,GAAG,MAAM,IAAI,KAAK,EAAE,WAAW,EAAE,QAAQ,IAAI,IAAI,KAAK,EAAE,WAAW,EAAE,QAAQ,CAAC,EACpF,MAAM,GAAG,CAAC,GACf,CAAC,CAAY,CACf,GAEM,IAAc,QAAc,EAAU,MAAM,GAAG,CAAC,GAAG,CAAC,CAAS,CAAC,GAE9D,IAAoB,EAAa,QAAQ,MAAM,EAAE,WAAW,WAAW,EAAE,QAEzE,IAAW,EAAkB;EACjC,OAAO;EACP,UAAU;EACV,UAAU;EACV,UAAU;EACV,OAAO;CACT,CAAC,GAEK,IAAmB,QAErB,EAAS,KAAK,MAAS;EACrB,IAAM,IAAS,EAAgB,EAAK,OAC9B,IAAO,EAAO;EACpB,OAAO;GACL,IAAI,EAAK;GACT,MAAM,EAAO;GACb,MAAM,kBAAC,GAAD;IAAM,WAAU;IAAU,eAAY;GAAQ,CAAA;GACpD,OAAO,EAAK;GACZ,MAAM,EAAK;GACX,MAAM,EAAQ,EAAK,EAAE;EACvB;CACF,CAAC,GACH,CAAC,CAAQ,CACX;CAeA,OAZE,EAAM,aAAa,EAAS,aAAa,EAAS,aAAa,EAAS,YAItE,kBAAC,GAAD;EAAY,OAAM;EAAgB,MAAA;EAAK,eAAA;YACrC,kBAAC,GAAD,EACE,OAAO,EAAG,0CAA0C,kCAAkC,EACvF,CAAA;CACS,CAAA,IAKd,kBAAC,GAAD;EACE,OAAO,iBAAiB;EACxB,aAAY;EACZ,MAAA;EACA,eAAA;EACA,SACE,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,UAAD;IAAQ,MAAK;IAAS,eAAe,EAAW,YAAY;IAAG,WAAW;cAA1E,CACE,kBAAC,GAAD,EAAM,WAAU,UAAW,CAAA,GAAC,WACtB;OACR,kBAAC,UAAD;IAAQ,MAAK;IAAS,eAAe,EAAW,cAAc;IAAG,WAAW;cAA5E,CACE,kBAAC,GAAD,EAAY,WAAU,UAAW,CAAA,GAAC,oBAC5B;KACL;;YAbT;GAgBE,kBAAC,GAAD;IAAa,WAAU;cAAO;GAKjB,CAAA;GAGb,kBAAC,OAAD;IAAK,aAAU;IAAiB,WAAU;cAA1C;KACE,kBAAC,GAAD;MACE,MAAM,kBAAC,GAAD,EAAO,WAAU,UAAW,CAAA;MAClC,OAAO,EAAU;MACjB,OAAM;MACN,MAAK;MACL,UAAA;KACD,CAAA;KACD,kBAAC,GAAD;MACE,MAAM,kBAAC,GAAD,EAAc,WAAU,UAAW,CAAA;MACzC,OAAO,EAAa;MACpB,OAAM;MACN,MAAK;KACN,CAAA;KACD,kBAAC,GAAD;MACE,MAAM,kBAAC,GAAD,EAAU,WAAU,UAAW,CAAA;MACrC,OAAO,GAAG,EAAkB,GAAG,EAAa;MAC5C,OAAM;MACN,MAAK;KACN,CAAA;KACD,kBAAC,GAAD;MACE,MAAM,kBAAC,GAAD,EAAgB,WAAU,UAAW,CAAA;MAC3C,OAAO,EAAa;MACpB,OAAM;MACN,MAAK;KACN,CAAA;IACE;;GAGL,kBAAC,OAAD;IAAK,WAAU;cAAf,CAEE,kBAAC,WAAD;KAAS,aAAU;KAAqB,WAAU;eAAlD,CACE,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,MAAD;OAAI,WAAU;iBACX,EAAG,mDAAmD,mBAAmB;MACxE,CAAA,GACJ,kBAAC,UAAD;OACE,MAAK;OACL,eAAe,EAAW,WAAW;OACrC,WAAU;iBAHZ;QAKG,EAAG,kDAAkD,mBAAmB;QAAG;QAC5E,kBAAC,GAAD,EAAY,WAAU,cAAe,CAAA;OAC/B;QACL;SACJ,EAAiB,WAAW,IAC3B,kBAAC,GAAD;MACE,cAAa;MACb,MAAM,kBAAC,GAAD,EAAc,WAAU,YAAa,CAAA;MAC3C,OAAO,EAAG,6CAA6C,sBAAsB;MAC7E,aAAa,EACX,iDACA,2DACF;MACA,QACE,kBAAC,UAAD;OACE,MAAK;OACL,eAAe,EAAW,eAAe;OACzC,WAAW;iBAHb,CAKE,kBAAC,GAAD,EAAM,WAAU,UAAW,CAAA,GAAC,mBACtB;;KAEX,CAAA,IAED,kBAAC,GAAD;MAAW,WAAU;MAAQ,WAAU;gBACpC,EAAiB,KAAK,MACrB,kBAAC,GAAD;OAEW;OACT,eAAe,EAAW,aAAa,EAAQ,IAAI;MACpD,GAHM,EAAQ,EAGd,CACF;KACQ,CAAA,CAEN;QAGT,kBAAC,WAAD;KAAS,aAAU;eAAnB,CACE,kBAAC,OAAD;MAAK,WAAU;gBACb,kBAAC,MAAD;OAAI,WAAU;iBAA0C;MAAmB,CAAA;KACxE,CAAA,GACJ,EAAiB,WAAW,IAC3B,kBAAC,GAAD;MAAW,WAAU;MAAS,WAAU;gBACtC,kBAAC,GAAD;OACE,cAAa;OACb,MAAM,kBAAC,GAAD,EAAY,WAAU,YAAa,CAAA;OACzC,OAAM;OACN,aAAY;MACb,CAAA;KACQ,CAAA,IAEX,kBAAC,GAAD;MAAW,WAAU;MAAS,WAAU;gBACtC,kBAAC,GAAD,EAAU,OAAO,EAAmB,CAAA;KAC3B,CAAA,CAEN;MACN;;GAGL,kBAAC,WAAD;IAAS,aAAU;IAAqB,WAAU;cAAlD,CACE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,MAAD;MAAI,WAAU;gBAA0C;KAAqB,CAAA,GAC7E,kBAAC,UAAD;MACE,MAAK;MACL,eAAe,EAAW,WAAW;MACrC,WAAU;gBAHZ,CAIC,aACU,kBAAC,GAAD,EAAY,WAAU,cAAe,CAAA,CACxC;OACL;QACJ,EAAiB,WAAW,IAC3B,kBAAC,GAAD;KACE,cAAa;KACb,MAAM,kBAAC,GAAD,EAAgB,WAAU,YAAa,CAAA;KAC7C,OAAM;KACN,aAAY;KACZ,QACE,kBAAC,UAAD;MACE,MAAK;MACL,eAAe,EAAW,eAAe;MACzC,WAAW;gBAHb,CAKE,kBAAC,GAAD,EAAM,WAAU,UAAW,CAAA,GAAC,eACtB;;IAEX,CAAA,IAED,kBAAC,OAAD;KAAK,WAAU;eACZ,EAAiB,KAAK,MACrB,kBAAC,GAAD;MAEW;MACT,eAAe,EAAW,aAAa,EAAQ,IAAI;KACpD,GAHM,EAAQ,EAGd,CACF;IACE,CAAA,CAEA;;GAGT,kBAAC,WAAD;IAAS,aAAU;cAAnB,CACE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,MAAD;MAAI,WAAU;gBAA0C;KAAc,CAAA,GACtE,kBAAC,UAAD;MACE,MAAK;MACL,eAAe,EAAW,QAAQ;MAClC,WAAU;gBAHZ,CAIC,aACU,kBAAC,GAAD,EAAY,WAAU,cAAe,CAAA,CACxC;OACL;QACJ,EAAY,WAAW,IACtB,kBAAC,GAAD;KACE,cAAa;KACb,MAAM,kBAAC,GAAD,EAAQ,WAAU,YAAa,CAAA;KACrC,OAAM;KACN,aAAY;KACZ,QACE,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,UAAD;OACE,MAAK;OACL,eAAe,EAAW,aAAa;OACvC,WAAW;iBAHb,CAKE,kBAAC,GAAD,EAAQ,WAAU,UAAW,CAAA,GAAC,cACxB;UACR,kBAAC,UAAD;OACE,MAAK;OACL,eAAe,EAAW,YAAY;OACtC,WAAU;iBAHZ,CAKE,kBAAC,GAAD,EAAM,WAAU,UAAW,CAAA,GAAC,cACtB;QACL;;IAER,CAAA,IAED,kBAAC,OAAD;KAAK,WAAU;eACZ,EAAY,KAAK,MAChB,kBAAC,GAAD;MAA8B;MAAM,eAAe,EAAW,UAAU,EAAK,IAAI;KAAI,GAAtE,EAAK,EAAiE,CACtF;IACE,CAAA,CAEA;;EACC;;AAEhB"}
1
+ {"version":3,"file":"DashboardPage.js","names":[],"sources":["../../../src/atheletebridge/pages/DashboardPage.tsx"],"sourcesContent":["/**\n * Dashboard / Overview\n * @module atheletebridge/pages\n *\n * The AthleteBridge landing page: a coach command-center that reads live counts\n * and recent items across teams, fixtures, programs and sessions from the real\n * `ath*` API. Elevated to the concept bar: glass teal-stat KPI tiles, a\n * crest-vs-crest upcoming-fixtures rail, and a real (derived) recent-activity\n * timeline — every item mapped to a real record, nothing fabricated.\n */\n\nimport { useMemo } from 'react';\nimport {\n Users,\n CalendarDays,\n Dumbbell,\n ClipboardCheck,\n ArrowRight,\n Plus,\n Rocket,\n Trophy,\n TrendingUp,\n UserPlus,\n CheckCircle2,\n type LucideIcon,\n} from 'lucide-react';\nimport { GlassCard, PagePurpose } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../components/PageLayout';\nimport { MetricsCard } from '../components/MetricsCard';\nimport { TeamCard } from '../components/TeamCard';\nimport { MatchupRow } from '../components/MatchupRow';\nimport { SessionCard } from '../components/SessionCard';\nimport { EmptyState } from '../components/EmptyState';\nimport { LoadingState } from '../components/LoadingState';\nimport { Timeline, type TimelineItem, type TimelineTone } from '../components/viz';\nimport { useAthleteBridge } from '../context/AthleteBridgeContext';\nimport {\n useTeams,\n useFixtures,\n usePrograms,\n useSessions,\n useRecentActivity,\n type ActivityType,\n} from '../hooks/useAthleteBridgeApi';\nimport { timeAgo } from '../utils/timeAgo';\nimport { useAbTranslate } from '../i18n';\n\n/**\n * Brand gradient CTA — orange action-primary blended toward accent-purple, the\n * same brand gradient the hero title uses. Token-only (no raw colors).\n */\nconst GRADIENT_CTA =\n 'inline-flex items-center gap-1.5 rounded-lg px-4 py-2 text-sm font-semibold text-action-primary-text shadow-elevation-1 transition-[filter,box-shadow] hover:shadow-elevation-2 hover:brightness-110 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)] bg-[linear-gradient(120deg,var(--color-action-primary-bg),color-mix(in_oklab,var(--color-action-primary-bg)_62%,var(--color-accent-purple)),var(--color-action-primary-bg))]';\n\n/** Per-activity-type node styling for the recent-activity timeline. */\nconst ACTIVITY_VISUAL: Record<ActivityType, { tone: TimelineTone; Icon: LucideIcon }> = {\n 'program-published': { tone: 'success', Icon: ClipboardCheck },\n 'member-added': { tone: 'accent', Icon: UserPlus },\n 'fixture-updated': { tone: 'warning', Icon: CalendarDays },\n 'session-completed': { tone: 'info', Icon: CheckCircle2 },\n 'team-created': { tone: 'accent', Icon: Users },\n};\n\nexport function DashboardPage() {\n const tr = useAbTranslate();\n const { navigateTo, currentUser } = useAthleteBridge();\n\n const teams = useTeams({ pagination: { limit: 50 } });\n const fixtures = useFixtures({ pagination: { limit: 50 } });\n const programs = usePrograms({ pagination: { limit: 50 } });\n const sessions = useSessions({ pagination: { limit: 50 } });\n\n const firstName = currentUser?.firstName ?? currentUser?.name ?? 'coach';\n\n const teamItems = useMemo(() => teams.data?.items ?? [], [teams.data]);\n const fixtureItems = useMemo(() => fixtures.data?.items ?? [], [fixtures.data]);\n const programItems = useMemo(() => programs.data?.items ?? [], [programs.data]);\n const sessionItems = useMemo(() => sessions.data?.items ?? [], [sessions.data]);\n\n const upcomingFixtures = useMemo(\n () =>\n [...fixtureItems]\n .filter((f) => f.status === 'SCHEDULED' || f.status === 'LIVE')\n .sort((a, b) => new Date(a.scheduledAt).getTime() - new Date(b.scheduledAt).getTime())\n .slice(0, 5),\n [fixtureItems]\n );\n\n const upcomingSessions = useMemo(\n () =>\n [...sessionItems]\n .filter((s) => s.status === 'REQUESTED' || s.status === 'CONFIRMED')\n .sort((a, b) => new Date(a.scheduledAt).getTime() - new Date(b.scheduledAt).getTime())\n .slice(0, 3),\n [sessionItems]\n );\n\n const recentTeams = useMemo(() => teamItems.slice(0, 6), [teamItems]);\n\n const publishedPrograms = programItems.filter((p) => p.status === 'PUBLISHED').length;\n\n const activity = useRecentActivity({\n teams: teamItems,\n fixtures: fixtureItems,\n sessions: sessionItems,\n programs: programItems,\n limit: 6,\n });\n\n const activityTimeline = useMemo<TimelineItem[]>(\n () =>\n activity.map((item) => {\n const visual = ACTIVITY_VISUAL[item.type];\n const Icon = visual.Icon;\n return {\n id: item.id,\n tone: visual.tone,\n icon: <Icon className=\"h-3 w-3\" aria-hidden=\"true\" />,\n title: item.title,\n meta: item.subtitle,\n time: timeAgo(item.at),\n };\n }),\n [activity]\n );\n\n const isLoading =\n teams.isLoading || fixtures.isLoading || programs.isLoading || sessions.isLoading;\n\n if (isLoading) {\n return (\n <PageLayout title=\"AthleteBridge\" hero gradientTitle>\n <LoadingState\n label={tr('atheletebridge.pages.dashboard.loading', 'Loading your sporting operation…')}\n />\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title={`${tr('atheletebridge.pages.dashboard.welcomeBack', 'Welcome back')}, ${firstName}`}\n description={tr(\n 'atheletebridge.pages.dashboard.description',\n 'Your teams, fixtures, training and coaching — one connected record.'\n )}\n hero\n gradientTitle\n actions={\n <div className=\"flex flex-wrap items-center gap-2\">\n <button type=\"button\" onClick={() => navigateTo('/teams/new')} className={GRADIENT_CTA}>\n <Plus className=\"h-4 w-4\" /> {tr('atheletebridge.pages.dashboard.newTeam', 'New team')}\n </button>\n <button type=\"button\" onClick={() => navigateTo('/performance')} className={GRADIENT_CTA}>\n <TrendingUp className=\"h-4 w-4\" />{' '}\n {tr('atheletebridge.pages.dashboard.trackPerformance', 'Track performance')}\n </button>\n </div>\n }\n >\n <PagePurpose className=\"mb-6\">\n {tr(\n 'atheletebridge.pages.dashboard.purpose',\n 'AthleteBridge is the operating system for sports, coaching and training. From here you can assemble your roster, schedule fixtures, build training programs, run coaching sessions and track athlete performance — all reading and writing the same workspace-scoped source of truth.'\n )}\n </PagePurpose>\n\n {/* KPIs — glass tiles with teal stat values (2-col mobile → 4-col lg) */}\n <div data-tour=\"dashboard-kpis\" className=\"mb-8 grid grid-cols-2 gap-4 lg:grid-cols-4\">\n <MetricsCard\n icon={<Users className=\"h-5 w-5\" />}\n value={teamItems.length}\n label={tr('atheletebridge.pages.dashboard.kpi.teams', 'Teams')}\n tone=\"accent\"\n featured\n />\n <MetricsCard\n icon={<CalendarDays className=\"h-5 w-5\" />}\n value={fixtureItems.length}\n label={tr('atheletebridge.pages.dashboard.kpi.fixtures', 'Fixtures')}\n tone=\"accent\"\n />\n <MetricsCard\n icon={<Dumbbell className=\"h-5 w-5\" />}\n value={`${publishedPrograms}/${programItems.length}`}\n label={tr('atheletebridge.pages.dashboard.kpi.programsPublished', 'Programs published')}\n tone=\"accent\"\n />\n <MetricsCard\n icon={<ClipboardCheck className=\"h-5 w-5\" />}\n value={sessionItems.length}\n label={tr('atheletebridge.pages.dashboard.kpi.sessions', 'Sessions')}\n tone=\"accent\"\n />\n </div>\n\n {/* Upcoming fixtures (matchup rail) + Recent activity (timeline) */}\n <div className=\"mb-8 grid grid-cols-1 gap-6 lg:grid-cols-3\">\n {/* Fixtures — spans two columns on large screens */}\n <section data-tour=\"dashboard-fixtures\" className=\"lg:col-span-2\">\n <div className=\"mb-4 flex items-center justify-between\">\n <h2 className=\"text-lg font-semibold text-text-primary\">\n {tr('atheletebridge.pages.dashboard.upcomingFixtures', 'Upcoming fixtures')}\n </h2>\n <button\n type=\"button\"\n onClick={() => navigateTo('/fixtures')}\n className=\"flex items-center gap-1 text-sm font-medium text-text-link hover:underline\"\n >\n {tr('atheletebridge.pages.dashboard.viewAllFixtures', 'View all fixtures')}{' '}\n <ArrowRight className=\"h-3.5 w-3.5\" />\n </button>\n </div>\n {upcomingFixtures.length === 0 ? (\n <EmptyState\n illustration=\"empty-calendar\"\n icon={<CalendarDays className=\"h-10 w-10\" />}\n title={tr('atheletebridge.pages.dashboard.noFixtures', 'No upcoming fixtures')}\n description={tr(\n 'atheletebridge.pages.dashboard.noFixturesHint',\n 'Schedule a match to start tracking results and standings.'\n )}\n action={\n <button\n type=\"button\"\n onClick={() => navigateTo('/fixtures/new')}\n className={GRADIENT_CTA}\n >\n <Plus className=\"h-4 w-4\" />{' '}\n {tr('atheletebridge.pages.dashboard.scheduleFixture', 'Schedule fixture')}\n </button>\n }\n />\n ) : (\n <GlassCard treatment=\"glass\" className=\"divide-y divide-border-seam px-4 py-1 sm:px-5\">\n {upcomingFixtures.map((fixture) => (\n <MatchupRow\n key={fixture.id}\n fixture={fixture}\n onClick={() => navigateTo(`/fixtures/${fixture.id}`)}\n />\n ))}\n </GlassCard>\n )}\n </section>\n\n {/* Recent activity */}\n <section data-tour=\"dashboard-activity\">\n <div className=\"mb-4 flex items-center min-h-[1.75rem]\">\n <h2 className=\"text-lg font-semibold text-text-primary\">\n {tr('atheletebridge.pages.dashboard.recentActivity', 'Recent activity')}\n </h2>\n </div>\n {activityTimeline.length === 0 ? (\n <GlassCard treatment=\"metric\" className=\"p-6\">\n <EmptyState\n illustration=\"empty-data\"\n icon={<TrendingUp className=\"h-10 w-10\" />}\n title={tr('atheletebridge.pages.dashboard.noRecentActivity', 'No recent activity')}\n description={tr(\n 'atheletebridge.pages.dashboard.noRecentActivityHint',\n 'Create teams, publish programs or record results — the latest moves land here.'\n )}\n />\n </GlassCard>\n ) : (\n <GlassCard treatment=\"metric\" className=\"p-5\">\n <Timeline items={activityTimeline} />\n </GlassCard>\n )}\n </section>\n </div>\n\n {/* Upcoming sessions */}\n <section data-tour=\"dashboard-sessions\" className=\"mb-8\">\n <div className=\"mb-4 flex items-center justify-between\">\n <h2 className=\"text-lg font-semibold text-text-primary\">\n {tr('atheletebridge.pages.dashboard.upcomingSessions', 'Upcoming sessions')}\n </h2>\n <button\n type=\"button\"\n onClick={() => navigateTo('/sessions')}\n className=\"flex items-center gap-1 text-sm font-medium text-text-link hover:underline\"\n >\n {tr('atheletebridge.pages.dashboard.viewAll', 'View all')}{' '}\n <ArrowRight className=\"h-3.5 w-3.5\" />\n </button>\n </div>\n {upcomingSessions.length === 0 ? (\n <EmptyState\n illustration=\"empty-calendar\"\n icon={<ClipboardCheck className=\"h-10 w-10\" />}\n title={tr('atheletebridge.pages.dashboard.noSessions', 'No upcoming sessions')}\n description={tr(\n 'atheletebridge.pages.dashboard.noSessionsHint',\n 'Book a coaching session with an athlete to get started.'\n )}\n action={\n <button\n type=\"button\"\n onClick={() => navigateTo('/sessions/new')}\n className={GRADIENT_CTA}\n >\n <Plus className=\"h-4 w-4\" />{' '}\n {tr('atheletebridge.pages.dashboard.bookSession', 'Book session')}\n </button>\n }\n />\n ) : (\n <div className=\"grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3\">\n {upcomingSessions.map((session) => (\n <SessionCard\n key={session.id}\n session={session}\n onClick={() => navigateTo(`/sessions/${session.id}`)}\n />\n ))}\n </div>\n )}\n </section>\n\n {/* Teams */}\n <section data-tour=\"dashboard-teams\">\n <div className=\"mb-4 flex items-center justify-between\">\n <h2 className=\"text-lg font-semibold text-text-primary\">\n {tr('atheletebridge.pages.dashboard.yourTeams', 'Your teams')}\n </h2>\n <button\n type=\"button\"\n onClick={() => navigateTo('/teams')}\n className=\"flex items-center gap-1 text-sm font-medium text-text-link hover:underline\"\n >\n {tr('atheletebridge.pages.dashboard.viewAll', 'View all')}{' '}\n <ArrowRight className=\"h-3.5 w-3.5\" />\n </button>\n </div>\n {recentTeams.length === 0 ? (\n <EmptyState\n illustration=\"empty-data\"\n icon={<Trophy className=\"h-10 w-10\" />}\n title={tr('atheletebridge.pages.dashboard.noTeams', 'No teams yet')}\n description={tr(\n 'atheletebridge.pages.dashboard.noTeamsHint',\n 'Set up AthleteBridge in about a minute — pick your sport, create your first team and add yourself to the roster.'\n )}\n action={\n <div className=\"flex flex-wrap items-center justify-center gap-2\">\n <button\n type=\"button\"\n onClick={() => navigateTo('/onboarding')}\n className={GRADIENT_CTA}\n >\n <Rocket className=\"h-4 w-4\" />{' '}\n {tr('atheletebridge.pages.dashboard.getStarted', 'Get started')}\n </button>\n <button\n type=\"button\"\n onClick={() => navigateTo('/teams/new')}\n className=\"inline-flex items-center gap-1.5 rounded-lg border border-border-seam px-4 py-2 text-sm font-medium text-text-primary transition-colors hover:bg-bg-sunken\"\n >\n <Plus className=\"h-4 w-4\" />{' '}\n {tr('atheletebridge.pages.dashboard.createTeam', 'Create team')}\n </button>\n </div>\n }\n />\n ) : (\n <div className=\"grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3\">\n {recentTeams.map((team) => (\n <TeamCard key={team.id} team={team} onClick={() => navigateTo(`/teams/${team.id}`)} />\n ))}\n </div>\n )}\n </section>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"CoachAnalyticsPage.d.ts","sourceRoot":"","sources":["../../../../src/atheletebridge/pages/analytics/CoachAnalyticsPage.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AA2FH,wBAAgB,kBAAkB,gCAoVjC"}
1
+ {"version":3,"file":"CoachAnalyticsPage.d.ts","sourceRoot":"","sources":["../../../../src/atheletebridge/pages/analytics/CoachAnalyticsPage.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AA0GH,wBAAgB,kBAAkB,gCAkZjC"}