feat(student): polish structured ROOT learning flow

CourseView.jsx now shows an '(optional)' label on any activity marked
is_required=false, both in the module activity list and the activity
detail header — the only genuine UX need Phase 6B's new optional/
advanced practice content exposed. No other changes to the existing
Course/Module/Activity navigation, Launch Lab flow, or Practice tab.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
This commit is contained in:
2026-08-26 09:08:28 -05:00
co-authored by Claude Sonnet 5
parent de6c5b3286
commit 54b35e8ad7
+3 -1
View File
@@ -163,6 +163,7 @@ function ActivityRow({ activity, onOpen }) {
<div style={{ borderTop: '1px solid var(--border)', padding: '0.6rem 0', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}> <div style={{ borderTop: '1px solid var(--border)', padding: '0.6rem 0', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
<button className={styles.linkBtn} onClick={onOpen} style={{ textAlign: 'left' }}> <button className={styles.linkBtn} onClick={onOpen} style={{ textAlign: 'left' }}>
<span className={styles.stageCount}>{ACTIVITY_LABELS[activity.activity_type] || activity.activity_type}</span>{' — '}{activity.title} <span className={styles.stageCount}>{ACTIVITY_LABELS[activity.activity_type] || activity.activity_type}</span>{' — '}{activity.title}
{activity.is_required === false && <span className={styles.hint}> (optional)</span>}
</button> </button>
{activity.complete ? <span className={`${styles.pill} ${styles.pillOk}`}>done</span> : activity.estimated_duration_minutes ? <span className={styles.hint}>~{activity.estimated_duration_minutes} min</span> : null} {activity.complete ? <span className={`${styles.pill} ${styles.pillOk}`}>done</span> : activity.estimated_duration_minutes ? <span className={styles.hint}>~{activity.estimated_duration_minutes} min</span> : null}
</div> </div>
@@ -186,7 +187,8 @@ function ActivityDetail({ activity, onLaunchLab, onChange }) {
{activity.complete && <span className={`${styles.pill} ${styles.pillOk}`}>complete</span>} {activity.complete && <span className={`${styles.pill} ${styles.pillOk}`}>complete</span>}
</div> </div>
<p className={styles.stageCount}>{ACTIVITY_LABELS[activity.activity_type] || activity.activity_type} <p className={styles.stageCount}>{ACTIVITY_LABELS[activity.activity_type] || activity.activity_type}
{activity.estimated_duration_minutes && ` · ~${activity.estimated_duration_minutes} min`}</p> {activity.estimated_duration_minutes && ` · ~${activity.estimated_duration_minutes} min`}
{activity.is_required === false && ' · optional'}</p>
{activity.body ? ( {activity.body ? (
<div className="md" style={{ marginTop: '1rem' }}> <div className="md" style={{ marginTop: '1rem' }}>