lobo 44e23de6d6 fix(settings): keep Steam ID as string and store the new token
Number("76561198005679788") is 76561198005679790 in JavaScript, so the wrong
Steam ID was saved. The Steam ID now stays a 17-digit string. Theme and
language saves no longer send steamId 0. After a save the new token from Auth
replaces the old one.

Add Vitest and run it in CI.
2026-09-24 08:57:03 +02:00
2026-03-21 10:47:53 +01:00
2026-03-24 15:08:06 +01:00
2026-03-28 12:33:34 +01:00
2026-03-24 15:08:06 +01:00

To Be Played - Frontend

A modern web application to manage your game backlog, built with React and Vite.

🚀 Tech Stack

📂 Project Structure

├── public/          # Static assets (favicons, icons)
├── src/
│   ├── assets/      # Images and global media
│   ├── components/  # Reusable React components
│   ├── App.jsx      # Main application layout and entry component
│   ├── main.jsx     # App initialization (React DOM, Styles)
│   └── style.css    # Global Tailwind and custom CSS
├── index.html       # Entry HTML file
├── package.json     # Dependencies and scripts
└── vite.config.js   # Vite configuration

🛠️ Development

Setup

npm install

Start Development Server

npm run dev

Build for Production

npm run build

🗺️ Roadmap / Open Topics

Tracking known work that is not yet implemented. Each item is independently actionable.

Security

  • Move JWT out of localStorage. Today the token is stored under localStorage["tbp_jwt"], which makes it readable by any script running on the page — a single XSS in an npm dependency exfiltrates every session. Switch to an httpOnly Secure SameSite=Lax cookie set by tbp-auth-service on login. The SPA no longer touches the token directly; the browser attaches it automatically to requests to *.tbp.andreas-dahm.eu. Requires coordinated changes in Auth (set the cookie) and Deployment (cookie domain + CORS allowCredentials=true).
  • Add CSRF handling. Once auth rides on a cookie, the SPA must echo a CSRF token in a header on state-changing requests. Spring Security's CookieCsrfTokenRepository.withHttpOnlyFalse() on the server pairs with a small fetch interceptor on the client that reads XSRF-TOKEN and sets X-XSRF-TOKEN.
  • Content Security Policy. Add a CSP header in nginx.conf so XSS exfiltration paths are blocked even if a vulnerability slips in. Minimum starting point: default-src 'self'; img-src 'self' data: https://*.steamstatic.com; object-src 'none'; base-uri 'self'; frame-ancestors 'none'. Tighten further by replacing inline styles/scripts (Tailwind is already build-time, so this should be feasible).

Testing

The project has no test runner today. Suggested setup:

  • Unit / component tests: Vitest + React Testing Library. Tests live next to the component (Component.test.jsx).
  • API mocking: MSW (Mock Service Worker) so component tests don't hit the real backend and the same handlers can drive Storybook later.
  • End-to-end tests: Playwright, scoped to the golden paths (login → see library → log out, registration with invitation code, settings update). Run against the real tbp-auth-service + tbp-core-service via docker-compose.dev.yml in CI.
  • First test targets: the auth context / token-handling code, the dark-mode toggle (localStorage["tbp_dark_mode"]), and i18n string resolution.

Other

  • Audit localStorage usage. Currently used for tbp_jwt (planned to move) and tbp_dark_mode. Document any other keys before they accumulate.
  • API base URL handling. VITE_API_URL covers Auth; Core's base URL is implicit. Make both explicit (e.g. VITE_AUTH_URL, VITE_API_URL) so dev / prod / preview environments are unambiguous.

🎯 Product Roadmap (Frontend-owned slices)

The full cross-service product roadmap lives in ToBePlayed-Deployment/README.md. This section lists only the UI / UX slices that land in the Frontend.

1. Backlog tracking UI

Today GameLibrary.jsx is a paginated grid of synced Steam games — there is no per-game state. Once Core exposes status + notes + rating, the Frontend needs:

  • Status chips on each game card (BACKLOG / PLAYING / COMPLETED / DROPPED / ON_HOLD / WISHLIST) with one-click cycling or a popover for explicit selection.
  • Status filter bar above the grid; multi-select; persisted to URL search params so links are shareable and back-button works.
  • Game detail page (GameDetail.jsx exists — extend it) with rating widget (stars or 1–10), completion date picker, markdown notes editor with preview. Optimistic update on save, server reconciliation on failure.
  • Drag-to-reorder within BACKLOG for priority. Use a small library (@dnd-kit/core) — well-maintained, accessible.

2. "What to play next" page

  • New route: /play-next (or surface from Dashboard).
  • Form: time budget radio (15 min / 1 h / weekend), mood tag multi-select.
  • On submit: call Core's picker endpoint, render 3 cards. "Reroll" button calls again.
  • One-tap "Start playing" sets game status to PLAYING.

This page is the single best mobile entry point — design mobile-first.

3. Achievement views

Data is already in Core. The Frontend needs:

  • Achievement progress ring on each game card + game detail.
  • New route /achievements showing library-wide unlocked / total / percent.
  • "Closest to 100%" widget on Dashboard.

4. Public profile + sharing

  • New route /u/:username rendered server-friendly (consider SSR / pre-render for SEO, or at least set proper <title> / <meta> via react-router loaders so link previews work).
  • "Currently playing" + "Recently completed" sections.
  • "Share my profile" button (copies URL).
  • Settings toggle for profile_public.

5. Friends + compare

  • /friends page: list, request, accept, remove.
  • "Add friend" search by username (autocomplete against Auth endpoint).
  • "Compare backlogs with X" page: lists games both own, intersected with BACKLOG status on either side — i.e. "next co-op night candidates".

6. Mobile / PWA

  • Verify the SPA is installable as a PWA: manifest, icons (already in public/?), service worker via vite-plugin-pwa.
  • Test core flows (login, picker, status update) on a real phone, not just devtools. The "what to play tonight" use case is mobile-primary.

7. UX details that compound

  • Search: client-side fuzzy search across library (Fuse.js or similar) on the already-loaded page; server-side search if the library gets large enough that pagination hurts.
  • Empty states: every list should have an empty state with a clear next action ("Connect Steam to import games", "No completed games yet — mark one!").
  • Optimistic updates for any status / rating / notes change — they should feel instant.
  • Keyboard shortcuts for power users (j/k to navigate, s to set status, ? to show shortcut list).
  • i18n is already wired (i18next); make sure every new string lands in the translation files, not hardcoded.
S
Description
Frontend für mein ToBePlayed Projekt
Readme
6.5 MiB
0 Stars 3 Watchers 0 Forks
Languages
JavaScript 96.7%
CSS 3.2%