Fix sidebar collapse and redesign profile section
Build And Push Image / docker (push) Has been cancelled Details

- Increased rail mode width from 56px to 80px to properly fit icons
- Updated rail-width prop in all three layout files (admin, board, member)
- Redesigned profile section with improved layout and positioning
- Added horizontal layout in expanded mode with avatar, info, and menu button
- Implemented responsive design that switches to vertical layout in collapsed mode
- Enhanced menu with colorful icons and hover effects
- Added role badges (Admin, Board, Member) for better visual identification
- Improved glass morphism effects on profile card and menu
- Added smooth transitions and hover animations

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Matt 2025-08-31 23:19:50 +02:00
parent 9e4f037917
commit c37e0d0b1b
4 changed files with 237 additions and 117 deletions

View File

@ -938,9 +938,9 @@ $screen-xl: 1280px;
min-width: 280px; min-width: 280px;
} }
// Ensure rail mode uses correct width // Ensure rail mode uses correct width - increased to fit icons
&.v-navigation-drawer--rail { &.v-navigation-drawer--rail {
width: 56px !important; width: 80px !important;
} }
&__content { &__content {
@ -981,4 +981,58 @@ $screen-xl: 1280px;
.dashboard-header { .dashboard-header {
padding: 1rem !important; padding: 1rem !important;
} }
}
// Enhanced Profile Card Styles
.glass-profile-card {
background: rgba(255, 255, 255, 0.08) !important;
backdrop-filter: blur(10px) !important;
border: 1px solid rgba(255, 255, 255, 0.1) !important;
border-radius: 12px !important;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1) !important;
&:hover {
background: rgba(255, 255, 255, 0.12) !important;
border-color: rgba(255, 255, 255, 0.15) !important;
box-shadow: 0 8px 32px rgba(31, 38, 135, 0.15) !important;
}
}
.profile-menu-btn {
transition: all 0.2s ease !important;
&:hover {
transform: scale(1.05) !important;
background: rgba(255, 255, 255, 0.1) !important;
}
}
.glass-menu {
background: rgba(28, 28, 30, 0.95) !important;
backdrop-filter: blur(20px) !important;
border: 1px solid rgba(255, 255, 255, 0.1) !important;
border-radius: 12px !important;
overflow: hidden !important;
.v-list-item {
transition: all 0.2s ease !important;
&:hover {
background: rgba(255, 255, 255, 0.08) !important;
padding-left: 20px !important;
}
&.hover-lift:hover {
transform: translateX(4px) !important;
}
}
}
.glass-badge {
background: linear-gradient(135deg, rgba(206, 26, 26, 0.2), rgba(255, 255, 255, 0.1)) !important;
backdrop-filter: blur(10px) !important;
border: 1px solid rgba(206, 26, 26, 0.3) !important;
color: #CE1A1A !important;
font-weight: 600 !important;
letter-spacing: 0.5px !important;
} }

View File

@ -6,7 +6,7 @@
:expand-on-hover="false" :expand-on-hover="false"
permanent permanent
width="280" width="280"
rail-width="56" rail-width="80"
class="enhanced-glass-drawer" class="enhanced-glass-drawer"
> >
<!-- Enhanced Logo Section --> <!-- Enhanced Logo Section -->
@ -276,53 +276,72 @@
<!-- Enhanced Profile Card --> <!-- Enhanced Profile Card -->
<template v-slot:append> <template v-slot:append>
<div class="pa-3"> <div class="pa-2">
<v-card class="glass-profile-card pa-3"> <v-card class="glass-profile-card overflow-visible">
<div class="d-flex flex-column align-center"> <div class="d-flex align-center" :class="miniVariant ? 'flex-column pa-2' : 'pa-3'">
<!-- Avatar Section -->
<ProfileAvatar <ProfileAvatar
:member-id="memberData?.member_id || memberData?.Id" :member-id="memberData?.member_id || memberData?.Id"
:first-name="memberData?.first_name || user?.firstName" :first-name="memberData?.first_name || user?.firstName"
:last-name="memberData?.last_name || user?.lastName" :last-name="memberData?.last_name || user?.lastName"
:member-name="memberData?.FullName || user?.name" :member-name="memberData?.FullName || user?.name"
size="small" :size="miniVariant ? 'x-small' : 'small'"
class="mb-2" :class="miniVariant ? 'mb-2' : 'mr-3'"
/> />
<div class="text-center">
<!-- Info Section (Hidden in mini mode) -->
<div v-if="!miniVariant" class="flex-grow-1">
<div class="text-subtitle-2 font-weight-bold">{{ user?.name || 'Administrator' }}</div> <div class="text-subtitle-2 font-weight-bold">{{ user?.name || 'Administrator' }}</div>
<div class="text-caption text-medium-emphasis">{{ user?.email || 'admin@monacousa.org' }}</div> <div class="text-caption text-medium-emphasis">{{ user?.email?.split('@')[0] || 'admin' }}</div>
<v-chip size="x-small" class="mt-1 glass-badge">Admin</v-chip>
</div>
<!-- Action Buttons -->
<div :class="miniVariant ? '' : 'ml-auto'">
<v-menu location="top" offset-y>
<template v-slot:activator="{ props }">
<v-btn
v-bind="props"
:icon="miniVariant"
:size="miniVariant ? 'x-small' : 'small'"
:variant="miniVariant ? 'text' : 'tonal'"
class="profile-menu-btn"
>
<v-icon :size="miniVariant ? 'small' : 'default'">
{{ miniVariant ? 'mdi-dots-vertical' : 'mdi-menu' }}
</v-icon>
<span v-if="!miniVariant" class="ml-1">Menu</span>
</v-btn>
</template>
<v-list density="compact" class="glass-menu" min-width="200">
<v-list-item @click="() => {}" class="hover-lift">
<template v-slot:prepend>
<v-icon size="small" color="primary">mdi-account-circle</v-icon>
</template>
<v-list-item-title>My Profile</v-list-item-title>
</v-list-item>
<v-list-item @click="() => {}" class="hover-lift">
<template v-slot:prepend>
<v-icon size="small" color="info">mdi-cog-outline</v-icon>
</template>
<v-list-item-title>Settings</v-list-item-title>
</v-list-item>
<v-list-item @click="() => {}" class="hover-lift">
<template v-slot:prepend>
<v-icon size="small" color="warning">mdi-bell-outline</v-icon>
</template>
<v-list-item-title>Notifications</v-list-item-title>
</v-list-item>
<v-divider class="my-1 glass-divider" />
<v-list-item @click="logout" class="hover-lift">
<template v-slot:prepend>
<v-icon size="small" color="error">mdi-logout-variant</v-icon>
</template>
<v-list-item-title class="text-error">Sign Out</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
</div> </div>
<v-menu location="top">
<template v-slot:activator="{ props }">
<v-btn
v-bind="props"
icon="mdi-dots-vertical"
size="x-small"
variant="text"
class="mt-2"
/>
</template>
<v-list density="compact" class="glass-menu">
<v-list-item @click="() => {}">
<template v-slot:prepend>
<v-icon size="small">mdi-account</v-icon>
</template>
<v-list-item-title>Profile</v-list-item-title>
</v-list-item>
<v-list-item @click="() => {}">
<template v-slot:prepend>
<v-icon size="small">mdi-cog</v-icon>
</template>
<v-list-item-title>Settings</v-list-item-title>
</v-list-item>
<v-divider class="my-1" />
<v-list-item @click="logout">
<template v-slot:prepend>
<v-icon size="small">mdi-logout</v-icon>
</template>
<v-list-item-title>Logout</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
</div> </div>
</v-card> </v-card>
</div> </div>

View File

@ -6,7 +6,7 @@
:expand-on-hover="false" :expand-on-hover="false"
permanent permanent
width="280" width="280"
rail-width="56" rail-width="80"
class="enhanced-glass-drawer" class="enhanced-glass-drawer"
> >
<!-- Enhanced Logo Section --> <!-- Enhanced Logo Section -->
@ -209,53 +209,72 @@
<!-- Enhanced Profile Card --> <!-- Enhanced Profile Card -->
<template v-slot:append> <template v-slot:append>
<div class="pa-3"> <div class="pa-2">
<v-card class="glass-profile-card pa-3"> <v-card class="glass-profile-card overflow-visible">
<div class="d-flex flex-column align-center"> <div class="d-flex align-center" :class="miniVariant ? 'flex-column pa-2' : 'pa-3'">
<!-- Avatar Section -->
<ProfileAvatar <ProfileAvatar
:member-id="memberData?.member_id || memberData?.Id" :member-id="memberData?.member_id || memberData?.Id"
:first-name="memberData?.first_name || user?.firstName" :first-name="memberData?.first_name || user?.firstName"
:last-name="memberData?.last_name || user?.lastName" :last-name="memberData?.last_name || user?.lastName"
:member-name="memberData?.FullName || user?.name" :member-name="memberData?.FullName || user?.name"
size="small" :size="miniVariant ? 'x-small' : 'small'"
class="mb-2" :class="miniVariant ? 'mb-2' : 'mr-3'"
/> />
<div class="text-center">
<!-- Info Section (Hidden in mini mode) -->
<div v-if="!miniVariant" class="flex-grow-1">
<div class="text-subtitle-2 font-weight-bold">{{ user?.name || 'Board Member' }}</div> <div class="text-subtitle-2 font-weight-bold">{{ user?.name || 'Board Member' }}</div>
<div class="text-caption text-medium-emphasis">{{ user?.email || 'board@monacousa.org' }}</div> <div class="text-caption text-medium-emphasis">{{ user?.email?.split('@')[0] || 'board' }}</div>
<v-chip size="x-small" class="mt-1 glass-badge">Board</v-chip>
</div>
<!-- Action Buttons -->
<div :class="miniVariant ? '' : 'ml-auto'">
<v-menu location="top" offset-y>
<template v-slot:activator="{ props }">
<v-btn
v-bind="props"
:icon="miniVariant"
:size="miniVariant ? 'x-small' : 'small'"
:variant="miniVariant ? 'text' : 'tonal'"
class="profile-menu-btn"
>
<v-icon :size="miniVariant ? 'small' : 'default'">
{{ miniVariant ? 'mdi-dots-vertical' : 'mdi-menu' }}
</v-icon>
<span v-if="!miniVariant" class="ml-1">Menu</span>
</v-btn>
</template>
<v-list density="compact" class="glass-menu" min-width="200">
<v-list-item @click="() => {}" class="hover-lift">
<template v-slot:prepend>
<v-icon size="small" color="primary">mdi-account-circle</v-icon>
</template>
<v-list-item-title>My Profile</v-list-item-title>
</v-list-item>
<v-list-item @click="() => {}" class="hover-lift">
<template v-slot:prepend>
<v-icon size="small" color="info">mdi-cog-outline</v-icon>
</template>
<v-list-item-title>Settings</v-list-item-title>
</v-list-item>
<v-list-item @click="() => {}" class="hover-lift">
<template v-slot:prepend>
<v-icon size="small" color="warning">mdi-bell-outline</v-icon>
</template>
<v-list-item-title>Notifications</v-list-item-title>
</v-list-item>
<v-divider class="my-1 glass-divider" />
<v-list-item @click="logout" class="hover-lift">
<template v-slot:prepend>
<v-icon size="small" color="error">mdi-logout-variant</v-icon>
</template>
<v-list-item-title class="text-error">Sign Out</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
</div> </div>
<v-menu location="top">
<template v-slot:activator="{ props }">
<v-btn
v-bind="props"
icon="mdi-dots-vertical"
size="x-small"
variant="text"
class="mt-2"
/>
</template>
<v-list density="compact" class="glass-menu">
<v-list-item @click="() => {}">
<template v-slot:prepend>
<v-icon size="small">mdi-account</v-icon>
</template>
<v-list-item-title>Profile</v-list-item-title>
</v-list-item>
<v-list-item @click="() => {}">
<template v-slot:prepend>
<v-icon size="small">mdi-cog</v-icon>
</template>
<v-list-item-title>Settings</v-list-item-title>
</v-list-item>
<v-divider class="my-1" />
<v-list-item @click="logout">
<template v-slot:prepend>
<v-icon size="small">mdi-logout</v-icon>
</template>
<v-list-item-title>Logout</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
</div> </div>
</v-card> </v-card>
</div> </div>

View File

@ -6,7 +6,7 @@
:expand-on-hover="false" :expand-on-hover="false"
permanent permanent
width="280" width="280"
rail-width="56" rail-width="80"
class="enhanced-glass-drawer" class="enhanced-glass-drawer"
> >
<!-- Logo Section with Enhanced Glass Effect --> <!-- Logo Section with Enhanced Glass Effect -->
@ -75,50 +75,78 @@
<!-- Enhanced Profile Footer --> <!-- Enhanced Profile Footer -->
<template v-slot:append> <template v-slot:append>
<div class="profile-footer"> <div class="pa-2">
<v-divider class="mb-3" /> <v-card class="glass-profile-card overflow-visible">
<div class="profile-card-footer"> <div class="d-flex align-center" :class="miniVariant ? 'flex-column pa-2' : 'pa-3'">
<div class="profile-content"> <!-- Avatar Section -->
<div class="profile-avatar-wrapper"> <div class="position-relative">
<ProfileAvatar <ProfileAvatar
v-if="memberData" v-if="memberData"
:member-id="memberData?.member_id" :member-id="memberData?.member_id"
:first-name="memberData?.first_name || user?.firstName" :first-name="memberData?.first_name || user?.firstName"
:last-name="memberData?.last_name || user?.lastName" :last-name="memberData?.last_name || user?.lastName"
size="small" :size="miniVariant ? 'x-small' : 'small'"
:class="miniVariant ? 'mb-2' : 'mr-3'"
:show-badge="false" :show-badge="false"
/> />
<div class="online-indicator" /> <div v-if="!miniVariant" class="online-indicator" />
</div> </div>
<div class="profile-info">
<div class="profile-name">{{ fullName }}</div> <!-- Info Section (Hidden in mini mode) -->
<div class="profile-email">{{ email }}</div> <div v-if="!miniVariant" class="flex-grow-1">
<div class="text-subtitle-2 font-weight-bold">{{ fullName }}</div>
<div class="text-caption text-medium-emphasis">{{ email?.split('@')[0] || 'member' }}</div>
<v-chip size="x-small" class="mt-1 glass-badge">Member</v-chip>
</div>
<!-- Action Buttons -->
<div :class="miniVariant ? '' : 'ml-auto'">
<v-menu location="top" offset-y>
<template v-slot:activator="{ props }">
<v-btn
v-bind="props"
:icon="miniVariant"
:size="miniVariant ? 'x-small' : 'small'"
:variant="miniVariant ? 'text' : 'tonal'"
class="profile-menu-btn"
>
<v-icon :size="miniVariant ? 'small' : 'default'">
{{ miniVariant ? 'mdi-dots-vertical' : 'mdi-menu' }}
</v-icon>
<span v-if="!miniVariant" class="ml-1">Menu</span>
</v-btn>
</template>
<v-list density="compact" class="glass-menu" min-width="200">
<v-list-item to="/member/profile" class="hover-lift">
<template v-slot:prepend>
<v-icon size="small" color="primary">mdi-account-circle</v-icon>
</template>
<v-list-item-title>My Profile</v-list-item-title>
</v-list-item>
<v-list-item to="/member/settings" class="hover-lift">
<template v-slot:prepend>
<v-icon size="small" color="info">mdi-cog-outline</v-icon>
</template>
<v-list-item-title>Settings</v-list-item-title>
</v-list-item>
<v-list-item @click="() => {}" class="hover-lift">
<template v-slot:prepend>
<v-icon size="small" color="warning">mdi-bell-outline</v-icon>
</template>
<v-list-item-title>Notifications</v-list-item-title>
</v-list-item>
<v-divider class="my-1 glass-divider" />
<v-list-item @click="handleLogout" class="hover-lift">
<template v-slot:prepend>
<v-icon size="small" color="error">mdi-logout-variant</v-icon>
</template>
<v-list-item-title class="text-error">Sign Out</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
</div> </div>
<v-menu offset-y>
<template v-slot:activator="{ props }">
<v-btn
icon="mdi-dots-vertical"
size="x-small"
variant="text"
v-bind="props"
class="profile-menu-btn"
/>
</template>
<v-list class="glass-dropdown">
<v-list-item
prepend-icon="mdi-cog"
title="Settings"
to="/member/settings"
/>
<v-list-item
prepend-icon="mdi-logout"
title="Logout"
@click="handleLogout"
/>
</v-list>
</v-menu>
</div> </div>
</div> </v-card>
</div> </div>
</template> </template>
</v-navigation-drawer> </v-navigation-drawer>