mirror of
https://github.com/tiennm99/thptqg.git
synced 2026-10-11 03:13:48 +00:00
The app was a single-entry React SPA: one index.html that the assembler copied to every dataset path, with a hand-rolled router resolving the dataset from window.location and the title patched in at runtime because one file had to serve every route. SvelteKit prerenders a real page per route instead. The entry generator in routes/[dataset]/+page.ts reads the same datasets.json the assembler does, so the set of pages and the set of databases cannot drift apart, and each dataset page ships its own <title> and description. Everything framework-free moved across unchanged in behaviour and became typed: the admission blocks, subject list, query classifier and SQL presets. `Student` now mirrors the 22-column table, so a mistyped column name fails the build rather than rendering blank. Tailwind replaces the stylesheet. Theme tokens are CSS variables, which keeps dark mode a single block of overrides rather than a `dark:` variant on every class. The score tiers stay hand-written CSS: the class is chosen at runtime from a score, and no utility generator can see that. Adds the tests the frontend never had, over the three modules where a silent wrong answer is possible — most importantly that toAscii here folds exactly as ToAscii does in the parser, which is what makes accent-insensitive search find anything. The assembler stops copying index.html per dataset and checks that the build prerendered each one instead. The database presence, raw-artifact and idempotence guards are untouched. Verified: 25 tests, ESLint and svelte-check clean, and a full `assemble site` producing /thptqg/, /thptqg/2016/, /thptqg/2017/ and 404.html with absolute asset URLs. Not verified in a browser — this machine has none.
17 lines
674 B
TypeScript
17 lines
674 B
TypeScript
import { error } from "@sveltejs/kit";
|
|
import { DATASETS, datasetById } from "$lib/datasets";
|
|
import type { EntryGenerator, PageLoad } from "./$types";
|
|
|
|
/**
|
|
* One prerendered page per registered dataset. The registry is the repository
|
|
* root's datasets.json, so a dataset the assembler builds is a page that exists,
|
|
* and one it does not is a 404 at build time rather than a blank page.
|
|
*/
|
|
export const entries: EntryGenerator = () => DATASETS.map((d) => ({ dataset: d.id }));
|
|
|
|
export const load: PageLoad = ({ params }) => {
|
|
const dataset = datasetById(params.dataset);
|
|
if (!dataset) throw error(404, `Unknown dataset: ${params.dataset}`);
|
|
return { dataset };
|
|
};
|