@burdenoff/microfe-atheletebridge 2026.716.1 → 2026.720.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/atheletebridge/admin/AdminDashboardPage.js +2 -2
- package/dist/atheletebridge/admin/AdminDashboardPage.js.map +1 -1
- package/dist/atheletebridge/components/ProgramCard.js +1 -1
- package/dist/atheletebridge/components/ProgramCard.js.map +1 -1
- package/dist/atheletebridge/components/TeamCard.js +1 -1
- package/dist/atheletebridge/components/TeamCard.js.map +1 -1
- package/dist/atheletebridge/hooks/useAthleteBridgeApi.d.ts.map +1 -1
- package/dist/atheletebridge/hooks/useAthleteBridgeApi.js +12 -12
- package/dist/atheletebridge/hooks/useAthleteBridgeApi.js.map +1 -1
- package/dist/atheletebridge/pages/programs/ProgramDetailPage.js +3 -3
- package/dist/atheletebridge/pages/programs/ProgramDetailPage.js.map +1 -1
- package/dist/atheletebridge/pages/programs/ProgramsListPage.js +1 -1
- package/dist/atheletebridge/pages/programs/ProgramsListPage.js.map +1 -1
- package/dist/atheletebridge/pages/teams/TeamDetailPage.js +1 -1
- package/dist/atheletebridge/pages/teams/TeamDetailPage.js.map +1 -1
- package/dist/atheletebridge/pages/teams/TeamsListPage.js +1 -1
- package/dist/atheletebridge/pages/teams/TeamsListPage.js.map +1 -1
- package/dist/atheletebridge/types/index.d.ts +19 -3
- package/dist/atheletebridge/types/index.d.ts.map +1 -1
- package/dist/atheletebridge/utils/pageContext.d.ts +16 -7
- package/dist/atheletebridge/utils/pageContext.d.ts.map +1 -1
- package/dist/atheletebridge/utils/pageContext.js +111 -35
- package/dist/atheletebridge/utils/pageContext.js.map +1 -1
- package/package.json +5 -4
|
@@ -153,7 +153,7 @@ var U = 20, W = Object.keys(a).map((e) => ({
|
|
|
153
153
|
}),
|
|
154
154
|
/* @__PURE__ */ E(F, {
|
|
155
155
|
className: "text-right text-text-secondary",
|
|
156
|
-
children: e.members?.length ?? 0
|
|
156
|
+
children: e.members?.items.length ?? 0
|
|
157
157
|
}),
|
|
158
158
|
/* @__PURE__ */ E(F, {
|
|
159
159
|
className: "text-text-secondary",
|
|
@@ -235,7 +235,7 @@ var U = 20, W = Object.keys(a).map((e) => ({
|
|
|
235
235
|
}),
|
|
236
236
|
/* @__PURE__ */ E(F, {
|
|
237
237
|
className: "text-right text-text-secondary",
|
|
238
|
-
children: e.drills?.length ?? 0
|
|
238
|
+
children: e.drills?.items.length ?? 0
|
|
239
239
|
}),
|
|
240
240
|
/* @__PURE__ */ E(F, {
|
|
241
241
|
className: "text-text-secondary",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AdminDashboardPage.js","names":[],"sources":["../../../src/atheletebridge/admin/AdminDashboardPage.tsx"],"sourcesContent":["/**\n * AthleteBridge Admin Dashboard\n * @module atheletebridge/admin\n *\n * Product-specific governance surface mounted inside `admin-app` at\n * `/admin/atheletebridge` (BOFF-3258).\n *\n * Every tab below is backed by a REAL, shipped `wspace-atheletebridge-svc`\n * root field reached through the workspace gateway:\n *\n * Teams → athListTeams (useTeams)\n * Programs → athListPrograms (usePrograms)\n * Fixtures → athListFixtures (useFixtures) + athStandings (useStandings)\n * Sessions → athListSessions (useSessions)\n *\n * DELIBERATE OMISSION (RULINGS R6): governance surfaces that have no backing\n * query are OMITTED ENTIRELY rather than shipped with invented rows. This file\n * intentionally does NOT copy the `PLACEHOLDER_ADAPTERS` / `PLACEHOLDER_LISTINGS`\n * pattern from `microfe-subscriberbot/src/subscriberbot/admin/AdminDashboardPage.tsx`,\n * which renders fabricated data behind a \"backend not implemented\" banner. There\n * are zero hard-coded rows here.\n *\n * READ-ONLY BY DESIGN: this is an operations/support oversight view. Lifecycle\n * mutations (archive team, transition program, cancel session, …) already exist\n * in the product UI behind the same RBAC pairs; duplicating them here would add\n * a second write path to a service already on the duplication watch list\n * (05-OVERLAP-AND-DUPLICATION-REPORT.md:249) without a governance need.\n */\n\nimport { useMemo, useState, type FC } from 'react';\nimport {\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n Tabs,\n TabsContent,\n TabsList,\n TabsTrigger,\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n} from '@burdenoff/fe-libs/ui';\nimport { CalendarDays, ClipboardCheck, Dumbbell, Trophy, Users } from 'lucide-react';\n\nimport { CursorPager } from '../components/CursorPager';\nimport { EmptyState } from '../components/EmptyState';\nimport { FilterSelect } from '../components/FilterSelect';\nimport { LoadingState, ErrorState } from '../components/LoadingState';\nimport { PageLayout } from '../components/PageLayout';\nimport { StatusBadge } from '../components/StatusBadge';\nimport {\n FIXTURE_TYPE_LABELS,\n PROGRAM_LEVEL_LABELS,\n SESSION_TYPE_LABELS,\n SPORT_LABELS,\n} from '../components/domain';\nimport { useFixtures, usePrograms, useSessions, useStandings, useTeams } from '../hooks';\nimport { formatDate, formatDuration } from '../utils/formatters';\nimport type {\n AthFixtureStatus,\n AthProgramStatus,\n AthSessionStatus,\n AthSport,\n AthTeamStatus,\n} from '../types';\n\nconst PAGE_SIZE = 20;\n\nconst SPORT_OPTS = (Object.keys(SPORT_LABELS) as AthSport[]).map((value) => ({\n value,\n label: SPORT_LABELS[value],\n}));\n\nconst TEAM_STATUS_OPTS: ReadonlyArray<{ value: AthTeamStatus; label: string }> = [\n { value: 'FORMING', label: 'Forming' },\n { value: 'ACTIVE', label: 'Active' },\n { value: 'INACTIVE', label: 'Inactive' },\n { value: 'ARCHIVED', label: 'Archived' },\n];\n\nconst PROGRAM_STATUS_OPTS: ReadonlyArray<{ value: AthProgramStatus; label: string }> = [\n { value: 'DRAFT', label: 'Draft' },\n { value: 'PUBLISHED', label: 'Published' },\n { value: 'ARCHIVED', label: 'Archived' },\n];\n\nconst FIXTURE_STATUS_OPTS: ReadonlyArray<{ value: AthFixtureStatus; label: string }> = [\n { value: 'SCHEDULED', label: 'Scheduled' },\n { value: 'LIVE', label: 'Live' },\n { value: 'COMPLETED', label: 'Completed' },\n { value: 'POSTPONED', label: 'Postponed' },\n { value: 'CANCELLED', label: 'Cancelled' },\n];\n\nconst SESSION_STATUS_OPTS: ReadonlyArray<{ value: AthSessionStatus; label: string }> = [\n { value: 'REQUESTED', label: 'Requested' },\n { value: 'CONFIRMED', label: 'Confirmed' },\n { value: 'COMPLETED', label: 'Completed' },\n { value: 'CANCELLED', label: 'Cancelled' },\n { value: 'NO_SHOW', label: 'No show' },\n];\n\n/** Renders an em dash for absent values so empty cells never read as a bug. */\nconst orDash = (value: string | number | null | undefined): string =>\n value === null || value === undefined || value === '' ? '—' : String(value);\n\n// ============================================================================\n// Teams\n// ============================================================================\n\nconst TeamsTab: FC = () => {\n const [sport, setSport] = useState<AthSport | ''>('');\n const [status, setStatus] = useState<AthTeamStatus | ''>('');\n const [page, setPage] = useState(0);\n\n const teams = useTeams({\n sport: sport || undefined,\n status: status || undefined,\n pagination: { limit: PAGE_SIZE, offset: page * PAGE_SIZE },\n });\n\n const items = teams.data?.items ?? [];\n\n return (\n <Card>\n <CardHeader>\n <CardTitle>Teams</CardTitle>\n <CardDescription>\n Every squad, club side, academy group and esports roster in the active workspace.\n </CardDescription>\n </CardHeader>\n <CardContent>\n <div className=\"mb-4 flex flex-wrap items-center gap-3\">\n <FilterSelect\n ariaLabel=\"Filter teams by sport\"\n allLabel=\"All sports\"\n value={sport}\n onChange={(v) => {\n setSport(v);\n setPage(0);\n }}\n options={SPORT_OPTS}\n />\n <FilterSelect\n ariaLabel=\"Filter teams by status\"\n allLabel=\"All statuses\"\n value={status}\n onChange={(v) => {\n setStatus(v);\n setPage(0);\n }}\n options={TEAM_STATUS_OPTS}\n />\n </div>\n\n {teams.isLoading ? (\n <LoadingState label=\"Loading teams…\" />\n ) : teams.isError ? (\n <ErrorState onRetry={() => void teams.refetch()} />\n ) : items.length === 0 ? (\n <EmptyState\n icon={<Users className=\"h-6 w-6\" />}\n title=\"No teams match these filters\"\n description=\"Teams created in this workspace will appear here for oversight.\"\n />\n ) : (\n <>\n <div className=\"overflow-x-auto\">\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead>Name</TableHead>\n <TableHead>Sport</TableHead>\n <TableHead>Status</TableHead>\n <TableHead>Age group</TableHead>\n <TableHead>Season</TableHead>\n <TableHead className=\"text-right\">Members</TableHead>\n <TableHead>Created</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {items.map((team) => (\n <TableRow key={team.id}>\n <TableCell className=\"font-medium text-text-primary\">{team.name}</TableCell>\n <TableCell className=\"text-text-secondary\">\n {SPORT_LABELS[team.sport]}\n </TableCell>\n <TableCell>\n <StatusBadge status={team.status} />\n </TableCell>\n <TableCell className=\"text-text-secondary\">{orDash(team.ageGroup)}</TableCell>\n <TableCell className=\"text-text-secondary\">{orDash(team.season)}</TableCell>\n <TableCell className=\"text-right text-text-secondary\">\n {team.members?.length ?? 0}\n </TableCell>\n <TableCell className=\"text-text-secondary\">\n {formatDate(team.createdAt)}\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </div>\n <CursorPager\n page={page}\n hasMore={teams.data?.pageInfo.hasMore ?? false}\n onPrev={() => setPage((p) => Math.max(0, p - 1))}\n onNext={() => setPage((p) => p + 1)}\n />\n </>\n )}\n </CardContent>\n </Card>\n );\n};\n\n// ============================================================================\n// Programs\n// ============================================================================\n\nconst ProgramsTab: FC = () => {\n const [sport, setSport] = useState<AthSport | ''>('');\n const [status, setStatus] = useState<AthProgramStatus | ''>('');\n const [page, setPage] = useState(0);\n\n const programs = usePrograms({\n sport: sport || undefined,\n status: status || undefined,\n pagination: { limit: PAGE_SIZE, offset: page * PAGE_SIZE },\n });\n\n const items = programs.data?.items ?? [];\n\n return (\n <Card>\n <CardHeader>\n <CardTitle>Training programs</CardTitle>\n <CardDescription>\n Coaching programs and templates, with their drill counts and publication state.\n </CardDescription>\n </CardHeader>\n <CardContent>\n <div className=\"mb-4 flex flex-wrap items-center gap-3\">\n <FilterSelect\n ariaLabel=\"Filter programs by sport\"\n allLabel=\"All sports\"\n value={sport}\n onChange={(v) => {\n setSport(v);\n setPage(0);\n }}\n options={SPORT_OPTS}\n />\n <FilterSelect\n ariaLabel=\"Filter programs by status\"\n allLabel=\"All statuses\"\n value={status}\n onChange={(v) => {\n setStatus(v);\n setPage(0);\n }}\n options={PROGRAM_STATUS_OPTS}\n />\n </div>\n\n {programs.isLoading ? (\n <LoadingState label=\"Loading programs…\" />\n ) : programs.isError ? (\n <ErrorState onRetry={() => void programs.refetch()} />\n ) : items.length === 0 ? (\n <EmptyState\n icon={<Dumbbell className=\"h-6 w-6\" />}\n title=\"No programs match these filters\"\n description=\"Programs authored by coaches in this workspace will appear here.\"\n />\n ) : (\n <>\n <div className=\"overflow-x-auto\">\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead>Name</TableHead>\n <TableHead>Sport</TableHead>\n <TableHead>Level</TableHead>\n <TableHead>Status</TableHead>\n <TableHead className=\"text-right\">Weeks</TableHead>\n <TableHead className=\"text-right\">Drills</TableHead>\n <TableHead>Template</TableHead>\n <TableHead>Created</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {items.map((program) => (\n <TableRow key={program.id}>\n <TableCell className=\"font-medium text-text-primary\">\n {program.name}\n </TableCell>\n <TableCell className=\"text-text-secondary\">\n {SPORT_LABELS[program.sport]}\n </TableCell>\n <TableCell className=\"text-text-secondary\">\n {PROGRAM_LEVEL_LABELS[program.level]}\n </TableCell>\n <TableCell>\n <StatusBadge status={program.status} />\n </TableCell>\n <TableCell className=\"text-right text-text-secondary\">\n {program.weeks}\n </TableCell>\n <TableCell className=\"text-right text-text-secondary\">\n {program.drills?.length ?? 0}\n </TableCell>\n <TableCell className=\"text-text-secondary\">\n {program.isTemplate ? 'Yes' : 'No'}\n </TableCell>\n <TableCell className=\"text-text-secondary\">\n {formatDate(program.createdAt)}\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </div>\n <CursorPager\n page={page}\n hasMore={programs.data?.pageInfo.hasMore ?? false}\n onPrev={() => setPage((p) => Math.max(0, p - 1))}\n onNext={() => setPage((p) => p + 1)}\n />\n </>\n )}\n </CardContent>\n </Card>\n );\n};\n\n// ============================================================================\n// Fixtures + standings\n// ============================================================================\n\nconst FixturesTab: FC = () => {\n const [status, setStatus] = useState<AthFixtureStatus | ''>('');\n const [page, setPage] = useState(0);\n const [competition, setCompetition] = useState<string | ''>('');\n\n const fixtures = useFixtures({\n status: status || undefined,\n pagination: { limit: PAGE_SIZE, offset: page * PAGE_SIZE },\n });\n\n const items = useMemo(() => fixtures.data?.items ?? [], [fixtures.data]);\n\n // Competition options are derived from the competitions actually present on\n // the loaded fixtures — never a hard-coded league list.\n const competitionOpts = useMemo(() => {\n const names = new Set<string>();\n for (const fixture of items) {\n if (fixture.competition) names.add(fixture.competition);\n }\n return [...names].sort().map((value) => ({ value, label: value }));\n }, [items]);\n\n const standings = useStandings(competition || undefined);\n const standingRows = standings.data ?? [];\n\n return (\n <div className=\"flex flex-col gap-6\">\n <Card>\n <CardHeader>\n <CardTitle>Fixtures</CardTitle>\n <CardDescription>\n Scheduled, live and completed fixtures across every competition in this workspace.\n </CardDescription>\n </CardHeader>\n <CardContent>\n <div className=\"mb-4 flex flex-wrap items-center gap-3\">\n <FilterSelect\n ariaLabel=\"Filter fixtures by status\"\n allLabel=\"All statuses\"\n value={status}\n onChange={(v) => {\n setStatus(v);\n setPage(0);\n }}\n options={FIXTURE_STATUS_OPTS}\n />\n </div>\n\n {fixtures.isLoading ? (\n <LoadingState label=\"Loading fixtures…\" />\n ) : fixtures.isError ? (\n <ErrorState onRetry={() => void fixtures.refetch()} />\n ) : items.length === 0 ? (\n <EmptyState\n icon={<CalendarDays className=\"h-6 w-6\" />}\n title=\"No fixtures match these filters\"\n description=\"Fixtures scheduled in this workspace will appear here.\"\n />\n ) : (\n <>\n <div className=\"overflow-x-auto\">\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead>Home</TableHead>\n <TableHead>Away</TableHead>\n <TableHead>Competition</TableHead>\n <TableHead>Type</TableHead>\n <TableHead>Status</TableHead>\n <TableHead className=\"text-right\">Score</TableHead>\n <TableHead>Scheduled</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {items.map((fixture) => (\n <TableRow key={fixture.id}>\n <TableCell className=\"font-medium text-text-primary\">\n {orDash(fixture.homeTeam?.name)}\n </TableCell>\n <TableCell className=\"font-medium text-text-primary\">\n {orDash(fixture.awayTeam?.name)}\n </TableCell>\n <TableCell className=\"text-text-secondary\">\n {orDash(fixture.competition)}\n </TableCell>\n <TableCell className=\"text-text-secondary\">\n {FIXTURE_TYPE_LABELS[fixture.type]}\n </TableCell>\n <TableCell>\n <StatusBadge status={fixture.status} />\n </TableCell>\n <TableCell className=\"text-right text-text-secondary\">\n {fixture.homeScore === null || fixture.awayScore === null\n ? '—'\n : `${fixture.homeScore}–${fixture.awayScore}`}\n </TableCell>\n <TableCell className=\"text-text-secondary\">\n {formatDate(fixture.scheduledAt)}\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </div>\n <CursorPager\n page={page}\n hasMore={fixtures.data?.pageInfo.hasMore ?? false}\n onPrev={() => setPage((p) => Math.max(0, p - 1))}\n onNext={() => setPage((p) => p + 1)}\n />\n </>\n )}\n </CardContent>\n </Card>\n\n <Card>\n <CardHeader>\n <CardTitle>Standings</CardTitle>\n <CardDescription>\n League table for a competition, recomputed by the service when a fixture result is\n recorded. Pick a competition seen on the fixtures above.\n </CardDescription>\n </CardHeader>\n <CardContent>\n {competitionOpts.length === 0 ? (\n <EmptyState\n icon={<Trophy className=\"h-6 w-6\" />}\n title=\"No competitions to show\"\n description=\"Standings appear once fixtures in this workspace are assigned a competition.\"\n />\n ) : (\n <>\n <div className=\"mb-4 flex flex-wrap items-center gap-3\">\n <FilterSelect\n ariaLabel=\"Select a competition\"\n allLabel=\"Select a competition…\"\n value={competition}\n onChange={setCompetition}\n options={competitionOpts}\n />\n </div>\n\n {!competition ? (\n <EmptyState\n icon={<Trophy className=\"h-6 w-6\" />}\n title=\"Select a competition\"\n description=\"Choose a competition above to load its standings.\"\n />\n ) : standings.isLoading ? (\n <LoadingState label=\"Loading standings…\" />\n ) : standings.isError ? (\n <ErrorState onRetry={() => void standings.refetch()} />\n ) : standingRows.length === 0 ? (\n <EmptyState\n icon={<Trophy className=\"h-6 w-6\" />}\n title=\"No standings recorded yet\"\n description=\"Standings are computed once results are recorded for this competition.\"\n />\n ) : (\n <div className=\"overflow-x-auto\">\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead className=\"text-right\">#</TableHead>\n <TableHead>Team</TableHead>\n <TableHead className=\"text-right\">P</TableHead>\n <TableHead className=\"text-right\">W</TableHead>\n <TableHead className=\"text-right\">D</TableHead>\n <TableHead className=\"text-right\">L</TableHead>\n <TableHead className=\"text-right\">GF</TableHead>\n <TableHead className=\"text-right\">GA</TableHead>\n <TableHead className=\"text-right\">Pts</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {standingRows.map((row) => (\n <TableRow key={row.id}>\n <TableCell className=\"text-right text-text-secondary\">\n {orDash(row.rank)}\n </TableCell>\n <TableCell className=\"font-medium text-text-primary\">\n {orDash(row.team?.name)}\n </TableCell>\n <TableCell className=\"text-right text-text-secondary\">\n {row.played}\n </TableCell>\n <TableCell className=\"text-right text-text-secondary\">\n {row.won}\n </TableCell>\n <TableCell className=\"text-right text-text-secondary\">\n {row.drawn}\n </TableCell>\n <TableCell className=\"text-right text-text-secondary\">\n {row.lost}\n </TableCell>\n <TableCell className=\"text-right text-text-secondary\">\n {row.goalsFor}\n </TableCell>\n <TableCell className=\"text-right text-text-secondary\">\n {row.goalsAgainst}\n </TableCell>\n <TableCell className=\"text-right font-medium text-text-primary\">\n {row.points}\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </div>\n )}\n </>\n )}\n </CardContent>\n </Card>\n </div>\n );\n};\n\n// ============================================================================\n// Sessions\n// ============================================================================\n\nconst SessionsTab: FC = () => {\n const [status, setStatus] = useState<AthSessionStatus | ''>('');\n const [page, setPage] = useState(0);\n\n const sessions = useSessions({\n status: status || undefined,\n pagination: { limit: PAGE_SIZE, offset: page * PAGE_SIZE },\n });\n\n const items = sessions.data?.items ?? [];\n\n return (\n <Card>\n <CardHeader>\n <CardTitle>Coaching sessions</CardTitle>\n <CardDescription>\n Booked, confirmed and completed one-to-one coaching sessions in this workspace.\n </CardDescription>\n </CardHeader>\n <CardContent>\n <div className=\"mb-4 flex flex-wrap items-center gap-3\">\n <FilterSelect\n ariaLabel=\"Filter sessions by status\"\n allLabel=\"All statuses\"\n value={status}\n onChange={(v) => {\n setStatus(v);\n setPage(0);\n }}\n options={SESSION_STATUS_OPTS}\n />\n </div>\n\n {sessions.isLoading ? (\n <LoadingState label=\"Loading sessions…\" />\n ) : sessions.isError ? (\n <ErrorState onRetry={() => void sessions.refetch()} />\n ) : items.length === 0 ? (\n <EmptyState\n icon={<ClipboardCheck className=\"h-6 w-6\" />}\n title=\"No sessions match these filters\"\n description=\"Coaching sessions booked in this workspace will appear here.\"\n />\n ) : (\n <>\n <div className=\"overflow-x-auto\">\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead>Title</TableHead>\n <TableHead>Type</TableHead>\n <TableHead>Status</TableHead>\n <TableHead>Scheduled</TableHead>\n <TableHead>Duration</TableHead>\n <TableHead className=\"text-right\">Rating</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {items.map((session) => (\n <TableRow key={session.id}>\n <TableCell className=\"font-medium text-text-primary\">\n {session.title}\n </TableCell>\n <TableCell className=\"text-text-secondary\">\n {SESSION_TYPE_LABELS[session.type]}\n </TableCell>\n <TableCell>\n <StatusBadge status={session.status} />\n </TableCell>\n <TableCell className=\"text-text-secondary\">\n {formatDate(session.scheduledAt)}\n </TableCell>\n <TableCell className=\"text-text-secondary\">\n {formatDuration(session.durationMin)}\n </TableCell>\n <TableCell className=\"text-right text-text-secondary\">\n {orDash(session.rating)}\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </div>\n <CursorPager\n page={page}\n hasMore={sessions.data?.pageInfo.hasMore ?? false}\n onPrev={() => setPage((p) => Math.max(0, p - 1))}\n onNext={() => setPage((p) => p + 1)}\n />\n </>\n )}\n </CardContent>\n </Card>\n );\n};\n\n// ============================================================================\n// Dashboard\n// ============================================================================\n\nexport const AdminDashboardPage: FC = () => {\n const [activeTab, setActiveTab] = useState('teams');\n\n return (\n <PageLayout\n title=\"AthleteBridge Admin\"\n description=\"Operations oversight for AthleteBridge teams, programs, fixtures and sessions.\"\n hero\n gradientTitle\n >\n <Tabs value={activeTab} onValueChange={setActiveTab} className=\"w-full\">\n <TabsList className=\"mb-4 grid w-full grid-cols-4 sm:w-auto sm:inline-flex\">\n <TabsTrigger value=\"teams\" className=\"gap-2\">\n <Users size={16} />\n Teams\n </TabsTrigger>\n <TabsTrigger value=\"programs\" className=\"gap-2\">\n <Dumbbell size={16} />\n Programs\n </TabsTrigger>\n <TabsTrigger value=\"fixtures\" className=\"gap-2\">\n <CalendarDays size={16} />\n Fixtures\n </TabsTrigger>\n <TabsTrigger value=\"sessions\" className=\"gap-2\">\n <ClipboardCheck size={16} />\n Sessions\n </TabsTrigger>\n </TabsList>\n\n <TabsContent value=\"teams\">\n <TeamsTab />\n </TabsContent>\n <TabsContent value=\"programs\">\n <ProgramsTab />\n </TabsContent>\n <TabsContent value=\"fixtures\">\n <FixturesTab />\n </TabsContent>\n <TabsContent value=\"sessions\">\n <SessionsTab />\n </TabsContent>\n </Tabs>\n </PageLayout>\n );\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"AdminDashboardPage.js","names":[],"sources":["../../../src/atheletebridge/admin/AdminDashboardPage.tsx"],"sourcesContent":["/**\n * AthleteBridge Admin Dashboard\n * @module atheletebridge/admin\n *\n * Product-specific governance surface mounted inside `admin-app` at\n * `/admin/atheletebridge` (BOFF-3258).\n *\n * Every tab below is backed by a REAL, shipped `wspace-atheletebridge-svc`\n * root field reached through the workspace gateway:\n *\n * Teams → athListTeams (useTeams)\n * Programs → athListPrograms (usePrograms)\n * Fixtures → athListFixtures (useFixtures) + athStandings (useStandings)\n * Sessions → athListSessions (useSessions)\n *\n * DELIBERATE OMISSION (RULINGS R6): governance surfaces that have no backing\n * query are OMITTED ENTIRELY rather than shipped with invented rows. This file\n * intentionally does NOT copy the `PLACEHOLDER_ADAPTERS` / `PLACEHOLDER_LISTINGS`\n * pattern from `microfe-subscriberbot/src/subscriberbot/admin/AdminDashboardPage.tsx`,\n * which renders fabricated data behind a \"backend not implemented\" banner. There\n * are zero hard-coded rows here.\n *\n * READ-ONLY BY DESIGN: this is an operations/support oversight view. Lifecycle\n * mutations (archive team, transition program, cancel session, …) already exist\n * in the product UI behind the same RBAC pairs; duplicating them here would add\n * a second write path to a service already on the duplication watch list\n * (05-OVERLAP-AND-DUPLICATION-REPORT.md:249) without a governance need.\n */\n\nimport { useMemo, useState, type FC } from 'react';\nimport {\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n Tabs,\n TabsContent,\n TabsList,\n TabsTrigger,\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n} from '@burdenoff/fe-libs/ui';\nimport { CalendarDays, ClipboardCheck, Dumbbell, Trophy, Users } from 'lucide-react';\n\nimport { CursorPager } from '../components/CursorPager';\nimport { EmptyState } from '../components/EmptyState';\nimport { FilterSelect } from '../components/FilterSelect';\nimport { LoadingState, ErrorState } from '../components/LoadingState';\nimport { PageLayout } from '../components/PageLayout';\nimport { StatusBadge } from '../components/StatusBadge';\nimport {\n FIXTURE_TYPE_LABELS,\n PROGRAM_LEVEL_LABELS,\n SESSION_TYPE_LABELS,\n SPORT_LABELS,\n} from '../components/domain';\nimport { useFixtures, usePrograms, useSessions, useStandings, useTeams } from '../hooks';\nimport { formatDate, formatDuration } from '../utils/formatters';\nimport type {\n AthFixtureStatus,\n AthProgramStatus,\n AthSessionStatus,\n AthSport,\n AthTeamStatus,\n} from '../types';\n\nconst PAGE_SIZE = 20;\n\nconst SPORT_OPTS = (Object.keys(SPORT_LABELS) as AthSport[]).map((value) => ({\n value,\n label: SPORT_LABELS[value],\n}));\n\nconst TEAM_STATUS_OPTS: ReadonlyArray<{ value: AthTeamStatus; label: string }> = [\n { value: 'FORMING', label: 'Forming' },\n { value: 'ACTIVE', label: 'Active' },\n { value: 'INACTIVE', label: 'Inactive' },\n { value: 'ARCHIVED', label: 'Archived' },\n];\n\nconst PROGRAM_STATUS_OPTS: ReadonlyArray<{ value: AthProgramStatus; label: string }> = [\n { value: 'DRAFT', label: 'Draft' },\n { value: 'PUBLISHED', label: 'Published' },\n { value: 'ARCHIVED', label: 'Archived' },\n];\n\nconst FIXTURE_STATUS_OPTS: ReadonlyArray<{ value: AthFixtureStatus; label: string }> = [\n { value: 'SCHEDULED', label: 'Scheduled' },\n { value: 'LIVE', label: 'Live' },\n { value: 'COMPLETED', label: 'Completed' },\n { value: 'POSTPONED', label: 'Postponed' },\n { value: 'CANCELLED', label: 'Cancelled' },\n];\n\nconst SESSION_STATUS_OPTS: ReadonlyArray<{ value: AthSessionStatus; label: string }> = [\n { value: 'REQUESTED', label: 'Requested' },\n { value: 'CONFIRMED', label: 'Confirmed' },\n { value: 'COMPLETED', label: 'Completed' },\n { value: 'CANCELLED', label: 'Cancelled' },\n { value: 'NO_SHOW', label: 'No show' },\n];\n\n/** Renders an em dash for absent values so empty cells never read as a bug. */\nconst orDash = (value: string | number | null | undefined): string =>\n value === null || value === undefined || value === '' ? '—' : String(value);\n\n// ============================================================================\n// Teams\n// ============================================================================\n\nconst TeamsTab: FC = () => {\n const [sport, setSport] = useState<AthSport | ''>('');\n const [status, setStatus] = useState<AthTeamStatus | ''>('');\n const [page, setPage] = useState(0);\n\n const teams = useTeams({\n sport: sport || undefined,\n status: status || undefined,\n pagination: { limit: PAGE_SIZE, offset: page * PAGE_SIZE },\n });\n\n const items = teams.data?.items ?? [];\n\n return (\n <Card>\n <CardHeader>\n <CardTitle>Teams</CardTitle>\n <CardDescription>\n Every squad, club side, academy group and esports roster in the active workspace.\n </CardDescription>\n </CardHeader>\n <CardContent>\n <div className=\"mb-4 flex flex-wrap items-center gap-3\">\n <FilterSelect\n ariaLabel=\"Filter teams by sport\"\n allLabel=\"All sports\"\n value={sport}\n onChange={(v) => {\n setSport(v);\n setPage(0);\n }}\n options={SPORT_OPTS}\n />\n <FilterSelect\n ariaLabel=\"Filter teams by status\"\n allLabel=\"All statuses\"\n value={status}\n onChange={(v) => {\n setStatus(v);\n setPage(0);\n }}\n options={TEAM_STATUS_OPTS}\n />\n </div>\n\n {teams.isLoading ? (\n <LoadingState label=\"Loading teams…\" />\n ) : teams.isError ? (\n <ErrorState onRetry={() => void teams.refetch()} />\n ) : items.length === 0 ? (\n <EmptyState\n icon={<Users className=\"h-6 w-6\" />}\n title=\"No teams match these filters\"\n description=\"Teams created in this workspace will appear here for oversight.\"\n />\n ) : (\n <>\n <div className=\"overflow-x-auto\">\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead>Name</TableHead>\n <TableHead>Sport</TableHead>\n <TableHead>Status</TableHead>\n <TableHead>Age group</TableHead>\n <TableHead>Season</TableHead>\n <TableHead className=\"text-right\">Members</TableHead>\n <TableHead>Created</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {items.map((team) => (\n <TableRow key={team.id}>\n <TableCell className=\"font-medium text-text-primary\">{team.name}</TableCell>\n <TableCell className=\"text-text-secondary\">\n {SPORT_LABELS[team.sport]}\n </TableCell>\n <TableCell>\n <StatusBadge status={team.status} />\n </TableCell>\n <TableCell className=\"text-text-secondary\">{orDash(team.ageGroup)}</TableCell>\n <TableCell className=\"text-text-secondary\">{orDash(team.season)}</TableCell>\n <TableCell className=\"text-right text-text-secondary\">\n {team.members?.items.length ?? 0}\n </TableCell>\n <TableCell className=\"text-text-secondary\">\n {formatDate(team.createdAt)}\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </div>\n <CursorPager\n page={page}\n hasMore={teams.data?.pageInfo.hasMore ?? false}\n onPrev={() => setPage((p) => Math.max(0, p - 1))}\n onNext={() => setPage((p) => p + 1)}\n />\n </>\n )}\n </CardContent>\n </Card>\n );\n};\n\n// ============================================================================\n// Programs\n// ============================================================================\n\nconst ProgramsTab: FC = () => {\n const [sport, setSport] = useState<AthSport | ''>('');\n const [status, setStatus] = useState<AthProgramStatus | ''>('');\n const [page, setPage] = useState(0);\n\n const programs = usePrograms({\n sport: sport || undefined,\n status: status || undefined,\n pagination: { limit: PAGE_SIZE, offset: page * PAGE_SIZE },\n });\n\n const items = programs.data?.items ?? [];\n\n return (\n <Card>\n <CardHeader>\n <CardTitle>Training programs</CardTitle>\n <CardDescription>\n Coaching programs and templates, with their drill counts and publication state.\n </CardDescription>\n </CardHeader>\n <CardContent>\n <div className=\"mb-4 flex flex-wrap items-center gap-3\">\n <FilterSelect\n ariaLabel=\"Filter programs by sport\"\n allLabel=\"All sports\"\n value={sport}\n onChange={(v) => {\n setSport(v);\n setPage(0);\n }}\n options={SPORT_OPTS}\n />\n <FilterSelect\n ariaLabel=\"Filter programs by status\"\n allLabel=\"All statuses\"\n value={status}\n onChange={(v) => {\n setStatus(v);\n setPage(0);\n }}\n options={PROGRAM_STATUS_OPTS}\n />\n </div>\n\n {programs.isLoading ? (\n <LoadingState label=\"Loading programs…\" />\n ) : programs.isError ? (\n <ErrorState onRetry={() => void programs.refetch()} />\n ) : items.length === 0 ? (\n <EmptyState\n icon={<Dumbbell className=\"h-6 w-6\" />}\n title=\"No programs match these filters\"\n description=\"Programs authored by coaches in this workspace will appear here.\"\n />\n ) : (\n <>\n <div className=\"overflow-x-auto\">\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead>Name</TableHead>\n <TableHead>Sport</TableHead>\n <TableHead>Level</TableHead>\n <TableHead>Status</TableHead>\n <TableHead className=\"text-right\">Weeks</TableHead>\n <TableHead className=\"text-right\">Drills</TableHead>\n <TableHead>Template</TableHead>\n <TableHead>Created</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {items.map((program) => (\n <TableRow key={program.id}>\n <TableCell className=\"font-medium text-text-primary\">\n {program.name}\n </TableCell>\n <TableCell className=\"text-text-secondary\">\n {SPORT_LABELS[program.sport]}\n </TableCell>\n <TableCell className=\"text-text-secondary\">\n {PROGRAM_LEVEL_LABELS[program.level]}\n </TableCell>\n <TableCell>\n <StatusBadge status={program.status} />\n </TableCell>\n <TableCell className=\"text-right text-text-secondary\">\n {program.weeks}\n </TableCell>\n <TableCell className=\"text-right text-text-secondary\">\n {program.drills?.items.length ?? 0}\n </TableCell>\n <TableCell className=\"text-text-secondary\">\n {program.isTemplate ? 'Yes' : 'No'}\n </TableCell>\n <TableCell className=\"text-text-secondary\">\n {formatDate(program.createdAt)}\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </div>\n <CursorPager\n page={page}\n hasMore={programs.data?.pageInfo.hasMore ?? false}\n onPrev={() => setPage((p) => Math.max(0, p - 1))}\n onNext={() => setPage((p) => p + 1)}\n />\n </>\n )}\n </CardContent>\n </Card>\n );\n};\n\n// ============================================================================\n// Fixtures + standings\n// ============================================================================\n\nconst FixturesTab: FC = () => {\n const [status, setStatus] = useState<AthFixtureStatus | ''>('');\n const [page, setPage] = useState(0);\n const [competition, setCompetition] = useState<string | ''>('');\n\n const fixtures = useFixtures({\n status: status || undefined,\n pagination: { limit: PAGE_SIZE, offset: page * PAGE_SIZE },\n });\n\n const items = useMemo(() => fixtures.data?.items ?? [], [fixtures.data]);\n\n // Competition options are derived from the competitions actually present on\n // the loaded fixtures — never a hard-coded league list.\n const competitionOpts = useMemo(() => {\n const names = new Set<string>();\n for (const fixture of items) {\n if (fixture.competition) names.add(fixture.competition);\n }\n return [...names].sort().map((value) => ({ value, label: value }));\n }, [items]);\n\n const standings = useStandings(competition || undefined);\n const standingRows = standings.data ?? [];\n\n return (\n <div className=\"flex flex-col gap-6\">\n <Card>\n <CardHeader>\n <CardTitle>Fixtures</CardTitle>\n <CardDescription>\n Scheduled, live and completed fixtures across every competition in this workspace.\n </CardDescription>\n </CardHeader>\n <CardContent>\n <div className=\"mb-4 flex flex-wrap items-center gap-3\">\n <FilterSelect\n ariaLabel=\"Filter fixtures by status\"\n allLabel=\"All statuses\"\n value={status}\n onChange={(v) => {\n setStatus(v);\n setPage(0);\n }}\n options={FIXTURE_STATUS_OPTS}\n />\n </div>\n\n {fixtures.isLoading ? (\n <LoadingState label=\"Loading fixtures…\" />\n ) : fixtures.isError ? (\n <ErrorState onRetry={() => void fixtures.refetch()} />\n ) : items.length === 0 ? (\n <EmptyState\n icon={<CalendarDays className=\"h-6 w-6\" />}\n title=\"No fixtures match these filters\"\n description=\"Fixtures scheduled in this workspace will appear here.\"\n />\n ) : (\n <>\n <div className=\"overflow-x-auto\">\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead>Home</TableHead>\n <TableHead>Away</TableHead>\n <TableHead>Competition</TableHead>\n <TableHead>Type</TableHead>\n <TableHead>Status</TableHead>\n <TableHead className=\"text-right\">Score</TableHead>\n <TableHead>Scheduled</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {items.map((fixture) => (\n <TableRow key={fixture.id}>\n <TableCell className=\"font-medium text-text-primary\">\n {orDash(fixture.homeTeam?.name)}\n </TableCell>\n <TableCell className=\"font-medium text-text-primary\">\n {orDash(fixture.awayTeam?.name)}\n </TableCell>\n <TableCell className=\"text-text-secondary\">\n {orDash(fixture.competition)}\n </TableCell>\n <TableCell className=\"text-text-secondary\">\n {FIXTURE_TYPE_LABELS[fixture.type]}\n </TableCell>\n <TableCell>\n <StatusBadge status={fixture.status} />\n </TableCell>\n <TableCell className=\"text-right text-text-secondary\">\n {fixture.homeScore === null || fixture.awayScore === null\n ? '—'\n : `${fixture.homeScore}–${fixture.awayScore}`}\n </TableCell>\n <TableCell className=\"text-text-secondary\">\n {formatDate(fixture.scheduledAt)}\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </div>\n <CursorPager\n page={page}\n hasMore={fixtures.data?.pageInfo.hasMore ?? false}\n onPrev={() => setPage((p) => Math.max(0, p - 1))}\n onNext={() => setPage((p) => p + 1)}\n />\n </>\n )}\n </CardContent>\n </Card>\n\n <Card>\n <CardHeader>\n <CardTitle>Standings</CardTitle>\n <CardDescription>\n League table for a competition, recomputed by the service when a fixture result is\n recorded. Pick a competition seen on the fixtures above.\n </CardDescription>\n </CardHeader>\n <CardContent>\n {competitionOpts.length === 0 ? (\n <EmptyState\n icon={<Trophy className=\"h-6 w-6\" />}\n title=\"No competitions to show\"\n description=\"Standings appear once fixtures in this workspace are assigned a competition.\"\n />\n ) : (\n <>\n <div className=\"mb-4 flex flex-wrap items-center gap-3\">\n <FilterSelect\n ariaLabel=\"Select a competition\"\n allLabel=\"Select a competition…\"\n value={competition}\n onChange={setCompetition}\n options={competitionOpts}\n />\n </div>\n\n {!competition ? (\n <EmptyState\n icon={<Trophy className=\"h-6 w-6\" />}\n title=\"Select a competition\"\n description=\"Choose a competition above to load its standings.\"\n />\n ) : standings.isLoading ? (\n <LoadingState label=\"Loading standings…\" />\n ) : standings.isError ? (\n <ErrorState onRetry={() => void standings.refetch()} />\n ) : standingRows.length === 0 ? (\n <EmptyState\n icon={<Trophy className=\"h-6 w-6\" />}\n title=\"No standings recorded yet\"\n description=\"Standings are computed once results are recorded for this competition.\"\n />\n ) : (\n <div className=\"overflow-x-auto\">\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead className=\"text-right\">#</TableHead>\n <TableHead>Team</TableHead>\n <TableHead className=\"text-right\">P</TableHead>\n <TableHead className=\"text-right\">W</TableHead>\n <TableHead className=\"text-right\">D</TableHead>\n <TableHead className=\"text-right\">L</TableHead>\n <TableHead className=\"text-right\">GF</TableHead>\n <TableHead className=\"text-right\">GA</TableHead>\n <TableHead className=\"text-right\">Pts</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {standingRows.map((row) => (\n <TableRow key={row.id}>\n <TableCell className=\"text-right text-text-secondary\">\n {orDash(row.rank)}\n </TableCell>\n <TableCell className=\"font-medium text-text-primary\">\n {orDash(row.team?.name)}\n </TableCell>\n <TableCell className=\"text-right text-text-secondary\">\n {row.played}\n </TableCell>\n <TableCell className=\"text-right text-text-secondary\">\n {row.won}\n </TableCell>\n <TableCell className=\"text-right text-text-secondary\">\n {row.drawn}\n </TableCell>\n <TableCell className=\"text-right text-text-secondary\">\n {row.lost}\n </TableCell>\n <TableCell className=\"text-right text-text-secondary\">\n {row.goalsFor}\n </TableCell>\n <TableCell className=\"text-right text-text-secondary\">\n {row.goalsAgainst}\n </TableCell>\n <TableCell className=\"text-right font-medium text-text-primary\">\n {row.points}\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </div>\n )}\n </>\n )}\n </CardContent>\n </Card>\n </div>\n );\n};\n\n// ============================================================================\n// Sessions\n// ============================================================================\n\nconst SessionsTab: FC = () => {\n const [status, setStatus] = useState<AthSessionStatus | ''>('');\n const [page, setPage] = useState(0);\n\n const sessions = useSessions({\n status: status || undefined,\n pagination: { limit: PAGE_SIZE, offset: page * PAGE_SIZE },\n });\n\n const items = sessions.data?.items ?? [];\n\n return (\n <Card>\n <CardHeader>\n <CardTitle>Coaching sessions</CardTitle>\n <CardDescription>\n Booked, confirmed and completed one-to-one coaching sessions in this workspace.\n </CardDescription>\n </CardHeader>\n <CardContent>\n <div className=\"mb-4 flex flex-wrap items-center gap-3\">\n <FilterSelect\n ariaLabel=\"Filter sessions by status\"\n allLabel=\"All statuses\"\n value={status}\n onChange={(v) => {\n setStatus(v);\n setPage(0);\n }}\n options={SESSION_STATUS_OPTS}\n />\n </div>\n\n {sessions.isLoading ? (\n <LoadingState label=\"Loading sessions…\" />\n ) : sessions.isError ? (\n <ErrorState onRetry={() => void sessions.refetch()} />\n ) : items.length === 0 ? (\n <EmptyState\n icon={<ClipboardCheck className=\"h-6 w-6\" />}\n title=\"No sessions match these filters\"\n description=\"Coaching sessions booked in this workspace will appear here.\"\n />\n ) : (\n <>\n <div className=\"overflow-x-auto\">\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead>Title</TableHead>\n <TableHead>Type</TableHead>\n <TableHead>Status</TableHead>\n <TableHead>Scheduled</TableHead>\n <TableHead>Duration</TableHead>\n <TableHead className=\"text-right\">Rating</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {items.map((session) => (\n <TableRow key={session.id}>\n <TableCell className=\"font-medium text-text-primary\">\n {session.title}\n </TableCell>\n <TableCell className=\"text-text-secondary\">\n {SESSION_TYPE_LABELS[session.type]}\n </TableCell>\n <TableCell>\n <StatusBadge status={session.status} />\n </TableCell>\n <TableCell className=\"text-text-secondary\">\n {formatDate(session.scheduledAt)}\n </TableCell>\n <TableCell className=\"text-text-secondary\">\n {formatDuration(session.durationMin)}\n </TableCell>\n <TableCell className=\"text-right text-text-secondary\">\n {orDash(session.rating)}\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </div>\n <CursorPager\n page={page}\n hasMore={sessions.data?.pageInfo.hasMore ?? false}\n onPrev={() => setPage((p) => Math.max(0, p - 1))}\n onNext={() => setPage((p) => p + 1)}\n />\n </>\n )}\n </CardContent>\n </Card>\n );\n};\n\n// ============================================================================\n// Dashboard\n// ============================================================================\n\nexport const AdminDashboardPage: FC = () => {\n const [activeTab, setActiveTab] = useState('teams');\n\n return (\n <PageLayout\n title=\"AthleteBridge Admin\"\n description=\"Operations oversight for AthleteBridge teams, programs, fixtures and sessions.\"\n hero\n gradientTitle\n >\n <Tabs value={activeTab} onValueChange={setActiveTab} className=\"w-full\">\n <TabsList className=\"mb-4 grid w-full grid-cols-4 sm:w-auto sm:inline-flex\">\n <TabsTrigger value=\"teams\" className=\"gap-2\">\n <Users size={16} />\n Teams\n </TabsTrigger>\n <TabsTrigger value=\"programs\" className=\"gap-2\">\n <Dumbbell size={16} />\n Programs\n </TabsTrigger>\n <TabsTrigger value=\"fixtures\" className=\"gap-2\">\n <CalendarDays size={16} />\n Fixtures\n </TabsTrigger>\n <TabsTrigger value=\"sessions\" className=\"gap-2\">\n <ClipboardCheck size={16} />\n Sessions\n </TabsTrigger>\n </TabsList>\n\n <TabsContent value=\"teams\">\n <TeamsTab />\n </TabsContent>\n <TabsContent value=\"programs\">\n <ProgramsTab />\n </TabsContent>\n <TabsContent value=\"fixtures\">\n <FixturesTab />\n </TabsContent>\n <TabsContent value=\"sessions\">\n <SessionsTab />\n </TabsContent>\n </Tabs>\n </PageLayout>\n );\n};\n"],"mappings":"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"}
|
|
@@ -11,7 +11,7 @@ var f = {
|
|
|
11
11
|
ADVANCED: "warning",
|
|
12
12
|
ELITE: "default"
|
|
13
13
|
}, p = ({ program: p, onClick: m, drillCount: h }) => {
|
|
14
|
-
let g = r[p.sport], _ = h ?? p.drills?.length;
|
|
14
|
+
let g = r[p.sport], _ = h ?? p.drills?.items.length;
|
|
15
15
|
return /* @__PURE__ */ l(d, {
|
|
16
16
|
treatment: "metric",
|
|
17
17
|
role: "button",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProgramCard.js","names":[],"sources":["../../../src/atheletebridge/components/ProgramCard.tsx"],"sourcesContent":["/**\n * Program Card\n * @module atheletebridge/components\n *\n * A training-program tile with a sport-icon tile, a level Badge tinted per tier\n * (green Beginner / blue Intermediate / amber Advanced / brand Elite), a status\n * pill, and a footer stat row of weeks + drill counts. Semantic tokens only.\n */\n\nimport type { FC } from 'react';\nimport { CalendarRange, Copy, Dumbbell } from 'lucide-react';\nimport { GlassCard, Badge, type BadgeProps } from '@burdenoff/fe-libs/ui';\nimport { StatusBadge } from './StatusBadge';\nimport { SPORT_ICONS, SPORT_LABELS, PROGRAM_LEVEL_LABELS } from './domain';\nimport { cn } from '../utils/cn';\nimport type { AthProgram, AthProgramLevel } from '../types';\n\ninterface ProgramCardProps {\n program: AthProgram;\n onClick?: () => void;\n /**\n * Drill count for the footer chip. Falls back to `program.drills?.length`\n * when the query selected drills; omit the chip if neither is available.\n */\n drillCount?: number;\n}\n\nconst LEVEL_VARIANT: Record<AthProgramLevel, BadgeProps['variant']> = {\n BEGINNER: 'success',\n INTERMEDIATE: 'info',\n ADVANCED: 'warning',\n ELITE: 'default',\n};\n\nexport const ProgramCard: FC<ProgramCardProps> = ({ program, onClick, drillCount }) => {\n const SportIcon = SPORT_ICONS[program.sport];\n const drills = drillCount ?? program.drills?.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 <div className=\"flex h-11 w-11 shrink-0 items-center justify-center rounded-xl bg-[var(--color-accent-soft)] text-text-primary\">\n <SportIcon className=\"h-5 w-5\" aria-hidden=\"true\" />\n </div>\n <div className=\"min-w-0\">\n <h3 className=\"truncate text-base font-semibold text-text-primary\">{program.name}</h3>\n <div className=\"mt-1 flex flex-wrap items-center gap-1.5\">\n <Badge variant={LEVEL_VARIANT[program.level]}>\n {PROGRAM_LEVEL_LABELS[program.level]}\n </Badge>\n <span className=\"text-xs text-text-secondary\">{SPORT_LABELS[program.sport]}</span>\n </div>\n </div>\n </div>\n <StatusBadge status={program.status} />\n </div>\n\n {program.summary && (\n <p className=\"mt-3 line-clamp-2 text-sm text-text-secondary\">{program.summary}</p>\n )}\n\n <div className=\"mt-4 flex flex-wrap items-center gap-x-4 gap-y-1.5 text-xs text-text-secondary\">\n <span className=\"flex items-center gap-1\">\n <CalendarRange className=\"h-3.5 w-3.5\" aria-hidden=\"true\" /> {program.weeks}{' '}\n {program.weeks === 1 ? 'week' : 'weeks'}\n </span>\n {drills !== undefined && (\n <span className=\"flex items-center gap-1\">\n <Dumbbell className=\"h-3.5 w-3.5\" aria-hidden=\"true\" /> {drills}{' '}\n {drills === 1 ? 'drill' : 'drills'}\n </span>\n )}\n {program.isTemplate && (\n <span className=\"flex items-center gap-1\">\n <Copy className=\"h-3.5 w-3.5\" aria-hidden=\"true\" /> Template\n </span>\n )}\n </div>\n </GlassCard>\n );\n};\n"],"mappings":";;;;;;;AA2BA,IAAM,IAAgE;CACpE,UAAU;CACV,cAAc;CACd,UAAU;CACV,OAAO;CACR,EAEY,KAAqC,EAAE,YAAS,YAAS,oBAAiB;CACrF,IAAM,IAAY,EAAY,EAAQ,QAChC,IAAS,KAAc,EAAQ,QAAQ;
|
|
1
|
+
{"version":3,"file":"ProgramCard.js","names":[],"sources":["../../../src/atheletebridge/components/ProgramCard.tsx"],"sourcesContent":["/**\n * Program Card\n * @module atheletebridge/components\n *\n * A training-program tile with a sport-icon tile, a level Badge tinted per tier\n * (green Beginner / blue Intermediate / amber Advanced / brand Elite), a status\n * pill, and a footer stat row of weeks + drill counts. Semantic tokens only.\n */\n\nimport type { FC } from 'react';\nimport { CalendarRange, Copy, Dumbbell } from 'lucide-react';\nimport { GlassCard, Badge, type BadgeProps } from '@burdenoff/fe-libs/ui';\nimport { StatusBadge } from './StatusBadge';\nimport { SPORT_ICONS, SPORT_LABELS, PROGRAM_LEVEL_LABELS } from './domain';\nimport { cn } from '../utils/cn';\nimport type { AthProgram, AthProgramLevel } from '../types';\n\ninterface ProgramCardProps {\n program: AthProgram;\n onClick?: () => void;\n /**\n * Drill count for the footer chip. Falls back to `program.drills?.length`\n * when the query selected drills; omit the chip if neither is available.\n */\n drillCount?: number;\n}\n\nconst LEVEL_VARIANT: Record<AthProgramLevel, BadgeProps['variant']> = {\n BEGINNER: 'success',\n INTERMEDIATE: 'info',\n ADVANCED: 'warning',\n ELITE: 'default',\n};\n\nexport const ProgramCard: FC<ProgramCardProps> = ({ program, onClick, drillCount }) => {\n const SportIcon = SPORT_ICONS[program.sport];\n const drills = drillCount ?? program.drills?.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 <div className=\"flex h-11 w-11 shrink-0 items-center justify-center rounded-xl bg-[var(--color-accent-soft)] text-text-primary\">\n <SportIcon className=\"h-5 w-5\" aria-hidden=\"true\" />\n </div>\n <div className=\"min-w-0\">\n <h3 className=\"truncate text-base font-semibold text-text-primary\">{program.name}</h3>\n <div className=\"mt-1 flex flex-wrap items-center gap-1.5\">\n <Badge variant={LEVEL_VARIANT[program.level]}>\n {PROGRAM_LEVEL_LABELS[program.level]}\n </Badge>\n <span className=\"text-xs text-text-secondary\">{SPORT_LABELS[program.sport]}</span>\n </div>\n </div>\n </div>\n <StatusBadge status={program.status} />\n </div>\n\n {program.summary && (\n <p className=\"mt-3 line-clamp-2 text-sm text-text-secondary\">{program.summary}</p>\n )}\n\n <div className=\"mt-4 flex flex-wrap items-center gap-x-4 gap-y-1.5 text-xs text-text-secondary\">\n <span className=\"flex items-center gap-1\">\n <CalendarRange className=\"h-3.5 w-3.5\" aria-hidden=\"true\" /> {program.weeks}{' '}\n {program.weeks === 1 ? 'week' : 'weeks'}\n </span>\n {drills !== undefined && (\n <span className=\"flex items-center gap-1\">\n <Dumbbell className=\"h-3.5 w-3.5\" aria-hidden=\"true\" /> {drills}{' '}\n {drills === 1 ? 'drill' : 'drills'}\n </span>\n )}\n {program.isTemplate && (\n <span className=\"flex items-center gap-1\">\n <Copy className=\"h-3.5 w-3.5\" aria-hidden=\"true\" /> Template\n </span>\n )}\n </div>\n </GlassCard>\n );\n};\n"],"mappings":";;;;;;;AA2BA,IAAM,IAAgE;CACpE,UAAU;CACV,cAAc;CACd,UAAU;CACV,OAAO;CACR,EAEY,KAAqC,EAAE,YAAS,YAAS,oBAAiB;CACrF,IAAM,IAAY,EAAY,EAAQ,QAChC,IAAS,KAAc,EAAQ,QAAQ,MAAM;AAEnD,QACE,kBAAC,GAAD;EACE,WAAU;EACV,MAAK;EACL,UAAU;EACD;EACT,YAAY,MAAM;AAChB,IAAI,EAAE,QAAQ,WAAW,EAAE,QAAQ,SACjC,EAAE,gBAAgB,EAClB,KAAW;;EAGf,WAAW,EACT,2KACD;YAbH;GAeE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,OAAD;MAAK,WAAU;gBACb,kBAAC,GAAD;OAAW,WAAU;OAAU,eAAY;OAAS,CAAA;MAChD,CAAA,EACN,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,MAAD;OAAI,WAAU;iBAAsD,EAAQ;OAAU,CAAA,EACtF,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,GAAD;QAAO,SAAS,EAAc,EAAQ;kBACnC,EAAqB,EAAQ;QACxB,CAAA,EACR,kBAAC,QAAD;QAAM,WAAU;kBAA+B,EAAa,EAAQ;QAAc,CAAA,CAC9E;SACF;QACF;QACN,kBAAC,GAAD,EAAa,QAAQ,EAAQ,QAAU,CAAA,CACnC;;GAEL,EAAQ,WACP,kBAAC,KAAD;IAAG,WAAU;cAAiD,EAAQ;IAAY,CAAA;GAGpF,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,QAAD;MAAM,WAAU;gBAAhB;OACE,kBAAC,GAAD;QAAe,WAAU;QAAc,eAAY;QAAS,CAAA;;OAAE,EAAQ;OAAO;OAC5E,EAAQ,UAAU,IAAI,SAAS;OAC3B;;KACN,MAAW,KAAA,KACV,kBAAC,QAAD;MAAM,WAAU;gBAAhB;OACE,kBAAC,GAAD;QAAU,WAAU;QAAc,eAAY;QAAS,CAAA;;OAAE;OAAQ;OAChE,MAAW,IAAI,UAAU;OACrB;;KAER,EAAQ,cACP,kBAAC,QAAD;MAAM,WAAU;gBAAhB,CACE,kBAAC,GAAD;OAAM,WAAU;OAAc,eAAY;OAAS,CAAA,EAAA,YAC9C;;KAEL;;GACI"}
|
|
@@ -7,7 +7,7 @@ import { jsx as c, jsxs as l } from "react/jsx-runtime";
|
|
|
7
7
|
import { Badge as u, GlassCard as d } from "@burdenoff/fe-libs/ui";
|
|
8
8
|
//#region src/atheletebridge/components/TeamCard.tsx
|
|
9
9
|
var f = ({ team: f, onClick: p, memberCount: m }) => {
|
|
10
|
-
let h = n[f.sport], g = m ?? f.members?.length;
|
|
10
|
+
let h = n[f.sport], g = m ?? f.members?.items.length;
|
|
11
11
|
return /* @__PURE__ */ l(d, {
|
|
12
12
|
treatment: "metric",
|
|
13
13
|
role: "button",
|
|
@@ -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?.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;
|
|
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;AAEjD,QACE,kBAAC,GAAD;EACE,WAAU;EACV,MAAK;EACL,UAAU;EACD;EACT,YAAY,MAAM;AAChB,IAAI,EAAE,QAAQ,WAAW,EAAE,QAAQ,SACjC,EAAE,gBAAgB,EAClB,KAAW;;EAGf,WAAW,EACT,2KACD;YAbH;GAeE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,GAAD;MAAO,MAAM,EAAK;MAAM,OAAO,EAAK;MAAO,MAAM;MAAM,CAAA,EACvD,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,MAAD;OAAI,WAAU;iBAAsD,EAAK;OAAU,CAAA,EACnF,kBAAC,OAAD;OAAK,WAAU;iBACb,kBAAC,GAAD;QAAO,SAAQ;QAAY,WAAU;kBAArC,CACE,kBAAC,GAAD;SAAW,WAAU;SAAU,eAAY;SAAS,CAAA,EACnD,EAAa,EAAK,OACb;;OACJ,CAAA,CACF;QACF;QACN,kBAAC,GAAD,EAAa,QAAQ,EAAK,QAAU,CAAA,CAChC;;GAEN,kBAAC,OAAD;IAAK,WAAU;cAAf;KACG,EAAK,YACJ,kBAAC,QAAD;MAAM,WAAU;gBAAhB;OACE,kBAAC,GAAD;QAAO,WAAU;QAAc,eAAY;QAAS,CAAA;;OAAE,EAAK;OACtD;;KAER,EAAK,UACJ,kBAAC,QAAD;MAAM,WAAU;gBAAhB;OACE,kBAAC,GAAD;QAAc,WAAU;QAAc,eAAY;QAAS,CAAA;;OAAE,EAAK;OAC7D;;KAER,EAAK,aACJ,kBAAC,QAAD;MAAM,WAAU;gBAAhB;OACE,kBAAC,GAAD;QAAQ,WAAU;QAAuB,eAAY;QAAS,CAAA;;OAAE,EAAK;OAChE;;KAEL;;GAEL,EAAK,KAAK,SAAS,KAClB,kBAAC,OAAD;IAAK,WAAU;cACZ,EAAK,KAAK,MAAM,GAAG,EAAE,CAAC,KAAK,MAC1B,kBAAC,QAAD;KAEE,WAAU;eAET;KACI,EAJA,EAIA,CACP;IACE,CAAA;GAGP,MAAU,KAAA,KACT,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,GAAD;MAAO,WAAU;MAAc,eAAY;MAAS,CAAA;KACnD;KAAM;KAAE,MAAU,IAAI,WAAW;KAC9B;;GAEE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useAthleteBridgeApi.d.ts","sourceRoot":"","sources":["../../../src/atheletebridge/hooks/useAthleteBridgeApi.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AASH,OAAO,KAAK,EACV,uBAAuB,EACvB,qBAAqB,EACrB,qBAAqB,EACrB,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EAChB,mBAAmB,EACnB,QAAQ,EACR,UAAU,EACV,oBAAoB,EACpB,gBAAgB,EAChB,kBAAkB,EAClB,SAAS,
|
|
1
|
+
{"version":3,"file":"useAthleteBridgeApi.d.ts","sourceRoot":"","sources":["../../../src/atheletebridge/hooks/useAthleteBridgeApi.ts"],"names":[],"mappings":"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"}
|
|
@@ -35,7 +35,7 @@ var c = async (e, t, n) => {
|
|
|
35
35
|
],
|
|
36
36
|
queryFn: async () => (await c(`query AthListTeams($sport: AthSport, $status: AthTeamStatus, $pagination: PaginationInput) {
|
|
37
37
|
athListTeams(sport: $sport, status: $status, pagination: $pagination) {
|
|
38
|
-
items { ${u} members { id } }
|
|
38
|
+
items { ${u} members { items { id } } }
|
|
39
39
|
pageInfo { cursor hasMore }
|
|
40
40
|
}
|
|
41
41
|
}`, {
|
|
@@ -55,8 +55,8 @@ var c = async (e, t, n) => {
|
|
|
55
55
|
queryFn: async () => (await c(`query AthTeam($id: ID!) {
|
|
56
56
|
athTeam(id: $id) {
|
|
57
57
|
${u}
|
|
58
|
-
members { ${d} }
|
|
59
|
-
fixtures { ${f} }
|
|
58
|
+
members { items { ${d} } }
|
|
59
|
+
fixtures { items { ${f} } }
|
|
60
60
|
}
|
|
61
61
|
}`, { id: t }, n)).athTeam,
|
|
62
62
|
enabled: !!t
|
|
@@ -71,11 +71,11 @@ var c = async (e, t, n) => {
|
|
|
71
71
|
n
|
|
72
72
|
],
|
|
73
73
|
queryFn: async () => (await c(`query AthListMembers($teamId: ID!, $status: AthMemberStatus) {
|
|
74
|
-
athListMembers(teamId: $teamId, status: $status) { ${d} }
|
|
74
|
+
athListMembers(teamId: $teamId, status: $status) { items { ${d} } }
|
|
75
75
|
}`, {
|
|
76
76
|
teamId: t,
|
|
77
77
|
status: n
|
|
78
|
-
}, r)).athListMembers,
|
|
78
|
+
}, r)).athListMembers.items,
|
|
79
79
|
enabled: !!t
|
|
80
80
|
});
|
|
81
81
|
}, S = () => {
|
|
@@ -188,8 +188,8 @@ var c = async (e, t, n) => {
|
|
|
188
188
|
t
|
|
189
189
|
],
|
|
190
190
|
queryFn: async () => (await c(`query AthStandings($competition: String!) {
|
|
191
|
-
athStandings(competition: $competition) { ${p} }
|
|
192
|
-
}`, { competition: t }, n)).athStandings,
|
|
191
|
+
athStandings(competition: $competition) { items { ${p} } }
|
|
192
|
+
}`, { competition: t }, n)).athStandings.items,
|
|
193
193
|
enabled: !!t
|
|
194
194
|
});
|
|
195
195
|
}, A = () => {
|
|
@@ -229,7 +229,7 @@ var c = async (e, t, n) => {
|
|
|
229
229
|
],
|
|
230
230
|
queryFn: async () => (await c(`query AthListPrograms($sport: AthSport, $level: AthProgramLevel, $status: AthProgramStatus, $pagination: PaginationInput) {
|
|
231
231
|
athListPrograms(sport: $sport, level: $level, status: $status, pagination: $pagination) {
|
|
232
|
-
items { ${h} drills { id } }
|
|
232
|
+
items { ${h} drills { items { id } } }
|
|
233
233
|
pageInfo { cursor hasMore }
|
|
234
234
|
}
|
|
235
235
|
}`, {
|
|
@@ -250,7 +250,7 @@ var c = async (e, t, n) => {
|
|
|
250
250
|
queryFn: async () => (await c(`query AthProgram($id: ID!) {
|
|
251
251
|
athProgram(id: $id) {
|
|
252
252
|
${h}
|
|
253
|
-
drills { ${m} }
|
|
253
|
+
drills { items { ${m} } }
|
|
254
254
|
}
|
|
255
255
|
}`, { id: t }, n)).athProgram,
|
|
256
256
|
enabled: !!t
|
|
@@ -449,8 +449,8 @@ var c = async (e, t, n) => {
|
|
|
449
449
|
t
|
|
450
450
|
],
|
|
451
451
|
queryFn: async () => (await c(`query AthPerformanceMetrics($athleteId: ID!) {
|
|
452
|
-
athPerformanceMetrics(athleteId: $athleteId) { ${v} }
|
|
453
|
-
}`, { athleteId: t }, n)).athPerformanceMetrics,
|
|
452
|
+
athPerformanceMetrics(athleteId: $athleteId) { items { ${v} } }
|
|
453
|
+
}`, { athleteId: t }, n)).athPerformanceMetrics.items,
|
|
454
454
|
enabled: !!t
|
|
455
455
|
});
|
|
456
456
|
}, K = () => {
|
|
@@ -577,7 +577,7 @@ var c = async (e, t, n) => {
|
|
|
577
577
|
entityId: t.id,
|
|
578
578
|
entityKind: "team"
|
|
579
579
|
});
|
|
580
|
-
for (let e of t.members ?? []) n.push({
|
|
580
|
+
for (let e of t.members?.items ?? []) n.push({
|
|
581
581
|
id: `member-${e.id}`,
|
|
582
582
|
type: "member-added",
|
|
583
583
|
title: `${e.displayName} added to ${t.name}`,
|