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

@@ -60,8 +60,8 @@
"Header cu logo, Footer cu profil utilizator și logout", "Header cu logo, Footer cu profil utilizator și logout",
"npm run build passes" "npm run build passes"
], ],
"passes": false, "passes": true,
"notes": "" "notes": "Completed in iteration 2"
}, },
{ {
"id": "US-304", "id": "US-304",

View File

@@ -21,3 +21,9 @@ User Stories: 11 (US-301 to US-311)
[2026-01-12 13:39:00] Working on story: US-308 [2026-01-12 13:39:00] Working on story: US-308
[2026-01-12 13:39:00] Running Claude... (log: /workspace/roa2web/scripts/ralph/logs/iteration_2_US-308.log) [2026-01-12 13:39:00] Running Claude... (log: /workspace/roa2web/scripts/ralph/logs/iteration_2_US-308.log)
[2026-01-12 13:39:23] SUCCESS: Story US-307 passed! [2026-01-12 13:39:23] SUCCESS: Story US-307 passed!
[2026-01-12 13:39:23] Changes committed
[2026-01-12 13:39:23] Progress: 1/11 stories completed
[2026-01-12 13:39:25] === Iteration 2/100 ===
[2026-01-12 13:39:25] Working on story: US-308
[2026-01-12 13:39:25] Running Claude... (log: /workspace/roa2web/scripts/ralph/logs/iteration_2_US-308.log)
[2026-01-12 13:41:03] SUCCESS: Story US-308 passed!

View File

@@ -11,25 +11,89 @@
</div> </div>
</div> </div>
<!-- Main Navigation Section --> <!-- Navigation Sections (scrollable) -->
<div class="drawer-section"> <div class="drawer-sections">
<ul class="drawer-nav"> <!-- PRINCIPALE Section -->
<li v-for="item in navigationItems" :key="item.to"> <div class="drawer-section">
<router-link <div class="section-header">PRINCIPALE</div>
:to="item.to" <ul class="drawer-nav">
class="drawer-link" <li v-for="item in principaleItems" :key="item.to">
:class="{ 'active': isActive(item.to, item.exactMatch) }" <router-link
@click="handleNavClick" :to="item.to"
> class="drawer-link"
<i :class="['drawer-icon', item.icon]"></i> :class="{ 'active': isActive(item.to, item.exactMatch) }"
<span class="drawer-label">{{ item.label }}</span> @click="handleNavClick"
</router-link> >
</li> <i :class="['drawer-icon', item.icon]"></i>
</ul> <span class="drawer-label">{{ item.label }}</span>
</div> </router-link>
</li>
</ul>
</div>
<!-- Divider --> <!-- Section Divider -->
<div class="drawer-divider"></div> <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) --> <!-- Profile Section (at bottom) -->
<div class="drawer-profile"> <div class="drawer-profile">
@@ -75,10 +139,15 @@ import { useRoute, useRouter } from 'vue-router'
* *
* Features: * Features:
* - Slide-in animation from left * - Slide-in animation from left
* - Header with logo * - Header with ROA2WEB logo
* - Main navigation links (Dashboard, Bonuri, Facturi, Balanță, Trezorerie, Setări) * - 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 * - 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 * - Close on tap outside or on link click
* - Full dark mode support * - Full dark mode support
* - Teleported to body to avoid z-index issues * - Teleported to body to avoid z-index issues
@@ -117,15 +186,31 @@ const router = useRouter()
const drawerRef = ref(null) const drawerRef = ref(null)
/** /**
* Navigation items for the drawer menu * Navigation items organized by category
* Based on acceptance criteria: Dashboard, Bonuri, Facturi, Balanță, Trezorerie, Setări * Based on US-308 acceptance criteria
*/ */
const navigationItems = [
{ to: '/reports/dashboard', icon: 'pi pi-home', label: 'Dashboard', exactMatch: true }, // PRINCIPALE: Dashboard, Bonuri
{ to: '/data-entry', icon: 'pi pi-receipt', label: 'Bonuri', exactMatch: false }, 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/invoices', icon: 'pi pi-file', label: 'Facturi', exactMatch: true },
{ to: '/reports/trial-balance', icon: 'pi pi-calculator', label: 'Balanță', 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 } { 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 { .drawer-section {
flex: 1; padding: var(--space-xs) 0;
padding: var(--space-sm) 0; }
overflow-y: auto;
-webkit-overflow-scrolling: touch; /* 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 { .drawer-nav {
@@ -463,6 +566,10 @@ const handleLogout = async () => {
background: var(--surface-border); background: var(--surface-border);
} }
[data-theme="dark"] .section-header {
color: var(--text-color-secondary);
}
[data-theme="dark"] .drawer-profile { [data-theme="dark"] .drawer-profile {
border-top-color: var(--surface-border); border-top-color: var(--surface-border);
} }
@@ -544,6 +651,10 @@ const handleLogout = async () => {
background: var(--surface-border); background: var(--surface-border);
} }
:root:not([data-theme]) .section-header {
color: var(--text-color-secondary);
}
:root:not([data-theme]) .drawer-profile { :root:not([data-theme]) .drawer-profile {
border-top-color: var(--surface-border); border-top-color: var(--surface-border);
} }