feat(unified-mobile-desktop-ui): Complete US-505 - Meniu Hamburger Desktop = Mobil

Implemented by Ralph autonomous loop.
Iteration: 5

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Claude Agent
2026-01-12 22:29:44 +00:00
parent cf912693ca
commit 9d66a0b2aa
3 changed files with 144 additions and 71 deletions

View File

@@ -133,8 +133,8 @@
"npm run build passes",
"Verify in browser desktop: meniul arată la fel ca pe mobil ca structură"
],
"passes": false,
"notes": ""
"passes": true,
"notes": "Completed in iteration 5"
},
{
"id": "US-506",

View File

@@ -94,3 +94,9 @@ Design Reference: src/modules/reports/views/InvoicesView.vue
[2026-01-12 22:23:53] Working on story: US-504
[2026-01-12 22:23:53] Running Claude... (log: /workspace/roa2web/scripts/ralph/logs/iteration_4_US-504.log)
[2026-01-12 22:27:34] SUCCESS: Story US-504 passed!
[2026-01-12 22:27:34] Changes committed
[2026-01-12 22:27:34] Progress: 4/19 stories completed
[2026-01-12 22:27:36] === Iteration 5/100 ===
[2026-01-12 22:27:36] Working on story: US-505
[2026-01-12 22:27:36] Running Claude... (log: /workspace/roa2web/scripts/ralph/logs/iteration_5_US-505.log)
[2026-01-12 22:29:44] SUCCESS: Story US-505 passed!

View File

@@ -7,83 +7,75 @@
@click="closeMenu"
></div>
<!-- Slide Menu -->
<!-- Slide Menu - Unified structure matching MobileDrawerMenu -->
<nav class="slide-menu" :class="{ open: isOpen }">
<!-- Navigation Section -->
<!-- PRINCIPALE Section -->
<div class="menu-section">
<h3 class="menu-title">Navigare</h3>
<h3 class="menu-title">Principale</h3>
<ul class="menu-list">
<li class="menu-item">
<li class="menu-item" v-for="item in principaleItems" :key="item.to">
<router-link
to="/reports/dashboard"
:to="item.to"
class="menu-link"
:class="{ active: $route.name === 'Dashboard' }"
:class="{ active: isActive(item.to, item.exactMatch) }"
@click="closeMenu"
>
<i class="menu-icon pi pi-home"></i>
<span>Dashboard</span>
</router-link>
</li>
<li class="menu-item">
<router-link
to="/reports/invoices"
class="menu-link"
:class="{ active: $route.name === 'Invoices' }"
@click="closeMenu"
>
<i class="menu-icon pi pi-file"></i>
<span>Facturi</span>
</router-link>
</li>
<li class="menu-item">
<router-link
to="/reports/bank-cash"
class="menu-link"
:class="{ active: $route.name === 'BankCash' }"
@click="closeMenu"
>
<i class="menu-icon pi pi-money-bill"></i>
<span>Casa și Banca</span>
</router-link>
</li>
<li class="menu-item">
<router-link
to="/reports/trial-balance"
class="menu-link"
:class="{ active: $route.name === 'TrialBalance' }"
@click="closeMenu"
>
<i class="menu-icon pi pi-calculator"></i>
<span>Balanță de Verificare</span>
<i :class="['menu-icon', item.icon]"></i>
<span>{{ item.label }}</span>
</router-link>
</li>
</ul>
</div>
<!-- System Section -->
<!-- RAPOARTE Section -->
<div class="menu-section">
<h3 class="menu-title">Sistem</h3>
<h3 class="menu-title">Rapoarte</h3>
<ul class="menu-list">
<li class="menu-item">
<li class="menu-item" v-for="item in rapoarteItems" :key="item.to">
<router-link
to="/reports/cache-stats"
:to="item.to"
class="menu-link"
:class="{ active: $route.name === 'CacheStats' }"
:class="{ active: isActive(item.to, item.exactMatch) }"
@click="closeMenu"
>
<i class="menu-icon pi pi-chart-bar"></i>
<span>Statistici cache</span>
<i :class="['menu-icon', item.icon]"></i>
<span>{{ item.label }}</span>
</router-link>
</li>
<li class="menu-item">
</ul>
</div>
<!-- ANALIZE Section -->
<div class="menu-section">
<h3 class="menu-title">Analize</h3>
<ul class="menu-list">
<li class="menu-item" v-for="item in analizeItems" :key="item.to">
<router-link
to="/reports/server-logs"
:to="item.to"
class="menu-link"
:class="{ active: $route.name === 'ServerLogs' }"
:class="{ active: isActive(item.to, item.exactMatch) }"
@click="closeMenu"
>
<i class="menu-icon pi pi-file-edit"></i>
<span>Server Logs</span>
<i :class="['menu-icon', item.icon]"></i>
<span>{{ item.label }}</span>
</router-link>
</li>
</ul>
</div>
<!-- ADMINISTRARE Section -->
<div class="menu-section">
<h3 class="menu-title">Administrare</h3>
<ul class="menu-list">
<li class="menu-item" v-for="item in administrareItems" :key="item.to">
<router-link
:to="item.to"
class="menu-link"
:class="{ active: isActive(item.to, item.exactMatch) }"
@click="closeMenu"
>
<i :class="['menu-icon', item.icon]"></i>
<span>{{ item.label }}</span>
</router-link>
</li>
</ul>
@@ -97,18 +89,7 @@
</div>
<ul class="menu-list">
<li class="menu-item">
<router-link
to="/reports/telegram"
class="menu-link"
:class="{ active: $route.name === 'Telegram' }"
@click="closeMenu"
>
<i class="menu-icon pi pi-telegram"></i>
<span>Telegram Bot</span>
</router-link>
</li>
<li class="menu-item">
<a href="#" class="menu-link" @click.prevent="handleLogout">
<a href="#" class="menu-link menu-link-logout" @click.prevent="handleLogout">
<i class="menu-icon pi pi-sign-out"></i>
<span>Deconectare</span>
</a>
@@ -120,8 +101,8 @@
</template>
<script>
import { computed } from "vue";
import { useRouter } from "vue-router";
import { computed, ref } from "vue";
import { useRoute, useRouter } from "vue-router";
import { useAuthStore } from "@reports/stores/sharedStores";
export default {
@@ -134,13 +115,51 @@ export default {
},
emits: ["close"],
setup(props, { emit }) {
console.log('[HamburgerMenu] Component loaded - Server Logs should be visible in Sistem section');
const route = useRoute();
const router = useRouter();
const authStore = useAuthStore();
const currentUser = computed(() => authStore.currentUser);
/**
* Navigation items organized by category - matching MobileDrawerMenu structure
*/
// PRINCIPALE: Dashboard, Bonuri
const principaleItems = ref([
{ 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 = ref([
{ 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: 'Casa și Banca', exactMatch: true }
]);
// ANALIZE: Scadențe, Facturi Detaliate
const analizeItems = ref([
{ 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 = ref([
{ to: '/settings', icon: 'pi pi-cog', label: 'Setări', exactMatch: false }
]);
/**
* Check if a navigation item is active based on current route
*/
const isActive = (to, exactMatch) => {
if (exactMatch) {
return route.path === to;
}
// For non-exact match, check if current path starts with the route
return route.path.startsWith(to);
};
const closeMenu = () => {
emit("close");
};
@@ -157,9 +176,57 @@ export default {
return {
currentUser,
principaleItems,
rapoarteItems,
analizeItems,
administrareItems,
isActive,
closeMenu,
handleLogout,
};
},
};
</script>
<style scoped>
/* Logout link styling - matches MobileDrawerMenu */
.menu-link-logout {
color: var(--color-error);
}
.menu-link-logout .menu-icon {
color: var(--color-error);
}
.menu-link-logout:hover {
background: var(--red-50);
color: var(--color-error);
}
/* Dark mode support */
[data-theme="dark"] .menu-link-logout {
color: var(--red-400);
}
[data-theme="dark"] .menu-link-logout .menu-icon {
color: var(--red-400);
}
[data-theme="dark"] .menu-link-logout:hover {
background: var(--red-900);
}
@media (prefers-color-scheme: dark) {
:root:not([data-theme]) .menu-link-logout {
color: var(--red-400);
}
:root:not([data-theme]) .menu-link-logout .menu-icon {
color: var(--red-400);
}
:root:not([data-theme]) .menu-link-logout:hover {
background: var(--red-900);
}
}
</style>