Case / public site + admin panel
Lördagsgolf
React / JWT-protected API / admin panel
Lördagsgolf is a public season site with an admin panel behind JWT login, where organizers register players, rounds, and courses against a purpose-built backend API.
ProblemVisitors need to quickly understand the course, setup, and results, while organizers need a way to enter rounds, players, and courses without touching the database directly or risking unauthorized writes.
SolutionI built a React/Vite frontend that talks to a purpose-built ASP.NET Core backend: public pages for season results and player profiles, an admin panel behind JWT login for managing players, rounds, and courses, an adapter layer that normalizes the API's varying response shapes, and an API client with timeout and retry.
Technical decisionsAdapter layer (src/services/adapters) that normalizes the API contract — e.g. $values wrappers and inconsistent casing — so UI components never need to know the backend's raw shape.Central API configuration via environment variables, with fallback URLs if the env is missing.Auth token with an expiry stored in sessionStorage, cleared automatically on a 401 from the backend.The backend (ASP.NET Core) requires JWT for every write (POST/PUT/DELETE) on players, rounds, and courses, with IP-based rate limiting on login.GitHub Actions runs lint, test, and build on every push/PR against main.
What it showsThe project shows that I can build and wire a frontend to a self-authored authenticated backend across two repos, with adapters and a resilient API client that keep the UI decoupled from the backend's exact response shape.
TechReact 19Vite 6React Router 7Tailwind CSS 4VitestASP.NET CoreJWTRender