A video game collection tracker and backlog manager built with React, TypeScript, and Lovable Cloud.
- Add games manually with title, system, genre, format (physical/digital), estimated completion time, status, rating (1–10), notes, start/end dates (for backlog progression timeline), and box art
- Edit and delete existing entries
- Duplicate detection warns before adding a game that's already in your library
- Game lookup — search button auto-fills genre, system, and box art from an external database via backend functions
- Title autocomplete — suggests game titles as you type (powered by a backend function)
- Box art upload — upload custom cover art to cloud storage
- Import your Steam library by entering a Steam ID, vanity URL, or full profile link
- Resolves vanity URLs automatically
- Fetches genre info for your top 100 games by playtime
- Preview and selectively import games with duplicate detection
- "What should I play next?" recommendation engine
- Scores candidates based on your completed game ratings, genre preferences, system familiarity, estimated length, and current play status
- Prioritises games you've already started
- Full-text search with clear button
- Searchable dropdowns for System and Genre filters (type to filter long lists)
- Status filter (Unplayed / Playing / Completed / Abandoned)
- Paginated results — 10 games per page
- Total games, completed, backlog (unplayed), and physical format counts displayed at a glance
- Email/password sign-up and login
- Google OAuth support
- Two-factor authentication (TOTP) — users can enrol an authenticator app (Google Authenticator, Authy, 1Password, etc.) from the user menu → "Two-Factor Auth". On next sign-in they're prompted for a 6-digit code. Built on Supabase MFA APIs (
supabase.auth.mfa.*); no custom DB tables — factors are stored by Supabase. Components:MfaSetupDialog.tsx(enrol/remove),MfaChallengeDialog.tsx(code prompt at login). Login flow checksgetAuthenticatorAssuranceLevel()after password sign-in; ifnextLevel === "aal2", the challenge dialog opens.UserMenualso re-checks on mount so OAuth/page-refresh sessions are also gated. - Games sync to the cloud when logged in; local storage fallback when logged out
- Row-level security ensures users only access their own data
| Layer | Technology |
|---|---|
| Framework | React 18 + TypeScript 5 |
| Build | Vite 5 |
| Styling | Tailwind CSS 3 + shadcn/ui |
| Routing | React Router 6 |
| State | React Query + local state |
| Backend | Lovable Cloud (database, auth, storage, edge functions) |
src/
├── components/
│ ├── AddGameDialog.tsx # Add/edit game form with lookup & autocomplete
│ ├── AuthDialog.tsx # Login/signup dialog
│ ├── GameCard.tsx # Individual game display card
│ ├── NavLink.tsx # Navigation link component
│ ├── SearchableSelect.tsx # Filterable dropdown (used for System/Genre)
│ ├── StatsBar.tsx # Collection statistics bar
│ ├── SteamImportDialog.tsx # Steam library import wizard
│ ├── SuggestionCard.tsx # "What to play next" recommendation
│ ├── UserMenu.tsx # Auth/user menu
│ └── ui/ # shadcn/ui primitives
├── hooks/
│ ├── useAuth.tsx # Auth context provider & hook
│ ├── use-game-autocomplete.ts # Debounced game title autocomplete
│ └── use-toast.ts # Toast notification hook
├── lib/
│ ├── gameData.ts # Game types, constants, storage helpers, suggestion algorithm
│ └── utils.ts # Utility functions
├── pages/
│ ├── Index.tsx # Main app page
│ └── NotFound.tsx # 404 page
└── integrations/
└── supabase/ # Auto-generated client & types (do not edit)
supabase/functions/
├── game-autocomplete/ # Title autocomplete endpoint
├── game-lookup/ # Game info lookup endpoint
└── steam-import/ # Steam library fetch endpoint
| Column | Type | Description |
|---|---|---|
| id | uuid | Primary key |
| user_id | uuid | Owner (references auth.users) |
| title | text | Game title |
| system | text | Platform (e.g. "PC", "Nintendo Switch") |
| genre | text | Genre (e.g. "RPG", "Action") |
| status | text | Play status: unplayed, playing, completed, abandoned |
| rating | integer | User rating 1–10 |
| notes | text | Personal notes |
| box_art | text | URL to box art image |
| hours_played | numeric | Hours played (from Steam import) |
| start_date | date | When the user started playing (optional) |
| end_date | date | When the user finished/stopped playing (optional) |
| created_at | timestamptz | When added |
| updated_at | timestamptz | Last modified |
| Column | Type | Description |
|---|---|---|
| id | uuid | Primary key |
| user_id | uuid | References auth.users |
| display_name | text | User display name |
| avatar_url | text | Profile avatar URL |
| created_at | timestamptz | When created |
| updated_at | timestamptz | Last modified |
Both tables have row-level security policies restricting access to the owning user.
PC, Steam Deck, PlayStation (PS1–PS5, PSP, Vita), Xbox (all generations), Nintendo (NES through Switch), Sega (Genesis, Saturn, Dreamcast), Atari 2600, Neo Geo, Mobile, VR, Other
Action, Adventure, RPG, JRPG, Strategy, Simulation, Puzzle, Platformer, Shooter, Fighting, Racing, Sports, Horror, Survival, Open World, Metroidvania, Roguelike, Visual Novel, Indie, MMO, Other