Files
admin/src/layouts/AdminLayout.vue
T

111 lines
3.6 KiB
Vue
Raw Normal View History

2026-06-30 00:50:13 +03:30
<template>
<div class="flex min-h-screen bg-slate-50">
<!-- Sidebar -->
<aside class="fixed inset-y-0 right-0 z-30 flex w-64 flex-col border-l border-slate-200 bg-white shadow-sm">
<div class="flex items-center gap-3 border-b border-slate-100 px-5 py-5">
<div class="flex h-10 w-10 items-center justify-center rounded-xl bg-brand text-lg font-bold text-white">
ن
</div>
<div>
<p class="text-sm font-bold text-slate-900">استودیو نورو</p>
<p class="text-xs text-slate-500">پنل مدیریت CMS</p>
</div>
</div>
<nav class="flex-1 space-y-1 overflow-y-auto p-3">
<RouterLink
v-for="item in navItems"
:key="item.name"
:to="{ name: item.name }"
class="flex items-center gap-3 rounded-lg px-3 py-2.5 text-sm font-medium transition-colors"
:class="isActive(item.name)
? 'bg-brand/10 text-brand-700'
: 'text-slate-600 hover:bg-slate-50 hover:text-slate-900'"
>
<span class="text-lg" aria-hidden="true">{{ item.icon }}</span>
{{ item.label }}
</RouterLink>
</nav>
<div class="border-t border-slate-100 p-4">
<p class="truncate text-xs text-slate-500">{{ userEmail }}</p>
<button
type="button"
class="mt-2 w-full rounded-lg px-3 py-2 text-right text-sm text-red-600 transition-colors hover:bg-red-50"
@click="logout"
>
خروج از حساب
</button>
</div>
</aside>
<!-- Main -->
<div class="mr-64 flex min-h-screen flex-1 flex-col">
<header class="sticky top-0 z-20 border-b border-slate-200 bg-white/90 px-8 py-4 backdrop-blur">
<h1 class="text-lg font-semibold text-slate-800">{{ pageTitle }}</h1>
</header>
<main class="flex-1 p-8">
<RouterView />
</main>
</div>
</div>
</template>
<script setup lang="ts">
import { computed, onMounted, ref } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { api, clearToken } from '@/api/client'
const route = useRoute()
const router = useRouter()
const userEmail = ref('')
const navItems = [
{ name: 'dashboard', label: 'داشبورد', icon: '📊' },
{ name: 'site', label: 'تنظیمات سایت', icon: '⚙️' },
{ name: 'portfolio', label: 'نمونه‌کارها', icon: '🎨' },
{ name: 'services', label: 'خدمات', icon: '💼' },
{ name: 'clients', label: 'مشتریان', icon: '🤝' },
{ name: 'blog', label: 'وبلاگ', icon: '📝' },
{ name: 'media', label: 'رسانه', icon: '🖼️' },
]
const titles: Record<string, string> = {
dashboard: 'داشبورد',
site: 'تنظیمات سایت',
portfolio: 'نمونه‌کارها',
'portfolio-edit': 'ویرایش نمونه‌کار',
services: 'خدمات',
'service-edit': 'ویرایش خدمت',
clients: 'مشتریان',
blog: 'وبلاگ',
'blog-edit': 'ویرایش مطلب',
media: 'کتابخانه رسانه',
}
const pageTitle = computed(() => titles[String(route.name)] || 'پنل مدیریت')
function isActive(name: string) {
if (route.name === name) return true
if (name === 'portfolio' && route.name === 'portfolio-edit') return true
if (name === 'services' && route.name === 'service-edit') return true
if (name === 'blog' && route.name === 'blog-edit') return true
return false
}
function logout() {
clearToken()
router.push({ name: 'login' })
}
onMounted(async () => {
try {
const { user } = await api.me()
userEmail.value = user.email
} catch {
clearToken()
router.push({ name: 'login' })
}
})
</script>