Files
projects-jenz/RaceTimer_2026/racetimer_react/README.md
T

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 with racetimer/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.