feat(mobile-fixes-phase3): Complete US-308 - Actualizare Hamburger Menu - Grupat pe Categorii

Implemented by Ralph autonomous loop.
Iteration: 2

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Claude Agent
2026-01-12 13:41:03 +00:00
parent 8ee3da987e
commit edccf27db1
3 changed files with 151 additions and 34 deletions

View File

@@ -11,25 +11,89 @@
</div>
</div>
<!-- Main Navigation Section -->
<div class="drawer-section">
<ul class="drawer-nav">
<li v-for="item in navigationItems" :key="item.to">
<router-link
:to="item.to"
class="drawer-link"
:class="{ 'active': isActive(item.to, item.exactMatch) }"
@click="handleNavClick"
>
<i :class="['drawer-icon', item.icon]"></i>
<span class="drawer-label">{{ item.label }}</span>
</router-link>
</li>
</ul>
</div>
<!-- Navigation Sections (scrollable) -->
<div class="drawer-sections">
<!-- PRINCIPALE Section -->
<div class="drawer-section">
<div class="section-header">PRINCIPALE</div>
<ul class="drawer-nav">
<li v-for="item in principaleItems" :key="item.to">
<router-link
:to="item.to"
class="drawer-link"
:class="{ 'active': isActive(item.to, item.exactMatch) }"
@click="handleNavClick"
>
<i :class="['drawer-icon', item.icon]"></i>
<span class="drawer-label">{{ item.label }}</span>
</router-link>
</li>
</ul>
</div>
<!-- Divider -->
<div class="drawer-divider"></div>
<!-- Section Divider -->
<div class="drawer-divider"></div>
<!-- RAPOARTE Section -->
<div class="drawer-section">
<div class="section-header">RAPOARTE</div>
<ul class="drawer-nav">
<li v-for="item in rapoarteItems" :key="item.to">
<router-link
:to="item.to"
class="drawer-link"
:class="{ 'active': isActive(item.to, item.exactMatch) }"
@click="handleNavClick"
>
<i :class="['drawer-icon', item.icon]"></i>
<span class="drawer-label">{{ item.label }}</span>
</router-link>
</li>
</ul>
</div>
<!-- Section Divider -->
<div class="drawer-divider"></div>
<!-- ANALIZE Section -->
<div class="drawer-section">
<div class="section-header">ANALIZE</div>
<ul class="drawer-nav">
<li v-for="item in analizeItems" :key="item.to">
<router-link
:to="item.to"
class="drawer-link"
:class="{ 'active': isActive(item.to, item.exactMatch) }"
@click="handleNavClick"
>
<i :class="['drawer-icon', item.icon]"></i>
<span class="drawer-label">{{ item.label }}</span>
</router-link>
</li>
</ul>
</div>
<!-- Section Divider -->
<div class="drawer-divider"></div>
<!-- ADMINISTRARE Section -->
<div class="drawer-section">
<div class="section-header">ADMINISTRARE</div>
<ul class="drawer-nav">
<li v-for="item in administrareItems" :key="item.to">
<router-link
:to="item.to"
class="drawer-link"
:class="{ 'active': isActive(item.to, item.exactMatch) }"
@click="handleNavClick"
>
<i :class="['drawer-icon', item.icon]"></i>
<span class="drawer-label">{{ item.label }}</span>
</router-link>
</li>
</ul>
</div>
</div>
<!-- Profile Section (at bottom) -->
<div class="drawer-profile">
@@ -75,10 +139,15 @@ import { useRoute, useRouter } from 'vue-router'
*
* Features:
* - Slide-in animation from left
* - Header with logo
* - Main navigation links (Dashboard, Bonuri, Facturi, Balanță, Trezorerie, Setări)
* - Header with ROA2WEB logo
* - Navigation organized into 4 category sections:
* - PRINCIPALE: Dashboard, Bonuri
* - RAPOARTE: Facturi, Balanță, Casa și Banca
* - ANALIZE: Scadențe, Facturi Detaliate
* - ADMINISTRARE: Setări
* - Visual separators between sections
* - Active state highlighting based on current route
* - Profile section with user name and logout button
* - Profile section with user name and logout button (footer)
* - Close on tap outside or on link click
* - Full dark mode support
* - Teleported to body to avoid z-index issues
@@ -117,15 +186,31 @@ const router = useRouter()
const drawerRef = ref(null)
/**
* Navigation items for the drawer menu
* Based on acceptance criteria: Dashboard, Bonuri, Facturi, Balanță, Trezorerie, Setări
* Navigation items organized by category
* Based on US-308 acceptance criteria
*/
const navigationItems = [
{ to: '/reports/dashboard', icon: 'pi pi-home', label: 'Dashboard', exactMatch: true },
{ to: '/data-entry', icon: 'pi pi-receipt', label: 'Bonuri', exactMatch: false },
// PRINCIPALE: Dashboard, Bonuri
const principaleItems = [
{ to: '/dashboard', icon: 'pi pi-home', label: 'Dashboard', exactMatch: true },
{ to: '/data-entry', icon: 'pi pi-receipt', label: 'Bonuri', exactMatch: false }
]
// RAPOARTE: Facturi, Balanță, Casa și Banca
const rapoarteItems = [
{ to: '/reports/invoices', icon: 'pi pi-file', label: 'Facturi', exactMatch: true },
{ to: '/reports/trial-balance', icon: 'pi pi-calculator', label: 'Balanță', exactMatch: true },
{ to: '/reports/bank-cash', icon: 'pi pi-money-bill', label: 'Trezorerie', exactMatch: true },
{ to: '/reports/bank-cash', icon: 'pi pi-money-bill', label: 'Casa și Banca', exactMatch: true }
]
// ANALIZE: Scadențe, Facturi Detaliate
const analizeItems = [
{ to: '/reports/maturity-analysis', icon: 'pi pi-clock', label: 'Scadențe', exactMatch: true },
{ to: '/reports/detailed-invoices', icon: 'pi pi-list', label: 'Facturi Detaliate', exactMatch: true }
]
// ADMINISTRARE: Setări
const administrareItems = [
{ to: '/settings', icon: 'pi pi-cog', label: 'Setări', exactMatch: false }
]
@@ -234,14 +319,32 @@ const handleLogout = async () => {
}
/* ================================================
Navigation Section
Navigation Sections Container (scrollable)
================================================ */
.drawer-sections {
flex: 1;
overflow-y: auto;
-webkit-overflow-scrolling: touch;
padding: var(--space-sm) 0;
}
/* ================================================
Individual Section
================================================ */
.drawer-section {
flex: 1;
padding: var(--space-sm) 0;
overflow-y: auto;
-webkit-overflow-scrolling: touch;
padding: var(--space-xs) 0;
}
/* Section header label (PRINCIPALE, RAPOARTE, etc.) */
.section-header {
padding: var(--space-sm) var(--space-lg);
font-size: var(--text-xs);
font-weight: var(--font-semibold);
color: var(--text-color-secondary);
text-transform: uppercase;
letter-spacing: 0.05em;
}
.drawer-nav {
@@ -463,6 +566,10 @@ const handleLogout = async () => {
background: var(--surface-border);
}
[data-theme="dark"] .section-header {
color: var(--text-color-secondary);
}
[data-theme="dark"] .drawer-profile {
border-top-color: var(--surface-border);
}
@@ -544,6 +651,10 @@ const handleLogout = async () => {
background: var(--surface-border);
}
:root:not([data-theme]) .section-header {
color: var(--text-color-secondary);
}
:root:not([data-theme]) .drawer-profile {
border-top-color: var(--surface-border);
}