import { useState, useEffect } from 'react' import { api, getCachedDisplay } from './api' import LoginScreen from './LoginScreen' import EntryScreen from './EntryScreen' import SetPasswordScreen from './SetPasswordScreen' import ForgotPasswordScreen from './ForgotPasswordScreen' import StudentDashboard from './StudentDashboard' // Top-level Platform Shell. Phase 5A: the credentialed LoginScreen is now the default entry // point (was EntryScreen's pilot name-picker); an activation/reset link // (?activate= or ?reset=) short-circuits straight to SetPasswordScreen before // any session check, since neither flow requires an existing session. Session validity is // still decided by the server (GET /api/session/whoami against the rn_session cookie), not by // anything read from localStorage/sessionStorage. export default function PlatformShell() { const [student, setStudent] = useState(null) const [checking, setChecking] = useState(true) const params = new URLSearchParams(window.location.search) const [view, setView] = useState( params.get('activate') ? 'activate' : params.get('reset') ? 'reset' : 'login' ) const [resetToken, setResetToken] = useState(params.get('reset') || null) useEffect(() => { if (view === 'activate' || view === 'reset') { setChecking(false); return } const cached = getCachedDisplay() if (cached) setStudent(cached) // optimistic paint while we confirm with the server api.whoami() .then(({ student_id }) => { if (!cached || cached.student_id !== student_id) setStudent({ student_id, display_name: cached?.display_name || student_id }) }) .catch(() => setStudent(null)) .finally(() => setChecking(false)) }, [view]) if (checking) return null if (view === 'activate') { return { setStudent(s); setView('dashboard'); window.history.replaceState({}, '', '/') }} onCancel={() => { setView('login'); window.history.replaceState({}, '', '/') }} /> } if (view === 'reset') { return { setView('login'); window.history.replaceState({}, '', '/') }} onCancel={() => { setView('login'); window.history.replaceState({}, '', '/') }} /> } if (view === 'forgot') { return setView('login')} onHaveToken={(t) => { setResetToken(t); setView('reset') }} /> } if (view === 'pilot') { return { setStudent(s); setView('dashboard') }} /> } if (!student) { return { setStudent(s); setView('dashboard') }} onShowPilotEntry={() => setView('pilot')} onShowForgotPassword={() => setView('forgot')} /> } return { setStudent(null); setView('login') }} /> }