// Archive — full sorted grid of every published case, with a category filter bar.
// Data comes from window.CASES (loaded async by data.jsx).
const ArchiveIntro = ({ total, unsolved }) => (
▸ SECTION / 档案库
全部档案
Every file on record — sorted by when it was filed.
总计 · {total} 卷
其中未结 · {unsolved} 卷
最新更新 · {new Date().toISOString().slice(0,10)}
);
const ArchiveFilter = ({ active, onChange }) => (
{CATEGORIES.map(c => {
const on = active === c.k;
return (
onChange(c.k)} style={{
padding: "8px 16px",
marginRight: -1, marginBottom: -1,
border: "1px solid #2a2620",
background: on ? "#8b0000" : "transparent",
color: on ? "#f4ecd8" : "#c9bda0",
display: "flex", flexDirection: "column", alignItems: "flex-start",
minWidth: 130,
}}>
{c.zh}
{c.en} · {c.count}
);
})}
);
const App = () => {
useDataReady();
const [active, setActive] = React.useState(() => {
const p = new URLSearchParams(location.search);
return p.get("cat") || "all";
});
if (!window.DATA_READY) {
return (<>
>);
}
const cases = active === "all" ? CASES.slice() : CASES.filter(c => c.cat === active);
cases.sort((a, b) => (b.published_ts || 0) - (a.published_ts || 0));
return (
<>
{active === "all" ? "全部" : active} · {cases.length} FILES
排序 ▾ 最新归档
{cases.length === 0 ? (
该分类下暂无案卷。
) : (
{cases.map((item, i) => (
))}
)}
>
);
};
ReactDOM.createRoot(document.getElementById("root")).render( );