- Added import for ErrorBoundary from src/components/ErrorBoundary.tsx
- Wrapped {store && <Tldraw>} block in ErrorBoundary with 'Canvas failed to load — Reload' fallback
- ErrorBoundary.tsx already existed with full error/reload UI
- Timetable pages (J2) already have loading states via timetableStore loading flags
- tsc: 177 (master baseline) → 173 on this branch (no regression)
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>
- Remove NeoUserProvider + NeoInstituteProvider from App.tsx startup chain
- Strip user_db_name/school_db_name from CCUser; add school_id (Phase B wires it to Supabase)
- Remove DatabaseNameService from AuthContext and UserContext
- Remove provisionUser() call from login path; API endpoint preserved for Phase B decision
- Simplify UserContext.resolveProfile: fast-path JWT metadata then background Supabase fetch
- Replace user.user_db_name reads in singlePlayerPage + snapshotService with null-safe guards
- Add useDeviceContext hook (desktop/tablet/phone/iwb, persists to localStorage)
App now loads to dashboard without any Neo4j dependency at startup.
Canvas opens to blank TLDraw state; Phase B rebuilds navigation on Supabase.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Three changes to singlePlayerPage:
1. Store creation no longer waits for isEditorReady. The editor ref
is already passed as optional to NavigationSnapshotService and
loadNodeSnapshotFromDatabase, so we can create and populate the
store without needing the editor to be mounted first.
2. <Tldraw> only renders when store is defined: {store && <Tldraw>}.
Previously it rendered immediately with store={undefined}, which
caused TLDraw to initialize with no backing store and crash
reading topOffset on an unresolved internal object.
3. Loading guard also checks !user so the component never renders
with a null profile before the redirect effect fires.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
singlePlayerPage was using useUser().user which is always null (no setter
in UserContext). This caused the redirect effect to always fire, making
the workspace completely inaccessible. Fixed by destructuring profile as
user, which IS properly set from the Supabase profiles query.
Also added 8s timeout to NeoUserContext.switchContext call to match the
NeoInstituteContext timeout fix, preventing infinite spinner if the
navigation API call hangs.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>