A small Create React App (TypeScript) site that shows tunnel/road status. The UI is composed of compact React components that fetch JSON from a public API and render per-road cards, feeds and lightweight ads.
Key points
- Framework: Create React App (TypeScript) using
react-scripts. - UI:
semantic-ui-react+fomantic-ui-css. - API: reads road list from
https://api.stengttunnel.no/roads.jsonand individual road status JSON from eachIRoad.url.
Quick start (local)
- Use the Node version in
.nvmrc(recommended). - Install dependencies:
npm install- Start dev server:
npm startApp runs at http://localhost:3000 and reloads on changes.
Scripts
npm start— development servernpm test— CRA test runnernpm run build— production bundle (output inbuild/)npm run github— runs./scripts/github.sh, used in CI to addCNAMEand404.htmltobuild/
Build / Postbuild
postbuildrunspurgecssto trim unused CSS frombuild/static/cssusingbuild/index.htmlandbuild/static/js/*.jsas content sources. Be careful when renaming CSS classes used only from strings or templates.
Deploy / CI
- GitHub Actions workflow is in
.github/workflows/main.yml— it installs node (reads.nvmrc), runsnpm i,npm run build,npm run github,npm run test, then publishes thebuild/artifact to GitHub Pages (viapeaceiris/actions-gh-pages).
Files and patterns to know
src/App.tsx— top-level component: fetchesroads.json, stores favorites inlocalStorage, and composesHeader+Roads.src/types.ts— authoritative data shapes (IRoad, IRoadStatus, IMessage, IGPS). Update types first when adding fields.src/Road.tsx— per-road presentation: fetchesIRoad.urland rendersIRoadStatus. Usesvisibilitychangeto trigger updates while page is visible. This file now imports an inline SVG component for the traffic light (status template).src/Roads.tsx— composesRoadcomponents and injectsAd/Annonsealternately; contains mobile-scroll helper.src/Header.tsx— Dropdown to pick favorites; builds external links likehttps://stengttunnel.no/<urlFriendly>.public/status/— images for traffic-light; currently the project uses an inline SVG template (moved intosrc/for React import) and previously used PNGs as fallback.scripts/github.sh— writesbuild/CNAMEand symlinks404.htmlfor GitHub Pages.
Assets and sharing
- Traffic-light images are under
public/status/. If you switch to an inline SVG template, move it intosrc/(or import it via SVGR) so React can setclassNameon the<svg>element. Road.tsxuses Clipboard API andnavigator.sharewhen available — tests running in headless CI may need to mock these.
Testing notes
- Tests use the CRA runner (Jest + React Testing Library). See
App.test.tsxfor examples. Keep tests small and component-focused.
Conventions & gotchas
- Keep components small and local-state driven (hooks); there is no global store.
- When adding or renaming classes referenced only inside templates or inline SVGs, remember
purgecssmay strip them duringpostbuildif they're not present in the built HTML/JS. - For any change to the API contract, update
src/types.tsfirst, then consumers.
How to contribute
- Create a branch, add a small unit/component test for behavioral changes, and open a pull request against
main.
Contact / deployment
- The CI job expects
.nvmrcto be accurate; update it if you change Node major versions. npm run githubis run in CI before tests to prepare thebuild/directory for deployment.
License
- See
LICENSEat repository root.
If anything in this README is out of date or you'd like a short developer checklist (pre-merge build/tests/lint hooks), tell me which area to expand and I’ll update it.