3.3 KiB
Racetimer website (2026)
React 18 + TypeScript + Vite frontend for the UNLOZE racetimer. It reads everything from the new Java backend (racetimer_endpoints).
Pages
| URL | What it shows |
|---|---|
#/leaderboard |
Players ranked by points, with a ZE1 / ZE2 switch. The choice is remembered in the browser. |
#/player/<steamid> |
Profile with ZE1 and ZE2 points and ranks. Records tab: best time per category with place, bonus multiplier, points and date ("Legacy record" for Classic data). A faster run that was invalidated is listed too, marked Run invalidated. Improvement history tab: every improvement and how much faster it was, with a chart for one category. |
#/maps |
Every map with its stages, categories, servers and record counts. |
#/map/<mapname>?stage=&category= |
Stage tabs and category cards. Categories with exactly the same server settings share a number on ZE1 and ZE2 ("Category 1 ZE1", "Category 1 ZE2"). Shows the category's server settings, highlighting values that differ from other categories of the stage. Leaderboard with gap to #1, bonus, points and the 50% points cut-off line. Invalidated runs stay in the list where their time places them, marked Invalid, with no position and 0 points. |
#/search?q= |
Players and maps matching the header search box. |
#/points |
Plain-language explanation of the points rules. |
Old links still work: #/mapboard goes to #/maps, and #/map/<name>/<stage> opens that stage.
Dates are shown in full, down to the second, in the visitor's own time zone.
Admins
The footer has Admin sign-in with Steam. It goes to the backend (/api/auth/steam/login). The backend checks SourceBans and sends the admin back with #token=…. The site stores the token in the browser and removes it from the address bar.
While signed in:
- a yellow bar shows who is signed in, with Sign out
- map leaderboards, profile records and profile history show Invalidate / Restore buttons for single runs
- the category panel has Invalidate / Restore for the whole category
Every action asks for confirmation first. After a change, all pages reload their data.
Everybody (signed in or not) sees which admin invalidated a run or category and when, under the Invalid tag.
Set frontendUrl in the backend settings to this site's URL, or the Steam sign-in cannot find its way back.
Build and deploy
Requires Node 18 or newer.
npm install
npm run build # output in dist/
Upload the contents of dist/ to the web server. The site uses # URLs, so no server rewrite rules are needed, and it works from any folder.
The backend URL defaults to https://racebackend.unloze.com/racetimer_endpoints-1.0/api. To use another one, create .env.local from .env.example before building:
VITE_API_BASE=https://your-backend/racetimer_endpoints-1.0/api
For development, npm run dev serves the site on http://localhost:5173 with live reload.
Code layout
src/api/types.ts: JSON shapes returned by the backend. Keep in sync withracetimer/dto/Dto.java.src/api/client.ts: all API calls and the login token.src/pages/: one file per page.src/components/: shared pieces (layout, chips, admin button, chart).src/styles.css: the dark theme. Colors are CSS variables at the top of the file.