feat(nav): consolidate Posts/Artists/Tags into a Browse hub
CI / lint (push) Successful in 2s
CI / frontend-build (push) Successful in 24s
CI / backend-lint-and-test (push) Successful in 37s
CI / integration (push) Successful in 3m13s

Posts, Artists, and Tags are the three 'browse the library by an axis'
surfaces; Subscriptions stays purely management (operator-asked 2026-06-09).
New BrowseView renders them as tabs (?tab=posts|artists|tags); only the active
tab mounts. The old standalone paths become redirects into the matching tab,
preserving deep-link query (/posts?post_id=N → /browse?tab=posts&post_id=N) and
keeping the route names so existing { name: 'posts'|'artists'|'tags' } links and
path pushes still resolve. Nav now reads Showcase · Gallery · Browse · Series ·
Subscriptions, with Settings pinned right.

Test: /browse resolves; /tags and /artists redirect into their tabs; a posts
deep link survives the redirect.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-09 21:18:02 -04:00
parent a50902071a
commit d5d23a92f2
3 changed files with 86 additions and 16 deletions
+47
View File
@@ -0,0 +1,47 @@
<template>
<div class="fc-browse">
<v-container fluid class="pt-2 pb-0">
<v-tabs v-model="tab" density="compact">
<v-tab value="posts">Posts</v-tab>
<v-tab value="artists">Artists</v-tab>
<v-tab value="tags">Tags</v-tab>
</v-tabs>
</v-container>
<!-- Each tab's view is self-contained (its own container + state). Only the
active one is mounted; switching tabs swaps it. The Posts tab still
reads its deep-link (post_id/artist_id/platform) from route.query, so
/browse?tab=posts&post_id=N works exactly like the old /posts deep link.
(FC nav consolidation, operator-asked 2026-06-09: Posts/Artists/Tags are
the three "browse the library by an axis" surfaces.) -->
<component :is="activeComponent" :key="tab" />
</div>
</template>
<script setup>
import { computed } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import ArtistsView from './ArtistsView.vue'
import PostsView from './PostsView.vue'
import TagsView from './TagsView.vue'
const TABS = { posts: PostsView, artists: ArtistsView, tags: TagsView }
const route = useRoute()
const router = useRouter()
const tab = computed({
get() {
const t = route.query.tab
return typeof t === 'string' && t in TABS ? t : 'posts'
},
set(value) {
// Switching tabs starts a clean tab — a posts deep link (post_id, etc.)
// belongs only to the Posts tab and shouldn't bleed into Artists/Tags.
router.replace({ name: 'browse', query: { tab: value } })
},
})
const activeComponent = computed(() => TABS[tab.value])
</script>