// desidium-journal.jsx — Journal index, Article page, Author page. Exported to window. const { useEffect: useEffectJr } = React; function authorById(id) { return AUTHORS.find((a) => a.id === id); } function postsByAuthor(id) { return POSTS.filter((p) => p.author === id); } /* ---------------- JOURNAL INDEX ---------------- */ function JournalIndex({ lang, motion, onPost, onAuthor }) { const j = I18N.journal; useEffectJr(() => { window.scrollTo(0, 0); }, []); const featured = POSTS.find((p) => p.feature) || POSTS[0]; const rest = POSTS.filter((p) => p.id !== featured.id); return (
{/* HEADER */}
{j.kicker[lang] || j.kicker.en}

{L(j.title1, lang)} {L(j.title2, lang)}

{L(j.sub, lang)}

{/* FEATURED */}
{L(featured.cat, lang)} · {L(featured.date, lang)} · {L(featured.read, lang)}

onPost(featured.id)}>{L(featured.title, lang)}

{L(featured.excerpt, lang)}

{/* GRID */}
{L(j.latest, lang)}
{rest.map((p, i) => (
{L(p.cat, lang)} · {L(p.read, lang)}

onPost(p.id)}>{L(p.title, lang)}

{L(p.excerpt, lang)}

))}
); } /* ---------------- ARTICLE PAGE ---------------- */ function ArticlePage({ post, lang, motion, onBack, onPost, onAuthor }) { const j = I18N.journal; useEffectJr(() => { window.scrollTo(0, 0); }, [post.id]); const author = authorById(post.author); const idx = POSTS.findIndex((p) => p.id === post.id); const next = POSTS[(idx + 1) % POSTS.length]; const body = post.body || []; const mid = Math.ceil(body.length / 2); return (
{/* HERO */}
{L(post.cat, lang)} · {L(post.date, lang)} · {L(post.read, lang)}

{L(post.title, lang)}

{/* BODY */}
{L(post.excerpt, lang)}
{body.slice(0, mid).map((p, i) => ( {L(p, lang)} ))} {post.pull && ( {L(post.pull, lang)} )} {body.slice(mid).map((p, i) => ( {L(p, lang)} ))}
{/* AUTHOR CARD */}
{L(j.aboutAuthor, lang)}

{author.name}

{L(author.role, lang)}

{L(author.bio, lang)}

{/* NEXT */}
onPost(next.id)}>
{L(j.nextRead, lang)}
{L(next.cat, lang)}·{L(next.read, lang)}

{L(next.title, lang)}

{L(j.read, lang)}
); } /* ---------------- AUTHOR PAGE ---------------- */ function AuthorPage({ author, lang, motion, onBack, onPost }) { const j = I18N.journal; useEffectJr(() => { window.scrollTo(0, 0); }, [author.id]); const posts = postsByAuthor(author.id); const countLabel = posts.length === 1 ? L(j.piece, lang) : L(j.pieces, lang); return (
{L(j.authorRole, lang)}

{author.name}

{L(author.role, lang)}

{L(author.bio, lang)}

{L(j.authorFocus, lang)}
{L(author.focus, lang)}
{L(j.authorWrites, lang)}
{posts.length} {countLabel}
{L(j.authorWrites, lang)} {author.name}
{posts.map((p, i) => (
{L(p.cat, lang)} · {L(p.date, lang)} · {L(p.read, lang)}

onPost(p.id)}>{L(p.title, lang)}

{L(p.excerpt, lang)}

))}
); } Object.assign(window, { JournalIndex, ArticlePage, AuthorPage });