All checks were successful
CI / Check / Test (push) Successful in 38m33s
Movies Diary — SPA
Mobile-first single page application for Movies Diary, served at /app/.
Stack
- React 19 + TypeScript
- TanStack Router — file-based routing
- TanStack Query — data fetching, caching, mutations
- Tailwind CSS v4 + shadcn/ui — styling and components
- Vaul — mobile drawers
- date-fns — date formatting
- i18next — internationalization
- Zod — API response validation
Routes
| Path | Page |
|---|---|
/login |
Login |
/register |
Registration |
/ |
Home — Feed / Watchlist / Queue tabs |
/diary |
Diary with month navigation + CSV export |
/search |
Search movies and people |
/profile |
Own profile with trends |
/social |
Following / Followers / Pending |
/movies/:id |
Movie detail — cast, crew, stats, reviews |
/people/:id |
Person detail — filmography |
/users/:id |
Other user's profile |
/wrapup/:id |
Year in Review report |
/settings/ |
Settings hub |
/settings/edit-profile |
Edit display name, bio, avatar, banner |
/settings/import |
CSV/JSON/XLSX import wizard |
/settings/webhooks |
Jellyfin/Plex webhook tokens |
/settings/wrapup |
Generate/manage year wrap-ups |
/settings/blocked |
Blocked users and domains (admin) |
Development
npm install
npm run dev
The SPA expects the backend API at the URL defined by VITE_API_URL (defaults to empty string = same origin).
Create spa/.env for local development:
VITE_API_URL=http://localhost:3000
Build
npm run build
Output goes to dist/, served by the backend at /app/.
Project Structure
src/
├── components/ # Reusable UI components
│ ├── ui/ # shadcn/ui primitives
│ ├── back-button # History-aware back navigation
│ ├── movie-card # Movie display (compact/full)
│ ├── review-card # Review with user, rating, date
│ ├── person-row # Person search result
│ ├── log-sheet # Log review drawer
│ ├── star-rating # Interactive star input (with haptics)
│ ├── swipe-to-delete
│ └── ...
├── hooks/ # TanStack Query hooks
│ ├── use-diary # Feed, diary, log/delete review
│ ├── use-movies # Movie detail, profile, history
│ ├── use-search # Search with infinite scroll
│ ├── use-social # Follow/unfollow, block
│ ├── use-users # User profiles, admin reindex
│ ├── use-watchlist # Watchlist CRUD
│ ├── use-webhooks # Webhook tokens, watch queue
│ └── use-wrapup # Wrap-up generation/reports
├── lib/
│ ├── api/ # Typed API client (get/post/put/del)
│ ├── auth.ts # Token storage
│ ├── date.ts # timeAgo, shortDate formatters
│ ├── haptics.ts # Vibration feedback
│ └── query-client.ts # QueryClient with error toasts
├── locales/ # i18n translations
└── routes/ # File-based TanStack Router pages
Features
- Federation-aware — globe badge on federated reviews,
@user@instancehandles - Admin tools — search reindex, user picker for wrap-ups, domain blocking
- Offline-friendly — stale-while-revalidate caching, retry on 5xx
- Mobile UX — swipe-to-delete, haptic feedback, iOS keyboard-safe drawers
- Interactivity — clickable cast/crew → people pages, movie highlights → detail