From 3afd3cd0ec152dc15371ae4dca6f3252b7343e7d Mon Sep 17 00:00:00 2001 From: Claude Agent Date: Mon, 12 Jan 2026 16:46:26 +0000 Subject: [PATCH] feat(mobile-fixes-phase3): Complete US-303 - FAB pe Pagina Bonuri (Mutare Upload) Implemented by Ralph autonomous loop. Iteration: 5 Co-Authored-By: Claude --- scripts/ralph/prd.json | 4 +- scripts/ralph/progress.txt | 6 + .../views/receipts/ReceiptsListView.vue | 120 +++++++++++++++++- 3 files changed, 124 insertions(+), 6 deletions(-) diff --git a/scripts/ralph/prd.json b/scripts/ralph/prd.json index 05fe869..d37e950 100644 --- a/scripts/ralph/prd.json +++ b/scripts/ralph/prd.json @@ -144,8 +144,8 @@ "FAB vizibil doar pe mobil (isMobile)", "npm run build passes" ], - "passes": false, - "notes": "" + "passes": true, + "notes": "Completed in iteration 5" }, { "id": "US-306", diff --git a/scripts/ralph/progress.txt b/scripts/ralph/progress.txt index 7382bb2..0f91015 100644 --- a/scripts/ralph/progress.txt +++ b/scripts/ralph/progress.txt @@ -1044,3 +1044,9 @@ User Stories: 11 (US-301 to US-311) [2026-01-12 16:40:03] Working on story: US-302 [2026-01-12 16:40:03] Running Claude... (log: /workspace/roa2web/scripts/ralph/logs/iteration_4_US-302.log) [2026-01-12 16:42:59] SUCCESS: Story US-302 passed! +[2026-01-12 16:42:59] Changes committed +[2026-01-12 16:42:59] Progress: 6/11 stories completed +[2026-01-12 16:43:01] === Iteration 5/100 === +[2026-01-12 16:43:01] Working on story: US-303 +[2026-01-12 16:43:01] Running Claude... (log: /workspace/roa2web/scripts/ralph/logs/iteration_5_US-303.log) +[2026-01-12 16:46:26] SUCCESS: Story US-303 passed! diff --git a/src/modules/data-entry/views/receipts/ReceiptsListView.vue b/src/modules/data-entry/views/receipts/ReceiptsListView.vue index 4fdf38e..052fdca 100644 --- a/src/modules/data-entry/views/receipts/ReceiptsListView.vue +++ b/src/modules/data-entry/views/receipts/ReceiptsListView.vue @@ -545,18 +545,30 @@ /> - + + + + @@ -1038,6 +1050,10 @@ const handleResize = () => { const showDrawer = ref(false) const moreMenuRef = ref(null) const fabVisible = ref(true) + +// US-303: FAB Menu State +const fabMenuRef = ref(null) +const fabMenuOpen = ref(false) let lastScrollY = 0 let scrollTimeout = null @@ -1075,6 +1091,32 @@ const moreMenuItems = computed(() => [ } ]) +// US-303: FAB Menu Items (Bon Nou | Upload Bulk) +const fabMenuItems = [ + { + label: 'Bon Nou', + icon: 'pi pi-plus', + command: () => { + fabMenuOpen.value = false + goToCreate() + } + }, + { + label: 'Upload Bulk', + icon: 'pi pi-cloud-upload', + command: () => { + fabMenuOpen.value = false + openBulkFileInput() + } + } +] + +// US-303: Toggle FAB Menu +const toggleFabMenu = (event) => { + fabMenuOpen.value = !fabMenuOpen.value + fabMenuRef.value?.toggle(event) +} + // US-103: Top bar actions for MobileTopBar component const mobileTopBarActions = computed(() => { if (mobileSelectionMode.value) { @@ -4398,6 +4440,50 @@ const cleanupCompletedBatches = (storedBatchIds) => { .mobile-fab i { font-size: var(--text-2xl); + transition: transform var(--transition-fast); +} + +/* US-303: FAB active state when menu is open */ +.mobile-fab.fab-active { + background: var(--color-primary-dark); +} + +.mobile-fab .fab-icon-rotate { + transform: rotate(45deg); +} + +/* US-303: FAB Popup Menu positioning */ +.fab-popup-menu { + /* Position above FAB, aligned to right */ + position: fixed !important; + bottom: 140px !important; /* 72px FAB position + 56px FAB height + 12px spacing */ + right: var(--space-md) !important; + left: auto !important; + top: auto !important; + min-width: 180px; + z-index: 1000 !important; + border-radius: var(--radius-lg); + box-shadow: var(--shadow-xl); +} + +.fab-popup-menu .p-menuitem { + padding: 0; +} + +.fab-popup-menu .p-menuitem-link { + padding: var(--space-md) var(--space-lg); + gap: var(--space-sm); + font-size: var(--text-base); + min-height: 48px; /* Touch-friendly */ +} + +.fab-popup-menu .p-menuitem-icon { + font-size: var(--text-lg); + color: var(--color-primary); +} + +.fab-popup-menu .p-menuitem-text { + font-weight: var(--font-medium); } /* FAB slide animation */ @@ -4523,6 +4609,19 @@ const cleanupCompletedBatches = (storedBatchIds) => { box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4); } +[data-theme="dark"] .mobile-fab.fab-active { + background: var(--blue-700); +} + +[data-theme="dark"] .fab-popup-menu { + background: var(--surface-card); + border: 1px solid var(--surface-border); +} + +[data-theme="dark"] .fab-popup-menu .p-menuitem-icon { + color: var(--blue-400); +} + [data-theme="dark"] .sidebar-item.active, [data-theme="dark"] .sidebar-item.router-link-active { color: var(--blue-400); @@ -4568,6 +4667,19 @@ const cleanupCompletedBatches = (storedBatchIds) => { box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4); } + :root:not([data-theme]) .mobile-fab.fab-active { + background: var(--blue-700); + } + + :root:not([data-theme]) .fab-popup-menu { + background: var(--surface-card); + border: 1px solid var(--surface-border); + } + + :root:not([data-theme]) .fab-popup-menu .p-menuitem-icon { + color: var(--blue-400); + } + :root:not([data-theme]) .sidebar-item.active, :root:not([data-theme]) .sidebar-item.router-link-active { color: var(--blue-400);