151 Commits

Author SHA1 Message Date
CC Worker
0150ca3c32 merge: CCLiveTranscriptionShapeUtil unit tests — 26 tests (P1c) 2026-05-31 22:25:10 +00:00
CC Worker
33b9278085 merge: replace console.log with logger in CCLiveTranscriptionShapeUtil (P3b) 2026-05-31 22:25:07 +00:00
CC Worker
9196af12f8 merge: static shape styles to CSS classes + pointer-events fix (P3a) — resolve CCBaseShapeUtil conflict, update panel.css shape-title to --cc-text-inverse 2026-05-31 22:24:46 +00:00
CC Worker
f6e2ab63dd merge: hoist ThemeProvider to App.tsx root (P2b) — resolve BasePanel conflict by keeping MUI-free version 2026-05-31 22:23:21 +00:00
CC Worker
f1c1a72f44 merge: remove MUI/styled-components from BasePanel — cc- CSS classes (P2a) 2026-05-31 22:22:31 +00:00
CC Worker
1e7b387b43 merge: --cc-* CSS variable system + design tokens (P1b) 2026-05-31 22:22:27 +00:00
CC Worker
135ba4d26d merge: dirty-flag auto-save in SharedStoreService (P1a) 2026-05-31 22:22:27 +00:00
CC Worker
8c1623256b merge: canvas core stability — TLStore useRef + single-effect state machine (P0a/P0b) 2026-05-31 22:22:19 +00:00
CC Worker
b246106876 Add CCLiveTranscriptionShapeUtil unit tests (26 passing) 2026-05-31 22:20:43 +00:00
CC Worker
d5a7464e15 fix(logger): remove unused CC_BASE_STYLE_CONSTANTS import from CCBaseShapeUtil 2026-05-31 22:10:08 +00:00
CC Worker
061cd22748 fix(shape-css): add pointer-events:all to header/toolbar; fix hardcoded white on lock icon
- .cc-shape-header and .cc-shape-toolbar button were missing pointer-events:all,
  causing toolbar buttons to be unclickable inside tldraw canvas
- Replace color:'white' on lock indicator with var(--cc-text-inverse)
2026-05-31 22:10:08 +00:00
CC Worker
55da04a3f7 refactor(shape-css): move static shape styles to CSS classes and drop unused constants import 2026-05-31 21:48:09 +00:00
CC Worker
2a6359e247 feat: extract static shape styles to CSS classes in CCBaseShapeUtil 2026-05-31 21:46:33 +00:00
CC Worker
3afba919c4 P4.2-W: replace console.log with logger in CCLiveTranscriptionShapeUtil 2026-05-31 21:37:45 +00:00
07ceef1294 refactor(theme): hoist ThemeProvider to App.tsx root 2026-05-31 21:24:05 +00:00
CC Worker
50c7bb68bb refactor: remove MUI and styled-components from BasePanel\n\n- Replace MUI Button/Menu/MenuItem with cc-btn + cc-menu + native div/button\n- Replace MUI icons with inline SVG icons\n- Replace MUI ThemeProvider/useMediaQuery with dataset/colorMode\n- Preserve TldrawUiButton for pin control in panel header\n- Minor: keep local panel state instead of MUI Menu open state 2026-05-31 21:21:06 +00:00
CC Worker
3ffbb11552 fix: restore design-system files accidentally reverted in prior commit
Commit 669a661 had a stale staged deletion of cc-design-system.css and
reverted three other CSS-variable files. This commit restores them to
the state from cd37771 (adopt --cc-* CSS variable system).
2026-05-31 21:15:13 +00:00
CC Worker
669a6616d8 fix(design-system): replace hardcoded color:white in CCBaseShapeUtil with --cc-text-inverse 2026-05-31 21:13:14 +00:00
CC Worker
65bce2c52d fix(auto-save): dirty-flag pattern in SharedStoreService
Replaces JSON.stringify snapshot comparison with a store.listen() dirty flag.
Eliminates 5-15ms main-thread serialize on every poll tick when canvas is idle.
2026-05-31 21:09:38 +00:00
CC Worker
cd37771c52 adopt --cc-* CSS variable system 2026-05-31 21:05:04 +00:00
CC Worker
df59207add Add CCLiveTranscriptionShapeUtil unit tests (26 passing) 2026-05-31 21:01:56 +00:00
CC Worker
2d15b7cc03 feat: replace triple context.node useEffect with single state machine 2026-05-31 20:51:22 +00:00
CC Worker
d3bd25d544 fix: remove TLStore from useState and dead state vars in singlePlayerPage 2026-05-31 20:41:51 +00:00
bf592886c6 fix(F2,F3): onboarding chip in Header, auth catch-all redirects to dashboard
Some checks failed
app-ci-deploy / test-build-deploy (push) Has been cancelled
F3: authenticated unknown routes now redirect to /dashboard instead of
rendering private NotFound.

F2: Header shows a warning Chip with the current onboarding next_step
when the user has not completed onboarding (next_step != 'ready').
Chip navigates to /dashboard on click. Hidden on xs screens.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-05-31 11:00:55 +00:00
fedbd903ff fix: centralize app API URL fallbacks
Some checks failed
app-ci-deploy / test-build-deploy (push) Has been cancelled
2026-05-28 19:26:00 +01:00
65ce1bede8 feat: migrate app state to bootstrap endpoint
Some checks failed
app-ci-deploy / test-build-deploy (push) Has been cancelled
Use GET /me/bootstrap as the primary authenticated state source per ADR-0003. AuthContext now fetches and exposes typed bootstrapData, Header and class/detail admin checks use bootstrap permissions/roles, dashboard surfaces onboarding/calendar/timetable/graph status, and graph navigation derives school setup state from bootstrap instead of /school/status.

Refs: t_44353587
2026-05-28 19:07:07 +01:00
67e47fc47f feat(tlsync): fetch short-lived token from API before multiplayer connect
Some checks failed
app-ci-deploy / test-build-deploy (push) Has been cancelled
- Remove VITE_TLSYNC_SECRET from browser env (no longer exposed to bundle)
- Add useTlsyncToken hook that fetches /api/tlsync/token with Supabase auth
- Extract TldrawCanvas sub-component: only renders after token is ready
- Pass API-issued short-lived token to createSyncConnectionOptions
- Add vite.config.ts blocklist to prevent secret leak (defense-in-depth)
- Remove VITE_TLSYNC_SECRET from .env.example (server-side only now)

Related: t_a69128a1 (API token endpoint), t_41a844a7 (this task)
2026-05-28 18:00:43 +01:00
0db53bfd9c test: add admin route guard coverage
Some checks failed
app-ci-deploy / test-build-deploy (push) Has been cancelled
2026-05-27 23:24:26 +01:00
e68eef8865 chore: consolidate app compose dev and prod 2026-05-27 22:55:00 +01:00
77282893f3 chore: add .gitignore for React frontend project 2026-05-27 21:56:23 +01:00
6642d5fa22 docs: add .env.example with all app environment variables 2026-05-27 21:55:27 +01:00
b2973dc6ad feat: add error boundary to prevent full app crashes 2026-05-27 21:44:59 +01:00
b69c4d3e4f fix: remove 4 empty stub files (dead code) 2026-05-27 21:40:17 +01:00
1c9ed4bd65 fix: remove last classItem.class.academic_year reference in MyClassesPage
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 13:50:27 +01:00
de21c56543 fix: navigate scope in CCGraphNavPanel, class.code -> class_code in MyClassesPage
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 13:45:12 +01:00
7a1032a3bd fix(classes): flat shape for MyClassesPage, SubjectClass nav -> class detail page
- MyClassesPage: fix all classItem.class?.* references to flat field access (class_code, name, description etc)
- MyClassesPage: fix class detail link /timetable/classes/:id -> /classes/:id (actual route)
- CCGraphNavPanel: SubjectClass click navigates to /classes/:id since no Neo4j SubjectClass nodes exist yet

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 13:30:38 +01:00
63d6d1bbca fix(nav): trim burger menu, fix MyClasses for teachers, fix NotFound crash
- Header: trim menu to My Work section (My Lessons, My Classes, Lesson Plans), School Admin (gated), Platform Admin (gated)
- MyClassesPage: fix loading/error state destructure (classesLoading not myClassesLoading)
- NotFound: fix ErrorOutline -> ErrorOutlineIcon to prevent 404 page crash
- timetableService: getMyClasses now calls both /me/teacher and /me/student, merges with role annotation
- timetableStore: myClasses type updated to ClassWithRole[]
- timetable.types: add ClassWithRole interface and code/institute_id optional fields to Class

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 12:58:33 +01:00
98a4212e46 feat(nav): timetable view toggle (By Class / By Term), fix cc-section-node crash
- Fix: skip canvas navigation for Section-type nodes (was crashing on cc-section-node)
- Add By Class / By Term toggle to My Timetable section (mirrors calendar Generic/Academic)
- By Class: pre-loaded SubjectClass children shown immediately on expand
- By Term: lazy-loads AcademicTerms -> Weeks -> TaughtLessons when switched to term view
- displayChildren respects timetableView context for the timetable section

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 12:12:59 +01:00
510bef02b6 feat(timetable): add assign lesson plan dialog to TaughtLessonsPage
Each lesson card gets a LibraryAdd button that opens a searchable
plan picker. Falls back gracefully to empty state when no plans exist,
with a link to /lesson-plans to create one.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 11:25:55 +01:00
9438e17f88 feat(nav): add launch buttons for My Timetable and My Classes sections
Add useNavigate + Launch icon to TreeItem; timetable section shows a
launch button routing to /my-lessons, classes section routes to /my-classes.
Both buttons only appear when the section status is populated.
Exclude classes section from the unlinked/pending icon fallback.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 11:22:26 +01:00
61ef95a35e fix(nav): register Journal/Planner shapes, fix headerColor crash, enable academic week expansion
Bugs fixed:
- 'cc-teacher-timetable-node' missing from NODE_TYPE_THEMES caused
  Cannot read properties of undefined (reading 'headerColor') crash
  when clicking My Timetable
- 'cc-journal-node' and 'cc-planner-node' had no shape utils registered,
  causing 'No shape util found for type' error on Journal/Planner click
- Added null safety (?? fallback) to getNodeTheme to prevent future crashes
  from any other unmapped type
- Removed AcademicWeek from canExpand exclusion so weeks can be expanded
  to show individual academic days

Added:
- CCJournalNodeShapeUtil and CCPlannerNodeShapeUtil (stub shapes)
- CCJournalNodeProps and CCPlannerNodeProps types
- Journal/Planner added to CCNodeTypes, ccGraphShapeProps, NODE_TYPE_THEMES
- 'cc-department-structure-node' mapping added to NODE_TYPE_THEMES

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 10:55:40 +01:00
0f5dbd12bf feat(phase-c): lesson plans library — browse, create, and edit lesson plans
Adds LessonPlansPage (card grid with search/filter, create dialog) and
LessonPlanDetailPage (structured editor with objectives, activities, Bloom
taxonomy tags, per-field AI suggest via  button, and auto-save).

Routes: /lesson-plans and /lesson-plans/:planId wired into AppRoutes.
Nav: Lesson Plans item added to Header menu under Timetable & Classes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 03:59:44 +01:00
6ac5ab7b5c feat(phase-b): student enrollment UI, teacher/student management pages, lesson views
- ClassDetailPage: full rewrite with MUI tabs (students, enrollment requests, teachers),
  add/remove students, approve/reject enrollment requests, AddStudentDialog
- StudentLessonsPage: new — student's weekly lesson view with week navigation
- TaughtLessonsPage: teacher's taught lesson week view
- SchoolSettingsPage, StaffManagerPage, StudentManagerPage: school admin management pages
- PlatformAdminPage: platform admin reset/seed controls
- Header: expanded nav menu (student lessons, school management, platform admin items)
- AppRoutes: routes for all new pages
- SchoolCalendarWizard, TeacherTimetableWizard: week_cycle support and improvements
- CCGraphNavPanel: updated navigation integration
- index.ts: export all new timetable pages

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 02:56:04 +01:00
138dfb1531 chore: add .dockerignore to exclude node_modules from build context
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-26 02:03:17 +01:00
9d78f06c97 feat(phase-b): school onboarding wizard + GAIS school search UI
- SchoolOnboardingWizard.tsx: new 3-step wizard (GAIS search → confirm →
  calendar setup) triggered from the nav panel school section when no school
  is linked. Calls GET /school/search for live school lookup and
  POST /school/register to create the institute record.
- CCGraphNavPanel.tsx: add showOnboard button for no_school state,
  onOnboardSchool context action, wire up SchoolOnboardingWizard state.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-26 01:56:37 +01:00
b0b2a7f2c3 feat(phase-a+b): merge clean auth + Supabase navigation to master
Merges Phase A (Neo4j removed from startup) and Phase B (Supabase navigation,
school/timetable setup, graph nav panel) into master.

Phase A: NeoUserProvider removed, CCUser simplified, snapshotService null-safe
Phase B: navigationStore → Supabase whiteboard_rooms, snapshotService → Supabase Storage,
  CCGraphNavPanel, SchoolCalendarWizard, TeacherTimetableWizard, CIS auth fixes

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-26 01:25:41 +01:00
83adcce951 feat(phase-b): school/timetable wizards, graph nav panel, UI updates
New components:
- CCGraphNavPanel: Supabase-driven navigation tree (school/timetable/calendar/classes sections),
  role-aware setup buttons, lazy child loading, academic/generic calendar toggle
- SchoolCalendarWizard: 3-step admin-only school setup (details → term dates → daily periods)
- TeacherTimetableWizard: period grid with existing slot pre-loading, edit-mode title

Updated:
- CCNodeSnapshotPanel: saves via Supabase storage path + accessToken
- BasePanel: nav panel tab wired to CCGraphNavPanel
- CCFilesPanelEnhanced: auth context fixes
- CCDocumentIntelligence suite: accessToken threading, Supabase storage integration

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-26 01:25:29 +01:00
b0c7758135 feat(phase-b): Supabase navigation store, snapshot service, auth wiring
navigationStore: rewritten off Neo4j db names — Supabase whiteboard_rooms table,
  setAuthInfo(token, userId) pattern, auto-creates default room per context on first use
snapshotService: rewritten to Supabase Storage REST (/storage/v1/object/authenticated/cc.users/…),
  setAccessToken() instance method, static methods take accessToken not dbName
AuthContext/NeoUserContext: auth injected into nav store, no Neo4j db names required
singlePlayerPage: loadNodeData no longer calls Neo4j; snapshot wired via accessToken
navigation types: NeoGraphNode updated for Supabase-backed tree structure
transcriptionStore/Service: getSession() removed, accessToken via AuthContext
LLMConfigModal: auth context wiring fixes
GraphNavigator/GraphSidebar: updated nav components

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-26 01:25:15 +01:00
3a65cf436b fix(panels): eliminate getSession() from transcription store and cabinets panel
Same GoTrueClient lock contention fix as CCFilesPanel:
- transcriptionStore: add _accessToken/_userId state + setAuthInfo() action;
  replace all 6 getSession() calls (startSession, flushCanvasEvents, loadSessions,
  loadKeywordWatches, addKeywordWatch, deleteKeywordWatch, checkSegmentForKeywords)
  with stored values — zero getSession() calls remain in the store
- CCTranscriptionPanel: destructure accessToken from useAuth; sync both values into
  store via setAuthInfo() on every auth change; gate loadSessions on authUser.id
- CCCabinetsPanel: same pattern as CCFilesPanel — useAuth for token, useCallback on
  apiFetch/loadCabinets, gate effect on authUser.id

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 15:13:37 +01:00
6bd85671d2 fix(panels): bypass GoTrueClient lock — expose accessToken via AuthContext, gate panels on auth
Root cause: apiFetch called supabase.auth.getSession() on every API request, acquiring
the GoTrueClient internal lock. On refresh, concurrent mount of panels caused lock
contention — the loadCabinets/loadSessions fetch awaits hung, loading spinner never
cleared.

- AuthContext: add accessToken state, set/clear it alongside user on all auth events
- CCFilesPanel: apiFetch reads accessToken from AuthContext (no lock), loadCabinets
  effect gated on authUser.id (fires only after SIGNED_IN, session guaranteed valid)
- CCTranscriptionPanel: loadSessions effect gated on authUser.id for same reason

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 15:06:51 +01:00