cc-dashboard/web/src/views/AdminView.vue
Vadym Samoilenko 0ac7d71e9b refactor(admin): ConfirmDialog for destructive actions, spacing
Apply space-y-8 rhythm to admin page sections (no destructive actions currently present in this view — no confirm dialog needed yet).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 11:18:59 +01:00

80 lines
2.8 KiB
Vue

<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { useRouter } from 'vue-router'
import { useAuthStore } from '@/stores/auth'
import { adminApi } from '@/api/endpoints/admin'
import Card from '@/components/ui/Card.vue'
import CardContent from '@/components/ui/CardContent.vue'
import Badge from '@/components/ui/Badge.vue'
import Spinner from '@/components/ui/Spinner.vue'
import { formatDate } from '@/lib/utils'
import type { UserOut } from '@/types'
const authStore = useAuthStore()
const router = useRouter()
const users = ref<UserOut[]>([])
const loading = ref(false)
onMounted(async () => {
if (!authStore.isAdmin) {
router.push('/')
return
}
loading.value = true
try {
const res = await adminApi.users()
users.value = res.data
} finally {
loading.value = false
}
})
</script>
<template>
<div class="p-6 space-y-8">
<h2 class="text-lg font-semibold text-foreground">Admin Users</h2>
<div v-if="loading" class="flex items-center justify-center h-20">
<Spinner class="text-primary" />
</div>
<Card v-else>
<CardContent class="p-0">
<table class="w-full">
<thead>
<tr class="border-b border-border">
<th class="text-left text-xs font-medium text-muted-foreground px-4 py-3">User</th>
<th class="text-left text-xs font-medium text-muted-foreground px-4 py-3">Email</th>
<th class="text-left text-xs font-medium text-muted-foreground px-4 py-3">Role</th>
<th class="text-left text-xs font-medium text-muted-foreground px-4 py-3">Status</th>
<th class="text-left text-xs font-medium text-muted-foreground px-4 py-3">Joined</th>
</tr>
</thead>
<tbody>
<tr
v-for="user in users"
:key="user.id"
class="border-b border-border last:border-0 hover:bg-muted/30"
>
<td class="px-4 py-3">
<p class="text-sm font-medium text-foreground">{{ user.username }}</p>
</td>
<td class="px-4 py-3 text-sm text-muted-foreground">{{ user.email }}</td>
<td class="px-4 py-3">
<Badge :variant="user.role === 'admin' ? 'default' : 'secondary'" class="text-xs">
{{ user.role }}
</Badge>
</td>
<td class="px-4 py-3">
<Badge :variant="user.is_active ? 'success' : 'outline'" class="text-xs">
{{ user.is_active ? 'Active' : 'Inactive' }}
</Badge>
</td>
<td class="px-4 py-3 text-xs text-muted-foreground">{{ formatDate(user.created_at) }}</td>
</tr>
</tbody>
</table>
</CardContent>
</Card>
</div>
</template>