import { useState, useEffect } from 'react'; import { Trash2, Loader, AlertCircle, BookOpen, ArrowLeft, Eye, Clock, Layers, } from 'lucide-react'; import * as db from '../../lib/db'; import Card from '../ui/Card'; import Button from '../ui/Button'; import Tag from '../ui/Tag'; // Admin "Learning content" panel. // // The Learn flow stores generated content in the `theme_sessions` PB collection // — one record per (curriculum_version, week_number, theme). The legacy // per-topic `content` collection is no longer fed by the user-facing flow, so // this panel surfaces theme sessions instead. View shows the full session, // Delete removes the record (next visitor to that week will regenerate it). const ContentManager = () => { const [sessions, setSessions] = useState([]); const [loading, setLoading] = useState(true); const [selected, setSelected] = useState(null); const [busyId, setBusyId] = useState(null); const [error, setError] = useState(null); const refresh = async () => { setLoading(true); setError(null); try { const fresh = await db.getAllThemeSessions(); setSessions(fresh); if (selected) { const updated = fresh.find(s => s.id === selected.id); if (updated) setSelected(updated); else setSelected(null); } } catch (e) { setError(e.message); } finally { setLoading(false); } }; useEffect(() => { refresh(); }, []); const handleDelete = async (id) => { if (!confirm('Delete this theme session? The next learner to open this week will regenerate it with the AI.')) return; setBusyId(id); setError(null); try { await db.deleteThemeSession(id); if (selected?.id === id) setSelected(null); await refresh(); } catch (e) { setError(e.message); } finally { setBusyId(null); } }; // ─── Loading ────────────────────────────────────────────── if (loading && sessions.length === 0) { return (

Loading theme sessions…

); } // ─── Empty ──────────────────────────────────────────────── if (!loading && sessions.length === 0) { return (

No theme sessions generated yet.

When a learner opens the Learn page for a week with an active curriculum, its theme session is generated and cached here.

{error && (

{error}

)}
); } // ─── Detail view ────────────────────────────────────────── if (selected) { const content = selected.content || {}; const topicSections = Array.isArray(content.topicSections) ? content.topicSections : []; const takeaways = Array.isArray(content.keyTakeaways) ? content.keyTakeaways : []; return (

{content.title || selected.theme || 'Untitled theme session'}

Week {selected.week_number} {selected.theme && {selected.theme}}
{selected.updated && (

Updated {new Date(selected.updated).toLocaleString()}

)}
{error && (
{error}
)} {content.intro && (

Introduction

{content.intro}

)} {topicSections.length > 0 && (

Topics covered

{topicSections.map((s, i) => (
{s.label} {s.topic_id && ( {s.topic_id} )}
))}
)} {content.connections && (

How these topics connect

)} {takeaways.length > 0 && (

Key takeaways

    {takeaways.map((t, i) => (
  • {t}
  • ))}
)}
); } // ─── List view ─────────────────────────────────────────── return (
{error && (
{error}
)} {sessions.map(s => { const c = s.content || {}; const topicCount = Array.isArray(c.topicSections) ? c.topicSections.length : 0; const isBusy = busyId === s.id; return (
{c.title || s.theme || 'Untitled'} Week {s.week_number} {s.theme && ( {s.theme} )} {topicCount} topics
{s.updated && (

Updated {new Date(s.updated).toLocaleString()}

)}
); })}
); }; export default ContentManager;