make static

This commit is contained in:
2026-09-17 01:29:20 -04:00
parent 3d4d75fdfb
commit 7a0101bcae
11 changed files with 280 additions and 26 deletions
+56 -5
View File
@@ -19,9 +19,12 @@ estimated **remaining** balance, for both meal blocks and FLEX.
- Checkboxes for configured breaks ("missing periods") you spent off campus.
- A numeric input for any additional days you don't want counted.
- Live-updating results — every input recomputes the estimate instantly.
- Everything is config-driven: plans, dates, and breaks live in one JSON file. No code changes
needed to adjust them.
- Everything is config-driven: plans, dates, and breaks live in one JSON file that is fetched at
runtime. Edit it on the server and changes appear on the next page load — no rebuild needed.
- Your plan, checked breaks, and extra-days value are remembered between visits (via
`localStorage`). The date always resets to today.
- Dark theme with restrained CMU Tartan-red accents.
- Ships as plain static files — no server-side code or backend.
## Getting started
@@ -42,8 +45,11 @@ npm test # run the estimation-engine tests
## Configuration
All tunable values live in [`src/config.json`](src/config.json). Edit that file, then reload the
page — the UI updates reactively.
All tunable values live in [`public/config.json`](public/config.json). This file is **fetched at
runtime**, not compiled into the bundle — so after deployment you can edit the deployed
`config.json` directly and the changes take effect on the next page load, with no rebuild.
During development, edit `public/config.json` and reload the page.
```jsonc
{
@@ -96,17 +102,62 @@ Notes:
Checking a break or adding excluded days shifts your expected consumption down, which is what you
want when you were away and not eating on campus.
## Deployment (static hosting)
The app is a purely client-side static site — no backend, no server-side rendering. To deploy:
```bash
npm run build # outputs everything to dist/
```
Then copy the **contents of `dist/`** to wherever you're serving from. The build produces:
```
dist/
index.html
config.json # the live, editable config
assets/ # hashed JS + CSS
```
### Subpath hosting
Asset paths in the build are **relative**, and `config.json` is loaded relative to the page's
own location. That means the app works unchanged whether it's served from a domain root or a
subpath — e.g. `https://www.cmu.edu/~you/meal-estimator/`. No base-path configuration or rebuild
is needed to move it between locations.
The one requirement is that the app is served as a directory with a trailing slash (e.g.
`.../meal-estimator/`). Virtually all static servers (Apache, nginx, and the like) redirect
`.../meal-estimator` to `.../meal-estimator/` automatically, so this is handled for you.
### Editing config after deployment
Because `config.json` sits alongside `index.html` in the deployed files and is fetched at
runtime, you can update plan numbers, dates, or breaks by editing the deployed
`config.json` directly. No rebuild or redeploy of the JS is required — just reload the page.
## Data persistence
The selected plan, checked breaks, and additional-days value are saved to the browser's
`localStorage` and restored on the next visit. The "as of" date is intentionally **not**
persisted — it always defaults to today. Persistence fails silently if `localStorage` is
unavailable (e.g. private browsing), and stale entries (a plan or break no longer in the config)
are ignored on load.
## Project structure
```
index.html # app shell
public/
config.json # all tunable values (plans, dates, breaks); served + fetched at runtime
src/
config.json # all tunable values (plans, dates, breaks)
types.ts # shared types
dates.ts # whole-day date helpers
configLoader.ts # validates + normalizes config
configFetch.ts # fetches config.json at runtime (subpath-aware)
engine.ts # pure estimation math (no DOM)
store.ts # tiny reactive state store
persistence.ts # localStorage load/save of selections
main.ts # builds the UI, re-renders on change
style.css # dark CMU-accented theme
engine.test.ts # engine unit tests