feat: /profile dashboard with tabbed preferences, account, bookmarks, collections (0.18.0)
Tabbed user dashboard at `/profile` that absorbs `/settings` and surfaces bookmarks + collections in one place. - New `/profile` shell with tabs: Overview (counts), Preferences (theme + reader prefs, ported from /settings; works for guests via localStorage), Account (password change; auth-gated), Bookmarks, Collections. Guest tab list is filtered to what they can actually use. - `/settings` is a 308 redirect to `/profile/preferences` so old bookmarks land cleanly. The "Settings" link in the top nav is replaced by a Profile link between Upload and Bookmarks; Bookmarks + Collections stay as shortcuts per the user spec. - Extracts `lib/components/BookmarkList.svelte` and `lib/components/CollectionsGrid.svelte` so the top-level /bookmarks + /collections routes and the new profile tabs render the same UI without duplication. Both layers use a three-state load (authenticated / guest / error) to handle network hiccups inline. - Deep links preserved via `?next=` on every sign-in CTA. 88 frontend unit tests + svelte-check clean; 12 of 12 e2e tests in profile.spec.ts and reader-mode.spec.ts pass (8 other e2e failures predate this branch and stay flagged for cleanup). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -201,13 +201,13 @@ test('reader-mode preference set on one page is honored when the reader opens',
|
||||
);
|
||||
});
|
||||
|
||||
test('settings page hides the gap picker while in single-page mode', async ({ page }) => {
|
||||
test('preferences page hides the gap picker while in single-page mode', async ({ page }) => {
|
||||
// Visually verifies the conditional render. The radio-click semantics
|
||||
// are exercised in src/lib/preferences.svelte.test.ts; the visible
|
||||
// mode toggle in the reader top bar covers the cross-route propagation
|
||||
// path in the test above.
|
||||
await mockReaderApis(page);
|
||||
await page.goto('/settings');
|
||||
await page.goto('/profile/preferences');
|
||||
|
||||
await expect(page.getByTestId('reader-mode-radio-single')).toBeAttached();
|
||||
await expect(page.getByTestId('reader-mode-radio-continuous')).toBeAttached();
|
||||
|
||||
Reference in New Issue
Block a user