Iterate admin pages with smarter workflows
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
import { BarChart3, CheckCircle2, Tags, Users, Vote } from '@lucide/vue'
|
||||
import { RouterLink } from 'vue-router'
|
||||
|
||||
import AdminPageHeader from '../../components/admin/AdminPageHeader.vue'
|
||||
import AdminSeasonToolbar from '../../components/admin/AdminSeasonToolbar.vue'
|
||||
@@ -22,12 +23,33 @@ const votingReadiness = computed(() =>
|
||||
}),
|
||||
)
|
||||
const readyCount = computed(() => votingReadiness.value.filter((category) => category.ready).length)
|
||||
const notReadyCategories = computed(() => votingReadiness.value.filter((category) => !category.ready))
|
||||
const stats = computed(() => [
|
||||
{ label: 'Stimmen gesamt', value: totalVotes.value, icon: Vote },
|
||||
{ label: 'Voting-ready', value: readyCount.value, icon: CheckCircle2 },
|
||||
{ label: 'Kategorien', value: seasonDetail.value.categories.length, icon: Tags },
|
||||
{ label: 'Kandidaten', value: seasonDetail.value.candidates.length, icon: Users },
|
||||
])
|
||||
const votingChecklist = computed(() => [
|
||||
{
|
||||
label: 'Voting-Phase aktiv',
|
||||
done: seasonDetail.value.currentPhase.toLowerCase().includes('voting'),
|
||||
note: seasonDetail.value.currentPhase || 'Keine Phase gesetzt',
|
||||
to: '/admin/settings',
|
||||
},
|
||||
{
|
||||
label: 'Alle Kategorien haben Kandidaten',
|
||||
done: notReadyCategories.value.every((category) => category.candidateCount > 0) && seasonDetail.value.categories.length > 0,
|
||||
note: `${notReadyCategories.value.filter((category) => category.candidateCount === 0).length} Kategorien ohne Kandidaten`,
|
||||
to: '/admin/categories',
|
||||
},
|
||||
{
|
||||
label: 'Offene Reviews niedrig',
|
||||
done: seasonDetail.value.pendingNominations.length === 0,
|
||||
note: `${seasonDetail.value.pendingNominations.length} offene Reviews`,
|
||||
to: '/admin/reviews',
|
||||
},
|
||||
])
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -102,5 +124,29 @@ const stats = computed(() => [
|
||||
</div>
|
||||
</Card>
|
||||
</section>
|
||||
|
||||
<Card class="p-6">
|
||||
<p class="text-xs font-semibold uppercase tracking-[0.24em] text-violet-500">Voting Checkliste</p>
|
||||
<h2 class="mt-2 font-[Cormorant_Garamond] text-4xl text-violet-800">Vor dem Public Push</h2>
|
||||
<div class="mt-5 grid gap-3 lg:grid-cols-3">
|
||||
<RouterLink
|
||||
v-for="item in votingChecklist"
|
||||
:key="item.label"
|
||||
:to="item.to"
|
||||
class="rounded-[22px] border p-4 transition hover:-translate-y-0.5 hover:bg-violet-50/50"
|
||||
:class="item.done ? 'border-emerald-100 bg-emerald-50/40' : 'border-amber-100 bg-amber-50/50'"
|
||||
>
|
||||
<div class="flex items-start justify-between gap-3">
|
||||
<div>
|
||||
<p class="font-semibold text-slate-900">{{ item.label }}</p>
|
||||
<p class="mt-1 text-sm leading-5 text-slate-500">{{ item.note }}</p>
|
||||
</div>
|
||||
<span class="rounded-full px-3 py-1 text-xs font-semibold" :class="item.done ? 'bg-emerald-100 text-emerald-700' : 'bg-amber-100 text-amber-700'">
|
||||
{{ item.done ? 'ok' : 'pruefen' }}
|
||||
</span>
|
||||
</div>
|
||||
</RouterLink>
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user