import { useEffect, useState } from 'react' import { useNavigate } from 'react-router-dom' import SearchBar from '../components/SearchBar.tsx' import { RetroMenuBar, RetroWindow, RetroIcon } from '../components/retro' import { fetchCorpora, fetchManuscripts, type Corpus, type Manuscript, } from '../lib/api.ts' /** Map profile IDs to desktop icon glyphs */ const PROFILE_GLYPHS: Record = { 'medieval-illuminated': '\u{1F4DC}', 'medieval-textual': '\u{1F4D6}', 'early-modern-print': '\u{1F5A8}', 'modern-handwritten': '\u{270D}', } export default function Home() { const navigate = useNavigate() const [corpora, setCorpora] = useState([]) const [loading, setLoading] = useState(true) const [error, setError] = useState(null) const [manuscripts, setManuscripts] = useState>({}) const [expanding, setExpanding] = useState(null) const [selectedCorpus, setSelectedCorpus] = useState(null) const [expandError, setExpandError] = useState(null) useEffect(() => { fetchCorpora() .then(setCorpora) .catch((e: Error) => setError(e.message)) .finally(() => setLoading(false)) }, []) const handleCorpusClick = async (corpus: Corpus) => { setSelectedCorpus(corpus) const cached = manuscripts[corpus.id] if (cached) { if (cached.length === 1) navigate(`/reader/${cached[0].id}?profile=${corpus.profile_id}`) return } setExpanding(corpus.id) setExpandError(null) try { const ms = await fetchManuscripts(corpus.id) setManuscripts((prev) => ({ ...prev, [corpus.id]: ms })) if (ms.length === 1) navigate(`/reader/${ms[0].id}?profile=${corpus.profile_id}`) } catch (e: unknown) { setExpandError(e instanceof Error ? e.message : 'Erreur de chargement') } finally { setExpanding(null) } } // ── Loading state ─────────────────────────────────────────────────── if (loading) { return (
Chargement...
) } // ── Error state ───────────────────────────────────────────────────── if (error) { return (

Erreur de connexion

{error}

) } const selectedMs = selectedCorpus ? manuscripts[selectedCorpus.id] : undefined return (
{/* ── Menu bar (top of screen) ─────────────────────────────── */} navigate('/admin') }, ]} right={ navigate(`/editor/${r.page_id}`)} /> } /> {/* ── Desktop area ─────────────────────────────────────────── */}
{/* ── Corpus list window (center) ──────────────────────── */}
1 ? 's' : ''}`} className="w-full max-w-2xl" scrollable > {corpora.length === 0 ? (
Aucun corpus enregistré. Créez-en un via Administration.
) : (
{corpora.map((corpus) => (
{expanding === corpus.id && (
Chargement...
)} {expandError && selectedCorpus?.id === corpus.id && !expanding && (
Erreur: {expandError}
)}
))}
)}
{/* ── Manuscripts sub-window (appears when a corpus has multiple) ── */} {selectedMs && selectedMs.length > 1 && selectedCorpus && ( setSelectedCorpus(null)} statusBar={`${selectedMs.length} manuscrit${selectedMs.length > 1 ? 's' : ''}`} className="w-80" scrollable >
{selectedMs.map((ms) => ( ))}
)}
{/* ── Desktop icons (bottom dock) ────────────────────────── */}
{corpora.map((corpus) => ( void handleCorpusClick(corpus)} /> ))} {corpora.length === 0 && (
Aucun corpus
)}
) }