Improve admin candidate modal UX and add clip menu visibility toggle

- Widen AdminCandidateEditorModal to size lg for better readability
- Rename "Clip-Compilation" section to "Clip / Compilation", update copy to reflect single clips too, drop upload hint and Clip-Plattform field, rename label to "Link"
- Fix NativeSelect dropdown clipping inside overflow-y-auto modals by teleporting the menu to body with fixed positioning, flip-up logic, and dynamic maxHeight capped to viewport
- Add ClipAdminMenuVisible setting (backend domain, contracts, endpoint, migration) with matching frontend types, defaults, form wiring, and toggle in the Clip-Workflow modal — hides the Clips nav item from the admin sidebar when disabled

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
AzuTear
2026-06-27 18:39:35 +02:00
parent 494eba5edd
commit 18b61bed52
119 changed files with 15638 additions and 367 deletions
@@ -1,5 +1,5 @@
<script setup lang="ts">
import { CheckCircle2, Trash2 } from '@lucide/vue'
import { Ban, CheckCircle2, Loader2, Trash2 } from '@lucide/vue'
import Button from '../ui/Button.vue'
import NativeSelect from '../ui/NativeSelect.vue'
@@ -24,6 +24,7 @@ defineProps<{
} | null
streamUrl?: string
canApproveSelected: boolean
blacklistSaving: boolean
selectedPlatformValue: (platform: string) => string
}>()
@@ -31,6 +32,7 @@ const emit = defineEmits<{
'platform-change': [value: string]
approve: [nominationId: number]
reject: [nominationId: number]
'blacklist-link': [streamUrl: string]
}>()
</script>
@@ -51,14 +53,28 @@ const emit = defineEmits<{
<div v-if="streamUrl" class="mt-5 rounded-2xl border border-sky-100 bg-sky-50/70 p-4">
<p class="text-xs font-semibold uppercase tracking-[0.18em] text-sky-700">Eingereichter Stream-Link</p>
<a
:href="streamUrl"
target="_blank"
rel="noopener"
class="mt-2 inline-flex max-w-full items-center rounded-full border border-sky-200 bg-white px-3 py-1.5 text-sm font-semibold text-sky-800 underline-offset-4 hover:underline"
>
<span class="truncate">{{ streamUrl }}</span>
</a>
<div class="mt-2 flex flex-wrap items-center gap-2">
<a
:href="streamUrl"
target="_blank"
rel="noopener"
class="inline-flex max-w-full items-center rounded-full border border-sky-200 bg-white px-3 py-1.5 text-sm font-semibold text-sky-800 underline-offset-4 hover:underline"
>
<span class="truncate">{{ streamUrl }}</span>
</a>
<Button
type="button"
variant="ghost"
size="sm"
class="gap-2 rounded-full border-rose-200 bg-white px-3 text-rose-700 hover:bg-rose-50 hover:text-rose-800"
:disabled="blacklistSaving"
@click="emit('blacklist-link', streamUrl)"
>
<Loader2 v-if="blacklistSaving" class="h-3.5 w-3.5 animate-spin" />
<Ban v-else class="h-3.5 w-3.5" />
{{ blacklistSaving ? 'Blockiert ...' : 'Zur Blacklist' }}
</Button>
</div>
</div>
<div v-if="signalSummary" class="mt-4 grid gap-3 sm:grid-cols-3">