feat: stabilize admin dashboard, refactor group management, implement PWA, and fix routing

This commit is contained in:
2026-05-03 19:51:18 +05:00
parent 622ca04170
commit 0598e07823
36 changed files with 1387 additions and 467 deletions
+81
View File
@@ -0,0 +1,81 @@
<template>
<div class="min-h-screen bg-slate-950 p-6">
<div class="max-w-4xl mx-auto" v-if="group">
<div class="flex items-center gap-4 mb-8 text-sm">
<NuxtLink to="/admin/groups" class="text-slate-500 hover:text-white transition">Группы</NuxtLink>
<span class="text-slate-700">/</span>
<span class="text-slate-300">{{ group.name }}</span>
</div>
<div class="bg-slate-900 border border-slate-800 rounded-3xl p-8 mb-8">
<div class="flex items-center justify-between mb-6">
<h1 class="text-3xl font-bold text-white">{{ group.name }}</h1>
<button @click="deleteGroup" class="px-4 py-2 bg-red-900/20 text-red-400 hover:bg-red-900/40 rounded-lg text-sm transition">Удалить группу</button>
</div>
<p class="text-slate-400">{{ group.description || 'Нет описания' }}</p>
</div>
<!-- Members Section -->
<div class="bg-slate-900 border border-slate-800 rounded-3xl overflow-hidden">
<div class="p-6 border-b border-slate-800 flex items-center justify-between">
<h2 class="text-xl font-bold text-white">Участники ({{ members.length }})</h2>
<button @click="showAddMemberModal = true" class="px-4 py-2 bg-blue-600 hover:bg-blue-500 text-white rounded-lg text-sm font-bold transition">+ Добавить</button>
</div>
<div class="divide-y divide-slate-800">
<div v-for="m in members" :key="m.id" class="p-4 flex items-center justify-between hover:bg-slate-800/30 transition">
<div class="flex items-center gap-3">
<div class="w-10 h-10 bg-slate-800 rounded-full flex items-center justify-center font-bold text-slate-400">
{{ m.user.username.charAt(0).toUpperCase() }}
</div>
<div>
<div class="text-slate-200 font-medium">{{ m.user.username }}</div>
<div class="text-xs text-slate-500">{{ m.role }}</div>
</div>
</div>
<button v-if="m.role !== 'admin'" @click="removeMember(m.userId)" class="text-slate-600 hover:text-red-400 transition text-xl">&times;</button>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
definePageMeta({
middleware: ['auth', 'admin']
})
const route = useRoute()
const auth = useAuth()
const group = ref(null)
const members = ref([])
const showAddMemberModal = ref(false)
const fetchGroup = async () => {
try {
const data = await $fetch(`/api/groups/${route.params.id}`, {
headers: { Authorization: `Bearer ${auth.token.value}` }
})
group.value = data.group
members.value = data.members || []
} catch (e) {
console.error('Failed to fetch group', e)
navigateTo('/admin/groups')
}
}
const deleteGroup = async () => {
if (!confirm('Вы уверены, что хотите удалить эту группу?')) return
try {
await $fetch(`/api/groups/${route.params.id}`, {
method: 'DELETE',
headers: { Authorization: `Bearer ${auth.token.value}` }
})
navigateTo('/admin/groups')
} catch (e) {
alert('Ошибка при удалении')
}
}
onMounted(fetchGroup)
</script>