BikeControl (SwiftControl)
Use Zwift Click, Zwift Play, Shimano Di2, or any Bluetooth controller with MyWhoosh, Rouvy, Zwift, and more. Free to try on iOS, Android, Windows, and macOS.
Explore Formula 1 stats, view race replays and compare drivers and teams
Translation pending
AI summary · website content
Sports & fitnessTypeScript · CSSGitHub @VladBryzhakOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
The maker's introduction consists of the line above. Read the repository README for more details. Repository README ↗
Loading the full README.
Read the full README ↗A full-stack Formula 1 statistics web app: championship standings, race calendar, driver & team profiles, head-to-head comparisons, past-race telemetry, and a session replay player that plays back completed races lap-by-lap.
Live: https://paddocktimes.com
Paddock Times is a monorepo with a React SPA and an Express API. The client
only ever talks to our own backend; the backend fetches data from free public F1
sources, normalizes their verbose shapes into flat types, and caches everything in
memory. One deployed web service serves both the API (/api/*) and the built SPA.
The project covers 1950 → present for historical stats, and 2023 → present for telemetry and replays.
pageimages API (CC-BY-SA / public domain).P154, image P18) and
licence-checked on Commons — a free PD/CC logo is used when available,
otherwise a free car photo, otherwise a team-coloured tile. Trademarked / non-free
emblems are deliberately skipped.robots.txt.| Layer | Stack |
|---|---|
| Frontend | React 18, TypeScript, Vite 6, React Router 7, Recharts |
| Backend | Node 20, Express 4, TypeScript, Helmet, node-cache |
| Data | f1db (CC-BY 4.0), OpenF1, Wikimedia Commons / Wikidata |
| Hosting | Render (single web service) |
f1db-json-splitted.zip once, unzips it in memory
(adm-zip), and joins the normalized tables into our flat types. The dataset is
held in a single in-flight promise for the process lifetime.┌────────────┐ /api/* ┌──────────────┐ HTTP ┌──────────────────┐
│ React SPA │ ──────────────▶ │ Express API │ ────────▶ │ f1db · OpenF1 · │
│ (Vite) │ ◀────────────── │ normalize + │ ◀──────── │ Wikimedia · RSS │
└────────────┘ flat JSON │ cache (TTL) │ └──────────────────┘
└──────────────┘
/api/*). In dev, Vite proxies /api
to the server; in production, Express serves both the API and the built SPA.cached(key, ttlSeconds, producer) (in-memory
TTL cache) to stay well within rate limits.502 { error }.F1_Dashboard/
├── client/ # React + Vite SPA
│ ├── src/
│ │ ├── pages/ # route components (Home, Standings, Live, …)
│ │ ├── components/ # shared UI (ReplayPlayer, EntityCards, Footer, …)
│ │ ├── hooks/ # useAsync, useSeo, useSeasonRoute
│ │ ├── lib/ # f1 metadata, team colours, JSON-LD helpers
│ │ ├── api/client.ts # typed wrapper around /api
│ │ └── types/f1.ts # client-side mirror of the backend types
│ └── public/ # sitemap.xml, robots.txt, icons
└── server/ # Node + Express API
└── src/
├── routes/ # thin Express handlers (standings, live, …)
├── services/ # fetch + normalize + cache (f1db, live, teamImages, …)
├── cache/ # node-cache TTL wrapper
└── types/f1.ts # canonical normalized types
All endpoints are prefixed with /api.
| Endpoint | Description |
|---|---|
GET /health | Liveness probe |
GET /home | Weekend highlights + news headlines |
GET /standings/drivers/:season | Driver championship for a season |
GET /standings/constructors/:season | Constructor championship for a season |
GET /standings/progression/:season | Title-race progression (chart data) |
GET /calendar/:season | Season schedule + winners (sprint-flagged) |
GET /calendar/:season/:round | A single race result |
GET /calendar/:season/:round/weekend | Full weekend: race, qualifying, sprint, highlights |
GET /drivers · GET /drivers/:id | Driver list / full profile |
GET /drivers/photos | Driver photos (Wikimedia), keyed by id |
GET /constructors · GET /constructors/:id | Constructor list / full profile |
GET /constructors/images | Licence-checked team logos/photos |
GET /compare/drivers/:a/:b | Head-to-head comparison |
GET /telemetry/sessions/:season · /telemetry/drivers/:sessionKey | Telemetry metadata |
GET /live/status | Live-session status (handles OpenF1 lock) |
GET /live/races | Replayable races and sprints (2023+) |
GET /live/:sessionKey/replay · /board · /driver/:num | Replay / board / driver detail |
POST /feedback | Submit user feedback |
Requires Node 18+ (Node 20 recommended).
# Terminal 1 — backend (http://localhost:3001)
cd server
npm install
npm run dev
# Terminal 2 — frontend (http://localhost:5173)
cd client
npm install
npm run dev
Open http://localhost:5173 — the Vite dev server proxies /api to the backend.
client: npm run dev · npm run build (type-check + production build) · npm run lint
server: npm run dev (tsx watch) · npm run build (tsc) · npm start
| Variable | Purpose |
|---|---|
PORT | API port (default 3001) |
/api/home every 10 minutes, which both keeps the process awake and keeps the f1db
dataset warm in memory. (A sleeping server returning errors on robots.txt can also
stall Googlebot, so the keep-alive doubles as an SEO safeguard.)Повноцінний веб-застосунок зі статистикою Формули-1: турнірні таблиці чемпіонату, календар гонок, профілі пілотів і команд, порівняння «голова-в-голову», телеметрія минулих гонок і плеєр реплеїв сесій, що відтворює завершені гонки коло за колом.
Онлайн: https://paddocktimes.com
Paddock Times — це монорепозиторій із React SPA та Express API. Клієнт
спілкується виключно з нашим бекендом; бекенд отримує дані з безкоштовних публічних
джерел F1, нормалізує їхні громіздкі формати у плоскі типи й кешує все в пам'яті. Один
розгорнутий веб-сервіс віддає і API (/api/*), і зібраний SPA.
Проєкт охоплює історичну статистику від 1950 до сьогодні, а телеметрію й реплеї — від 2023 до сьогодні.
pageimages API (CC-BY-SA / суспільне надбання).P154, зображення
P18) із перевіркою ліцензії на Commons — вільний PD/CC логотип, якщо є, інакше
вільне фото боліда, інакше плитка в кольорі команди. Торгові марки / невільні
емблеми свідомо пропускаються.robots.txt.| Рівень | Стек |
|---|---|
| Фронтенд | React 18, TypeScript, Vite 6, React Router 7, Recharts |
| Бекенд | Node 20, Express 4, TypeScript, Helmet, node-cache |
| Дані | f1db (CC-BY 4.0), OpenF1, Wikimedia Commons / Wikidata |
| Хостинг | Render (один веб-сервіс) |
f1db-json-splitted.zip, розпаковує його в
пам'яті (adm-zip) і зшиває нормалізовані таблиці у наші плоскі типи. Датасет
тримається в єдиному проміжному промісі на весь час життя процесу.┌────────────┐ /api/* ┌──────────────┐ HTTP ┌──────────────────┐
│ React SPA │ ──────────────▶ │ Express API │ ────────▶ │ f1db · OpenF1 · │
│ (Vite) │ ◀────────────── │ нормалізація │ ◀──────── │ Wikimedia · RSS │
└────────────┘ плоский JSON │ + кеш (TTL) │ └──────────────────┘
└──────────────┘
/api/*). У розробці Vite проксує /api
на сервер; у продакшені Express віддає і API, і зібраний SPA.cached(key, ttlSeconds, producer) (кеш у
пам'яті з TTL), щоб упевнено лишатися в межах лімітів.502 { error }.F1_Dashboard/
├── client/ # React + Vite SPA
│ ├── src/
│ │ ├── pages/ # компоненти маршрутів (Home, Standings, Live, …)
│ │ ├── components/ # спільний UI (ReplayPlayer, EntityCards, Footer, …)
│ │ ├── hooks/ # useAsync, useSeo, useSeasonRoute
│ │ ├── lib/ # метадані F1, кольори команд, хелпери JSON-LD
│ │ ├── api/client.ts # типізована обгортка над /api
│ │ └── types/f1.ts # клієнтська копія бекенд-типів
│ └── public/ # sitemap.xml, robots.txt, іконки
└── server/ # Node + Express API
└── src/
├── routes/ # тонкі Express-хендлери (standings, live, …)
├── services/ # fetch + нормалізація + кеш (f1db, live, teamImages, …)
├── cache/ # обгортка node-cache з TTL
└── types/f1.ts # канонічні нормалізовані типи
Усі ендпоінти мають префікс /api.
| Ендпоінт | Опис |
|---|---|
GET /health | Перевірка доступності |
GET /home | Підсумки вікенду + новинні заголовки |
GET /standings/drivers/:season | Чемпіонат пілотів за сезон |
GET /standings/constructors/:season | Чемпіонат конструкторів за сезон |
GET /standings/progression/:season | Перебіг боротьби за титул (дані графіка) |
GET /calendar/:season | Календар сезону + переможці (з позначкою спринтів) |
GET /calendar/:season/:round | Результат однієї гонки |
GET /calendar/:season/:round/weekend | Увесь вікенд: гонка, кваліфікація, спринт, хайлайти |
GET /drivers · GET /drivers/:id | Список / повний профіль пілота |
GET /drivers/photos | Фото пілотів (Wikimedia), за id |
GET /constructors · GET /constructors/:id | Список / повний профіль конструктора |
GET /constructors/images | Логотипи/фото команд із перевіркою ліцензії |
GET /compare/drivers/:a/:b | Порівняння «голова-в-голову» |
GET /telemetry/sessions/:season · /telemetry/drivers/:sessionKey | Метадані телеметрії |
GET /live/status | Статус живої сесії (з обробкою блокування OpenF1) |
GET /live/races | Гонки та спринти для реплею (2023+) |
GET /live/:sessionKey/replay · /board · /driver/:num | Реплей / табло / деталі пілота |
POST /feedback | Надсилання зворотного зв'язку |
Потрібен Node 18+ (рекомендовано Node 20).
# Термінал 1 — бекенд (http://localhost:3001)
cd server
npm install
npm run dev
# Термінал 2 — фронтенд (http://localhost:5173)
cd client
npm install
npm run dev
Відкрий http://localhost:5173 — Vite проксує /api на бекенд.
client: npm run dev · npm run build (перевірка типів + продакшн-збірка) · npm run lint
server: npm run dev (tsx watch з перезапуском) · npm run build (tsc) · npm start
| Змінна | Призначення |
|---|---|
PORT | Порт API (за замовчуванням 3001) |
/api/home кожні 10 хвилин, що і тримає процес активним, і зберігає датасет f1db
теплим у пам'яті. (Сплячий сервер, який віддає помилки на robots.txt, також може
застопорити Googlebot, тож keep-alive слугує ще й запобіжником для SEO.)Built incrementally — standings, calendar, profiles, telemetry, F1.com-inspired design, live timing, session replays, search, media, and SEO.