- ProgramsTab.jsx: Active/Completed programs, real progress, deterministic Continue Learning (reuses the same launch/poll pattern MyLearningTab already established), entitlement-blocked states shown with a real reason, never a silent dead end. - StudentDashboard.jsx: new My Programs tab. api.js: programs/program/launchProgram.
60 lines
2.3 KiB
React
60 lines
2.3 KiB
React
import { useState } from 'react'
|
|
import { api } from './api'
|
|
import styles from './Platform.module.css'
|
|
import MyLearningTab from './MyLearningTab'
|
|
import PracticeTab from './PracticeTab'
|
|
import AssessmentsTab from './AssessmentsTab'
|
|
import CapstoneTab from './CapstoneTab'
|
|
import AchievementsTab from './AchievementsTab'
|
|
import ClassroomTab from './ClassroomTab'
|
|
import ProfileTab from './ProfileTab'
|
|
import ProgramsTab from './ProgramsTab'
|
|
|
|
const TABS = [
|
|
{ key: 'learning', label: 'My Learning' },
|
|
{ key: 'programs', label: 'My Programs' },
|
|
{ key: 'classroom', label: 'Classroom' },
|
|
{ key: 'practice', label: 'Practice' },
|
|
{ key: 'assessments', label: 'Assessments' },
|
|
{ key: 'capstone', label: 'Capstone' },
|
|
{ key: 'achievements', label: 'Achievements' },
|
|
{ key: 'profile', label: 'Profile' },
|
|
]
|
|
|
|
// Student home — tabbed as of Phase 3B (docs/PHASE3B_LEARNING_AND_ASSESSMENT.md §10): My
|
|
// Learning (the original Phase 2A/2B "Up Next" + Lab launch flow, unchanged in behavior, just
|
|
// extracted into its own component), Practice, Assessments, Capstone, Achievements/History.
|
|
export default function StudentDashboard({ student, onLogout }) {
|
|
const [tab, setTab] = useState('learning')
|
|
const handleLogout = () => { api.logout().then(onLogout) }
|
|
|
|
return (
|
|
<div className={styles.dashWrap}>
|
|
<header className={styles.dashHeader}>
|
|
<div className={styles.brand}><span className={styles.brandIcon}>⎈</span> RootNode Academy</div>
|
|
<div className={styles.headerRight}>
|
|
<span className={styles.studentName}>{student.display_name}</span>
|
|
<button className={styles.linkBtn} onClick={handleLogout}>Sign out</button>
|
|
</div>
|
|
</header>
|
|
|
|
<nav className={styles.tabNav}>
|
|
{TABS.map((t) => (
|
|
<button key={t.key} className={`${styles.tab} ${tab === t.key ? styles.tabActive : ''}`} onClick={() => setTab(t.key)}>
|
|
{t.label}
|
|
</button>
|
|
))}
|
|
</nav>
|
|
|
|
{tab === 'learning' && <MyLearningTab />}
|
|
{tab === 'programs' && <ProgramsTab />}
|
|
{tab === 'classroom' && <ClassroomTab />}
|
|
{tab === 'practice' && <PracticeTab />}
|
|
{tab === 'assessments' && <AssessmentsTab />}
|
|
{tab === 'capstone' && <CapstoneTab />}
|
|
{tab === 'achievements' && <AchievementsTab />}
|
|
{tab === 'profile' && <ProfileTab />}
|
|
</div>
|
|
)
|
|
}
|