refactor: move KPI cards into Algemeen tab, Danger Zone into own tab
Platform org detail: - KPI cards (events, users, persons) moved inside Algemeen tab - Danger Zone moved from below tabs into a dedicated "Danger Zone" tab with red-colored tab icon - Tab bar now shows: Algemeen | Leden | Danger Zone Platform user detail: - Added VTabs with Algemeen (profile info) and Organisaties tabs - Timestamps moved below title as muted caption - Content reorganised into tab structure matching org detail pattern Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -52,6 +52,7 @@ const roleOptions = [
|
||||
const tabs = [
|
||||
{ value: 'algemeen', label: 'Algemeen', icon: 'tabler-building' },
|
||||
{ value: 'leden', label: 'Leden', icon: 'tabler-users-group' },
|
||||
{ value: 'danger', label: 'Danger Zone', icon: 'tabler-alert-triangle' },
|
||||
]
|
||||
|
||||
const activeTab = computed({
|
||||
@@ -277,104 +278,17 @@ function formatDate(iso: string): string {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- KPI Cards -->
|
||||
<VRow class="mb-6 mt-4">
|
||||
<VCol
|
||||
cols="12"
|
||||
md="4"
|
||||
>
|
||||
<VCard>
|
||||
<VCardText class="d-flex align-center gap-x-4">
|
||||
<VAvatar
|
||||
color="primary"
|
||||
variant="tonal"
|
||||
size="44"
|
||||
rounded
|
||||
>
|
||||
<VIcon
|
||||
icon="tabler-calendar-event"
|
||||
size="28"
|
||||
/>
|
||||
</VAvatar>
|
||||
<div>
|
||||
<p class="text-body-1 mb-0">
|
||||
Events
|
||||
</p>
|
||||
<h4 class="text-h4">
|
||||
{{ org.events_count }}
|
||||
</h4>
|
||||
</div>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</VCol>
|
||||
<VCol
|
||||
cols="12"
|
||||
md="4"
|
||||
>
|
||||
<VCard>
|
||||
<VCardText class="d-flex align-center gap-x-4">
|
||||
<VAvatar
|
||||
color="success"
|
||||
variant="tonal"
|
||||
size="44"
|
||||
rounded
|
||||
>
|
||||
<VIcon
|
||||
icon="tabler-users-group"
|
||||
size="28"
|
||||
/>
|
||||
</VAvatar>
|
||||
<div>
|
||||
<p class="text-body-1 mb-0">
|
||||
Gebruikers
|
||||
</p>
|
||||
<h4 class="text-h4">
|
||||
{{ org.users_count }}
|
||||
</h4>
|
||||
</div>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</VCol>
|
||||
<VCol
|
||||
cols="12"
|
||||
md="4"
|
||||
>
|
||||
<VCard>
|
||||
<VCardText class="d-flex align-center gap-x-4">
|
||||
<VAvatar
|
||||
color="info"
|
||||
variant="tonal"
|
||||
size="44"
|
||||
rounded
|
||||
>
|
||||
<VIcon
|
||||
icon="tabler-user"
|
||||
size="28"
|
||||
/>
|
||||
</VAvatar>
|
||||
<div>
|
||||
<p class="text-body-1 mb-0">
|
||||
Totaal personen
|
||||
</p>
|
||||
<h4 class="text-h4">
|
||||
{{ org.total_persons }}
|
||||
</h4>
|
||||
</div>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</VCol>
|
||||
</VRow>
|
||||
|
||||
<!-- Tabs -->
|
||||
<VTabs
|
||||
v-model="activeTab"
|
||||
class="mb-6"
|
||||
class="mb-6 mt-4"
|
||||
>
|
||||
<VTab
|
||||
v-for="tab in tabs"
|
||||
:key="tab.value"
|
||||
:value="tab.value"
|
||||
:prepend-icon="tab.icon"
|
||||
:color="tab.value === 'danger' ? 'error' : undefined"
|
||||
>
|
||||
{{ tab.label }}
|
||||
</VTab>
|
||||
@@ -386,6 +300,95 @@ function formatDate(iso: string): string {
|
||||
>
|
||||
<!-- Algemeen tab -->
|
||||
<VWindowItem value="algemeen">
|
||||
<!-- KPI Cards -->
|
||||
<VRow class="mb-6">
|
||||
<VCol
|
||||
cols="12"
|
||||
md="4"
|
||||
>
|
||||
<VCard>
|
||||
<VCardText class="d-flex align-center gap-x-4">
|
||||
<VAvatar
|
||||
color="primary"
|
||||
variant="tonal"
|
||||
size="44"
|
||||
rounded
|
||||
>
|
||||
<VIcon
|
||||
icon="tabler-calendar-event"
|
||||
size="28"
|
||||
/>
|
||||
</VAvatar>
|
||||
<div>
|
||||
<p class="text-body-1 mb-0">
|
||||
Events
|
||||
</p>
|
||||
<h4 class="text-h4">
|
||||
{{ org.events_count }}
|
||||
</h4>
|
||||
</div>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</VCol>
|
||||
<VCol
|
||||
cols="12"
|
||||
md="4"
|
||||
>
|
||||
<VCard>
|
||||
<VCardText class="d-flex align-center gap-x-4">
|
||||
<VAvatar
|
||||
color="success"
|
||||
variant="tonal"
|
||||
size="44"
|
||||
rounded
|
||||
>
|
||||
<VIcon
|
||||
icon="tabler-users-group"
|
||||
size="28"
|
||||
/>
|
||||
</VAvatar>
|
||||
<div>
|
||||
<p class="text-body-1 mb-0">
|
||||
Gebruikers
|
||||
</p>
|
||||
<h4 class="text-h4">
|
||||
{{ org.users_count }}
|
||||
</h4>
|
||||
</div>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</VCol>
|
||||
<VCol
|
||||
cols="12"
|
||||
md="4"
|
||||
>
|
||||
<VCard>
|
||||
<VCardText class="d-flex align-center gap-x-4">
|
||||
<VAvatar
|
||||
color="info"
|
||||
variant="tonal"
|
||||
size="44"
|
||||
rounded
|
||||
>
|
||||
<VIcon
|
||||
icon="tabler-user"
|
||||
size="28"
|
||||
/>
|
||||
</VAvatar>
|
||||
<div>
|
||||
<p class="text-body-1 mb-0">
|
||||
Totaal personen
|
||||
</p>
|
||||
<h4 class="text-h4">
|
||||
{{ org.total_persons }}
|
||||
</h4>
|
||||
</div>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</VCol>
|
||||
</VRow>
|
||||
|
||||
<!-- Details -->
|
||||
<VCard>
|
||||
<VCardTitle>Details</VCardTitle>
|
||||
<VCardText>
|
||||
@@ -514,65 +517,65 @@ function formatDate(iso: string): string {
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</VWindowItem>
|
||||
|
||||
<!-- Danger Zone tab -->
|
||||
<VWindowItem value="danger">
|
||||
<VCard
|
||||
variant="outlined"
|
||||
color="error"
|
||||
>
|
||||
<VCardText>
|
||||
<div class="d-flex justify-space-between align-center mb-4">
|
||||
<div>
|
||||
<p class="text-subtitle-1 font-weight-medium mb-1">
|
||||
Verwijder organisatie
|
||||
</p>
|
||||
<p class="text-body-2 text-medium-emphasis mb-0">
|
||||
Alle gegevens van deze organisatie worden permanent verwijderd.
|
||||
Deze actie kan niet ongedaan worden gemaakt.
|
||||
</p>
|
||||
</div>
|
||||
<VBtn
|
||||
color="error"
|
||||
variant="outlined"
|
||||
class="ms-4 flex-shrink-0"
|
||||
@click="openDeleteDialog"
|
||||
>
|
||||
Verwijder
|
||||
</VBtn>
|
||||
</div>
|
||||
|
||||
<VDivider class="mb-4" />
|
||||
|
||||
<div class="d-flex justify-space-between align-center">
|
||||
<div>
|
||||
<p class="text-subtitle-1 font-weight-medium mb-1">
|
||||
Transfer Ownership
|
||||
</p>
|
||||
<p class="text-body-2 text-medium-emphasis mb-0">
|
||||
Draag het eigenaarschap van deze organisatie over aan een andere gebruiker.
|
||||
</p>
|
||||
</div>
|
||||
<VTooltip location="top">
|
||||
<template #activator="{ props }">
|
||||
<span v-bind="props">
|
||||
<VBtn
|
||||
color="error"
|
||||
variant="outlined"
|
||||
class="ms-4 flex-shrink-0"
|
||||
disabled
|
||||
>
|
||||
Transfer
|
||||
</VBtn>
|
||||
</span>
|
||||
</template>
|
||||
Nog niet beschikbaar
|
||||
</VTooltip>
|
||||
</div>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</VWindowItem>
|
||||
</VWindow>
|
||||
|
||||
<!-- Danger Zone -->
|
||||
<VCard
|
||||
variant="outlined"
|
||||
color="error"
|
||||
class="mt-6"
|
||||
>
|
||||
<VCardTitle>Danger Zone</VCardTitle>
|
||||
<VCardText>
|
||||
<div class="d-flex justify-space-between align-center mb-4">
|
||||
<div>
|
||||
<p class="text-subtitle-1 font-weight-medium mb-1">
|
||||
Verwijder organisatie
|
||||
</p>
|
||||
<p class="text-body-2 text-medium-emphasis mb-0">
|
||||
Alle gegevens van deze organisatie worden permanent verwijderd.
|
||||
Deze actie kan niet ongedaan worden gemaakt.
|
||||
</p>
|
||||
</div>
|
||||
<VBtn
|
||||
color="error"
|
||||
variant="outlined"
|
||||
class="ms-4 flex-shrink-0"
|
||||
@click="openDeleteDialog"
|
||||
>
|
||||
Verwijder
|
||||
</VBtn>
|
||||
</div>
|
||||
|
||||
<VDivider class="mb-4" />
|
||||
|
||||
<div class="d-flex justify-space-between align-center">
|
||||
<div>
|
||||
<p class="text-subtitle-1 font-weight-medium mb-1">
|
||||
Transfer Ownership
|
||||
</p>
|
||||
<p class="text-body-2 text-medium-emphasis mb-0">
|
||||
Draag het eigenaarschap van deze organisatie over aan een andere gebruiker.
|
||||
</p>
|
||||
</div>
|
||||
<VTooltip location="top">
|
||||
<template #activator="{ props }">
|
||||
<span v-bind="props">
|
||||
<VBtn
|
||||
color="error"
|
||||
variant="outlined"
|
||||
class="ms-4 flex-shrink-0"
|
||||
disabled
|
||||
>
|
||||
Transfer
|
||||
</VBtn>
|
||||
</span>
|
||||
</template>
|
||||
Nog niet beschikbaar
|
||||
</VTooltip>
|
||||
</div>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</template>
|
||||
|
||||
<!-- Edit Dialog -->
|
||||
|
||||
@@ -14,10 +14,21 @@ definePage({
|
||||
})
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const impersonationStore = useImpersonationStore()
|
||||
|
||||
const userId = computed(() => String((route.params as { id: string }).id))
|
||||
|
||||
const activeTab = computed({
|
||||
get: () => {
|
||||
const tab = route.query.tab as string
|
||||
return ['algemeen', 'organisaties'].includes(tab) ? tab : 'algemeen'
|
||||
},
|
||||
set: (value: string) => {
|
||||
router.replace({ query: { ...route.query, tab: value } })
|
||||
},
|
||||
})
|
||||
|
||||
const { data: user, isLoading, isError, refetch } = useAdminUser(userId)
|
||||
|
||||
const roleColorMap: Record<string, string> = {
|
||||
@@ -123,7 +134,7 @@ function getInitials(name: string): string {
|
||||
|
||||
<template v-else-if="user">
|
||||
<!-- Header -->
|
||||
<div class="d-flex align-center justify-space-between mb-6">
|
||||
<div class="d-flex align-center justify-space-between mb-2">
|
||||
<div class="d-flex align-center gap-x-3">
|
||||
<VBtn
|
||||
icon="tabler-arrow-left"
|
||||
@@ -145,21 +156,23 @@ function getInitials(name: string): string {
|
||||
<span>{{ getInitials(user.full_name) }}</span>
|
||||
</VAvatar>
|
||||
<div>
|
||||
<h4 class="text-h4">
|
||||
{{ user.full_name }}
|
||||
<div class="d-flex align-center gap-x-2">
|
||||
<h4 class="text-h4">
|
||||
{{ user.full_name }}
|
||||
</h4>
|
||||
<VChip
|
||||
v-for="role in user.roles"
|
||||
:key="role"
|
||||
:color="roleColorMap[role] ?? 'default'"
|
||||
size="small"
|
||||
class="ms-1"
|
||||
>
|
||||
{{ role }}
|
||||
</VChip>
|
||||
</h4>
|
||||
<p class="text-body-2 text-disabled mb-0">
|
||||
</div>
|
||||
<span class="text-caption text-medium-emphasis">
|
||||
{{ user.email }}
|
||||
</p>
|
||||
· Aangemaakt op {{ formatDate(user.created_at) }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex gap-x-2">
|
||||
@@ -181,19 +194,36 @@ function getInitials(name: string): string {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- User Info -->
|
||||
<VRow class="mb-6">
|
||||
<VCol
|
||||
cols="12"
|
||||
md="6"
|
||||
<!-- Tabs -->
|
||||
<VTabs
|
||||
v-model="activeTab"
|
||||
class="mb-6 mt-4"
|
||||
>
|
||||
<VTab
|
||||
value="algemeen"
|
||||
prepend-icon="tabler-user"
|
||||
>
|
||||
Algemeen
|
||||
</VTab>
|
||||
<VTab
|
||||
value="organisaties"
|
||||
prepend-icon="tabler-buildings"
|
||||
>
|
||||
Organisaties
|
||||
</VTab>
|
||||
</VTabs>
|
||||
|
||||
<VWindow
|
||||
v-model="activeTab"
|
||||
class="disable-tab-transition"
|
||||
>
|
||||
<!-- Algemeen tab -->
|
||||
<VWindowItem value="algemeen">
|
||||
<VCard>
|
||||
<VCardTitle>Profiel</VCardTitle>
|
||||
<VCardText>
|
||||
<VRow>
|
||||
<VCol
|
||||
cols="6"
|
||||
>
|
||||
<VCol cols="6">
|
||||
<p class="text-body-2 text-disabled mb-1">
|
||||
Tijdzone
|
||||
</p>
|
||||
@@ -201,9 +231,7 @@ function getInitials(name: string): string {
|
||||
{{ user.timezone }}
|
||||
</p>
|
||||
</VCol>
|
||||
<VCol
|
||||
cols="6"
|
||||
>
|
||||
<VCol cols="6">
|
||||
<p class="text-body-2 text-disabled mb-1">
|
||||
Taal
|
||||
</p>
|
||||
@@ -211,9 +239,7 @@ function getInitials(name: string): string {
|
||||
{{ user.locale === 'nl' ? 'Nederlands' : 'English' }}
|
||||
</p>
|
||||
</VCol>
|
||||
<VCol
|
||||
cols="6"
|
||||
>
|
||||
<VCol cols="6">
|
||||
<p class="text-body-2 text-disabled mb-1">
|
||||
E-mail geverifieerd
|
||||
</p>
|
||||
@@ -227,31 +253,17 @@ function getInitials(name: string): string {
|
||||
{{ user.email_verified_at ? formatDate(user.email_verified_at) : 'Niet geverifieerd' }}
|
||||
</p>
|
||||
</VCol>
|
||||
<VCol
|
||||
cols="6"
|
||||
>
|
||||
<p class="text-body-2 text-disabled mb-1">
|
||||
Aangemaakt
|
||||
</p>
|
||||
<p class="text-body-1">
|
||||
{{ formatDate(user.created_at) }}
|
||||
</p>
|
||||
</VCol>
|
||||
</VRow>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</VCol>
|
||||
</VWindowItem>
|
||||
|
||||
<!-- Organisations -->
|
||||
<VCol
|
||||
cols="12"
|
||||
md="6"
|
||||
>
|
||||
<!-- Organisaties tab -->
|
||||
<VWindowItem value="organisaties">
|
||||
<VCard>
|
||||
<VCardTitle>Organisaties</VCardTitle>
|
||||
<VCardText
|
||||
v-if="user.organisations.length === 0"
|
||||
class="text-disabled"
|
||||
class="text-center text-disabled"
|
||||
>
|
||||
Geen organisaties
|
||||
</VCardText>
|
||||
@@ -276,8 +288,8 @@ function getInitials(name: string): string {
|
||||
</VListItem>
|
||||
</VList>
|
||||
</VCard>
|
||||
</VCol>
|
||||
</VRow>
|
||||
</VWindowItem>
|
||||
</VWindow>
|
||||
</template>
|
||||
|
||||
<!-- Edit Dialog -->
|
||||
|
||||
Reference in New Issue
Block a user