Skip to content
Merged
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
278 commits
Select commit Hold shift + click to select a range
7115aed
Merge remote-tracking branch 'origin/fix/baseball-459-activate-exposu…
njrini99-code Jul 1, 2026
5ed719f
Merge remote-tracking branch 'origin/fix/baseball-490-lineup-swap' in…
njrini99-code Jul 1, 2026
a7057a9
Merge remote-tracking branch 'origin/fix/baseball-500-scout-packet-vi…
njrini99-code Jul 1, 2026
51f9991
Merge remote-tracking branch 'origin/fix/baseball-477-postgame-dispos…
njrini99-code Jul 1, 2026
2c0b20c
Merge remote-tracking branch 'origin/fix/baseball-467-dead-demo-link'…
njrini99-code Jul 1, 2026
318b656
Merge remote-tracking branch 'origin/fix/baseball-511-coach-note-scop…
njrini99-code Jul 1, 2026
892e087
Merge remote-tracking branch 'origin/fix/baseball-436-auto' into batc…
njrini99-code Jul 1, 2026
f330316
Merge remote-tracking branch 'origin/fix/baseball-444-auto' into batc…
njrini99-code Jul 1, 2026
0b01ee5
Merge remote-tracking branch 'origin/fix/baseball-445-auto' into batc…
njrini99-code Jul 1, 2026
35ef654
Merge remote-tracking branch 'origin/fix/baseball-474-auto' into batc…
njrini99-code Jul 1, 2026
2e53f2b
Merge remote-tracking branch 'origin/fix/baseball-478-auto' into batc…
njrini99-code Jul 1, 2026
5258b24
Merge remote-tracking branch 'origin/fix/baseball-491-auto' into batc…
njrini99-code Jul 1, 2026
c555544
Merge remote-tracking branch 'origin/fix/baseball-498-auto' into batc…
njrini99-code Jul 1, 2026
828b357
Merge remote-tracking branch 'origin/fix/baseball-509-auto' into batc…
njrini99-code Jul 1, 2026
7352c75
Merge remote-tracking branch 'origin/fix/baseball-434-auto' into batc…
njrini99-code Jul 1, 2026
80258cf
fix(baseball): per-row ERA/WHIP divide by true innings in PlayerGameL…
njrini99-code Jul 1, 2026
48d739c
fix(baseball): type the calendar events map row (fromUntyped implicit…
njrini99-code Jul 1, 2026
84418b9
fix(baseball): practice coach embeds select full_name (not first/last)
njrini99-code Jul 1, 2026
e10baba
fix(baseball): eliminate duplicate top-bar chrome across dashboard shell
njrini99-code Jul 1, 2026
627d164
fix(baseball): repair nav dead-ends (player Roster, coach Profile, re…
njrini99-code Jul 1, 2026
73db16b
fix(baseball): resolve head-coach recruiting/scout/camp redirects to …
njrini99-code Jul 1, 2026
fcc98b7
fix(baseball): reconcile Player Today lifts, fix coach-notes read, un…
njrini99-code Jul 1, 2026
dc077de
fix(baseball): repair Stats Center saved-views crash + elevate empty …
njrini99-code Jul 1, 2026
826bebc
fix(baseball): render calendar events + de-ambiguate calendar toolbar
njrini99-code Jul 1, 2026
4923bd6
fix(baseball): resolve misc-visual QA cluster (stats W-L, videos copy…
njrini99-code Jul 1, 2026
3a42b03
Merge remote-tracking branch 'origin/fix/qa-stats-charts' into batch/…
njrini99-code Jul 1, 2026
90c1f04
Merge remote-tracking branch 'origin/fix/qa-shell-chrome-dup' into ba…
njrini99-code Jul 1, 2026
78b0f1f
Merge remote-tracking branch 'origin/fix/qa-calendar' into batch/base…
njrini99-code Jul 1, 2026
15ffb84
Merge remote-tracking branch 'origin/fix/qa-capability-redirects' int…
njrini99-code Jul 1, 2026
99f45b3
Merge remote-tracking branch 'origin/fix/qa-player-today' into batch/…
njrini99-code Jul 1, 2026
1ee1c34
Merge remote-tracking branch 'origin/fix/qa-nav-deadends' into batch/…
njrini99-code Jul 1, 2026
c9ce8e5
Merge remote-tracking branch 'origin/fix/qa-misc-visual' into batch/b…
njrini99-code Jul 1, 2026
4dbcc30
fix(calendar): move JSX comment out of conditional expression in page…
njrini99-code Jul 1, 2026
7c5d88c
chore(seed): add env-gated box-score + season-stats seeder for demo team
njrini99-code Jul 1, 2026
7df4eaf
docs(baseball): add 'The Living Annual' design system — north star fo…
njrini99-code Jul 1, 2026
7a86ad3
feat(baseball): Living-Annual design-system foundation kit + tokens +…
njrini99-code Jul 1, 2026
74d1ba8
feat(baseball): complete Living-Annual atom set (17) + wire Space Gro…
njrini99-code Jul 1, 2026
457f564
feat(baseball): harmonize kit to Space Grotesk + deeper cream (founde…
njrini99-code Jul 1, 2026
987cce5
feat(baseball): Living-Annual molecule layer (data + viz) + rate form…
njrini99-code Jul 1, 2026
e7c341a
feat(baseball): migrate Command Center + Stats Center to the Living-A…
njrini99-code Jul 1, 2026
f7ef4dc
docs(baseball): long-tail surface migration execution plan (per-surfa…
njrini99-code Jul 1, 2026
7812a58
fix(baseball): close self-terminating CSS comment in globals.css (P0 …
njrini99-code Jul 1, 2026
2fff8f6
fix(baseball): use active coach id for travel itinerary created_by
njrini99-code Jul 1, 2026
8423a6f
fix(baseball): stop permanent blank page for activated players on col…
njrini99-code Jul 1, 2026
e3efc89
fix(baseball): stop hard-404 on public team profile
njrini99-code Jul 1, 2026
fda310a
fix(baseball): repair Discover peek panel + message routing
njrini99-code Jul 1, 2026
be249e2
fix(baseball): un-hide delete-game button on games list
njrini99-code Jul 1, 2026
79b0d14
fix(baseball): add logos storage bucket + RLS for program logo upload
njrini99-code Jul 1, 2026
7015c84
fix(baseball): persist distinct verdicts on practice-effectiveness re…
njrini99-code Jul 1, 2026
7972450
fix(baseball): source colleges state filter from college states, surf…
njrini99-code Jul 1, 2026
aad7f93
fix(baseball): wire Send Message and Add to Watchlist CTAs on player …
njrini99-code Jul 1, 2026
d871880
fix(baseball): wire stats-upload wizard column-map + player-match edi…
njrini99-code Jul 1, 2026
d590ad6
fix(baseball): wire liftingOrgId/liftingAthleteId into canonical play…
njrini99-code Jul 1, 2026
275c57b
fix(baseball): enforce clip bounds at playback and move clip create s…
njrini99-code Jul 1, 2026
06e925f
fix(baseball): camps write status=published, use audited action layer
njrini99-code Jul 1, 2026
4f98e63
fix(baseball): mount BaseballProgramBrand consumer + wire brand-accen…
njrini99-code Jul 1, 2026
99de969
fix(baseball): validate + own-check player journey status, drop dead …
njrini99-code Jul 1, 2026
0640faa
fix(baseball): atomic CSV box-score save + remove dead PDF tab
njrini99-code Jul 2, 2026
9bc6cce
fix(baseball): wire complete/uncomplete controls into dev plan detail
njrini99-code Jul 2, 2026
cc495ee
fix(baseball): reconcile Lift Lab session/set writes to the reader's …
njrini99-code Jul 2, 2026
a82cafb
fix(baseball): stable goal ids so coach-created dev-plan goals can be…
njrini99-code Jul 2, 2026
944c5e9
feat(baseball): add team edit/delete/leave + invite revoke, harden in…
njrini99-code Jul 2, 2026
8cb8897
fix(baseball): wire team-documents edit/version-history/move-to-folde…
njrini99-code Jul 2, 2026
fd53e23
fix(baseball): reconcile readiness reads to helm_lifting_readiness_ch…
njrini99-code Jul 2, 2026
ab64f33
fix(baseball): never leave delete-game button invisible-but-clickable
Jul 2, 2026
d12e3df
fix(baseball): scope logos bucket INSERT/UPDATE/DELETE to coaches only
Jul 2, 2026
a17d3f7
fix(baseball): correct baseball_coaches columns in team profile staff…
Jul 2, 2026
c169d05
fix(baseball): strip ?player= before pushState to close history trap
Jul 2, 2026
100975e
fix(baseball): gate player-profile coach CTAs on real coach role, not…
Jul 2, 2026
b845e0d
fix(baseball): make 'use server' messages barrel export async wrapper…
Jul 2, 2026
9c39499
fix(baseball): reject off-roster coachMatch playerIds + honest failed…
Jul 2, 2026
50e4c03
fix: remove unsafe (supabase as any) casts and add missing auth check…
Jul 2, 2026
6c22ba9
fix(baseball): stop Edit Details/Move to Folder from clobbering signe…
Jul 2, 2026
73cee76
fix(baseball): wire brand-accent CSS into the legacy shell, not just …
Jul 2, 2026
f1391ec
fix(baseball): persist backfilled goal ids, demo-gate coach read, add…
Jul 2, 2026
0da63d2
fix(baseball): harden delete-team history guard, fix leave-team RLS gap
Jul 2, 2026
71bc996
fix(baseball): bound clip playback on the two surfaces PR #665 missed
Jul 2, 2026
cabc0f9
integrate fix/baseball-p0-globals-css
Jul 2, 2026
3f24a81
integrate fix/baseball-p0-use-server-messages
Jul 2, 2026
3d2fc72
integrate fix/baseball-p1-travel-fk
Jul 2, 2026
fbccfd6
integrate fix/baseball-p1-college-interest
Jul 2, 2026
a296a37
integrate fix/baseball-p1-public-team-profile
Jul 2, 2026
7e689fa
integrate fix/baseball-p1-discover-peek
Jul 2, 2026
6cdc375
integrate fix/baseball-p1-video-clip
Jul 2, 2026
2a5d74c
integrate fix/baseball-p1-camps
Jul 2, 2026
8d88990
integrate fix/baseball-p2-stats-games-list-delete
Jul 2, 2026
5ead67e
integrate fix/baseball-p2-program-logo-upload
Jul 2, 2026
0393b0d
integrate fix/baseball-p2-practice-effectiveness-verdicts
Jul 2, 2026
28ed3a8
integrate fix/baseball-p2-colleges-directory-filter
Jul 2, 2026
7583989
integrate fix/baseball-p2-player-profile-coach-ctas
Jul 2, 2026
6febf9d
integrate fix/baseball-p2-player-detail-performance
Jul 2, 2026
a12d6ad
integrate fix/baseball-p2-stats-upload-wizard
Jul 2, 2026
922f55f
integrate fix/baseball-p2-settings-appearance
Jul 2, 2026
c9620a5
integrate fix/baseball-p2-team-documents-actions
Jul 2, 2026
f38e96b
integrate fix/baseball-p2-stats-game-detail
Jul 2, 2026
5d56fc3
integrate fix/baseball-p1-lift-lab
Jul 2, 2026
001461f
integrate fix/baseball-p1-readiness
Jul 2, 2026
1bc6d7c
integrate fix/baseball-p2-dev-plans-goal-schema
Jul 2, 2026
13343b7
integrate fix/baseball-p2-dev-plan-detail
Jul 2, 2026
d01010a
integrate fix/baseball-p2-journey-vocab
Jul 2, 2026
0f62f50
integrate fix/baseball-p2-teams-manage
Jul 2, 2026
8661582
db(baseball): migration files matching tonight's applied prod state (…
njrini99-code Jul 2, 2026
c4c5a42
feat(baseball): Living-Annual interaction layer — shared motion vocab…
njrini99-code Jul 2, 2026
af4e82f
fix(baseball): P4.1 — EmptyIssue presets for announcements/travel/dis…
njrini99-code Jul 2, 2026
7af9a10
feat(baseball): consolidate coach nav into 8 grouped hubs (registry-d…
njrini99-code Jul 2, 2026
0c8d6f4
fix(baseball): Command Center roster pulse — split unjoinable nested …
njrini99-code Jul 2, 2026
18710c9
fix(baseball): resolve document uploader without the broken users.ful…
njrini99-code Jul 2, 2026
f3de005
fix(baseball): dev-plan player picker always claimed an empty roster …
njrini99-code Jul 2, 2026
e1ef057
fix(baseball): unify calendar upcoming count with type badges, shape …
njrini99-code Jul 2, 2026
3c1108d
fix(baseball): make public team/program profiles truly public for log…
njrini99-code Jul 2, 2026
fd54139
fix(baseball): repair Discover permanent-skeleton + peek-panel-to-Com…
njrini99-code Jul 2, 2026
ebf7bfd
feat(baseball): demo-freshness reseed script for Rini University Base…
njrini99-code Jul 2, 2026
5a7ec8a
fix(baseball): stop legacy sidebar nav list clipping under Settings/S…
njrini99-code Jul 2, 2026
3129f50
fix(baseball): P4.11 — Living-Annual migration for postgame review (#…
njrini99-code Jul 2, 2026
8a7467a
fix(baseball): P4.10 — Living-Annual migration for Practice Effective…
njrini99-code Jul 2, 2026
7a27564
fix(baseball): P4.16 — Program Settings → Living-Annual kit (#691)
njrini99-code Jul 2, 2026
569da17
fix(baseball): P4.27 — Living-Annual recruiting activation GO LIVE ga…
njrini99-code Jul 2, 2026
d6cce0d
fix(baseball): P4.24b — migrate coach Player Passport off PlayerPassp…
njrini99-code Jul 2, 2026
ccc08ed
fix(baseball): P4.26 — Living-Annual migration for the profile editor…
njrini99-code Jul 2, 2026
193806d
fix(baseball): P4.24 — Player Passport → Living-Annual kit (#695)
njrini99-code Jul 2, 2026
9947cf6
fix(baseball): P4.13 — Living-Annual migration for Import Center (#696)
njrini99-code Jul 2, 2026
9353992
fix(baseball): P4.29 — Living-Annual migration for player timeline (#…
njrini99-code Jul 2, 2026
f247be5
fix(baseball): Living-Annual — College Interest surface (P4.30) (#698)
njrini99-code Jul 2, 2026
51dca83
fix(baseball): P4.21.a — pipeline board onto Living-Annual kit (#699)
njrini99-code Jul 2, 2026
af21094
fix(baseball): P4.7 — Living-Annual reskin for messages/[id] thread p…
njrini99-code Jul 2, 2026
f336165
P4.2 — Roster Living-Annual migration (#701)
njrini99-code Jul 2, 2026
ea9f3c0
P4.4: Living-Annual migration — Announcements (#702)
njrini99-code Jul 2, 2026
34756f0
feat(baseball): P4.8 — Living-Annual migration for my-stats surface (…
njrini99-code Jul 2, 2026
2c5c83b
feat(baseball): P4.9 — analytics (player recruiting interest) → Livin…
njrini99-code Jul 2, 2026
04582d1
fix(baseball): P4.5 — Living-Annual migration for Tasks (#705)
njrini99-code Jul 2, 2026
7fabd73
fix(baseball): P4.15 — migrate settings/staff to the Living Annual ki…
njrini99-code Jul 2, 2026
87020b2
fix(baseball): P4.14.a — Performance Command Center onto Living-Annua…
njrini99-code Jul 2, 2026
d60d73e
fix(baseball): P4.18 — Scout Packets hub → Living-Annual kit (#708)
njrini99-code Jul 2, 2026
8b044ac
feat(baseball): Living-Annual migration — practice planner (P4.12.a) …
njrini99-code Jul 2, 2026
91eb5d8
fix(baseball): P4.14.b — PerformanceDashboardClient onto Living-Annua…
njrini99-code Jul 2, 2026
74878ac
fix(baseball): P4.20 — watchlist onto Living-Annual kit (clay, WAR RO…
njrini99-code Jul 2, 2026
9dd1ca1
fix(baseball): P4.23 — Decision Room (Living-Annual) (#712)
njrini99-code Jul 2, 2026
d384d8a
fix(baseball): P4.22 — signals inbox onto the Living-Annual kit (#713)
njrini99-code Jul 2, 2026
bcc4eee
feat(baseball): Lift Lab entry + first-run onboarding
Jul 2, 2026
cf6a247
feat(baseball): redesign coach onboarding as a Living Annual editoria…
Jul 2, 2026
d45b892
feat(baseball): redesign auth suite as the Living-Annual front door
Jul 2, 2026
7e0d98d
feat(landing): First Light photography assets (free-license)
Jul 2, 2026
a78d43d
feat(landing): upgrade hero + golf photography after design review
Jul 2, 2026
13bf6bd
feat(landing): First Light foundation — scaffold, glass grammar, scro…
Jul 2, 2026
749278e
Merge remote-tracking branch 'origin/feat/entry-world-foundation' int…
Jul 2, 2026
ad25e8c
feat(landing): sage & cream palette respec — token repoint + sage fam…
Jul 2, 2026
8119cdf
wip: inherited partial work (pre-sage)
Jul 2, 2026
efe0803
wip: inherited partial work (pre-sage)
Jul 2, 2026
6a1e1f6
wip: inherited partial work (pre-sage)
Jul 2, 2026
3476c36
Merge remote-tracking branch 'origin/feat/entry-world-foundation' int…
Jul 2, 2026
8ffe8f6
wip: inherited partial work (pre-sage)
Jul 2, 2026
723d6c4
Merge remote-tracking branch 'origin/feat/entry-world-foundation' int…
Jul 2, 2026
28338cd
Merge remote-tracking branch 'origin/feat/entry-world-foundation' int…
Jul 2, 2026
5b4fd79
wip: inherited partial work (pre-sage)
Jul 2, 2026
a3ad99c
Merge remote-tracking branch 'origin/feat/entry-world-foundation' int…
Jul 2, 2026
d876af7
Merge remote-tracking branch 'origin/feat/entry-world-foundation' int…
Jul 2, 2026
810ba0f
wip: sage partial work (builder killed mid-build)
Jul 2, 2026
eca2b6b
wip: sage partial work (builder killed mid-build)
Jul 2, 2026
200ea2f
wip: sage partial work (builder killed mid-build)
Jul 2, 2026
95e5ba9
feat(landing): M2/M5/M6/M7 editorial moments — sage & cream
Jul 2, 2026
9ea08d9
wip: inherited sage partial work
Jul 2, 2026
e3142d3
fix(baseball): entry redesign — The Practice Field at First Light (au…
Jul 2, 2026
6674810
wip: sage partial work (builder killed mid-build)
Jul 2, 2026
ed3cf89
Merge remote-tracking branch 'origin/feat/entry-world-scenes' into fe…
Jul 2, 2026
6c5a8ee
Merge remote-tracking branch 'origin/feat/entry-world-scenes' into fe…
Jul 2, 2026
b78e77d
feat(baseball): Lift Lab first-run — plates load the bar on the abstr…
Jul 2, 2026
ff61a63
feat(baseball): onboarding arc — the field gets chalked (stacked on #…
Jul 2, 2026
edeef81
fix(landing): M4 daylight grade + double-bezel portal cards (Fable spec)
Jul 2, 2026
36ec31a
fix(landing): M2 ledger rules draw in (Fable spec)
Jul 2, 2026
89e0be6
fix(baseball): render login shell eagerly — narrow useSearchParams Su…
Jul 2, 2026
f1f3656
feat(landing): IMMACULATE foundation — aurora field, light pools, cta…
Jul 2, 2026
d8a65dc
feat(landing): M3 rebuild — film-strip column, hardware bezel, ledger…
Jul 2, 2026
3060bbe
fix(baseball): guard drift-only migration statements against fresh DBs
Jul 2, 2026
2058ea6
fix(baseball): close real auth gaps, silence rule-blindness on protec…
Jul 2, 2026
0a59653
fix(baseball): re-pin pitching-invariants contract to thirds-notation…
Jul 2, 2026
d9bfef6
fix(baseball): grandfather 2 deprecated-table consumers (#381)
Jul 2, 2026
f36c558
fix(baseball): route announcements load-failure through ReadModelStat…
Jul 2, 2026
ca0647c
Merge remote-tracking branch 'origin/feat/entry-world-foundation' int…
Jul 2, 2026
9f3e434
Merge remote-tracking branch 'origin/feat/entry-world-foundation' int…
Jul 2, 2026
b79e8d1
Merge remote-tracking branch 'origin/feat/entry-world-foundation' int…
Jul 2, 2026
b29e4f6
feat(landing): M1+nav immaculate pass — photo dissolve, corner light,…
Jul 2, 2026
4532046
feat(landing): portals/CTA/footer immaculate pass — photo craft, magn…
Jul 2, 2026
3526855
feat(landing): editorial immaculate pass — aurora field, light pools,…
Jul 2, 2026
11fd8df
feat(landing): §D2 more cream, no white — demote cream-high to lips/t…
Jul 2, 2026
488372d
fix(baseball): auth panel — win the cream-glass specificity battle, i…
Jul 2, 2026
cb164a4
feat(landing): M1+nav §D2 cream sweep (Nick)
Jul 2, 2026
b203b06
fix(baseball): §D2 — auth panel fill is true cream, not near-white (N…
Jul 2, 2026
47cfa4d
fix(baseball): §D2 follow-up — cream ring-offset + no-white autofill …
Jul 2, 2026
68944a3
feat(landing): brand foundation — HelmMark/HelmRosette/SportGlyph lin…
Jul 2, 2026
df2a297
ci(e2e): Node 22 for Playwright jobs — supabase-js throws at createCl…
Jul 2, 2026
58b03fe
Merge remote-tracking branch 'origin/feat/entry-world-foundation' int…
Jul 2, 2026
bbd2cb3
Merge remote-tracking branch 'origin/feat/entry-world-foundation' int…
Jul 2, 2026
5f60213
Merge remote-tracking branch 'origin/feat/entry-world-foundation' int…
Jul 2, 2026
98dc22d
feat(landing): GlassNav brand lockup — HelmMark + sport glyph popover…
Jul 2, 2026
5093865
feat(landing): portals brand weave — sport motifs, card glyphs, foote…
Jul 2, 2026
a581444
feat(landing): editorial architecture — asymmetric splits, bento, gol…
Jul 2, 2026
994ade9
Merge remote-tracking branch 'origin/feat/entry-world-assets' into ba…
Jul 2, 2026
9bda911
Merge remote-tracking branch 'origin/feat/entry-world-foundation' int…
Jul 2, 2026
34a5f41
Merge remote-tracking branch 'origin/feat/entry-world-hero' into batc…
Jul 2, 2026
bee4966
Merge remote-tracking branch 'origin/feat/entry-world-editorial' into…
Jul 2, 2026
80f22c8
Merge remote-tracking branch 'origin/feat/entry-world-cinema' into ba…
Jul 2, 2026
43f519a
Merge remote-tracking branch 'origin/feat/entry-world-portals' into b…
Jul 2, 2026
a226db0
Merge remote-tracking branch 'origin/feat/baseball-front-door-auth' i…
Jul 2, 2026
12ca2fd
Merge remote-tracking branch 'origin/feat/entry-world-scenes' into ba…
Jul 2, 2026
604b8ac
Merge remote-tracking branch 'origin/feat/baseball-front-door-onboard…
Jul 2, 2026
733b031
Merge remote-tracking branch 'origin/feat/entry-world-onboarding' int…
Jul 2, 2026
201fe10
Merge remote-tracking branch 'origin/feat/baseball-lift-lab-onboardin…
Jul 2, 2026
c1a4833
Merge remote-tracking branch 'origin/feat/entry-world-liftlab' into b…
Jul 2, 2026
0d68727
fix(entry-world): rebalance M1 hero grade stack — photo was buried in…
Jul 2, 2026
3789fa6
fix(entry-world): cap M5 band's dark edge, stop it reading as 2nd dar…
Jul 2, 2026
edf17e0
fix(entry-world): remove M3 reflection strip — rendered as a left-hea…
Jul 2, 2026
c249058
feat(landing): sports by viewport 3 — M4 two-fields moves ahead of M3…
Jul 2, 2026
ca34951
feat(landing): footer watermark uses the real Helm logo (Nick A-OVERR…
Jul 2, 2026
8a52013
fix(entry-world): recolor auth-panel helm-wheel mark, kelly -> sage-deep
Jul 2, 2026
76cfd80
fix(entry-world): M3 — drop cream veil, predecessor moment is now M4
Jul 2, 2026
b28e835
test: mock next/font/google in vitest setup
Jul 2, 2026
2e74697
fix(baseball): rename event-ack RLS policies to canonical naming
Jul 2, 2026
a64dc38
ci: pin baseball-smoke actions to full commit SHAs
Jul 2, 2026
c9cd21b
fix(baseball): resolve CodeQL alerts in performance-command, announce…
Jul 2, 2026
c4bb04b
feat(landing): real Helm logo in nav + two-sport hero chips (Nick A-O…
Jul 2, 2026
2d3a0e5
fix(baseball): event-ack SELECT staff branch — canonical is_baseball_…
Jul 2, 2026
423c086
feat(baseball): entry field — render the base-path diamond in-viewpor…
Jul 2, 2026
d643a4e
feat(landing): M3 sport-obvious screen replicas + veil removed for ne…
Jul 2, 2026
ef3bb88
Revert "fix(entry-world): recolor auth-panel helm-wheel mark, kelly -…
Jul 2, 2026
631bc0e
docs(baseball): note why the auth masthead logo stays kelly (A-OVERRIDE)
Jul 2, 2026
d7872d6
feat(landing): M4 section anchor id=fields
Jul 2, 2026
ab5d9b0
Merge remote-tracking branch 'origin/feat/entry-world-foundation' int…
Jul 2, 2026
504367b
Merge remote-tracking branch 'origin/feat/entry-world-editorial' into…
Jul 2, 2026
0b1e247
Merge remote-tracking branch 'origin/feat/entry-world-cinema' into ba…
Jul 2, 2026
263d6d2
Merge remote-tracking branch 'origin/feat/entry-world-scenes' into ba…
Jul 2, 2026
dd759fa
Merge remote-tracking branch 'origin/feat/entry-world-hero' into batc…
Jul 2, 2026
d499eeb
Merge remote-tracking branch 'origin/feat/entry-world-portals' into b…
Jul 2, 2026
ace5c30
fix(baseball): foul lines collinear with base paths — one chalk geome…
Jul 2, 2026
5739d89
feat(landing): real GolfHelm/BaseballHelm logo marks on hero sport ch…
Jul 2, 2026
0b21b70
feat(landing): real product marks in cream coins on M4 field cards (N…
Jul 2, 2026
5b8b876
fix(ci): final-red forensics — stale pgTAP index assert, invite-code …
Jul 2, 2026
23fd455
feat(landing): M3 screens are live interactive replicas of the real a…
Jul 2, 2026
03c6e00
Merge feat/entry-world-scenes into batch/baseball-fixes
Jul 2, 2026
e53e5ea
Merge feat/entry-world-hero into batch/baseball-fixes
Jul 2, 2026
abe1a26
Merge feat/entry-world-portals into batch/baseball-fixes
Jul 2, 2026
fd37197
Merge feat/entry-world-cinema into batch/baseball-fixes
Jul 2, 2026
e7f416b
Merge branch 'main' into batch/baseball-fixes
njrini99-code Jul 2, 2026
a2433ea
fix(landing): M3 desktop screens fill the well — density pass (Nick: …
Jul 2, 2026
66a6b77
fix(security): clear the two swept-in CodeQL alerts — null-proto CSV …
Jul 2, 2026
cbd691c
Merge remote-tracking branch 'origin/feat/entry-world-cinema' into ba…
Jul 2, 2026
ade9c22
fix(landing): Decision Room cards — center content in tall 1fr rows
Jul 3, 2026
97c6524
Merge remote-tracking branch 'origin/feat/entry-world-cinema' into ba…
Jul 3, 2026
5726a1a
fix(security): lift-canvas draft ids via crypto.randomUUID (CodeQL js…
Jul 3, 2026
ce71cd9
Merge branch 'main' into batch/baseball-fixes
njrini99-code Jul 3, 2026
d729630
revert(landing): strip Entry World marketing surface — ship internal …
Jul 3, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 8 additions & 18 deletions src/app/baseball/(dashboard)/dashboard/activate/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { Badge } from '@/components/ui/badge';
import { PageLoading } from '@/components/ui/loading';
import { IconTarget, IconUsers, IconChart, IconCheck, IconEye, IconLock } from '@/components/icons';
import { useAuth } from '@/hooks/use-auth';
import { createClient } from '@/lib/supabase/client';
import { activateRecruitingExposure } from '@/app/baseball/actions/player-access';

export default function ActivateRecruitingPage() {
const { user, player, loading: authLoading, updatePlayer } = useAuth();
Expand Down Expand Up @@ -58,21 +58,11 @@ export default function ActivateRecruitingPage() {
setError(null);

try {
const supabase = createClient();

const { error: updateError } = await supabase
.from('baseball_players')
.update({
recruiting_activated: true,
recruiting_activated_at: new Date().toISOString(),
})
.eq('id', player.id);

if (updateError) {
setError(updateError.message);
setActivating(false);
return;
}
// Go through the gated server action so the team's
// recruiting_exposure_enabled toggle is enforced. The old raw client-side
// update bypassed it — a program with exposure disabled could still be
// activated from this page if RLS permitted the write.
await activateRecruitingExposure();

// Update local state
await updatePlayer?.({
Expand All @@ -81,8 +71,8 @@ export default function ActivateRecruitingPage() {
});

router.push('/baseball/player/today');
} catch {
setError('An error occurred. Please try again.');
} catch (err) {
setError(err instanceof Error ? err.message : 'An error occurred. Please try again.');
setActivating(false);
}
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ const gradYearOptions = [

const statusOptions = PIPELINE_STAGES.map((s) => ({ value: s.id, label: s.label }));

// Droppable columns use the stage id; draggable cards use the watchlist-row
// UUID. This set lets the drag handler tell a real drop-target column apart
// from a card that `closestCorners` happened to land on.
const PIPELINE_STAGE_IDS = new Set<PipelineStage>(PIPELINE_STAGES.map((s) => s.id));

const filterTabs = [
{ value: 'all', label: 'All' },
...PIPELINE_STAGES.map((s) => ({ value: s.id, label: s.label })),
Expand Down Expand Up @@ -243,20 +248,23 @@ export default function PipelinePage() {
return;
}

const activeItem = filteredByGradYear.find((item) => item.id === active.id);
const newStage = over.id as PipelineStage;

if (activeItem && activeItem.pipeline_stage !== newStage) {
try {
await updateStage(activeItem.player_id, newStage);
setError(null);
const playerName = getFullName(activeItem.player?.first_name, activeItem.player?.last_name);
const stageLabel = statusOptions.find(o => o.value === newStage)?.label || newStage;
showToast(`${playerName} moved to ${stageLabel}`, 'success');
} catch (err) {
console.error('Error updating pipeline stage:', err);
setError('Failed to update player stage. Please try again.');
}
const draggedItem = filteredByGradYear.find((item) => item.id === active.id);

// With closestCorners, `over` is often another card (a watchlist UUID),
// not a column. Resolve the target stage from the column id, falling back
// to the stage of the card being hovered; anything else is an invalid drop
// and must be a no-op (no DB write).
const overId = over.id as string;
const newStage: PipelineStage | null = PIPELINE_STAGE_IDS.has(overId as PipelineStage)
? (overId as PipelineStage)
: (filteredByGradYear.find((item) => item.id === overId)?.pipeline_stage ?? null);

if (draggedItem && newStage && draggedItem.pipeline_stage !== newStage) {
// updateStage shows its own success/error toast and only refetches on
// success (so the card reverts to its column on failure). Just reflect
// the boolean return — never a second, unconditional success toast.
const ok = await updateStage(draggedItem.player_id, newStage);
setError(ok ? null : 'Failed to update player stage. Please try again.');
}

setActiveId(null);
Expand All @@ -265,7 +273,11 @@ export default function PipelinePage() {
// Watchlist handlers
async function handleStatusChange(watchlistId: string, newStatus: PipelineStage) {
try {
await updateWatchlistStatus(watchlistId, newStatus);
const result = await updateWatchlistStatus(watchlistId, newStatus);
if (!result.success) {
showToast(result.error || 'Failed to update status', 'error');
return;
}
refetch();
} catch {
showToast('Failed to update status', 'error');
Expand Down Expand Up @@ -336,11 +348,15 @@ export default function PipelinePage() {
if (selectedPlayers.size === 0) return;

try {
await Promise.all(
const results = await Promise.all(
Array.from(selectedPlayers).map(watchlistId =>
updateWatchlistStatus(watchlistId, newStatus)
)
);
const failed = results.filter(r => !r.success).length;
if (failed > 0) {
showToast(`Failed to update ${failed} player${failed !== 1 ? 's' : ''}`, 'error');
}
refetch();
setSelectedPlayers(new Set());
} catch {
Expand Down Expand Up @@ -547,7 +563,7 @@ export default function PipelinePage() {
onDragStart={handleDragStart}
onDragEnd={handleDragEnd}
>
<div className="flex lg:grid lg:grid-cols-7 gap-4 overflow-x-auto pb-4 -mx-6 px-6 lg:mx-0 lg:px-0 lg:overflow-visible snap-x snap-mandatory lg:snap-none scroll-smooth">
<div className="flex lg:grid lg:grid-cols-5 gap-4 overflow-x-auto pb-4 -mx-6 px-6 lg:mx-0 lg:px-0 lg:overflow-visible snap-x snap-mandatory lg:snap-none scroll-smooth">
{PIPELINE_STAGES.map((s) => (
<PipelineColumn
key={s.id}
Expand Down
6 changes: 4 additions & 2 deletions src/app/baseball/(dashboard)/dashboard/profile/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,10 @@ export default function ProfilePage() {
await updatePlayer(updates);
};

// Use CollegeProfileEditor for college/juco players
const isCollegePlayer = player.player_type === 'college' || player.player_type === 'juco';
// Only true college players get the team-only editor. JUCO players are
// transfer-recruiting-eligible (opt-in activation), so they need the
// recruiting ProfileEditor with showcase fields like videos — same as HS.
const isCollegePlayer = player.player_type === 'college';

return (
<>
Expand Down
11 changes: 9 additions & 2 deletions src/app/baseball/(dashboard)/dashboard/roster/RosterClient.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1016,12 +1016,19 @@ export function RosterClient({ teamId: serverTeamId, initialModel }: RosterClien

setSavingLineup(true);
try {
await saveLineup({
// saveLineup returns { success: false, error } for validation
// failures (duplicate orders, > 9 players, missing coach) without
// throwing, so check the result before claiming success.
const result = await saveLineup({
teamId: resolvedTeamId,
name: name || 'Untitled Lineup',
positions,
});
showToast('Lineup saved successfully', 'success');
if (result.success) {
showToast('Lineup saved successfully', 'success');
} else {
showToast(result.error || 'Failed to save lineup', 'error');
}
} catch (error) {
showToast(
error instanceof Error ? error.message : 'Failed to save lineup',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,19 @@
//
// Wave 4 / packet: qa-screens (Settings routes coverage completeness)
//
// Demo Mode Settings is an ACCEPTED consolidation: its controls live as a section of the
// single Program Settings page (one save surface, one capability gate). This
// dedicated spec route (v4 §Settings Architecture) resolves by redirecting to
// that section's anchor, so every route in the spec route map is reachable and
// deep-linkable without duplicating the editor or its server enforcement.
// The Demo Mode section was removed from the consolidated Program Settings page
// (PKT-12) and has no controls yet, so there is no `#demo-mode` anchor to
// deep-link to. This spec route stays reachable (v4 §Settings Architecture) by
// redirecting to the Program Settings page itself rather than a dead anchor.
// =============================================================================

import { permanentRedirect } from 'next/navigation';
import { getBaseballSettingsAliasHref } from '@/lib/baseball/settings-route-aliases';
import { BASEBALL_PROGRAM_SETTINGS_PATH } from '@/lib/baseball/settings-route-aliases';

export const metadata = {
title: 'Demo Mode Settings | Helm Baseball',
};

export default function Page() {
permanentRedirect(getBaseballSettingsAliasHref('demo-mode'));
permanentRedirect(BASEBALL_PROGRAM_SETTINGS_PATH);
}
35 changes: 10 additions & 25 deletions src/app/baseball/(dashboard)/dashboard/settings/privacy/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,31 +25,16 @@ export default async function PrivacySettingsPage() {
.eq('player_id', player.id)
.maybeSingle();

// Transform database settings to component format
// Map database fields to component expected fields (use defaults for missing fields)
// Database columns: show_contact_info, show_academics, show_dream_schools, profile_visibility
const transformedSettings = settings ? {
id: settings.id,
player_id: settings.player_id,
// Map database fields that exist
show_contact_email: settings.show_contact_info ?? undefined,
show_academics: settings.show_academics ?? undefined,
show_dream_schools: settings.show_dream_schools ?? undefined,
profile_visibility: settings.profile_visibility ?? undefined,
// Default values for fields not in database
show_full_name: true,
show_school: true,
show_phone: settings.show_contact_info ?? undefined,
show_social_links: true,
show_height_weight: true,
show_position: true,
show_grad_year: true,
show_bats_throws: true,
show_videos: true,
show_calendar: true,
show_stats: true,
allow_messages: true,
} : undefined;
// Map the real baseball_player_settings privacy columns to the form. Only
// show_contact_info, show_academics, and show_dream_schools are editable
// toggles; profile_visibility is managed elsewhere and left untouched.
const transformedSettings = settings
? {
show_contact_info: settings.show_contact_info ?? undefined,
show_academics: settings.show_academics ?? undefined,
show_dream_schools: settings.show_dream_schools ?? undefined,
}
: undefined;

return (
<div className="min-h-dvh bg-[#FAF6F1]">
Expand Down
3 changes: 2 additions & 1 deletion src/app/baseball/(public)/packet/[token]/csv/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ function fileName(name: string | null): string {

export async function GET(_req: Request, { params }: RouteParams): Promise<Response> {
const { token } = await params;
const model = await resolveScoutPacketByToken(token ?? '');
// A CSV download isn't a packet "view" — don't bump view_count/last_viewed_at.
const model = await resolveScoutPacketByToken(token ?? '', { trackView: false });
const csv = scoutPacketToCsv(model);
const status = model.ok ? 200 : model.reason === 'not_found' ? 404 : 403;
return new Response(csv, {
Expand Down
23 changes: 22 additions & 1 deletion src/app/baseball/actions/postgame.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,9 +176,30 @@ export const generatePostgameReview = withBaseballAction(
// overwrite content + re-open NEW items; never clobber a coach conversion.
// -------------------------------------------------------------------------
const emittedKeys = new Set<string>();

// Preserve any coach disposition (converted_to_timeline/converted_to_task/
// dismissed/resolved) across re-runs. The upsert below (ignoreDuplicates:
// false) would otherwise reset every conflicting row's disposition to
// mapItem's default 'new', re-opening items the coach already actioned.
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const { data: priorItems } = await (supabase as any)
.from('baseball_postgame_review_items')
.select('dedupe_key, disposition')
.eq('review_id', reviewId);
const priorDisposition = new Map<string, string>(
((priorItems ?? []) as { dedupe_key: string; disposition: string }[]).map(
(r) => [r.dedupe_key, r.disposition],
),
);
Comment on lines +185 to +193

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

3. Postgame prioritems db error ignored 🐞 Bug ☼ Reliability

The new query that fetches prior dispositions to preserve coach actions (converted_to_timeline,
dismissed, etc.) destructures only data and silently ignores the error field. If the DB query
fails, priorDisposition is an empty Map and the subsequent upsert overwrites all existing
dispositions back to 'new', re-opening items the coach already actioned.
Agent Prompt
## Issue description
The query that fetches prior postgame review item dispositions ignores the Supabase error field. If the query fails, all prior coach dispositions are silently lost on the next regeneration.

## Issue Context
The preservation logic was introduced to prevent the upsert from resetting coach-actioned items (dismissed, converted_to_timeline, etc.) back to 'new'. But if the lookup query itself fails, the protection is bypassed silently.

## Fix Focus Areas
- src/app/baseball/actions/postgame.ts[185-193] — destructure `{ data: priorItems, error: priorItemsError }` and if `priorItemsError` is set, either return early with an error or log a warning and skip the upsert (to avoid overwriting dispositions when the lookup is unreliable)

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


const itemRows: BaseballPostgameReviewItemInsert[] = built.items.map((c) => {
emittedKeys.add(c.dedupeKey);
return mapItem(c, teamId, reviewId);
const row = mapItem(c, teamId, reviewId);
const prior = priorDisposition.get(c.dedupeKey);
if (prior && prior !== 'new') {
row.disposition = prior as BaseballPostgameReviewItemInsert['disposition'];
}
return row;
});

let itemsGenerated = 0;
Expand Down
12 changes: 9 additions & 3 deletions src/app/baseball/actions/scout-packet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,13 @@ export const getScoutPacketPreview = withBaseballAction(
* Side effect: a successful, live resolution bumps the token's view telemetry
* (best-effort; never blocks the packet).
*/
export async function resolveScoutPacketByToken(token: string): Promise<ScoutPacketModel> {
export async function resolveScoutPacketByToken(
token: string,
options: { trackView?: boolean } = {},
): Promise<ScoutPacketModel> {
// A CSV export is data retrieval, not a human "view" of the packet, so callers
// like the CSV route pass trackView: false to avoid inflating view_count.
const { trackView = true } = options;
const generatedAt = new Date().toISOString();
const fail = (reason: ScoutPacketModel['reason']): ScoutPacketModel => ({
ok: false,
Expand Down Expand Up @@ -439,8 +445,8 @@ export async function resolveScoutPacketByToken(token: string): Promise<ScoutPac
recipientLabel: (row.recipient_label as string | null) ?? null,
});

// Telemetry: only count a live, exposed open.
if (packet.ok) {
// Telemetry: only count a live, exposed open — and never for CSV exports.
if (packet.ok && trackView) {
try {
await fromUntyped(admin, 'baseball_player_passport_share_tokens')
.update({
Expand Down
29 changes: 28 additions & 1 deletion src/components/baseball/player-profile/PlayerProfileClient.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import {
IconCheck,
} from '@/components/icons';
import type { BaseballPlayerStats, BaseballPlayerAggregates, BaseballCoachInsight } from '@/lib/types';
import type { BaseballNoteScope } from '@/lib/types/baseball-extended';

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Deep import bypasses the @/lib/types barrel.

BaseballNoteScope is imported from @/lib/types/baseball-extended while every other type in this file (line 41) comes from the @/lib/types barrel. Per path instructions for src/lib/types/**: "All re-exports happen via src/lib/types/index.ts — flag deep imports," and the general coding guideline: "Always import shared types from @/lib/types."

-import type { BaseballNoteScope } from '`@/lib/types/baseball-extended`';
+import type { BaseballCoachInsight, BaseballNoteScope, BaseballPlayerAggregates, BaseballPlayerStats } from '`@/lib/types`';

If BaseballNoteScope isn't currently re-exported from the barrel, add it there rather than deep-importing.

🔧 Verify the type is re-exported from the barrel
#!/bin/bash
rg -n "BaseballNoteScope" src/lib/types/index.ts src/lib/types/baseball-extended.ts
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import type { BaseballNoteScope } from '@/lib/types/baseball-extended';
import type { BaseballCoachInsight, BaseballNoteScope, BaseballPlayerAggregates, BaseballPlayerStats } from '`@/lib/types`';
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/baseball/player-profile/PlayerProfileClient.tsx` at line 42,
The import of BaseballNoteScope is a deep import that bypasses the shared
`@/lib/types` barrel used elsewhere in PlayerProfileClient; update the type import
so it comes from `@/lib/types` instead of `@/lib/types/baseball-extended`. If
BaseballNoteScope is not already re-exported, add the re-export in
src/lib/types/index.ts and then switch PlayerProfileClient to the barrel import.

Source: Path instructions

import type { SnapshotHeader } from '@/lib/baseball/read-models/player-snapshot-cards';
import type { TimelineEventView } from '@/lib/baseball/read-models/timeline';
import { PlayerInsightsPanel } from './PlayerInsightsPanel';
Expand All @@ -47,6 +48,7 @@ import { ProfileTimeline } from './ProfileTimeline';
import { SnapshotHeaderBand } from './snapshot-cards';
import { Button, IconButton } from '@/components/ui/button';
import { Textarea } from '@/components/ui/textarea';
import { NativeSelect } from '@/components/ui/select';
import { PlayerPerformanceTab } from '@/components/lifting/performance/PlayerPerformanceTab';
import { createCoachNote } from '@/app/baseball/actions/coach-notes';

Expand Down Expand Up @@ -269,6 +271,9 @@ export function PlayerProfileClient({
const [activeTab, setActiveTab] = useState<MainTab>('overview');
// ── Note add form state ────────────────────────────────────────────────────
const [noteBody, setNoteBody] = useState('');
// Both scopes are authorable by any staff member (canAuthorScope), so no
// capability data is needed to offer this choice; the server still enforces it.
const [noteScope, setNoteScope] = useState<BaseballNoteScope>('staff_public');
const [noteError, setNoteError] = useState<string | null>(null);
const [noteSuccess, setNoteSuccess] = useState(false);
const [isPendingNote, startNoteTransition] = useTransition();
Expand Down Expand Up @@ -409,7 +414,7 @@ export function PlayerProfileClient({
setNoteError(null);
setNoteSuccess(false);
startNoteTransition(async () => {
const result = await createCoachNote({ playerId: player.id, body, scope: 'staff_public' });
const result = await createCoachNote({ playerId: player.id, body, scope: noteScope });
if (result.success) {
setNoteBody('');
setNoteSuccess(true);
Expand Down Expand Up @@ -1376,6 +1381,28 @@ export function PlayerProfileClient({
rows={4}
disabled={isPendingNote}
/>
{/* Visibility scope — staff-only vs. shared with the player. A
player_visible note surfaces on the player's Today + timeline. */}
<div className="mt-3">
<label htmlFor="note-visibility" className="block text-xs font-medium text-warm-500 mb-1.5">
Visibility
</label>
<NativeSelect
id="note-visibility"
value={noteScope}
onChange={(e) => setNoteScope(e.target.value as BaseballNoteScope)}
disabled={isPendingNote}
className="w-56 text-sm"
>
<option value="staff_public">Staff only</option>
<option value="player_visible">Visible to player</option>
</NativeSelect>
<p className="text-xs text-warm-400 mt-1.5">
{noteScope === 'player_visible'
? 'The player will see this note on their Today and timeline.'
: 'Only staff can see this note.'}
</p>
</div>
<div className="flex items-center justify-between mt-3">
<div>
{noteError && (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,7 @@ export function PlayerQuickView({ player, watchlistItem, onClose }: PlayerQuickV
'backdrop-blur-sm'
)}
>
<Link href={`/baseball/dashboard/players/${player.id}`} className="block">
<Link href={`/baseball/player/${player.id}`} className="block">
<Button
variant="primary"
className={cn(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ function SectionCard({
/**
* Optional stable anchor so the dedicated spec routes that fold into this page
* (player-access, guardian-access, showcase-profile, ai, notifications,
* data-retention, demo-mode) can deep-link to their section via #anchor.
* data-retention) can deep-link to their section via #anchor.
* scroll-mt keeps the section clear of the sticky header on jump.
*/
anchorId?: string;
Expand Down
2 changes: 1 addition & 1 deletion src/components/coach/PlayerDetailModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export function PlayerDetailModal({ player, coachId, onClose }: PlayerDetailModa
setMessaging(true);
try {
const result = await createConversation([player.user_id]);
router.push(`/dashboard/messages/${result.conversationId}`);
router.push(`/baseball/dashboard/messages/${result.conversationId}`);
} catch (error) {
console.error('Error creating conversation:', error);
showToast('Failed to create conversation', 'error');
Expand Down
Loading
Loading