@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":"OnboardingPage.js","names":[],"sources":["../../../../src/atheletebridge/pages/onboarding/OnboardingPage.tsx"],"sourcesContent":["/**\n * First-run onboarding wizard\n * @module atheletebridge/pages/onboarding\n *\n * The AthleteBridge first-run flow: three steps — your sport → create your team\n * → your role — landing the user on a usable team page. Design reference is\n * mockup 26 (`atheletebridge-specs/product/mockups`), realised entirely with\n * fe-libs semantic tokens (the mockup's orange→red brand ramp maps to\n * `--color-action-primary-bg` blended toward `--color-accent-purple`, exactly as\n * the dashboard hero CTA does; the mockup's teal-green \"complete\" maps to\n * `--color-accent-teal`).\n *\n * Scope is deliberately narrow — sport, team, role. Workspace/organization\n * creation is NOT part of this flow: `global-tenant-svc` owns it and it already\n * precedes product entry, so duplicating it here would fork a platform module\n * (see `workspaces-specs/business/strategy/module-ownership`).\n *\n * Data layer (all real, nothing mocked):\n * - `useCreateTeam` → `athCreateTeam` — creates the squad from step 2.\n * - `useAddMember` → `athAddMember` — puts the calling user on that squad's\n * roster with the role picked in step 3. Best-effort: the team is the primary\n * outcome and is already persisted, so a roster hiccup must not strand the\n * user mid-flow.\n *\n * Unlike the entity pages this is a calm, centered flow rather than the admin\n * `PageLayout` header, and it renders no product wordmark — the app shell chrome\n * already carries AthleteBridge branding above this surface.\n */\n\nimport { useCallback, useMemo, useState, type FC, type FormEvent } from 'react';\nimport { ArrowLeft, ArrowRight, Check, Loader2, Users } from 'lucide-react';\nimport { GlassCard } from '@burdenoff/fe-libs/ui';\n\nimport { FormField, fieldInputClass } from '../../components/form';\nimport {\n MEMBER_ROLE_LABELS,\n MEMBER_ROLE_OPTIONS,\n SPORT_ICONS,\n SPORT_LABELS,\n SPORT_OPTIONS,\n} from '../../components/domain';\nimport { useAthleteBridge } from '../../context/AthleteBridgeContext';\nimport { useAddMember, useCreateTeam } from '../../hooks/useAthleteBridgeApi';\nimport type { AthMemberRole, AthSport } from '../../types';\nimport { cn } from '../../utils/cn';\nimport { useAbTranslate } from '../../i18n';\n\n// ============================================================================\n// Static option catalogues\n// ============================================================================\n\n/**\n * `AthTeam.ageGroup` is a free-text column on the subgraph; these are the\n * conventional squad bands offered as a shortcut. \"Senior\" and \"Masters\" cover\n * non-age-banded squads, and the empty value leaves the column unset.\n */\nconst AGE_GROUPS: ReadonlyArray<{ value: string; label: string }> = [\n { value: '', label: 'Not age-banded' },\n { value: 'U8', label: 'U8' },\n { value: 'U10', label: 'U10' },\n { value: 'U12', label: 'U12' },\n { value: 'U14', label: 'U14' },\n { value: 'U16', label: 'U16' },\n { value: 'U18', label: 'U18' },\n { value: 'U21', label: 'U21' },\n { value: 'SENIOR', label: 'Senior' },\n { value: 'MASTERS', label: 'Masters' },\n];\n\n/**\n * `AthTeam.season` is also free text. Options are derived from the current date\n * rather than hard-coded, so the list never goes stale: the calendar year, the\n * split-year season either side of it, and the previous calendar year.\n */\nfunction buildSeasonOptions(now: Date): ReadonlyArray<{ value: string; label: string }> {\n const year = now.getFullYear();\n const short = (y: number): string => String(y % 100).padStart(2, '0');\n return [\n { value: '', label: 'No season' },\n { value: String(year), label: String(year) },\n { value: `${year}/${short(year + 1)}`, label: `${year}/${short(year + 1)}` },\n { value: `${year - 1}/${short(year)}`, label: `${year - 1}/${short(year)}` },\n { value: String(year - 1), label: String(year - 1) },\n ];\n}\n\nconst TOTAL_STEPS = 3;\nconst TEAM_NAME_LIMIT = 120;\n\ntype StepNumber = 1 | 2 | 3;\n\nconst STEP_LABELS: Record<StepNumber, string> = {\n 1: 'Your sport',\n 2: 'Create your team',\n 3: 'Your role',\n};\n\n// ============================================================================\n// Shared token-only styling\n// ============================================================================\n\n/**\n * Brand gradient — the same orange→purple ramp the dashboard hero CTA uses, so\n * the wizard's active step and primary action read as one brand with the rest of\n * the product. Token-only (no raw colors).\n */\nconst BRAND_GRADIENT =\n '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\nconst PRIMARY_BUTTON = cn(\n 'inline-flex items-center justify-center gap-1.5 rounded-lg px-5 py-2.5 text-sm font-semibold',\n 'text-action-primary-text shadow-elevation-1 transition-[filter,box-shadow]',\n 'hover:shadow-elevation-2 hover:brightness-110 disabled:cursor-not-allowed disabled:opacity-60',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)]',\n BRAND_GRADIENT\n);\n\nconst SECONDARY_BUTTON = cn(\n 'inline-flex items-center justify-center gap-1.5 rounded-lg border border-border-seam px-5 py-2.5',\n 'text-sm font-medium text-text-primary transition-colors hover:bg-bg-sunken',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)]'\n);\n\nconst GHOST_BUTTON = cn(\n 'rounded-lg px-4 py-2.5 text-sm font-medium text-text-secondary transition-colors',\n 'hover:text-text-primary focus-visible:outline-none focus-visible:ring-2',\n 'focus-visible:ring-[var(--color-focus-ring)]'\n);\n\nconst CHIP_BASE = cn(\n 'inline-flex items-center gap-2 rounded-full border px-4 py-2 text-sm font-medium transition-all',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)]',\n 'motion-safe:hover:-translate-y-0.5'\n);\n\nconst CHIP_IDLE =\n 'border-border-seam bg-bg-surface text-text-secondary hover:border-border-strong hover:text-text-primary';\n\nconst CHIP_ACTIVE = cn(\n 'border-transparent text-action-primary-text shadow-elevation-1',\n BRAND_GRADIENT\n);\n\n// ============================================================================\n// Stepper\n// ============================================================================\n\ninterface StepperProps {\n current: StepNumber;\n}\n\n/**\n * The mockup's three-node stepper: teal-green + tick for a completed step, brand\n * gradient for the active step, hollow outline for an upcoming one. The nodes are\n * decorative — the accessible state is carried by the `progressbar` wrapper and\n * the visible step caption below the card.\n */\nconst Stepper: FC<StepperProps> = ({ current }) => (\n <div\n className=\"flex items-start justify-center\"\n role=\"progressbar\"\n aria-valuemin={1}\n aria-valuemax={TOTAL_STEPS}\n aria-valuenow={current}\n aria-valuetext={`Step ${current} of ${TOTAL_STEPS}: ${STEP_LABELS[current]}`}\n aria-label=\"Onboarding progress\"\n >\n {([1, 2, 3] as StepNumber[]).map((step, index) => {\n const done = step < current;\n const active = step === current;\n return (\n <div key={step} className=\"flex items-start\" aria-hidden=\"true\">\n {index > 0 && (\n <span\n className={cn(\n 'mt-6 h-px w-10 shrink-0 transition-colors sm:w-20',\n step <= current ? 'bg-[var(--color-accent-teal)]' : 'bg-border-seam'\n )}\n />\n )}\n <div className=\"flex w-24 flex-col items-center gap-2 sm:w-32\">\n <span\n className={cn(\n 'flex h-12 w-12 items-center justify-center rounded-full text-base font-semibold transition-all',\n done && 'bg-[var(--color-accent-teal)] text-[var(--color-bg-canvas)]',\n active && cn('text-action-primary-text shadow-elevation-2', BRAND_GRADIENT),\n !done && !active && 'border border-border-strong text-text-muted'\n )}\n >\n {done ? <Check className=\"h-5 w-5\" /> : step}\n </span>\n <span\n className={cn(\n 'text-center text-sm',\n active ? 'font-semibold text-text-primary' : 'text-text-secondary'\n )}\n >\n {STEP_LABELS[step]}\n </span>\n </div>\n </div>\n );\n })}\n </div>\n);\n\n// ============================================================================\n// Sport chips\n// ============================================================================\n\ninterface SportChipsProps {\n value: AthSport | null;\n onSelect: (sport: AthSport) => void;\n size: 'lg' | 'sm';\n}\n\nconst SportChips: FC<SportChipsProps> = ({ value, onSelect, size }) => (\n <div className=\"flex flex-wrap gap-2\" role=\"group\" aria-label=\"Sport\">\n {SPORT_OPTIONS.map((sport) => {\n const Icon = SPORT_ICONS[sport];\n const active = value === sport;\n return (\n <button\n key={sport}\n type=\"button\"\n onClick={() => onSelect(sport)}\n aria-pressed={active}\n className={cn(\n CHIP_BASE,\n size === 'lg' && 'px-5 py-2.5 text-base',\n active ? CHIP_ACTIVE : CHIP_IDLE\n )}\n >\n <Icon className={size === 'lg' ? 'h-5 w-5' : 'h-4 w-4'} aria-hidden=\"true\" />\n {SPORT_LABELS[sport]}\n </button>\n );\n })}\n </div>\n);\n\n// ============================================================================\n// Page\n// ============================================================================\n\nexport const OnboardingPage: FC = () => {\n const tr = useAbTranslate();\n const { navigateTo, currentUser } = useAthleteBridge();\n\n const createTeam = useCreateTeam();\n const addMember = useAddMember();\n\n const [step, setStep] = useState<StepNumber>(1);\n const [sport, setSport] = useState<AthSport | null>(null);\n const [teamName, setTeamName] = useState('');\n const [ageGroup, setAgeGroup] = useState('');\n const [season, setSeason] = useState('');\n const [role, setRole] = useState<AthMemberRole | null>(null);\n const [error, setError] = useState<string | null>(null);\n\n const seasonOptions = useMemo(() => buildSeasonOptions(new Date()), []);\n\n const busy = createTeam.isPending || addMember.isPending;\n\n const goDashboard = useCallback(() => navigateTo('/'), [navigateTo]);\n\n const handleBack = useCallback(() => {\n setError(null);\n setStep((prev) => (prev === 1 ? 1 : ((prev - 1) as StepNumber)));\n }, []);\n\n const handleSelectSport = useCallback((next: AthSport) => {\n setSport(next);\n setError(null);\n }, []);\n\n /**\n * Step 1/2 advance. Step 3 submits, so this only guards the two picker steps.\n */\n const handleContinue = useCallback(() => {\n if (step === 1) {\n if (!sport) {\n setError(tr('atheletebridge.pages.onboarding.errorSport', 'Pick a sport to continue.'));\n return;\n }\n setError(null);\n setStep(2);\n return;\n }\n if (!teamName.trim()) {\n setError(\n tr('atheletebridge.pages.onboarding.errorTeamName', 'Give your team a name to continue.')\n );\n return;\n }\n setError(null);\n setStep(3);\n }, [step, sport, teamName, tr]);\n\n /**\n * Final submit — creates the team, then (best-effort) puts the calling user on\n * its roster with the chosen role, and lands them on the new team page.\n */\n const handleFinish = useCallback(\n async (event: FormEvent) => {\n event.preventDefault();\n if (!sport || !role || !teamName.trim()) {\n setError(tr('atheletebridge.pages.onboarding.errorRole', 'Pick your role to finish.'));\n return;\n }\n setError(null);\n\n try {\n const team = await createTeam.mutateAsync({\n name: teamName.trim(),\n sport,\n status: 'FORMING',\n ageGroup: ageGroup || undefined,\n season: season || undefined,\n });\n\n if (currentUser?.id) {\n const fullName = [currentUser.firstName, currentUser.lastName]\n .filter((part): part is string => Boolean(part))\n .join(' ')\n .trim();\n const displayName = currentUser.name ?? (fullName || currentUser.email);\n try {\n await addMember.mutateAsync({\n teamId: team.id,\n userId: currentUser.id,\n displayName,\n role,\n status: 'ACTIVE',\n });\n } catch {\n // The team is created and is the primary outcome — a roster failure\n // must not strand the user in the wizard. They can add themselves\n // from the team page.\n }\n }\n\n navigateTo(`/teams/${team.id}`);\n } catch (err) {\n setError(\n err instanceof Error\n ? err.message\n : tr(\n 'atheletebridge.pages.onboarding.errorCreate',\n \"We couldn't create your team. Please try again.\"\n )\n );\n }\n },\n [sport, role, teamName, ageGroup, season, currentUser, createTeam, addMember, navigateTo, tr]\n );\n\n const heading =\n step === 1\n ? tr('atheletebridge.pages.onboarding.step1Title', 'What do you coach?')\n : step === 2\n ? tr('atheletebridge.pages.onboarding.step2Title', 'Create your first team')\n : tr('atheletebridge.pages.onboarding.step3Title', \"What's your role?\");\n\n const subheading =\n step === 1\n ? tr(\n 'atheletebridge.pages.onboarding.step1Subtitle',\n 'Your sport shapes the squads, fixtures and training you set up next.'\n )\n : step === 2\n ? tr(\n 'atheletebridge.pages.onboarding.step2Subtitle',\n 'You can add players and fixtures once your team exists.'\n )\n : tr(\n 'atheletebridge.pages.onboarding.step3Subtitle',\n 'We add you to this squad so the roster starts with you.'\n );\n\n return (\n <div className=\"min-h-full bg-bg-canvas px-4 py-10 sm:px-6 sm:py-14\">\n <div className=\"mx-auto flex w-full max-w-2xl flex-col gap-8\">\n <Stepper current={step} />\n\n <header className=\"text-center\">\n <h1 className=\"text-3xl font-bold tracking-tight text-text-primary sm:text-4xl\">\n {heading}\n </h1>\n <p className=\"mx-auto mt-2 max-w-lg text-sm text-text-secondary sm:text-base\">\n {subheading}\n </p>\n </header>\n\n <form onSubmit={handleFinish} noValidate>\n <GlassCard treatment=\"insight\" className=\"p-6 sm:p-8\">\n <div className=\"space-y-6\">\n {step === 1 && <SportChips value={sport} onSelect={handleSelectSport} size=\"lg\" />}\n\n {step === 2 && (\n <>\n <FormField\n label={tr('atheletebridge.pages.onboarding.teamName', 'Team name')}\n htmlFor=\"onboarding-team-name\"\n required\n >\n <input\n id=\"onboarding-team-name\"\n className={fieldInputClass}\n value={teamName}\n maxLength={TEAM_NAME_LIMIT}\n onChange={(e) => {\n setTeamName(e.target.value);\n setError(null);\n }}\n placeholder=\"e.g. Riverside United U16\"\n />\n </FormField>\n\n <FormField label={tr('atheletebridge.pages.onboarding.sport', 'Sport')}>\n <SportChips value={sport} onSelect={handleSelectSport} size=\"sm\" />\n </FormField>\n\n <div className=\"grid grid-cols-1 gap-5 sm:grid-cols-2\">\n <FormField\n label={tr('atheletebridge.pages.onboarding.ageGroup', 'Age group')}\n htmlFor=\"onboarding-age-group\"\n >\n <select\n id=\"onboarding-age-group\"\n className={fieldInputClass}\n value={ageGroup}\n onChange={(e) => setAgeGroup(e.target.value)}\n >\n {AGE_GROUPS.map((option) => (\n <option key={option.value || 'none'} value={option.value}>\n {option.label}\n </option>\n ))}\n </select>\n </FormField>\n\n <FormField\n label={tr('atheletebridge.pages.onboarding.season', 'Season')}\n htmlFor=\"onboarding-season\"\n >\n <select\n id=\"onboarding-season\"\n className={fieldInputClass}\n value={season}\n onChange={(e) => setSeason(e.target.value)}\n >\n {seasonOptions.map((option) => (\n <option key={option.value || 'none'} value={option.value}>\n {option.label}\n </option>\n ))}\n </select>\n </FormField>\n </div>\n </>\n )}\n\n {step === 3 && (\n <div className=\"flex flex-wrap gap-2\" role=\"group\" aria-label=\"Your role\">\n {MEMBER_ROLE_OPTIONS.map((option) => {\n const active = role === option;\n return (\n <button\n key={option}\n type=\"button\"\n onClick={() => {\n setRole(option);\n setError(null);\n }}\n aria-pressed={active}\n className={cn(\n CHIP_BASE,\n 'px-5 py-2.5 text-base',\n active ? CHIP_ACTIVE : CHIP_IDLE\n )}\n >\n <Users className=\"h-5 w-5\" aria-hidden=\"true\" />\n {MEMBER_ROLE_LABELS[option]}\n </button>\n );\n })}\n </div>\n )}\n\n {error && (\n <p role=\"alert\" className=\"text-sm text-status-error-text\">\n {error}\n </p>\n )}\n </div>\n\n <div className=\"mt-8 flex flex-wrap items-center justify-between gap-3 border-t border-border-seam pt-6\">\n <button\n type=\"button\"\n onClick={step === 1 ? goDashboard : handleBack}\n className={SECONDARY_BUTTON}\n disabled={busy}\n >\n <ArrowLeft className=\"h-4 w-4\" aria-hidden=\"true\" />\n {step === 1\n ? tr('atheletebridge.pages.onboarding.exit', 'Exit')\n : tr('atheletebridge.pages.onboarding.back', 'Back')}\n </button>\n\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n onClick={goDashboard}\n className={GHOST_BUTTON}\n disabled={busy}\n >\n {tr('atheletebridge.pages.onboarding.skip', 'Skip for now')}\n </button>\n\n {step === 3 ? (\n <button type=\"submit\" className={PRIMARY_BUTTON} disabled={busy || !role}>\n {busy ? (\n <>\n <Loader2 className=\"h-4 w-4 animate-spin\" aria-hidden=\"true\" />\n {tr('atheletebridge.pages.onboarding.creating', 'Creating…')}\n </>\n ) : (\n <>\n {tr('atheletebridge.pages.onboarding.finish', 'Create team')}\n <ArrowRight className=\"h-4 w-4\" aria-hidden=\"true\" />\n </>\n )}\n </button>\n ) : (\n <button type=\"button\" onClick={handleContinue} className={PRIMARY_BUTTON}>\n {tr('atheletebridge.pages.onboarding.continue', 'Continue')}\n <ArrowRight className=\"h-4 w-4\" aria-hidden=\"true\" />\n </button>\n )}\n </div>\n </div>\n </GlassCard>\n </form>\n\n <p className=\"text-center text-sm text-text-secondary\">\n {tr('atheletebridge.pages.onboarding.footer', 'Step')} {step}{' '}\n {tr('atheletebridge.pages.onboarding.footerOf', 'of')} {TOTAL_STEPS} —{' '}\n {tr('atheletebridge.pages.onboarding.footerHint', 'takes about a minute.')}\n </p>\n </div>\n </div>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"OnboardingPage.js","names":[],"sources":["../../../../src/atheletebridge/pages/onboarding/OnboardingPage.tsx"],"sourcesContent":["/**\n * First-run onboarding wizard\n * @module atheletebridge/pages/onboarding\n *\n * The AthleteBridge first-run flow: three steps — your sport → create your team\n * → your role — landing the user on a usable team page. Design reference is\n * mockup 26 (`atheletebridge-specs/product/mockups`), realised entirely with\n * fe-libs semantic tokens (the mockup's orange→red brand ramp maps to\n * `--color-action-primary-bg` blended toward `--color-accent-purple`, exactly as\n * the dashboard hero CTA does; the mockup's teal-green \"complete\" maps to\n * `--color-accent-teal`).\n *\n * Scope is deliberately narrow — sport, team, role. Workspace/organization\n * creation is NOT part of this flow: `global-tenant-svc` owns it and it already\n * precedes product entry, so duplicating it here would fork a platform module\n * (see `workspaces-specs/business/strategy/module-ownership`).\n *\n * Data layer (all real, nothing mocked):\n * - `useCreateTeam` → `athCreateTeam` — creates the squad from step 2.\n * - `useAddMember` → `athAddMember` — puts the calling user on that squad's\n * roster with the role picked in step 3. Best-effort: the team is the primary\n * outcome and is already persisted, so a roster hiccup must not strand the\n * user mid-flow.\n *\n * Unlike the entity pages this is a calm, centered flow rather than the admin\n * `PageLayout` header, and it renders no product wordmark — the app shell chrome\n * already carries AthleteBridge branding above this surface.\n */\n\nimport { useCallback, useMemo, useState, type FC, type FormEvent } from 'react';\nimport { ArrowLeft, ArrowRight, Check, Loader2, Users } from 'lucide-react';\nimport { GlassCard } from '@burdenoff/fe-libs/ui';\n\nimport { FormField, fieldInputClass } from '../../components/form';\nimport { MEMBER_ROLE_OPTIONS, SPORT_ICONS, SPORT_OPTIONS } from '../../components/domain';\nimport { useAthleteBridge } from '../../context/AthleteBridgeContext';\nimport { useAddMember, useCreateTeam } from '../../hooks/useAthleteBridgeApi';\nimport type { AthMemberRole, AthSport } from '../../types';\nimport { cn } from '../../utils/cn';\nimport { useAbTranslate, type TranslateFn } from '../../i18n';\n\n// ============================================================================\n// Static option catalogues\n// ============================================================================\n\n/**\n * `AthTeam.ageGroup` is a free-text column on the subgraph; these are the\n * conventional squad bands offered as a shortcut. \"Senior\" and \"Masters\" cover\n * non-age-banded squads, and the empty value leaves the column unset.\n */\nfunction useAgeGroups(tr: TranslateFn): ReadonlyArray<{ value: string; label: string }> {\n return [\n { value: '', label: tr('atheletebridge.onboarding.ageGroup.none', 'Not age-banded') },\n { value: 'U8', label: 'U8' },\n { value: 'U10', label: 'U10' },\n { value: 'U12', label: 'U12' },\n { value: 'U14', label: 'U14' },\n { value: 'U16', label: 'U16' },\n { value: 'U18', label: 'U18' },\n { value: 'U21', label: 'U21' },\n { value: 'SENIOR', label: tr('atheletebridge.onboarding.ageGroup.senior', 'Senior') },\n { value: 'MASTERS', label: tr('atheletebridge.onboarding.ageGroup.masters', 'Masters') },\n ];\n}\n\n/**\n * `AthTeam.season` is also free text. Options are derived from the current date\n * rather than hard-coded, so the list never goes stale: the calendar year, the\n * split-year season either side of it, and the previous calendar year.\n */\nfunction buildSeasonOptions(\n now: Date,\n tr: TranslateFn\n): ReadonlyArray<{ value: string; label: string }> {\n const year = now.getFullYear();\n const short = (y: number): string => String(y % 100).padStart(2, '0');\n return [\n { value: '', label: tr('atheletebridge.onboarding.season.none', 'No season') },\n { value: String(year), label: String(year) },\n { value: `${year}/${short(year + 1)}`, label: `${year}/${short(year + 1)}` },\n { value: `${year - 1}/${short(year)}`, label: `${year - 1}/${short(year)}` },\n { value: String(year - 1), label: String(year - 1) },\n ];\n}\n\nconst TOTAL_STEPS = 3;\nconst TEAM_NAME_LIMIT = 120;\n\ntype StepNumber = 1 | 2 | 3;\n\nfunction stepLabel(step: StepNumber, tr: TranslateFn): string {\n switch (step) {\n case 1:\n return tr('atheletebridge.onboarding.stepLabel.sport', 'Your sport');\n case 2:\n return tr('atheletebridge.onboarding.stepLabel.team', 'Create your team');\n case 3:\n return tr('atheletebridge.onboarding.stepLabel.role', 'Your role');\n }\n}\n\n// ============================================================================\n// Shared token-only styling\n// ============================================================================\n\n/**\n * Brand gradient — the same orange→purple ramp the dashboard hero CTA uses, so\n * the wizard's active step and primary action read as one brand with the rest of\n * the product. Token-only (no raw colors).\n */\nconst BRAND_GRADIENT =\n '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\nconst PRIMARY_BUTTON = cn(\n 'inline-flex items-center justify-center gap-1.5 rounded-lg px-5 py-2.5 text-sm font-semibold',\n 'text-action-primary-text shadow-elevation-1 transition-[filter,box-shadow]',\n 'hover:shadow-elevation-2 hover:brightness-110 disabled:cursor-not-allowed disabled:opacity-60',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)]',\n BRAND_GRADIENT\n);\n\nconst SECONDARY_BUTTON = cn(\n 'inline-flex items-center justify-center gap-1.5 rounded-lg border border-border-seam px-5 py-2.5',\n 'text-sm font-medium text-text-primary transition-colors hover:bg-bg-sunken',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)]'\n);\n\nconst GHOST_BUTTON = cn(\n 'rounded-lg px-4 py-2.5 text-sm font-medium text-text-secondary transition-colors',\n 'hover:text-text-primary focus-visible:outline-none focus-visible:ring-2',\n 'focus-visible:ring-[var(--color-focus-ring)]'\n);\n\nconst CHIP_BASE = cn(\n 'inline-flex items-center gap-2 rounded-full border px-4 py-2 text-sm font-medium transition-all',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)]',\n 'motion-safe:hover:-translate-y-0.5'\n);\n\nconst CHIP_IDLE =\n 'border-border-seam bg-bg-surface text-text-secondary hover:border-border-strong hover:text-text-primary';\n\nconst CHIP_ACTIVE = cn(\n 'border-transparent text-action-primary-text shadow-elevation-1',\n BRAND_GRADIENT\n);\n\n// ============================================================================\n// Stepper\n// ============================================================================\n\ninterface StepperProps {\n current: StepNumber;\n}\n\n/**\n * The mockup's three-node stepper: teal-green + tick for a completed step, brand\n * gradient for the active step, hollow outline for an upcoming one. The nodes are\n * decorative — the accessible state is carried by the `progressbar` wrapper and\n * the visible step caption below the card.\n */\nconst Stepper: FC<\n StepperProps & { stepLabel: (step: StepNumber) => string; progressLabel: string }\n> = ({ current, stepLabel, progressLabel }) => (\n <div\n className=\"flex items-start justify-center\"\n role=\"progressbar\"\n aria-valuemin={1}\n aria-valuemax={TOTAL_STEPS}\n aria-valuenow={current}\n aria-valuetext={`${progressLabel} ${current} / ${TOTAL_STEPS}: ${stepLabel(current)}`}\n aria-label={progressLabel}\n >\n {([1, 2, 3] as StepNumber[]).map((step, index) => {\n const done = step < current;\n const active = step === current;\n return (\n <div key={step} className=\"flex items-start\" aria-hidden=\"true\">\n {index > 0 && (\n <span\n className={cn(\n 'mt-6 h-px w-10 shrink-0 transition-colors sm:w-20',\n step <= current ? 'bg-[var(--color-accent-teal)]' : 'bg-border-seam'\n )}\n />\n )}\n <div className=\"flex w-24 flex-col items-center gap-2 sm:w-32\">\n <span\n className={cn(\n 'flex h-12 w-12 items-center justify-center rounded-full text-base font-semibold transition-all',\n done && 'bg-[var(--color-accent-teal)] text-[var(--color-bg-canvas)]',\n active && cn('text-action-primary-text shadow-elevation-2', BRAND_GRADIENT),\n !done && !active && 'border border-border-strong text-text-muted'\n )}\n >\n {done ? <Check className=\"h-5 w-5\" /> : step}\n </span>\n <span\n className={cn(\n 'text-center text-sm',\n active ? 'font-semibold text-text-primary' : 'text-text-secondary'\n )}\n >\n {stepLabel(step)}\n </span>\n </div>\n </div>\n );\n })}\n </div>\n);\n\n// ============================================================================\n// Sport chips\n// ============================================================================\n\ninterface SportChipsProps {\n value: AthSport | null;\n onSelect: (sport: AthSport) => void;\n size: 'lg' | 'sm';\n getLabel: (sport: AthSport) => string;\n groupLabel: string;\n}\n\nconst SportChips: FC<SportChipsProps> = ({ value, onSelect, size, getLabel, groupLabel }) => (\n <div className=\"flex flex-wrap gap-2\" role=\"group\" aria-label={groupLabel}>\n {SPORT_OPTIONS.map((sport) => {\n const Icon = SPORT_ICONS[sport];\n const active = value === sport;\n return (\n <button\n key={sport}\n type=\"button\"\n onClick={() => onSelect(sport)}\n aria-pressed={active}\n className={cn(\n CHIP_BASE,\n size === 'lg' && 'px-5 py-2.5 text-base',\n active ? CHIP_ACTIVE : CHIP_IDLE\n )}\n >\n <Icon className={size === 'lg' ? 'h-5 w-5' : 'h-4 w-4'} aria-hidden=\"true\" />\n {getLabel(sport)}\n </button>\n );\n })}\n </div>\n);\n\n// ============================================================================\n// Page\n// ============================================================================\n\nexport const OnboardingPage: FC = () => {\n const tr = useAbTranslate();\n const { navigateTo, currentUser } = useAthleteBridge();\n\n const createTeam = useCreateTeam();\n const addMember = useAddMember();\n\n const [step, setStep] = useState<StepNumber>(1);\n const [sport, setSport] = useState<AthSport | null>(null);\n const [teamName, setTeamName] = useState('');\n const [ageGroup, setAgeGroup] = useState('');\n const [season, setSeason] = useState('');\n const [role, setRole] = useState<AthMemberRole | null>(null);\n const [error, setError] = useState<string | null>(null);\n\n const ageGroups = useAgeGroups(tr);\n const seasonOptions = useMemo(() => buildSeasonOptions(new Date(), tr), [tr]);\n\n const sportLabel = useCallback(\n (s: AthSport): string => {\n switch (s) {\n case 'ATHLETICS':\n return tr('atheletebridge.sport.athletics', 'Athletics');\n case 'BASKETBALL':\n return tr('atheletebridge.sport.basketball', 'Basketball');\n case 'CRICKET':\n return tr('atheletebridge.sport.cricket', 'Cricket');\n case 'ESPORTS':\n return tr('atheletebridge.sport.esports', 'Esports');\n case 'FOOTBALL':\n return tr('atheletebridge.sport.football', 'Football');\n case 'OTHER':\n return tr('atheletebridge.sport.other', 'Other');\n case 'SWIMMING':\n return tr('atheletebridge.sport.swimming', 'Swimming');\n case 'TENNIS':\n return tr('atheletebridge.sport.tennis', 'Tennis');\n }\n },\n [tr]\n );\n\n const roleLabel = useCallback(\n (r: AthMemberRole): string => {\n switch (r) {\n case 'PLAYER':\n return tr('atheletebridge.memberRole.player', 'Player');\n case 'CAPTAIN':\n return tr('atheletebridge.memberRole.captain', 'Captain');\n case 'COACH':\n return tr('atheletebridge.memberRole.coach', 'Coach');\n case 'ASSISTANT_COACH':\n return tr('atheletebridge.memberRole.assistantCoach', 'Assistant Coach');\n case 'PHYSIO':\n return tr('atheletebridge.memberRole.physio', 'Physio');\n case 'MANAGER':\n return tr('atheletebridge.memberRole.manager', 'Manager');\n }\n },\n [tr]\n );\n\n const busy = createTeam.isPending || addMember.isPending;\n\n const goDashboard = useCallback(() => navigateTo('/'), [navigateTo]);\n\n const handleBack = useCallback(() => {\n setError(null);\n setStep((prev) => (prev === 1 ? 1 : ((prev - 1) as StepNumber)));\n }, []);\n\n const handleSelectSport = useCallback((next: AthSport) => {\n setSport(next);\n setError(null);\n }, []);\n\n /**\n * Step 1/2 advance. Step 3 submits, so this only guards the two picker steps.\n */\n const handleContinue = useCallback(() => {\n if (step === 1) {\n if (!sport) {\n setError(tr('atheletebridge.pages.onboarding.errorSport', 'Pick a sport to continue.'));\n return;\n }\n setError(null);\n setStep(2);\n return;\n }\n if (!teamName.trim()) {\n setError(\n tr('atheletebridge.pages.onboarding.errorTeamName', 'Give your team a name to continue.')\n );\n return;\n }\n setError(null);\n setStep(3);\n }, [step, sport, teamName, tr]);\n\n /**\n * Final submit — creates the team, then (best-effort) puts the calling user on\n * its roster with the chosen role, and lands them on the new team page.\n */\n const handleFinish = useCallback(\n async (event: FormEvent) => {\n event.preventDefault();\n if (!sport || !role || !teamName.trim()) {\n setError(tr('atheletebridge.pages.onboarding.errorRole', 'Pick your role to finish.'));\n return;\n }\n setError(null);\n\n try {\n const team = await createTeam.mutateAsync({\n name: teamName.trim(),\n sport,\n status: 'FORMING',\n ageGroup: ageGroup || undefined,\n season: season || undefined,\n });\n\n if (currentUser?.id) {\n const fullName = [currentUser.firstName, currentUser.lastName]\n .filter((part): part is string => Boolean(part))\n .join(' ')\n .trim();\n const displayName = currentUser.name ?? (fullName || currentUser.email);\n try {\n await addMember.mutateAsync({\n teamId: team.id,\n userId: currentUser.id,\n displayName,\n role,\n status: 'ACTIVE',\n });\n } catch {\n // The team is created and is the primary outcome — a roster failure\n // must not strand the user in the wizard. They can add themselves\n // from the team page.\n }\n }\n\n navigateTo(`/teams/${team.id}`);\n } catch (err) {\n setError(\n err instanceof Error\n ? err.message\n : tr(\n 'atheletebridge.pages.onboarding.errorCreate',\n \"We couldn't create your team. Please try again.\"\n )\n );\n }\n },\n [sport, role, teamName, ageGroup, season, currentUser, createTeam, addMember, navigateTo, tr]\n );\n\n const heading =\n step === 1\n ? tr('atheletebridge.pages.onboarding.step1Title', 'What do you coach?')\n : step === 2\n ? tr('atheletebridge.pages.onboarding.step2Title', 'Create your first team')\n : tr('atheletebridge.pages.onboarding.step3Title', \"What's your role?\");\n\n const subheading =\n step === 1\n ? tr(\n 'atheletebridge.pages.onboarding.step1Subtitle',\n 'Your sport shapes the squads, fixtures and training you set up next.'\n )\n : step === 2\n ? tr(\n 'atheletebridge.pages.onboarding.step2Subtitle',\n 'You can add players and fixtures once your team exists.'\n )\n : tr(\n 'atheletebridge.pages.onboarding.step3Subtitle',\n 'We add you to this squad so the roster starts with you.'\n );\n\n return (\n <div className=\"min-h-full bg-bg-canvas px-4 py-10 sm:px-6 sm:py-14\">\n <div className=\"mx-auto flex w-full max-w-2xl flex-col gap-8\">\n <Stepper\n current={step}\n stepLabel={(s) => stepLabel(s, tr)}\n progressLabel={tr('atheletebridge.pages.onboarding.progressLabel', 'Onboarding progress')}\n />\n\n <header className=\"text-center\">\n <h1 className=\"text-3xl font-bold tracking-tight text-text-primary sm:text-4xl\">\n {heading}\n </h1>\n <p className=\"mx-auto mt-2 max-w-lg text-sm text-text-secondary sm:text-base\">\n {subheading}\n </p>\n </header>\n\n <form onSubmit={handleFinish} noValidate>\n <GlassCard treatment=\"insight\" className=\"p-6 sm:p-8\">\n <div className=\"space-y-6\">\n {step === 1 && (\n <SportChips\n value={sport}\n onSelect={handleSelectSport}\n size=\"lg\"\n getLabel={sportLabel}\n groupLabel={tr('atheletebridge.pages.onboarding.sport', 'Sport')}\n />\n )}\n\n {step === 2 && (\n <>\n <FormField\n label={tr('atheletebridge.pages.onboarding.teamName', 'Team name')}\n htmlFor=\"onboarding-team-name\"\n required\n >\n <input\n id=\"onboarding-team-name\"\n className={fieldInputClass}\n value={teamName}\n maxLength={TEAM_NAME_LIMIT}\n onChange={(e) => {\n setTeamName(e.target.value);\n setError(null);\n }}\n placeholder={tr(\n 'atheletebridge.pages.onboarding.teamNamePlaceholder',\n 'e.g. Riverside United U16'\n )}\n />\n </FormField>\n\n <FormField label={tr('atheletebridge.pages.onboarding.sport', 'Sport')}>\n <SportChips\n value={sport}\n onSelect={handleSelectSport}\n size=\"sm\"\n getLabel={sportLabel}\n groupLabel={tr('atheletebridge.pages.onboarding.sport', 'Sport')}\n />\n </FormField>\n\n <div className=\"grid grid-cols-1 gap-5 sm:grid-cols-2\">\n <FormField\n label={tr('atheletebridge.pages.onboarding.ageGroup', 'Age group')}\n htmlFor=\"onboarding-age-group\"\n >\n <select\n id=\"onboarding-age-group\"\n className={fieldInputClass}\n value={ageGroup}\n onChange={(e) => setAgeGroup(e.target.value)}\n >\n {ageGroups.map((option) => (\n <option key={option.value || 'none'} value={option.value}>\n {option.label}\n </option>\n ))}\n </select>\n </FormField>\n\n <FormField\n label={tr('atheletebridge.pages.onboarding.season', 'Season')}\n htmlFor=\"onboarding-season\"\n >\n <select\n id=\"onboarding-season\"\n className={fieldInputClass}\n value={season}\n onChange={(e) => setSeason(e.target.value)}\n >\n {seasonOptions.map((option) => (\n <option key={option.value || 'none'} value={option.value}>\n {option.label}\n </option>\n ))}\n </select>\n </FormField>\n </div>\n </>\n )}\n\n {step === 3 && (\n <div\n className=\"flex flex-wrap gap-2\"\n role=\"group\"\n aria-label={tr('atheletebridge.pages.onboarding.yourRole', 'Your role')}\n >\n {MEMBER_ROLE_OPTIONS.map((option) => {\n const active = role === option;\n return (\n <button\n key={option}\n type=\"button\"\n onClick={() => {\n setRole(option);\n setError(null);\n }}\n aria-pressed={active}\n className={cn(\n CHIP_BASE,\n 'px-5 py-2.5 text-base',\n active ? CHIP_ACTIVE : CHIP_IDLE\n )}\n >\n <Users className=\"h-5 w-5\" aria-hidden=\"true\" />\n {roleLabel(option)}\n </button>\n );\n })}\n </div>\n )}\n\n {error && (\n <p role=\"alert\" className=\"text-sm text-status-error-text\">\n {error}\n </p>\n )}\n </div>\n\n <div className=\"mt-8 flex flex-wrap items-center justify-between gap-3 border-t border-border-seam pt-6\">\n <button\n type=\"button\"\n onClick={step === 1 ? goDashboard : handleBack}\n className={SECONDARY_BUTTON}\n disabled={busy}\n >\n <ArrowLeft className=\"h-4 w-4\" aria-hidden=\"true\" />\n {step === 1\n ? tr('atheletebridge.pages.onboarding.exit', 'Exit')\n : tr('atheletebridge.pages.onboarding.back', 'Back')}\n </button>\n\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n onClick={goDashboard}\n className={GHOST_BUTTON}\n disabled={busy}\n >\n {tr('atheletebridge.pages.onboarding.skip', 'Skip for now')}\n </button>\n\n {step === 3 ? (\n <button type=\"submit\" className={PRIMARY_BUTTON} disabled={busy || !role}>\n {busy ? (\n <>\n <Loader2 className=\"h-4 w-4 animate-spin\" aria-hidden=\"true\" />\n {tr('atheletebridge.pages.onboarding.creating', 'Creating…')}\n </>\n ) : (\n <>\n {tr('atheletebridge.pages.onboarding.finish', 'Create team')}\n <ArrowRight className=\"h-4 w-4\" aria-hidden=\"true\" />\n </>\n )}\n </button>\n ) : (\n <button type=\"button\" onClick={handleContinue} className={PRIMARY_BUTTON}>\n {tr('atheletebridge.pages.onboarding.continue', 'Continue')}\n <ArrowRight className=\"h-4 w-4\" aria-hidden=\"true\" />\n </button>\n )}\n </div>\n </div>\n </GlassCard>\n </form>\n\n <p className=\"text-center text-sm text-text-secondary\">\n {tr('atheletebridge.pages.onboarding.footer', 'Step')} {step}{' '}\n {tr('atheletebridge.pages.onboarding.footerOf', 'of')} {TOTAL_STEPS} —{' '}\n {tr('atheletebridge.pages.onboarding.footerHint', 'takes about a minute.')}\n </p>\n </div>\n </div>\n );\n};\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"PerformancePage.d.ts","sourceRoot":"","sources":["../../../../src/atheletebridge/pages/performance/PerformancePage.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAuNH,wBAAgB,eAAe,gCAkC9B"}
1
+ {"version":3,"file":"PerformancePage.d.ts","sourceRoot":"","sources":["../../../../src/atheletebridge/pages/performance/PerformancePage.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAuNH,wBAAgB,eAAe,gCA4C9B"}