Commit Graph

160 Commits

Author SHA1 Message Date
bvandeusen 4bff8cc99a feat(web): make TrackRow click-to-play; pass tracks+index from album page
TrackRow becomes a <button> that dispatches playQueue(tracks, index).
Album page supplies the full track list + each index so the rest of
the album enqueues automatically when the user clicks a track.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-24 21:39:34 -04:00
bvandeusen 9b67bb7521 fix(web): restore album-page back link; loosen test matchers
The initial Task 13 pass dropped the back-chevron link above the hero
to satisfy a strict getByRole('link', {name: /Miles Davis/}) matcher
that was finding both the back link and the inline hero-artist link.

Better fix: keep the back affordance users expect, and use matchers
that accept ambiguity — getAllByRole for the hero check, and a
strict '^← …' regex for the back-link assertion.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-23 20:52:28 -04:00
bvandeusen 9d28c9d9de feat(web): add album detail page at /albums/:id
Hero with cover + title + linked artist + metadata; TrackRow list
below. Back link targets the artist page (not Library) so drilling
up feels correct. 404 renders a distinct non-retryable state.
2026-04-23 20:21:50 -04:00
bvandeusen 2e49335aab feat(web): add artist detail page at /artists/:id
Renders the artist name + album count and a responsive AlbumCard grid
from the nested ArtistDetail response. 404 surfaces a distinct
non-retryable 'not found' state; other errors share the retry banner.
2026-04-23 20:12:57 -04:00
bvandeusen 5174b093b9 feat(web): replace / placeholder with real artists list
Uses createArtistsQuery (infinite), URL-driven sort dropdown, Load
more pagination, delayed skeleton, and shared error banner. Also
introduces the test-utils/query.ts helpers for subsequent page tests.
2026-04-23 19:43:37 -04:00
bvandeusen 048663a4c8 feat(web): wire root layout — bootstrap, guard, Shell, QueryProvider
+layout.ts runs auth.bootstrap() in load() so the shell sees the user
synchronously. +layout.svelte installs the TanStack QueryClientProvider,
runs the route guard as a \$effect, and swaps Shell vs. bare slot
based on auth state.
2026-04-23 06:11:43 -04:00
bvandeusen 88961596b1 fix(web): rename route-colocated test to avoid +page.* collision
+page.test.ts triggered svelte-kit sync's route walker (which treats
any +-prefixed file as a route). Renaming to login.test.ts lets the
sync pass without disabling it in scripts, preserving the upstream
guarantee that types in .svelte-kit/ are fresh before check/test.

Plan bug introduced in Task 10 (filename chosen in the plan); fixing
here and updating the plan so re-runs use the correct name.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-23 06:10:11 -04:00
bvandeusen 78f69b8736 feat(web): add login page with returnTo support and typed error UX
Inline errors for invalid creds vs. server-side failures. Validates
returnTo to block open-redirect vectors (//, http://, /login,
parent-traversal).
2026-04-23 02:41:44 -04:00
bvandeusen d2d5d18e74 feat(web): add Library/Search/Playlists placeholder pages
Library replaces the scaffold splash. Search and Playlists are routable
so the Shell's sidebar nav works end-to-end before the real features land.
2026-04-22 22:22:11 -04:00
bvandeusen 86b024dc47 feat(web): scaffold SvelteKit SPA with Tailwind + adapter-static
- SvelteKit 2.x + Svelte 5 + TypeScript + Vite 5
- adapter-static with fallback:'index.html' for SPA deep-link routing
- Tailwind configured with dark-only palette matching spec
- Placeholder landing page at /
- Committed web/build/index.html placeholder (via .gitignore negation) so
  go:embed works before the SvelteKit build has been run
2026-04-22 09:26:36 -04:00