import { useState, useMemo } from 'react' import styles from './Sidebar.module.css' import { useConfirm } from './useConfirm' const DIFF_COLOR = { Easy: 'green', Medium: 'amber', Hard: 'red' } const TYPE_ICON = { task: '⚙', mcq: '◉' } async function resetProgress(scope, opts) { await fetch('/api/progress/reset', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ scope, ...opts }), }) } export default function Sidebar({ scenarios, activeId, onSelect, loading, collapsed, onToggleCollapse, width, activeBundleId, onProgressUpdate, isExamMode, examProgress, totalExamWeight, }) { const [filterDiff, setFilterDiff] = useState('All') const [filterType, setFilterType] = useState('All') const { confirm, ConfirmUI } = useConfirm() const filteredScenarios = useMemo(() => { return scenarios.filter(s => { if (filterDiff !== 'All' && s.difficulty !== filterDiff) return false if (filterType !== 'All' && s.type !== filterType) return false return true }) }, [scenarios, filterDiff, filterType]) const groups = useMemo(() => { const map = {} filteredScenarios.forEach(s => { if (!map[s.category]) map[s.category] = [] map[s.category].push(s) }) return map }, [filteredScenarios]) // Calculate index based on ALL scenarios so numbers stay absolute const scenarioIndex = useMemo(() => { const map = {} scenarios.forEach(s => { if (!map[s.category]) map[s.category] = [] map[s.category].push(s) }) const idx = {} let counter = 1 Object.values(map).forEach(items => { items.forEach(s => { idx[s.id] = counter++ }) }) return idx }, [scenarios]) // Number scenarios in accordion display order (category by category, then by position within category) const [open, setOpen] = useState({}) useMemo(() => { if (!activeId) return const s = scenarios.find(x => x.id === activeId) if (s) setOpen(o => ({ ...o, [s.category]: true })) }, [activeId, scenarios]) const toggle = cat => setOpen(o => ({ ...o, [cat]: !o[cat] })) const totalDone = isExamMode ? scenarios.filter(s => examProgress?.[s.id]?.status === 'completed').length : scenarios.filter(s => s.progress?.status === 'completed').length const handleCategoryReset = async (e, cat) => { e.stopPropagation() const ok = await confirm({ title: 'Reset Category Progress', message: `Reset all progress in "${cat}"?`, confirmLabel: 'Reset', danger: true, }) if (!ok) return await resetProgress('category', { category: cat }) onProgressUpdate?.() } const handleScenarioReset = async (e, scenarioId, title) => { e.stopPropagation() const ok = await confirm({ title: 'Reset Scenario Progress', message: `Reset progress for "${title}"?`, confirmLabel: 'Reset', danger: true, }) if (!ok) return await resetProgress('scenario', { scenarioId }) onProgressUpdate?.() } return ( <> {ConfirmUI} ) }