277 lines
6.3 KiB
Vue
277 lines
6.3 KiB
Vue
<template>
|
|
<aside
|
|
:class="[
|
|
'fixed left-0 top-0 h-full z-40 transition-all duration-300 glass-sidebar',
|
|
isCollapsed ? 'w-20' : 'w-72',
|
|
isMobile && !isOpen ? '-translate-x-full' : 'translate-x-0'
|
|
]"
|
|
>
|
|
<!-- Logo Section -->
|
|
<div class="flex items-center justify-between p-6 border-b border-white/20">
|
|
<div class="flex items-center gap-3">
|
|
<img
|
|
src="/MONACOUSA-Flags_376x376.png"
|
|
alt="MonacoUSA"
|
|
class="w-10 h-10 rounded-xl shadow-soft"
|
|
>
|
|
<transition name="fade">
|
|
<div v-if="!isCollapsed" class="flex flex-col">
|
|
<span class="text-lg font-bold text-gradient-monaco">MonacoUSA</span>
|
|
<span class="text-xs text-gray-500">Board Portal</span>
|
|
</div>
|
|
</transition>
|
|
</div>
|
|
|
|
<!-- Collapse Button (Desktop) -->
|
|
<button
|
|
v-if="!isMobile"
|
|
@click="toggleCollapse"
|
|
class="p-2 rounded-lg hover:bg-glass-monaco-soft transition-colors"
|
|
>
|
|
<ChevronLeft v-if="!isCollapsed" class="w-5 h-5 text-gray-600" />
|
|
<ChevronRight v-else class="w-5 h-5 text-gray-600" />
|
|
</button>
|
|
</div>
|
|
|
|
<!-- Navigation Section -->
|
|
<nav class="px-4 py-6 space-y-2 overflow-y-auto scrollbar-thin h-[calc(100%-200px)]">
|
|
<!-- Main Navigation -->
|
|
<div class="space-y-1">
|
|
<SidebarLink
|
|
v-for="item in mainNavItems"
|
|
:key="item.path"
|
|
:to="item.path"
|
|
:icon="item.icon"
|
|
:label="item.label"
|
|
:badge="item.badge"
|
|
:collapsed="isCollapsed"
|
|
/>
|
|
</div>
|
|
|
|
<!-- Divider -->
|
|
<div class="my-4 border-t border-white/20"></div>
|
|
|
|
<!-- Secondary Navigation -->
|
|
<div class="space-y-1">
|
|
<div v-if="!isCollapsed" class="px-3 py-2">
|
|
<span class="text-xs font-semibold text-gray-500 uppercase tracking-wider">
|
|
Management
|
|
</span>
|
|
</div>
|
|
<SidebarLink
|
|
v-for="item in managementItems"
|
|
:key="item.path"
|
|
:to="item.path"
|
|
:icon="item.icon"
|
|
:label="item.label"
|
|
:badge="item.badge"
|
|
:collapsed="isCollapsed"
|
|
/>
|
|
</div>
|
|
|
|
<!-- Settings Section -->
|
|
<div class="mt-6 pt-6 border-t border-white/20 space-y-1">
|
|
<SidebarLink
|
|
v-for="item in settingsItems"
|
|
:key="item.path"
|
|
:to="item.path"
|
|
:icon="item.icon"
|
|
:label="item.label"
|
|
:collapsed="isCollapsed"
|
|
/>
|
|
</div>
|
|
</nav>
|
|
|
|
<!-- User Profile Section -->
|
|
<div class="absolute bottom-0 left-0 right-0 p-4 border-t border-white/20 bg-glass-light">
|
|
<div class="flex items-center gap-3">
|
|
<div class="relative">
|
|
<img
|
|
:src="userAvatar"
|
|
alt="Profile"
|
|
class="w-10 h-10 rounded-full ring-2 ring-white/60"
|
|
>
|
|
<div class="absolute bottom-0 right-0 w-3 h-3 bg-green-500 rounded-full ring-2 ring-white"></div>
|
|
</div>
|
|
<transition name="fade">
|
|
<div v-if="!isCollapsed" class="flex-1">
|
|
<p class="text-sm font-semibold text-gray-800">{{ userName }}</p>
|
|
<p class="text-xs text-gray-500">{{ userRole }}</p>
|
|
</div>
|
|
</transition>
|
|
<transition name="fade">
|
|
<button
|
|
v-if="!isCollapsed"
|
|
@click="$emit('logout')"
|
|
class="p-2 rounded-lg hover:bg-glass-monaco-soft transition-colors"
|
|
>
|
|
<LogOut class="w-4 h-4 text-gray-600" />
|
|
</button>
|
|
</transition>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Mobile Close Overlay -->
|
|
<div
|
|
v-if="isMobile && isOpen"
|
|
@click="$emit('close')"
|
|
class="fixed inset-0 bg-black/20 backdrop-blur-sm -z-10"
|
|
></div>
|
|
</aside>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ref, computed } from 'vue'
|
|
import { useRoute } from 'vue-router'
|
|
import {
|
|
LayoutDashboard,
|
|
Users,
|
|
Calendar,
|
|
DollarSign,
|
|
FileText,
|
|
Mail,
|
|
BarChart3,
|
|
Settings,
|
|
HelpCircle,
|
|
LogOut,
|
|
ChevronLeft,
|
|
ChevronRight,
|
|
Bell,
|
|
Shield,
|
|
Globe,
|
|
Briefcase
|
|
} from 'lucide-vue-next'
|
|
|
|
// Component for individual sidebar links
|
|
import SidebarLink from './SidebarLink.vue'
|
|
|
|
const props = defineProps({
|
|
isOpen: {
|
|
type: Boolean,
|
|
default: true
|
|
},
|
|
isMobile: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
userName: {
|
|
type: String,
|
|
default: 'Board Member'
|
|
},
|
|
userRole: {
|
|
type: String,
|
|
default: 'Administrator'
|
|
},
|
|
userAvatar: {
|
|
type: String,
|
|
default: '/default-avatar.png'
|
|
}
|
|
})
|
|
|
|
const emit = defineEmits(['close', 'logout'])
|
|
|
|
const isCollapsed = ref(false)
|
|
const route = useRoute()
|
|
|
|
const toggleCollapse = () => {
|
|
isCollapsed.value = !isCollapsed.value
|
|
}
|
|
|
|
// Navigation items with Lucide icons
|
|
const mainNavItems = [
|
|
{
|
|
path: '/board/dashboard',
|
|
icon: LayoutDashboard,
|
|
label: 'Dashboard',
|
|
badge: null
|
|
},
|
|
{
|
|
path: '/board/members',
|
|
icon: Users,
|
|
label: 'Members',
|
|
badge: '1,234'
|
|
},
|
|
{
|
|
path: '/board/events',
|
|
icon: Calendar,
|
|
label: 'Events',
|
|
badge: '3'
|
|
},
|
|
{
|
|
path: '/board/dues',
|
|
icon: DollarSign,
|
|
label: 'Dues & Payments',
|
|
badge: '12'
|
|
}
|
|
]
|
|
|
|
const managementItems = [
|
|
{
|
|
path: '/board/documents',
|
|
icon: FileText,
|
|
label: 'Documents',
|
|
badge: null
|
|
},
|
|
{
|
|
path: '/board/communications',
|
|
icon: Mail,
|
|
label: 'Communications',
|
|
badge: '5'
|
|
},
|
|
{
|
|
path: '/board/reports',
|
|
icon: BarChart3,
|
|
label: 'Reports',
|
|
badge: null
|
|
},
|
|
{
|
|
path: '/board/governance',
|
|
icon: Shield,
|
|
label: 'Governance',
|
|
badge: null
|
|
}
|
|
]
|
|
|
|
const settingsItems = [
|
|
{
|
|
path: '/board/settings',
|
|
icon: Settings,
|
|
label: 'Settings',
|
|
badge: null
|
|
},
|
|
{
|
|
path: '/board/help',
|
|
icon: HelpCircle,
|
|
label: 'Help & Support',
|
|
badge: null
|
|
}
|
|
]
|
|
</script>
|
|
|
|
<style scoped>
|
|
/* Fade transition for collapsing elements */
|
|
.fade-enter-active,
|
|
.fade-leave-active {
|
|
transition: opacity 0.2s ease;
|
|
}
|
|
|
|
.fade-enter-from,
|
|
.fade-leave-to {
|
|
opacity: 0;
|
|
}
|
|
|
|
/* Custom scrollbar for navigation */
|
|
.scrollbar-thin::-webkit-scrollbar {
|
|
width: 6px;
|
|
}
|
|
|
|
.scrollbar-thin::-webkit-scrollbar-track {
|
|
background: rgba(0, 0, 0, 0.05);
|
|
border-radius: 9999px;
|
|
}
|
|
|
|
.scrollbar-thin::-webkit-scrollbar-thumb {
|
|
background: linear-gradient(135deg, #dc2626 0%, #b91c1c 100%);
|
|
border-radius: 9999px;
|
|
}
|
|
</style> |