Iterate admin pages with smarter workflows

This commit is contained in:
AzuTear
2026-06-18 01:00:58 +02:00
parent 0fa763667d
commit a2d6a5edc0
10 changed files with 422 additions and 36 deletions
@@ -28,6 +28,29 @@ const metricCards = computed(() => [
{ label: 'Kandidaten', value: seasonDetail.value.candidates.length, note: 'in allen Kategorien', icon: Users },
{ label: 'Reviews offen', value: seasonDetail.value.pendingNominations.length, note: 'Backlog', icon: Clock3 },
])
const insights = computed(() => {
const categoriesWithoutCandidates = categoryHealth.value.filter((category) => category.candidates === 0).length
const busiestReviewCategory = [...categoryHealth.value].sort((a, b) => b.reviews - a.reviews)[0]
const votesPerCandidate = seasonDetail.value.candidates.length === 0 ? 0 : Math.round(totalVotes.value / seasonDetail.value.candidates.length)
return [
{
label: 'Votes pro Kandidat',
value: votesPerCandidate,
note: 'Hilft einzuschaetzen, ob die Kandidatenbasis breit genug ist.',
},
{
label: 'Leere Kategorien',
value: categoriesWithoutCandidates,
note: categoriesWithoutCandidates === 0 ? 'Alle Kategorien sind besetzt.' : 'Diese Kategorien brauchen Kandidatenpflege.',
},
{
label: 'Review-Hotspot',
value: busiestReviewCategory?.reviews ?? 0,
note: busiestReviewCategory ? busiestReviewCategory.name : 'Keine Review-Daten vorhanden.',
},
]
})
</script>
<template>
@@ -96,5 +119,13 @@ const metricCards = computed(() => [
</div>
</Card>
</section>
<section class="grid gap-4 lg:grid-cols-3">
<Card v-for="insight in insights" :key="insight.label" class="p-5">
<p class="text-xs font-semibold uppercase tracking-[0.2em] text-violet-500">{{ insight.label }}</p>
<strong class="mt-3 block text-3xl text-violet-900">{{ insight.value.toLocaleString('de-DE') }}</strong>
<p class="mt-2 text-sm leading-6 text-slate-500">{{ insight.note }}</p>
</Card>
</section>
</div>
</template>