monacousa-portal/layouts/dashboard.vue

272 lines
6.7 KiB
Vue

<template>
<v-app>
<v-navigation-drawer v-model="drawer" app width="280">
<!-- Logo Section -->
<v-list-item class="pa-4 text-center">
<v-img
src="/MONACOUSA-Flags_376x376.png"
width="80"
height="80"
class="mx-auto mb-2"
/>
<div class="text-h6 font-weight-bold" style="color: #a31515;">
MonacoUSA Portal
</div>
</v-list-item>
<v-divider />
<!-- Navigation Menu -->
<v-list nav>
<!-- Always visible items -->
<v-list-item
to="/dashboard"
prepend-icon="mdi-view-dashboard"
title="Dashboard"
value="dashboard"
/>
<v-list-item
to="/dashboard/events"
prepend-icon="mdi-calendar"
title="Events"
value="events"
/>
<v-list-item
to="/dashboard/user"
prepend-icon="mdi-account"
title="My Profile"
value="profile"
/>
<!-- Board-only items -->
<template v-if="isBoard || isAdmin">
<v-divider class="my-2" />
<v-list-subheader>Board Tools</v-list-subheader>
<v-list-item
to="/dashboard/member-list"
prepend-icon="mdi-account-group"
title="Member List"
value="members"
/>
<v-list-item
to="/dashboard/board"
prepend-icon="mdi-shield-account"
title="Board Dashboard"
value="board-dashboard"
/>
</template>
<!-- Admin-only items -->
<template v-if="isAdmin">
<v-divider class="my-2" />
<v-list-subheader>Administration</v-list-subheader>
<v-list-item
@click="openUserManagement"
prepend-icon="mdi-account-cog"
title="Manage Users"
value="admin-users"
/>
<v-list-item
to="/dashboard/admin"
prepend-icon="mdi-cog"
title="Admin Panel"
value="admin-panel"
/>
</template>
</v-list>
<!-- Footer -->
<template v-slot:append>
<div class="pa-4 text-center">
<v-chip
:color="getTierColor(userTier)"
size="small"
variant="elevated"
>
<v-icon start :icon="getTierIcon(userTier)" />
{{ userTier.toUpperCase() }}
</v-chip>
</div>
</template>
</v-navigation-drawer>
<v-app-bar app color="primary" elevation="2">
<!-- MonacoUSA Logo as Navigation Toggle -->
<v-btn
variant="text"
@click="drawer = !drawer"
class="mr-2"
>
<MonacoUSALogo
size="small"
variant="white"
clickable
/>
</v-btn>
<v-toolbar-title class="text-white font-weight-bold">
MonacoUSA Portal
</v-toolbar-title>
<v-spacer />
<!-- User Menu -->
<v-menu offset-y>
<template v-slot:activator="{ props }">
<v-btn icon v-bind="props" color="white">
<v-avatar size="36" color="white">
<v-icon color="primary">mdi-account</v-icon>
</v-avatar>
</v-btn>
</template>
<v-list min-width="200">
<v-list-item>
<v-list-item-title class="font-weight-bold">
{{ user?.name || 'User' }}
</v-list-item-title>
<v-list-item-subtitle>
{{ user?.email }}
</v-list-item-subtitle>
</v-list-item>
<v-list-item>
<v-list-item-subtitle>
<v-chip
:color="getTierColor(userTier)"
size="x-small"
variant="flat"
>
{{ userTier.toUpperCase() }} TIER
</v-chip>
</v-list-item-subtitle>
</v-list-item>
<v-divider />
<v-list-item @click="navigateToProfile">
<v-list-item-title>
<v-icon start>mdi-account</v-icon>
Profile
</v-list-item-title>
</v-list-item>
<v-list-item @click="navigateToSettings">
<v-list-item-title>
<v-icon start>mdi-cog</v-icon>
Settings
</v-list-item-title>
</v-list-item>
<v-divider />
<v-list-item @click="handleLogout" class="text-error">
<v-list-item-title>
<v-icon start>mdi-logout</v-icon>
Logout
</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
</v-app-bar>
<v-main>
<!-- Dues Payment Banner -->
<DuesPaymentBanner />
<v-container fluid class="pa-0">
<slot />
</v-container>
</v-main>
</v-app>
</template>
<script setup lang="ts">
const { user, userTier, isBoard, isAdmin, logout } = useAuth();
const drawer = ref(true);
// Helper functions
const getTierColor = (tier: string) => {
switch (tier) {
case 'admin': return 'error';
case 'board': return 'primary';
case 'user': return 'info';
default: return 'grey';
}
};
const getTierIcon = (tier: string) => {
switch (tier) {
case 'admin': return 'mdi-shield-crown';
case 'board': return 'mdi-shield-account';
case 'user': return 'mdi-account';
default: return 'mdi-account';
}
};
// Navigation methods
const openUserManagement = () => {
window.open('https://auth.monacousa.org', '_blank');
};
const navigateToProfile = () => {
navigateTo('/dashboard/user');
};
const navigateToSettings = () => {
navigateTo('/dashboard/admin');
};
const handleLogout = async () => {
await logout();
};
// Responsive drawer behavior
const { width } = useDisplay();
watch(width, (newWidth) => {
drawer.value = newWidth >= 1024; // Show drawer on desktop by default
}, { immediate: true });
</script>
<style scoped>
.v-navigation-drawer {
border-right: 1px solid rgba(0, 0, 0, 0.12);
}
.v-list-item {
border-radius: 8px;
margin: 2px 8px;
}
.v-list-item--active {
background-color: rgba(163, 21, 21, 0.1) !important;
color: #a31515 !important;
}
.v-list-item--active .v-icon {
color: #a31515 !important;
}
.v-list-subheader {
color: #a31515 !important;
font-weight: 600;
font-size: 0.75rem;
text-transform: uppercase;
letter-spacing: 0.5px;
}
.v-app-bar {
background: linear-gradient(135deg, #a31515 0%, #8b1212 100%) !important;
}
.v-main {
background-color: #f8f9fa;
}
</style>