feat(artist): tab split (Overview/Settings) so DangerZone is reachable without exhausting the infinite-scroll image grid — Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

This commit is contained in:
2026-05-25 22:32:07 -04:00
parent 52d7905c43
commit 770bcf3aa6
+35 -2
View File
@@ -45,6 +45,25 @@
>Credential health · FC-3b</v-chip> >Credential health · FC-3b</v-chip>
</div> </div>
<!-- Tabs split (2026-05-25): Settings was previously slotted at the
bottom of the page after the infinite-scroll image grid, which
made it effectively unreachable for any artist with more than
a couple of pages of content. The Settings tab now hosts
destructive admin actions (artist+content cascade-delete) and
any future per-artist management UI. v-tabs is `position:
sticky; top: 64px` (under the 64px AppShell TopNav) so it
stays parked while the gallery scrolls. -->
<v-tabs
v-model="tab" color="accent" class="mb-4"
style="position: sticky; top: 64px; z-index: 4;
background: rgb(var(--v-theme-surface));"
>
<v-tab value="overview">Overview</v-tab>
<v-tab value="settings">Settings</v-tab>
</v-tabs>
<v-window v-model="tab">
<v-window-item value="overview">
<section v-if="store.overview.cooccurring_tags.length" class="fc-artist__sec"> <section v-if="store.overview.cooccurring_tags.length" class="fc-artist__sec">
<h2 class="fc-h2">Frequent tags</h2> <h2 class="fc-h2">Frequent tags</h2>
<div class="fc-artist__tags"> <div class="fc-artist__tags">
@@ -96,18 +115,22 @@
@open="openImage" @open="openImage"
/> />
</section> </section>
</v-window-item>
<v-window-item value="settings">
<ArtistDangerZone <ArtistDangerZone
:slug="slug" :slug="slug"
:artist-id="store.overview.id" :artist-id="store.overview.id"
:artist-name="store.overview.name" :artist-name="store.overview.name"
/> />
</v-window-item>
</v-window>
</template> </template>
</v-container> </v-container>
</template> </template>
<script setup> <script setup>
import { computed, watch } from 'vue' import { computed, ref, watch } from 'vue'
import { useRoute, useRouter, RouterLink } from 'vue-router' import { useRoute, useRouter, RouterLink } from 'vue-router'
import { useArtistStore } from '../stores/artist.js' import { useArtistStore } from '../stores/artist.js'
import { useModalStore } from '../stores/modal.js' import { useModalStore } from '../stores/modal.js'
@@ -120,8 +143,18 @@ const store = useArtistStore()
const modal = useModalStore() const modal = useModalStore()
const slug = computed(() => route.params.slug) const slug = computed(() => route.params.slug)
// Per-artist tab — defaults to Overview. Settings tab hosts destructive
// admin actions (DangerZone). Switching artists resets to Overview so the
// destructive surface isn't re-shown by accident when navigating between
// artists.
const tab = ref('overview')
watch(slug, (s) => { if (s) store.load(s) }, { immediate: true }) watch(slug, (s) => {
if (s) {
store.load(s)
tab.value = 'overview'
}
}, { immediate: true })
const dateRange = computed(() => { const dateRange = computed(() => {
const r = store.overview?.date_range const r = store.overview?.date_range