From 0d912305cf76fa8212125c548b76319a9dbb2349 Mon Sep 17 00:00:00 2001 From: TR Tajim Date: Sat, 10 Oct 2026 22:58:09 +0600 Subject: [PATCH 1/2] feat(admin): replace custom admin nav with global rail and add dashboard tool hub --- resources/js/layouts/AdminLayout.vue | 167 ++----- resources/js/pages/admin/Dashboard.vue | 655 +++++++++++++++---------- 2 files changed, 448 insertions(+), 374 deletions(-) diff --git a/resources/js/layouts/AdminLayout.vue b/resources/js/layouts/AdminLayout.vue index 8bae17dd..dec789fd 100644 --- a/resources/js/layouts/AdminLayout.vue +++ b/resources/js/layouts/AdminLayout.vue @@ -1,166 +1,90 @@ diff --git a/resources/js/pages/admin/Dashboard.vue b/resources/js/pages/admin/Dashboard.vue index 760c97cc..f4016d33 100644 --- a/resources/js/pages/admin/Dashboard.vue +++ b/resources/js/pages/admin/Dashboard.vue @@ -2,18 +2,30 @@ import { Head, Link } from '@inertiajs/vue3'; import { LayoutGrid, - Sparkles, Users, Eye, Share2, - BookOpen, - ArrowRight, Zap, RefreshCw, BarChart3, + CheckSquare, + BookOpen, + MessageSquare, + LifeBuoy, + Bell, + MessageCircle, + UserCheck, + Radio, + Mail, + FileText, + Boxes, + ArrowUpRight, } from 'lucide-vue-next'; -import { ref } from 'vue'; +import { computed, ref } from 'vue'; import EmptyState from '@/components/EmptyState.vue'; +import { usePermissions } from '@/lib/usePermissions'; + +const { can } = usePermissions(); const props = defineProps<{ totalAccounts?: number; @@ -24,6 +36,100 @@ const isLoading = ref(false); const hasFetched = ref(false); const errorMsg = ref(null); +const adminTools = [ + { + name: 'Resource Moderation', + description: 'Review and approve community submitted study materials', + href: '/admin/moderation/resources', + icon: CheckSquare, + color: 'text-emerald-600 bg-emerald-50 dark:bg-emerald-500/10 dark:text-emerald-400', + permission: 'moderate resources', + }, + { + name: 'Manage Contents', + description: 'Syllabus, subjects, chapters and learning resources', + href: '/admin/subjects', + icon: BookOpen, + color: 'text-indigo-600 bg-indigo-50 dark:bg-indigo-500/10 dark:text-indigo-400', + }, + { + name: 'Manage Forum', + description: 'Categories, pinned questions, and moderation', + href: '/admin/forums', + icon: MessageSquare, + color: 'text-blue-600 bg-blue-50 dark:bg-blue-500/10 dark:text-blue-400', + permission: 'manage forums', + }, + { + name: 'Support Tickets', + description: 'View and respond to student help tickets', + href: '/admin/tickets', + icon: LifeBuoy, + color: 'text-amber-600 bg-amber-50 dark:bg-amber-500/10 dark:text-amber-400', + permission: 'manage tickets', + }, + { + name: 'Site Notice', + description: 'Broadcast system banner and maintenance alerts', + href: '/admin/notice', + icon: Bell, + color: 'text-purple-600 bg-purple-50 dark:bg-purple-500/10 dark:text-purple-400', + permission: 'edit notice', + }, + { + name: 'Global Chat', + description: 'Live chat room moderation and flagged messages', + href: '/admin/chat', + icon: MessageCircle, + color: 'text-teal-600 bg-teal-50 dark:bg-teal-500/10 dark:text-teal-400', + permission: 'manage chat', + }, + { + name: 'Users & Roles', + description: 'Directory, verification badges, and permissions', + href: '/admin/users', + icon: UserCheck, + color: 'text-sky-600 bg-sky-50 dark:bg-sky-500/10 dark:text-sky-400', + permission: 'view users', + }, + { + name: 'Peer & Pokes', + description: 'Community interactions and study buddy settings', + href: '/admin/peers/settings', + icon: Radio, + color: 'text-rose-600 bg-rose-50 dark:bg-rose-500/10 dark:text-rose-400', + permission: 'manage peers', + }, + { + name: 'Send Emails', + description: 'Compose announcements and system updates', + href: '/admin/emails/send', + icon: Mail, + color: 'text-orange-600 bg-orange-50 dark:bg-orange-500/10 dark:text-orange-400', + permission: 'send email', + }, + { + name: 'Blogs & Articles', + description: 'Public authoring, editorial drafts, and posts', + href: '/blogs', + icon: FileText, + color: 'text-indigo-600 bg-indigo-50 dark:bg-indigo-500/10 dark:text-indigo-400', + permission: 'manage blogs', + }, + { + name: 'Products & Projects', + description: 'Public showcase platform apps and tools', + href: '/products', + icon: Boxes, + color: 'text-cyan-600 bg-cyan-50 dark:bg-cyan-500/10 dark:text-cyan-400', + permission: 'manage products', + }, +]; + +const visibleTools = computed(() => + adminTools.filter((tool) => !tool.permission || can(tool.permission)), +); + const fetchAnalytics = async (refresh = false) => { isLoading.value = true; errorMsg.value = null; @@ -34,13 +140,13 @@ const fetchAnalytics = async (refresh = false) => { ); if (!res.ok) { - throw new Error('Analytics ডাটা লোড করা যায়নি'); + throw new Error('Analytics could not be loaded'); } stats.value = await res.json(); hasFetched.value = true; } catch (e: any) { - errorMsg.value = e.message || 'Analytics লোড করতে সমস্যা হয়েছে'; + errorMsg.value = e.message || 'Failed to load analytics'; } finally { isLoading.value = false; } @@ -48,78 +154,118 @@ const fetchAnalytics = async (refresh = false) => {