Skip to content

Repository files navigation

tools.mbr.services

Small static web tools, published via GitHub Pages at tools.mbr.services. Everything runs entirely in the browser: all form input stays in localStorage and is never sent anywhere. (The site itself is served by GitHub Pages, so requesting it exposes the usual request metadata - IP address etc. - to GitHub; hence the privacy link in the footer.)

Tools

Path Tool
school-forms/ Fill in German school forms, preview them as an A4 sheet and save/print them as PDF

Repository layout

index.html                  Landing page (tool overview)
server.js                   Zero-dependency static dev server (npm run dev)
build.js                    Assembles dist/ incl. generated manifest.json files
manifest.js                 Shared directory-listing logic for server.js and build.js
school-forms/               npm workspace, one per tool
  package.json              Tool-specific dependencies, tests and vendor script
  vendor.js                 Copies the browser libraries into src/vendor/ (npm run vendor)
  update-holidays.js        Fetches Thuringian school holidays into src/data/
  src/                      Everything in here is deployed as-is to /school-forms/
    index.html              App shell
    styles.css              All styles incl. print CSS
    app.js                  App logic, template registry, shared view helpers
    profiles.js             Master data (school, children, contacts) shared across forms
    templates/*.mustache    Sheet markup per form template, fetched at runtime
    templates/*.js          Field definitions + view() (computed values) per template
    templates/partials/     Shared mustache partials (school header, signature row)
    data/                   holidays.json (auto-updated weekly), coverage.json and
                            schools.json (school directory for the autocomplete; manual)
    vendor/                 mustache, jsPDF, html2canvas - copied at install time,
                            not committed (the PDF pair is loaded on first export only)
  examples/                 Private scans of the original forms - gitignored, never deployed
  tests/smoke-test.js       Renders every template with the fixture data
  tests/dom-test.js         Boots the app in happy-dom and exercises master data,
                            child switching and persistence
  tests/fixtures/           Sample form data used by the tests

The dev server maps /<workspace>/ to <workspace>/src/, so local URLs match the deployed ones.

Every served directory answers <dir>/manifest.json with an array of its file names - a static stand-in for a listing API. The dev server generates it on the fly (no rebuild while developing), the build writes it as a real file. The app uses it e.g. to discover the mustache partials in templates/partials/.

Third-party code is not committed. mustache.js (templates), jsPDF and html2canvas (the "Als PDF" export) are pinned in the workspace's package.json, integrity-checked via the root package-lock.json and copied into school-forms/src/vendor/ by the vendor npm script (runs automatically on npm install).

The PDF export exists because mobile Safari prints its own header and footer (title, date, URL, page number) onto every page and offers no way to turn that off - no CSS reaches that part of the print job. A PDF file printed from the Files app comes out clean, so the app renders one from the very sheet the preview shows; that keeps preview and PDF from drifting apart.

Local development

Node is managed with mise (see mise.toml):

mise install
npm install        # installs all workspaces, copies the libraries into school-forms/src/vendor/
npm test           # template render test + DOM boot test (both also run in CI)
npm run dev        # serves the site at http://localhost:8080/school-forms/

The apps fetch their *.mustache templates at runtime, so the site must be served over HTTP - opening index.html via file:// is not supported.

Build

npm run build

build.js assembles the deployable site into dist/: the landing page, each workspace's src/ copied verbatim (incl. the vendored libraries) and a manifest.json per directory.

Deployment (GitHub Pages)

Pushes to main are deployed automatically by .github/workflows/deploy.yml (build with mise/npm, upload dist/, deploy).

Adding a form template

Create a pair in school-forms/src/templates/: <id>.mustache with the sheet markup, and <id>.js calling registerTemplate({...}) with id, label, fields and view(d). Nothing else - the app discovers both files via the directory manifest and loads them at runtime (dropdown sorted by label). fields may be a function of the current data for dynamic field lists, and a template can declare dataFiles (JSON fetched into this.data, see holiday-care.js). An optional <id>.notes.html renders as accompanying notes in the template panel - the file decides its own structure and wraps long sections in native <details> where useful. Computations (formatted dates, sums, derived values) belong in view(d) - the Mustache template itself stays logic-less.

Holiday data

school-forms/src/data/holidays.json (Thuringian school holiday dates, from the OpenHolidays API) is refreshed weekly by .github/workflows/update-holidays.yml, which commits only when dates actually changed - plus a keepalive commit after ~50 quiet days so GitHub's 60-day inactivity rule never disables the schedule. The fetch happens in the workflow runner; the published site stays fully static and users never contact third-party APIs. data/coverage.json (which school covers which care period) and data/schools.json (the school directory feeding the master-data autocomplete) have no public source and are maintained by hand.

About

Small static web tools, published via GitHub Pages at https://tools.mbr.services.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages