// ============================================================================ // archive.jsx — public "All Entries" devlog archive (English only) // Reuses: ambient.jsx (Eye, ParticleField, SparkBurst), i18n.jsx (LangPicker, // LanguageProvider), components.jsx (Footer), devlog-data.jsx (CANON_POSTS). // ============================================================================ const { useState: useArchiveState, useMemo: useArchiveMemo } = React; const ARCHIVE_T = { en: { back: "Back to site", label: "Devlog · Archive", title1: "All entries from", title2: "the desk.", lede: "Every note we've posted while building Dimension Disrupt — patch breakdowns, art passes, and the occasional confession.", all: "All", sort: "Sort", newest: "Newest", oldest: "Oldest", entry: "entry", entries: "entries", empty: "No entries with that tag yet.", }, es: { back: "Volver al sitio", label: "Devlog · Archivo", title1: "Todas las notas desde", title2: "el escritorio.", lede: "Cada nota que hemos publicado mientras construimos Dimension Disrupt: desgloses de parches, pasadas de arte y alguna que otra confesión.", all: "Todas", sort: "Orden", newest: "Recientes", oldest: "Antiguas", entry: "entrada", entries: "entradas", empty: "Aún no hay entradas con esa etiqueta.", }, }; // Brand mark reused from the homepage nav function BrandMark() { return ( ); } // Nav variant whose links point back to the homepage sections function ArchiveNav() { const { t } = useLang(); return ( Black Craft {t.nav.game} {t.nav.team} {t.nav.devlog} ); } function ArchiveContent() { const { lang } = useLang(); const at = ARCHIVE_T[lang] || ARCHIVE_T.en; const posts = CANON_POSTS; const [activeTag, setActiveTag] = useArchiveState("All"); const [sort, setSort] = useArchiveState("newest"); // tags that actually appear, in canonical order const usedTags = useArchiveMemo(() => { const present = new Set(posts.map((p) => p.tag)); return ["All", ...DEVLOG_TAGS.filter((t) => present.has(t))]; }, [posts]); const visible = useArchiveMemo(() => { let list = posts.slice(); if (activeTag !== "All") list = list.filter((p) => p.tag === activeTag); list.sort((a, b) => sort === "newest" ? b.dateISO.localeCompare(a.dateISO) : a.dateISO.localeCompare(b.dateISO)); return list; }, [posts, activeTag, sort]); return ( {at.back} {at.label} {at.title1}{at.title2} {at.lede} {usedTags.map((tg) => setActiveTag(tg)}> {tg === "All" ? at.all : tagLabel(tg, lang)} )} {at.sort} setSort("newest")}> {at.newest} setSort("oldest")}> {at.oldest} {visible.length} {visible.length === 1 ? at.entry : at.entries} {activeTag !== "All" ? ` · ${tagLabel(activeTag, lang)}` : ""} {visible.map((p) => { const loc = localized(p, lang); return ( {p.cover ? : {p.thumb}} {p.date} {tagLabel(p.tag, lang)} {p.author} {loc.title} {loc.excerpt} ); })} {visible.length === 0 && {at.empty} } ); } function ArchivePage() { return ( ); } const archiveRoot = ReactDOM.createRoot(document.getElementById("root")); archiveRoot.render();
{at.lede}
{loc.excerpt}