feat(unified-mobile-desktop-ui): Complete US-501 - Header Actions Bar Unificat - Rapoarte

Implemented by Ralph autonomous loop.
Iteration: 1

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Claude Agent
2026-01-12 22:16:53 +00:00
parent 3a11fcd81c
commit 94d215d6ae
8 changed files with 1074 additions and 206 deletions

View File

@@ -1,7 +1,7 @@
{
"projectName": "mobile-fixes-phase4",
"projectName": "unified-mobile-desktop-ui",
"branchName": "ralph/unified-mobile-md",
"description": "Fix layout mobil: ascundere header desktop, butoane filter/export vizibile, MobileDrawerMenu cu ANALIZE, persistență bonuri cu eroare",
"description": "Unificare UI/UX mobil-desktop: header actions bar (filter/reset/export), BottomSheet filtre, meniu hamburger unificat, fix bugs (grupuri expandabile, overlay butoane), MD3 styling pentru meniuri și dialoguri",
"cssRules": {
"documentation": [
"docs/ONBOARDING_CSS.md",
@@ -27,135 +27,384 @@
"touchTargetMin": "48px"
}
},
"referenceFiles": {
"designReference": "src/modules/reports/views/InvoicesView.vue",
"mobileComponents": [
"src/shared/components/mobile/MobileTopBar.vue",
"src/shared/components/mobile/MobileDrawerMenu.vue",
"src/shared/components/mobile/MobileBottomNav.vue",
"src/shared/components/mobile/BottomSheet.vue",
"src/shared/components/mobile/MobileSelectionFooter.vue"
]
},
"userStories": [
{
"id": "US-401",
"title": "Fix Layout Principal - Ascundere Header Desktop pe Mobil",
"description": "Ca utilizator mobil vreau să văd doar MobileTopBar și MobileBottomNav, nu header-ul desktop",
"id": "US-501",
"title": "Header Actions Bar Unificat - Rapoarte",
"description": "Ca utilizator vreau butoane de Filtre, Reset Filtre și Export (PDF/XLSX dropdown) în header-ul din dreapta pe toate rapoartele",
"priority": 1,
"scope": "LARGE - Multiple pages",
"pages": [
"/reports/trial-balance",
"/reports/cash-bank",
"/reports/detailed-invoices/clients",
"/reports/detailed-invoices/suppliers",
"/reports/maturity"
],
"acceptanceCriteria": [
"AppHeader.vue sau componenta părinte are v-if='!isMobile' pentru a se ascunde pe mobil",
"Sidebar-ul desktop (navigation cu Rapoarte/Introduceri Date/Sistem) este ascuns pe mobil cu v-if='!isMobile'",
"MobileTopBar este singurul header vizibil pe viewport < 768px",
"Nu există suprapunere între header desktop și MobileTopBar",
"isMobile computed folosește window.innerWidth < 768 și este reactiv la resize",
"Fiecare pagină are în header dreapta: [Filter icon] [Reset icon] [Export dropdown]",
"Export dropdown conține: 'Export PDF' și 'Export XLSX'",
"Butonul Filter are indicator vizual (active state) când filtrele sunt aplicate",
"Butonul Reset resetează toate filtrele la valori implicite",
"Pe mobil, acțiunile sunt în MobileTopBar actions array",
"Pe desktop, acțiunile sunt într-un grup în header dreapta",
"Pattern identic cu InvoicesView.vue (referință)",
"npm run build passes",
"Verify in browser (375x667): Header desktop cu 'Selectare perioada' și 'AXN' NU este vizibil"
"Verify in browser: butoanele funcționează pe desktop și mobil"
],
"passes": true,
"notes": "Completed in iteration 1"
},
{
"id": "US-402",
"title": "Fix MobileTopBar - Butoane Filter/Export Vizibile",
"description": "Ca utilizator mobil pe pagina Facturi/Bonuri vreau să văd butoanele de filtrare și export în header",
"id": "US-502",
"title": "Header Actions Bar Unificat - Lista Bonuri",
"description": "Ca utilizator vreau butoane de Filtre, Reset Filtre și Export în header-ul listei de bonuri, consistent cu rapoartele",
"priority": 2,
"acceptanceCriteria": [
"După US-401, pe InvoicesView.vue butoanele Filter/Refresh/Export sunt vizibile în MobileTopBar",
"Pe ReceiptsListView.vue butoanele Filter/Export/More sunt vizibile în MobileTopBar",
"Butoanele au dimensiune touch target minim 48px",
"npm run build passes",
"Verify in browser (375x667): Butoanele sunt vizibile și clickable pe pagina Facturi"
"pages": [
"/data-entry"
],
"passes": true,
"notes": "Completed - CSS media queries hide desktop header, buttons visible at 375x667. Touch targets 48px verified."
"acceptanceCriteria": [
"Lista bonuri are în header: [Filter] [Reset] [Export dropdown]",
"Stilul butoanelor este identic cu cel din /reports/invoices",
"Export dropdown: 'Export PDF' și 'Export XLSX'",
"Butoanele vechi 'Filtrează' și 'Resetează' sunt înlocuite cu noul pattern (icons)",
"npm run build passes",
"Verify in browser: butoanele au același aspect ca pe pagina Facturi"
],
"passes": false,
"notes": ""
},
{
"id": "US-403",
"title": "Fix MobileDrawerMenu - Secțiunea ANALIZE Vizibilă",
"description": "Ca utilizator mobil vreau să văd secțiunea ANALIZE în hamburger menu",
"id": "US-503",
"title": "BottomSheet Filtre pentru Lista Bonuri (Mobil)",
"description": "Ca utilizator pe mobil vreau ca filtrele din lista de bonuri să se deschidă într-un BottomSheet, nu inline",
"priority": 3,
"acceptanceCriteria": [
"Click pe butonul Meniu din MobileTopBar deschide MobileDrawerMenu (nu sidebar desktop)",
"MobileDrawerMenu afișează secțiunile: PRINCIPALE, RAPOARTE, ANALIZE, ADMINISTRARE",
"Secțiunea ANALIZE conține: Scadențe (/reports/maturity-analysis), Facturi Detaliate (/reports/detailed-invoices)",
"Link-urile din ANALIZE navighează corect și închid drawer-ul",
"npm run build passes",
"Verify in browser (375x667): Click pe Meniu → apare MobileDrawerMenu cu secțiunea ANALIZE vizibilă"
"pages": [
"/data-entry"
],
"passes": true,
"notes": "Completed in iteration 3"
"acceptanceCriteria": [
"Click pe butonul Filter deschide BottomSheet component (nu inline filters)",
"BottomSheet conține toate filtrele existente (status, dată, search, etc.)",
"BottomSheet are butoane 'Resetează' și 'Aplică' în footer",
"Swipe-down sau tap outside închide BottomSheet",
"Pattern identic cu InvoicesView.vue BottomSheet",
"npm run build passes",
"Verify in browser mobil (375x667): filtrele apar în BottomSheet"
],
"passes": false,
"notes": ""
},
{
"id": "US-404",
"title": "Fix Spațiu Blank - Padding Corect pentru Mobile",
"description": "Ca utilizator mobil vreau ca paginile să nu aibă spațiu blank excesiv în partea de sus",
"id": "US-504",
"title": "Fix Export Endpoints Backend",
"description": "Ca utilizator vreau ca exportul PDF/XLSX să funcționeze fără erori pe toate paginile",
"priority": 4,
"acceptanceCriteria": [
"Paginile de rapoarte au padding-top: 56px (doar MobileTopBar height) pe mobil",
"Nu există spațiu blank între MobileTopBar și conținut",
"Tab-urile Clienți/Furnizori sunt imediat sub MobileTopBar pe InvoicesView",
"Status chips sunt imediat sub MobileTopBar pe ReceiptsListView",
"Identificate și fixate erorile din endpoint-urile de export existente",
"Export PDF funcțional pentru: Facturi, Balanță, Casă și Bancă, Facturi Detaliate, Scadențe, Bonuri",
"Export XLSX funcțional pentru aceleași pagini",
"Exportul include DOAR datele filtrate (nu toate datele)",
"Folosește formatarea PDF existentă de la Facturi/Balanță/Casă și Bancă",
"npm run build passes",
"Verify in browser (375x667): Conținutul începe imediat sub MobileTopBar, fără gap de ~120px"
"Verify in browser: descărcare PDF și XLSX reușită"
],
"passes": true,
"notes": "Completed with US-401/US-402 - hiding desktop header eliminated the blank space. Screenshots confirm content starts immediately below MobileTopBar."
"passes": false,
"notes": ""
},
{
"id": "US-405",
"title": "Fix batchProgressStore - Restaurare Joburi Failed",
"description": "Ca utilizator care a uploadat bonuri cu erori OCR vreau ca acestea să rămână vizibile după refresh",
"id": "US-505",
"title": "Meniu Hamburger Desktop = Mobil",
"description": "Ca utilizator pe desktop vreau ca meniul hamburger să aibă aceeași structură ca pe mobil",
"priority": 5,
"acceptanceCriteria": [
"În batchProgressStore.js, funcția restoreJobsFromBatch() include joburi cu status 'failed' (nu doar pending/processing)",
"Batch-ul NU este șters din localStorage dacă are joburi failed nerezolvate",
"După refresh, bonurile cu eroare sunt afișate în listă",
"unifiedItems computed include joburile failed pentru afișare",
"npm run build passes"
"Meniul desktop are secțiunile: PRINCIPALE, RAPOARTE, ANALIZE, ADMINISTRARE",
"Ordinea și itemii sunt identici cu MobileDrawerMenu",
"Stilul vizual este consistent (poate fi adaptat pentru desktop dar structura identică)",
"npm run build passes",
"Verify in browser desktop: meniul arată la fel ca pe mobil ca structură"
],
"passes": true,
"notes": "Completed in iteration 4"
"passes": false,
"notes": ""
},
{
"id": "US-406",
"title": "Fix UI Bonuri cu Eroare - Afișare Corectă pe Mobil",
"description": "Ca utilizator mobil vreau să văd clar că un bon are eroare, nu 'în procesare'",
"id": "US-506",
"title": "Fix MobileDrawerMenu - Deconectare Vizibil",
"description": "Ca utilizator pe mobil vreau să văd și să pot accesa butonul de Deconectare care este ascuns sub bara de navigare",
"priority": 6,
"acceptanceCriteria": [
"Bonurile cu status 'failed' afișează chip/badge 'Eroare' cu culoare roșie (var(--red-500))",
"NU afișează 'În procesare' sau spinner pentru bonuri failed",
"Mesajul de eroare este vizibil (truncat cu ellipsis dacă e prea lung)",
"Utilizatorul poate vedea eroarea completă la click/hover",
"Butonul 'Deconectare' este complet vizibil în drawer menu",
"Adăugat padding-bottom suficient pentru a nu fi acoperit de MobileBottomNav (min 72px)",
"Scroll funcționează corect dacă meniul este mai lung decât ecranul",
"npm run build passes",
"Verify in browser (375x667): Bon cu eroare arată 'Eroare' nu 'În procesare'"
"Verify in browser mobil (375x667): butonul Deconectare este vizibil și clickabil"
],
"passes": true,
"notes": "Completed in iteration 5"
"passes": false,
"notes": ""
},
{
"id": "US-407",
"title": "Fix Editare Bonuri cu Eroare",
"description": "Ca utilizator care are un bon cu eroare OCR vreau să pot edita bonul pentru a corecta erorile manual",
"id": "US-507",
"title": "Selecție Companie/Perioadă în MobileDrawerMenu",
"description": "Ca utilizator pe mobil vreau să pot selecta compania și perioada contabilă din drawer menu",
"priority": 7,
"acceptanceCriteria": [
"Click pe bon cu eroare deschide formularul de editare (ReceiptCreateUnifiedView)",
"La salvare, processing_status este resetat la NULL în baza de date",
"După salvare, bonul poate fi trimis pe workflow (Submit for Approval)",
"Backend endpoint PATCH /receipts/{id} resetează processing_status la NULL când se salvează modificări",
"MobileDrawerMenu include selector companie sub secțiunea profil",
"Selector perioadă contabilă disponibil lângă selector companie",
"Selectarea companiei/perioadei actualizează datele pe toate paginile (folosește store-urile existente)",
"Valorile selectate persistă între sesiuni (localStorage)",
"UI similar cu selectoarele din desktop header",
"npm run build passes",
"Verify in browser: Editează bon cu eroare → Salvează → Statusul nu mai arată eroare"
"Verify in browser mobil: pot schimba compania și perioada din drawer"
],
"passes": true,
"notes": "Completed in iteration 7"
"passes": false,
"notes": ""
},
{
"id": "US-408",
"title": "Verificare Finală - Toate Fix-urile Funcționează",
"description": "Ca developer vreau să confirm că toate fix-urile din Phase 4 funcționează corect",
"id": "US-508",
"title": "Selector Temă în MobileDrawerMenu (Dark/Light/Auto)",
"description": "Ca utilizator pe mobil vreau să pot schimba tema din drawer menu",
"priority": 8,
"acceptanceCriteria": [
"Viewport 375x667: Header desktop (Selectare perioada, AXN) NU este vizibil",
"Viewport 375x667: MobileTopBar cu butoane Filter/Export este vizibil",
"Click pe Meniu deschide MobileDrawerMenu cu secțiunea ANALIZE",
"Pagina Facturi: Tab-uri Clienți/Furnizori imediat sub header, fără spațiu blank",
"Pagina Bonuri: Status chips imediat sub header, fără spațiu blank",
"Upload bon cu eroare: Afișează 'Eroare' nu 'În procesare'",
"Refresh după upload cu eroare: Bonul cu eroare rămâne vizibil în listă",
"npm run build passes"
"Opțiune de schimbare temă în MobileDrawerMenu (lângă alte setări/footer)",
"Trei opțiuni: Light, Dark, Auto (system)",
"Schimbarea temei se aplică imediat",
"Preferința persistă în localStorage",
"Folosește themeStore existent",
"npm run build passes",
"Verify in browser mobil: tema se schimbă corect din drawer"
],
"passes": true,
"notes": "Completed in iteration 8"
"passes": false,
"notes": ""
},
{
"id": "US-509",
"title": "Fix Detailed Invoices - Grupuri Expandabile Desktop",
"description": "Ca utilizator pe desktop vreau ca grupurile de facturi per client/furnizor să se expandeze la click (acum funcționează doar pe mobil)",
"priority": 9,
"pages": [
"/reports/detailed-invoices/clients",
"/reports/detailed-invoices/suppliers"
],
"acceptanceCriteria": [
"Click pe un grup (client/furnizor) expandează/colapsează facturile individuale",
"Indicator vizual pentru expand/collapse (chevron icon care rotește)",
"Animație smooth la expand/collapse",
"Comportament identic cu versiunea mobilă",
"npm run build passes",
"Verify in browser desktop: grupurile se extind la click"
],
"passes": false,
"notes": ""
},
{
"id": "US-510",
"title": "Detailed Invoices - Eliminare Filtru Clienți/Furnizori",
"description": "Ca utilizator vreau ca filtrele din Facturi Detaliate să NU aibă selecția Clienți/Furnizori pentru că sunt pagini separate",
"priority": 10,
"pages": [
"/reports/detailed-invoices/clients",
"/reports/detailed-invoices/suppliers"
],
"acceptanceCriteria": [
"Pagina /reports/detailed-invoices/clients NU are dropdown Clienți/Furnizori în filtre",
"Pagina /reports/detailed-invoices/suppliers NU are dropdown Clienți/Furnizori în filtre",
"Tipul (clienți/furnizori) este determinat automat din URL/route params",
"npm run build passes",
"Verify in browser: filtrul Clienți/Furnizori nu mai apare"
],
"passes": false,
"notes": ""
},
{
"id": "US-511",
"title": "Detailed Invoices - Eliminare Buton Filtru Duplicat",
"description": "Ca utilizator vreau un singur buton de filtre în header, nu și deasupra tabelului",
"priority": 11,
"pages": [
"/reports/detailed-invoices/clients",
"/reports/detailed-invoices/suppliers"
],
"acceptanceCriteria": [
"Butonul de filtre apare DOAR în header (dreapta)",
"Eliminat butonul duplicat de deasupra tabelului",
"Funcționalitatea rămâne identică (deschide BottomSheet pe mobil, filtre pe desktop)",
"npm run build passes",
"Verify in browser: un singur buton de filtre"
],
"passes": false,
"notes": ""
},
{
"id": "US-512",
"title": "Detailed Invoices - Fix Overlay Butoane Ascunse",
"description": "Ca utilizator vreau ca în overlay-ul cu selecții să văd toate butoanele (Reset Filtre și Export sunt ascunse sub footer)",
"priority": 12,
"pages": [
"/reports/detailed-invoices/clients",
"/reports/detailed-invoices/suppliers"
],
"acceptanceCriteria": [
"Toate butoanele din overlay sunt vizibile",
"Butoanele nu sunt acoperite de footer",
"Scroll funcționează dacă conținutul e mare",
"Z-index corect pentru overlay vs footer",
"npm run build passes",
"Verify in browser: toate butoanele sunt vizibile în overlay"
],
"passes": false,
"notes": ""
},
{
"id": "US-513",
"title": "Analize Scadențe - Eliminare Secțiune Facturi Detaliate",
"description": "Ca utilizator vreau ca pagina Analize Scadențe să NU conțină secțiunea Facturi Detaliate pentru că sunt pagini separate",
"priority": 13,
"pages": [
"/reports/maturity"
],
"acceptanceCriteria": [
"Pagina /reports/maturity afișează DOAR analiza scadențelor",
"Secțiunea 'Facturi Detaliate' este eliminată complet din această pagină",
"Link-urile către Facturi Detaliate rămân în meniu (separate)",
"npm run build passes",
"Verify in browser: pagina conține doar scadențe"
],
"passes": false,
"notes": ""
},
{
"id": "US-514",
"title": "Fix Spațiu Blank Excesiv Top (Toate Paginile)",
"description": "Ca utilizator vreau ca paginile să nu aibă spațiu gol mare în partea de sus",
"priority": 14,
"acceptanceCriteria": [
"Identificat cauza spațiului blank (margin/padding excesiv)",
"Redus spațiul la maximum 16px între header și conținut",
"Verificate și corectate: Facturi, Balanță, Casă și Bancă, Facturi Detaliate, Scadențe, Bonuri",
"Layout-ul rămâne corect pe toate device-urile (mobil și desktop)",
"npm run build passes",
"Verify in browser: spațiul blank este eliminat pe toate paginile"
],
"passes": false,
"notes": ""
},
{
"id": "US-515",
"title": "Lista Bonuri - Meniu 'Bon Nou/Bulk Upload' Material Design",
"description": "Ca utilizator vreau ca meniul pentru Bon Nou și Bulk Upload să arate modern, Material Design (acum arată înghesuit)",
"priority": 15,
"pages": [
"/data-entry"
],
"acceptanceCriteria": [
"Meniul redesenat în stil Material Design 3",
"Spacing adecvat între opțiuni (min 44px touch targets)",
"Iconițe clare pentru fiecare opțiune (pi-plus pentru Bon Nou, pi-upload pentru Bulk)",
"Hover/active states vizibile cu feedback vizual",
"Animații smooth la deschidere/închidere",
"Folosește design tokens pentru spacing și culori",
"npm run build passes",
"Verify in browser: meniul arată modern și consistent"
],
"passes": false,
"notes": ""
},
{
"id": "US-516",
"title": "Lista Bonuri - Meniu Acțiuni Per Bon Material Design",
"description": "Ca utilizator vreau ca meniul de acțiuni pentru fiecare bon (⋮) să arate modern și consistent",
"priority": 16,
"pages": [
"/data-entry"
],
"acceptanceCriteria": [
"Meniul acțiuni (Vizualizare, Editare, Ștergere) redesenat MD3",
"Opțiuni cu iconițe și text clar",
"Touch targets min 44px",
"Divider între acțiuni normale și destructive (Ștergere)",
"Folosește design tokens",
"npm run build passes",
"Verify in browser: meniul arată modern"
],
"passes": false,
"notes": ""
},
{
"id": "US-517",
"title": "Lista Bonuri Desktop - Dialog Ștergere Material Design",
"description": "Ca utilizator pe desktop vreau ca dialogul de confirmare ștergere să arate modern (acum arată înghesuit)",
"priority": 17,
"pages": [
"/data-entry"
],
"acceptanceCriteria": [
"Dialog redesenat în stil Material Design 3",
"Titlu clar: 'Șterge bonul?'",
"Mesaj descriptiv cu detalii bon (magazin, sumă)",
"Butoane: 'Anulează' (secondary) și 'Șterge' (danger/severity)",
"Spacing și padding corespunzătoare (folosește design tokens)",
"npm run build passes",
"Verify in browser: dialogul arată modern"
],
"passes": false,
"notes": ""
},
{
"id": "US-518",
"title": "Creare/Vizualizare/Editare Bon - Butoane Doar Sus",
"description": "Ca utilizator vreau ca în paginile de creare, vizualizare și editare bon, butoanele să fie DOAR în partea de sus",
"priority": 18,
"pages": [
"/data-entry/receipts/new",
"/data-entry/receipts/:id",
"/data-entry/receipts/:id/edit"
],
"acceptanceCriteria": [
"Pagina creare bon: butoane (Salvează, Anulează) doar în header/top",
"Pagina vizualizare bon: butoane (Editează, Șterge, Înapoi) doar în header/top",
"Pagina editare bon: butoane (Salvează, Anulează) doar în header/top",
"Eliminate butoanele din footer/body dacă există",
"Pe mobil: butoanele sunt în MobileTopBar actions",
"Pe desktop: butoanele sunt în header dreapta",
"npm run build passes",
"Verify in browser: butoane doar în header pe toate cele 3 pagini"
],
"passes": false,
"notes": ""
},
{
"id": "US-519",
"title": "Separare Casă și Bancă în Pagini Distincte",
"description": "Ca utilizator vreau ca Casă și Bancă să fie pagini separate (nu combinate) pentru navigare mai clară",
"priority": 19,
"pages": [
"/reports/cash",
"/reports/bank"
],
"acceptanceCriteria": [
"Pagină separată pentru Casă: /reports/cash",
"Pagină separată pentru Bancă: /reports/bank",
"Fiecare pagină are propriul titlu (Casă / Bancă)",
"Meniul hamburger (desktop și mobil) are intrări separate pentru Casă și Bancă",
"MobileDrawerMenu actualizat cu linkuri separate în secțiunea RAPOARTE",
"Rutele vechi /reports/cash-bank redirect către /reports/cash sau sunt eliminate",
"Filtrele și exportul funcționează independent pe fiecare pagină",
"Backend: endpoint-uri separate sau parametru pentru a filtra cash vs bank",
"npm run build passes",
"Verify in browser desktop: Casă și Bancă sunt pagini separate accesibile din meniu",
"Verify in browser mobil: Casă și Bancă sunt pagini separate în MobileDrawerMenu"
],
"passes": false,
"notes": ""
}
]
}

View File

@@ -1,52 +1,78 @@
# Ralph Progress Log - Phase 4
# Ralph Progress Log
## ══════════════════════════════════════════════════════════════
## Phase 4: Mobile Fixes (COMPLETED ✓)
## ══════════════════════════════════════════════════════════════
Started: Mon Jan 12 06:34:18 PM UTC 2026
Completed: Mon Jan 12 07:58:17 PM UTC 2026
Project: mobile-fixes-phase4
Branch: ralph/unified-mobile-md
Stories: 8 (US-401 to US-408)
Stories: 8/8 completed (US-401 to US-408)
Summary:
- US-401: Fixed desktop header hidden on mobile ✓
- US-402: MobileTopBar buttons visible ✓
- US-403: MobileDrawerMenu ANALIZE section ✓
- US-404: Fixed blank space top padding ✓
- US-405: batchProgressStore restores failed jobs ✓
- US-406: Error receipts show "Eroare" badge ✓
- US-407: Edit receipts with errors works ✓
- US-408: Final verification ✓
---
[2026-01-12 18:35:51] Starting Ralph for project: mobile-fixes-phase4
[2026-01-12 18:35:51] Max iterations: 50
[2026-01-12 18:35:51] === Iteration 1/50 ===
[2026-01-12 18:35:51] Working on story: US-401
[2026-01-12 18:35:51] Running Claude... (log: /workspace/roa2web/scripts/ralph/logs/iteration_1_US-401.log)
[2026-01-12 18:45:30] SUCCESS: Story US-401 passed!
[2026-01-12 18:45:30] Changes committed
[2026-01-12 18:45:30] Progress: 1/8 stories completed
[2026-01-12 18:45:32] === Iteration 2/50 ===
[2026-01-12 18:45:32] Working on story: US-402
[2026-01-12 18:45:32] Running Claude... (log: /workspace/roa2web/scripts/ralph/logs/iteration_2_US-402.log)
[2026-01-12 19:23:19] Story US-402 not yet complete, continuing...
[2026-01-12 19:23:19] Progress: 3/8 stories completed
[2026-01-12 19:23:21] === Iteration 3/50 ===
[2026-01-12 19:23:21] Working on story: US-403
[2026-01-12 19:23:21] Running Claude... (log: /workspace/roa2web/scripts/ralph/logs/iteration_3_US-403.log)
[2026-01-12 19:27:05] SUCCESS: Story US-403 passed!
[2026-01-12 19:27:05] Changes committed
[2026-01-12 19:27:05] Progress: 4/8 stories completed
[2026-01-12 19:27:07] === Iteration 4/50 ===
[2026-01-12 19:27:07] Working on story: US-405
[2026-01-12 19:27:07] Running Claude... (log: /workspace/roa2web/scripts/ralph/logs/iteration_4_US-405.log)
[2026-01-12 19:31:08] SUCCESS: Story US-405 passed!
[2026-01-12 19:31:09] Changes committed
[2026-01-12 19:31:09] Progress: 5/8 stories completed
[2026-01-12 19:31:11] === Iteration 5/50 ===
[2026-01-12 19:31:11] Working on story: US-406
[2026-01-12 19:31:11] Running Claude... (log: /workspace/roa2web/scripts/ralph/logs/iteration_5_US-406.log)
[2026-01-12 19:36:45] SUCCESS: Story US-406 passed!
[2026-01-12 19:36:45] Changes committed
[2026-01-12 19:36:45] Progress: 6/8 stories completed
[2026-01-12 19:36:47] === Iteration 6/50 ===
[2026-01-12 19:36:47] Working on story: US-407
[2026-01-12 19:36:47] Running Claude... (log: /workspace/roa2web/scripts/ralph/logs/iteration_6_US-407.log)
[2026-01-12 19:47:56] Story US-407 not yet complete, continuing...
[2026-01-12 19:47:56] Progress: 6/8 stories completed
[2026-01-12 19:47:58] === Iteration 7/50 ===
[2026-01-12 19:47:58] Working on story: US-407
[2026-01-12 19:47:58] Running Claude... (log: /workspace/roa2web/scripts/ralph/logs/iteration_7_US-407.log)
[2026-01-12 19:52:43] SUCCESS: Story US-407 passed!
[2026-01-12 19:52:43] Changes committed
[2026-01-12 19:52:43] Progress: 7/8 stories completed
[2026-01-12 19:52:45] === Iteration 8/50 ===
[2026-01-12 19:52:45] Working on story: US-408
[2026-01-12 19:52:45] Running Claude... (log: /workspace/roa2web/scripts/ralph/logs/iteration_8_US-408.log)
[2026-01-12 19:58:15] SUCCESS: Story US-408 passed!
## ══════════════════════════════════════════════════════════════
## Phase 5: Unified Mobile & Desktop UI (IN PROGRESS)
## ══════════════════════════════════════════════════════════════
Started: Sun Jan 12 21:30:00 UTC 2026
Project: unified-mobile-desktop-ui
Branch: ralph/unified-mobile-md (continuing)
Stories: 18 total (US-501 to US-518)
PRD: tasks/prd-unified-mobile-desktop-ui.md
Design Reference: src/modules/reports/views/InvoicesView.vue
### Stories Overview:
**Header Actions (1-3):**
- [ ] US-501: Header Actions Bar - Rapoarte (5 pages: trial-balance, cash-bank, detailed-invoices/clients, detailed-invoices/suppliers, maturity)
- [ ] US-502: Header Actions Bar - Lista Bonuri
- [ ] US-503: BottomSheet Filtre - Lista Bonuri (mobil)
**Backend & Export (4):**
- [ ] US-504: Fix Export Endpoints Backend (PDF/XLSX)
**Meniu & Navigare (5-8):**
- [ ] US-505: Meniu Hamburger Desktop = Mobil (structură identică)
- [ ] US-506: Fix MobileDrawerMenu - Deconectare Vizibil
- [ ] US-507: Selecție Companie/Perioadă în MobileDrawerMenu
- [ ] US-508: Selector Temă în MobileDrawerMenu
**Detailed Invoices Fixes (9-12):**
- [ ] US-509: Fix Grupuri Expandabile Desktop
- [ ] US-510: Eliminare Filtru Clienți/Furnizori
- [ ] US-511: Eliminare Buton Filtru Duplicat
- [ ] US-512: Fix Overlay Butoane Ascunse
**Cleanup (13-14):**
- [ ] US-513: Analize Scadențe - Eliminare Secțiune Facturi Detaliate
- [ ] US-514: Fix Spațiu Blank Excesiv Top (toate paginile)
**Material Design Styling (15-18):**
- [ ] US-515: Lista Bonuri - Meniu Bon Nou/Bulk Upload MD3
- [ ] US-516: Lista Bonuri - Meniu Acțiuni Per Bon MD3
- [ ] US-517: Lista Bonuri Desktop - Dialog Ștergere MD3
- [ ] US-518: Creare/Vizualizare/Editare Bon - Butoane Doar Sus
**Separare Rapoarte (19):**
- [ ] US-519: Separare Casă și Bancă în Pagini Distincte (/reports/cash, /reports/bank)
---
### Iteration Log:
[2026-01-12 22:09:40] Starting Ralph for project: unified-mobile-desktop-ui
[2026-01-12 22:09:40] Max iterations: 100
[2026-01-12 22:09:40] === Iteration 1/100 ===
[2026-01-12 22:09:40] Working on story: US-501
[2026-01-12 22:09:40] Running Claude... (log: /workspace/roa2web/scripts/ralph/logs/iteration_1_US-501.log)
[2026-01-12 22:16:53] SUCCESS: Story US-501 passed!

View File

@@ -1,6 +1,6 @@
<template>
<div class="app-container" :class="{ 'mobile-layout': isMobile }">
<!-- US-109: Mobile Material Design Top Bar -->
<!-- US-501: Mobile Material Design Top Bar -->
<MobileTopBar
v-if="isMobile"
title="Trezorerie"
@@ -10,6 +10,9 @@
@action-click="handleTopBarAction"
/>
<!-- US-501: Export Menu (for mobile export dropdown) -->
<Menu ref="exportMenu" :model="exportMenuItems" :popup="true" />
<!-- Mobile Drawer Menu (replaces old Sidebar) -->
<MobileDrawerMenu
v-model="showDrawer"
@@ -177,7 +180,7 @@
</div>
</div>
<!-- Desktop: Action buttons -->
<!-- US-501: Desktop Action buttons with Export dropdown -->
<div v-if="!isMobile" class="form-actions">
<Button
icon="pi pi-filter-slash"
@@ -185,18 +188,12 @@
class="p-button-outlined p-button-secondary"
@click="resetFilters"
/>
<Button
icon="pi pi-file-excel"
label="Export Excel"
class="p-button-outlined p-button-success"
@click="exportExcel"
:disabled="!hasData"
/>
<Button
icon="pi pi-file-pdf"
label="Export PDF"
class="p-button-outlined p-button-danger"
<SplitButton
label="Export"
icon="pi pi-download"
:model="desktopExportItems"
@click="exportPDF"
class="p-button-outlined"
:disabled="!hasData"
/>
<Button
@@ -395,11 +392,13 @@ import { useAccountingPeriodStore } from "@reports/stores/sharedStores";
import { format } from "date-fns";
import { exportToExcel, exportBankCashRegisterPDF } from "@reports/utils/exportUtils";
// US-109: Mobile Material Design components
// US-501: Mobile Material Design components
import MobileTopBar from "@shared/components/mobile/MobileTopBar.vue";
import MobileBottomNav from "@shared/components/mobile/MobileBottomNav.vue";
import BottomSheet from "@shared/components/mobile/BottomSheet.vue";
import MobileDrawerMenu from "@shared/components/mobile/MobileDrawerMenu.vue";
import Menu from "primevue/menu";
import SplitButton from "primevue/splitbutton";
import { useRouter } from "vue-router";
const toast = useToast();
@@ -424,7 +423,7 @@ const handleLogout = async () => {
router.push('/login');
};
// US-109: Mobile TopBar actions (filter, refresh, export)
// US-501: Mobile TopBar actions (filter, reset, export dropdown)
const mobileTopBarActions = computed(() => [
{
icon: "pi pi-filter",
@@ -433,25 +432,54 @@ const mobileTopBarActions = computed(() => [
active: hasActiveFilters.value
},
{
icon: "pi pi-refresh",
label: "Actualizează",
tooltip: "Actualizează"
icon: "pi pi-filter-slash",
label: "Resetează",
tooltip: "Resetează Filtrele"
},
{
icon: "pi pi-download",
label: "Export",
tooltip: "Export Excel"
tooltip: "Export"
}
]);
// US-109: Handle top bar action clicks
const handleTopBarAction = (action) => {
// US-501: Export menu ref for mobile
const exportMenu = ref(null);
const exportMenuItems = ref([
{
label: "Export PDF",
icon: "pi pi-file-pdf",
command: () => exportPDF()
},
{
label: "Export XLSX",
icon: "pi pi-file-excel",
command: () => exportExcel()
}
]);
// US-501: Desktop export dropdown items (SplitButton)
const desktopExportItems = ref([
{
label: "Export PDF",
icon: "pi pi-file-pdf",
command: () => exportPDF()
},
{
label: "Export XLSX",
icon: "pi pi-file-excel",
command: () => exportExcel()
}
]);
// US-501: Handle top bar action clicks
const handleTopBarAction = (action, event) => {
if (action.icon === "pi pi-filter") {
showFilters.value = !showFilters.value;
} else if (action.icon === "pi pi-refresh") {
refreshData();
} else if (action.icon === "pi pi-filter-slash") {
resetFilters();
} else if (action.icon === "pi pi-download") {
exportExcel();
exportMenu.value.toggle(event);
}
};

View File

@@ -1,5 +1,5 @@
<template>
<!-- Mobile Top Bar -->
<!-- US-501: Mobile Top Bar -->
<MobileTopBar
v-if="isMobile"
title="Facturi Detaliate"
@@ -9,6 +9,9 @@
@action-click="handleTopBarAction"
/>
<!-- US-501: Export Menu (for mobile export dropdown) -->
<Menu ref="exportMenu" :model="exportMenuItems" :popup="true" />
<main class="main-content" :class="{ 'mobile-layout': isMobile }">
<div class="app-container">
<!-- Page Header - only on desktop -->
@@ -71,6 +74,7 @@
/>
</div>
</div>
<!-- US-501: Desktop Action buttons with Export dropdown -->
<div class="filters-actions">
<Button
icon="pi pi-filter-slash"
@@ -79,20 +83,12 @@
outlined
@click="resetFilters"
/>
<Button
icon="pi pi-file-excel"
label="Export Excel"
severity="success"
outlined
@click="exportExcel"
:disabled="filteredData.length === 0"
/>
<Button
icon="pi pi-file-pdf"
label="Export PDF"
severity="danger"
outlined
<SplitButton
label="Export"
icon="pi pi-download"
:model="desktopExportItems"
@click="exportPDF"
outlined
:disabled="filteredData.length === 0"
/>
<Button
@@ -424,6 +420,8 @@ import { useToast } from 'primevue/usetoast'
import MobileTopBar from '@shared/components/mobile/MobileTopBar.vue'
import MobileBottomNav from '@shared/components/mobile/MobileBottomNav.vue'
import BottomSheet from '@shared/components/mobile/BottomSheet.vue'
import Menu from 'primevue/menu'
import SplitButton from 'primevue/splitbutton'
import { useDashboardStore } from '@reports/stores/dashboard'
import { useCompanyStore, useAccountingPeriodStore } from '@reports/stores/sharedStores'
import * as XLSX from 'xlsx'
@@ -472,13 +470,59 @@ const periodOptions = [
{ label: '12 luni', value: '12m' }
]
// Top bar actions for mobile
// US-501: Check if filters have non-default values
const hasActiveFilters = computed(() => {
return searchTerm.value !== '' ||
selectedPeriod.value !== 'all' ||
selectedType.value !== 'clients'
})
// US-501: Mobile TopBar actions (filter, reset, export dropdown)
const topBarActions = computed(() => [
{
icon: 'pi pi-filter',
label: 'Filtre',
tooltip: 'Deschide filtre',
active: searchTerm.value || selectedPeriod.value !== 'all'
active: hasActiveFilters.value
},
{
icon: 'pi pi-filter-slash',
label: 'Resetează',
tooltip: 'Resetează Filtrele'
},
{
icon: 'pi pi-download',
label: 'Export',
tooltip: 'Export'
}
])
// US-501: Export menu ref for mobile
const exportMenu = ref(null)
const exportMenuItems = ref([
{
label: 'Export PDF',
icon: 'pi pi-file-pdf',
command: () => exportPDF()
},
{
label: 'Export XLSX',
icon: 'pi pi-file-excel',
command: () => exportExcel()
}
])
// US-501: Desktop export dropdown items (SplitButton)
const desktopExportItems = ref([
{
label: 'Export PDF',
icon: 'pi pi-file-pdf',
command: () => exportPDF()
},
{
label: 'Export XLSX',
icon: 'pi pi-file-excel',
command: () => exportExcel()
}
])
@@ -598,10 +642,14 @@ const goBack = () => {
router.push('/reports/dashboard')
}
// Top bar action handler
const handleTopBarAction = (action) => {
// US-501: Top bar action handler
const handleTopBarAction = (action, event) => {
if (action.icon === 'pi pi-filter') {
openFilters()
} else if (action.icon === 'pi pi-filter-slash') {
resetFilters()
} else if (action.icon === 'pi pi-download') {
exportMenu.value.toggle(event)
}
}

View File

@@ -1,5 +1,5 @@
<template>
<!-- Mobile Top Bar - US-306: Added Export and Filter actions -->
<!-- US-501: Mobile Top Bar with unified header actions -->
<MobileTopBar
v-if="isMobile"
title="Scadențe"
@@ -9,6 +9,9 @@
@action-click="handleTopBarAction"
/>
<!-- US-501: Export Menu (for mobile export dropdown) -->
<Menu ref="exportMenu" :model="exportMenuItems" :popup="true" />
<!-- US-306: Filter BottomSheet for mobile -->
<BottomSheet v-model="showFilters">
<h3 class="bottom-sheet-title">Filtre</h3>
@@ -124,6 +127,7 @@ import Dropdown from 'primevue/dropdown'
import MobileTopBar from '@shared/components/mobile/MobileTopBar.vue'
import MobileBottomNav from '@shared/components/mobile/MobileBottomNav.vue'
import BottomSheet from '@shared/components/mobile/BottomSheet.vue'
import Menu from 'primevue/menu'
import MaturityAndDetailsCard from '@reports/components/dashboard/cards/MaturityAndDetailsCard.vue'
import { useCompanyStore } from '@reports/stores/sharedStores'
@@ -167,7 +171,7 @@ const hasActiveFilters = computed(() => {
return filterPeriod.value !== '1m' || filterType.value !== 'clients'
})
// US-306: Mobile TopBar actions (Export + Filter)
// US-501: Mobile TopBar actions (filter, reset, export dropdown)
const mobileTopBarActions = computed(() => [
{
icon: 'pi pi-filter',
@@ -175,15 +179,43 @@ const mobileTopBarActions = computed(() => [
tooltip: 'Filtre',
active: hasActiveFilters.value
},
{
icon: 'pi pi-filter-slash',
label: 'Resetează',
tooltip: 'Resetează Filtrele'
},
{
icon: 'pi pi-download',
label: 'Export',
tooltip: 'Export Excel'
tooltip: 'Export'
}
])
// US-306: Handle top bar action clicks
const handleTopBarAction = (action) => {
// US-501: Export menu ref for mobile
const exportMenu = ref(null)
const exportMenuItems = ref([
{
label: 'Export PDF',
icon: 'pi pi-file-pdf',
command: () => {
if (maturityCardRef.value) {
maturityCardRef.value.exportPDF()
}
}
},
{
label: 'Export XLSX',
icon: 'pi pi-file-excel',
command: () => {
if (maturityCardRef.value) {
maturityCardRef.value.exportExcel()
}
}
}
])
// US-501: Handle top bar action clicks
const handleTopBarAction = (action, event) => {
if (action.icon === 'pi pi-filter') {
// Sync current values from child component before opening
if (maturityCardRef.value) {
@@ -191,11 +223,10 @@ const handleTopBarAction = (action) => {
filterType.value = maturityCardRef.value.selectedType
}
showFilters.value = !showFilters.value
} else if (action.icon === 'pi pi-filter-slash') {
resetFilters()
} else if (action.icon === 'pi pi-download') {
// Trigger export from child component
if (maturityCardRef.value) {
maturityCardRef.value.exportExcel()
}
exportMenu.value.toggle(event)
}
}

View File

@@ -1,6 +1,6 @@
<template>
<div class="app-container" :class="{ 'mobile-layout': isMobile }">
<!-- US-108: Mobile Material Design Top Bar -->
<!-- US-501: Mobile Material Design Top Bar -->
<MobileTopBar
v-if="isMobile"
title="Balanță de Verificare"
@@ -10,6 +10,9 @@
@action-click="handleTopBarAction"
/>
<!-- US-501: Export Menu (for mobile export dropdown) -->
<Menu ref="exportMenu" :model="exportMenuItems" :popup="true" />
<!-- Mobile Drawer Menu (replaces old Sidebar) -->
<MobileDrawerMenu
v-model="showDrawer"
@@ -137,7 +140,7 @@
</div>
</div>
<!-- Desktop: Action buttons -->
<!-- US-501: Desktop Action buttons with Export dropdown -->
<div v-if="!isMobile" class="form-actions">
<Button
icon="pi pi-filter-slash"
@@ -145,18 +148,12 @@
class="p-button-outlined p-button-secondary"
@click="clearFilters"
/>
<Button
icon="pi pi-file-excel"
label="Export Excel"
class="p-button-outlined p-button-success"
@click="exportExcel"
:disabled="!trialBalanceStore.hasData"
/>
<Button
icon="pi pi-file-pdf"
label="Export PDF"
class="p-button-outlined p-button-danger"
<SplitButton
label="Export"
icon="pi pi-download"
:model="desktopExportItems"
@click="exportPDF"
class="p-button-outlined"
:disabled="!trialBalanceStore.hasData"
/>
<Button
@@ -373,11 +370,13 @@ import { useTrialBalanceStore } from "@reports/stores/trialBalance";
import { useAccountingPeriodStore } from "@reports/stores/sharedStores";
import { exportToExcel, exportToPDF } from "@reports/utils/exportUtils";
// US-108: Mobile Material Design components
// US-501: Mobile Material Design components
import MobileTopBar from "@shared/components/mobile/MobileTopBar.vue";
import MobileBottomNav from "@shared/components/mobile/MobileBottomNav.vue";
import BottomSheet from "@shared/components/mobile/BottomSheet.vue";
import MobileDrawerMenu from "@shared/components/mobile/MobileDrawerMenu.vue";
import Menu from "primevue/menu";
import SplitButton from "primevue/splitbutton";
import { useRouter } from "vue-router";
const toast = useToast();
@@ -402,7 +401,7 @@ const handleLogout = async () => {
router.push('/login');
};
// US-108: Mobile TopBar actions (filter + export)
// US-501: Mobile TopBar actions (filter, reset, export dropdown handled via menu)
const mobileTopBarActions = computed(() => [
{
icon: "pi pi-filter",
@@ -410,19 +409,55 @@ const mobileTopBarActions = computed(() => [
tooltip: "Filtre",
active: hasActiveFilters.value
},
{
icon: "pi pi-filter-slash",
label: "Resetează",
tooltip: "Resetează Filtrele"
},
{
icon: "pi pi-download",
label: "Export",
tooltip: "Export Excel"
tooltip: "Export"
}
]);
// US-108: Handle top bar action clicks
const handleTopBarAction = (action) => {
// US-501: Export menu ref for mobile
const exportMenu = ref(null);
const exportMenuItems = ref([
{
label: "Export PDF",
icon: "pi pi-file-pdf",
command: () => exportPDF()
},
{
label: "Export XLSX",
icon: "pi pi-file-excel",
command: () => exportExcel()
}
]);
// US-501: Desktop export dropdown items (SplitButton)
const desktopExportItems = ref([
{
label: "Export PDF",
icon: "pi pi-file-pdf",
command: () => exportPDF()
},
{
label: "Export XLSX",
icon: "pi pi-file-excel",
command: () => exportExcel()
}
]);
// US-501: Handle top bar action clicks
const handleTopBarAction = (action, event) => {
if (action.icon === "pi pi-filter") {
showFilters.value = !showFilters.value;
} else if (action.icon === "pi pi-filter-slash") {
clearFilters();
} else if (action.icon === "pi pi-download") {
exportExcel();
exportMenu.value.toggle(event);
}
};

View File

@@ -35,7 +35,7 @@
rounded
class="top-bar-btn"
:class="{ 'active': action.active }"
@click="$emit('action-click', action)"
@click="(e) => $emit('action-click', action, e)"
:aria-label="action.label || action.icon"
v-tooltip.bottom="action.tooltip"
/>

View File

@@ -0,0 +1,451 @@
# PRD: Unified Mobile & Desktop UI Improvements
## 1. Introducere
Acest PRD acoperă îmbunătățirile necesare pentru a unifica experiența UI între mobil și desktop, rezolvând inconsistențe de design, bugs și funcționalități lipsă. Referința de design este pagina `/reports/invoices` care implementează corect pattern-urile Material Design 3.
**Branch**: `ralph/unified-mobile-md` (continuare)
## 2. Obiective
### Obiectiv Principal
- Unificarea UI/UX între toate paginile (rapoarte, bonuri, analize) cu un design consistent Material Design 3
### Obiective Secundare
- Fix bugs existente (grupuri neexpandabile, butoane ascunse, export cu erori)
- Adăugare funcționalități lipsă pe mobil (selecție companie/perioadă, temă)
- Eliminare duplicări și inconsistențe în plasarea butoanelor
### Metrici de Succes
- Toate paginile au aceleași pattern-uri pentru header actions (filtre, reset, export)
- Export PDF/XLSX funcțional pe toate paginile
- Meniu hamburger identic pe desktop și mobil
- Zero bugs vizuale (butoane ascunse, spații blank excesive)
## 3. User Stories
---
### US-501: Header Actions Bar Unificat - Rapoarte
**Ca** utilizator
**Vreau** să am butoane de Filtre, Reset Filtre și Export (PDF/XLSX dropdown) în header-ul din dreapta pe toate rapoartele
**Pentru că** să am acces rapid și consistent la aceste funcții
**Pagini afectate**:
- `/reports/invoices` (referință - deja implementat parțial)
- `/reports/trial-balance` (Balanță)
- `/reports/cash-bank` (Casă și Bancă)
- `/reports/detailed-invoices/clients` (Facturi Detaliate Clienți)
- `/reports/detailed-invoices/suppliers` (Facturi Detaliate Furnizori)
- `/reports/maturity` (Analize Scadențe)
**Acceptance Criteria:**
- [ ] Fiecare pagină are în header dreapta: [Filter icon] [Reset icon] [Export dropdown]
- [ ] Export dropdown conține: "Export PDF" și "Export XLSX"
- [ ] Butonul Filter are indicator vizual (active) când filtrele sunt aplicate
- [ ] Butonul Reset resetează toate filtrele la valori implicite
- [ ] Pe mobil, acțiunile sunt în MobileTopBar actions
- [ ] Pe desktop, acțiunile sunt într-un grup în header dreapta
- [ ] npm run typecheck passes
- [ ] Verify in browser: butoanele funcționează pe desktop și mobil
---
### US-502: Header Actions Bar Unificat - Lista Bonuri
**Ca** utilizator
**Vreau** să am butoane de Filtre, Reset Filtre și Export în header-ul listei de bonuri
**Pentru că** să fie consistent cu celelalte pagini
**Acceptance Criteria:**
- [ ] Lista bonuri (`/data-entry`) are în header: [Filter] [Reset] [Export dropdown]
- [ ] Stilul butoanelor este identic cu cel din `/reports/invoices`
- [ ] Export dropdown: "Export PDF" și "Export XLSX"
- [ ] Butoanele vechi "Filtrează" și "Resetează" sunt înlocuite cu noul pattern
- [ ] npm run typecheck passes
- [ ] Verify in browser: butoanele au același aspect ca pe pagina Facturi
---
### US-503: BottomSheet Filtre pentru Lista Bonuri (Mobil)
**Ca** utilizator pe mobil
**Vreau** ca filtrele din lista de bonuri să se deschidă într-un BottomSheet
**Pentru că** să fie consistent cu Facturi, Balanță, Casă și Bancă
**Acceptance Criteria:**
- [ ] Click pe butonul Filter deschide BottomSheet (nu inline filters)
- [ ] BottomSheet conține toate filtrele existente (status, dată, etc.)
- [ ] BottomSheet are butoane "Resetează" și "Aplică" în footer
- [ ] Swipe-down sau tap outside închide BottomSheet
- [ ] npm run typecheck passes
- [ ] Verify in browser mobil: filtrele apar în BottomSheet
---
### US-504: Fix Export Endpoints Backend
**Ca** utilizator
**Vreau** ca exportul PDF/XLSX să funcționeze fără erori
**Pentru că** să pot descărca rapoartele
**Acceptance Criteria:**
- [ ] Identificate și fixate erorile din endpoint-urile de export existente
- [ ] Export PDF funcțional pentru: Facturi, Balanță, Casă și Bancă, Facturi Detaliate, Scadențe, Bonuri
- [ ] Export XLSX funcțional pentru aceleași pagini
- [ ] Exportul include DOAR datele filtrate (nu toate)
- [ ] npm run typecheck passes
- [ ] Verify in browser: descărcare PDF și XLSX reușită
---
### US-505: Meniu Hamburger Desktop = Mobil
**Ca** utilizator pe desktop
**Vreau** ca meniul hamburger să aibă aceeași structură ca pe mobil
**Pentru că** să am acces la toate opțiunile indiferent de dispozitiv
**Acceptance Criteria:**
- [ ] Meniul desktop are secțiunile: PRINCIPALE, RAPOARTE, ANALIZE, ADMINISTRARE
- [ ] Ordinea și itemii sunt identici cu MobileDrawerMenu
- [ ] Stilul vizual este consistent (poate fi adaptat pentru desktop dar structura identică)
- [ ] npm run typecheck passes
- [ ] Verify in browser desktop: meniul arată la fel ca pe mobil
---
### US-506: Fix MobileDrawerMenu - Deconectare Vizibil
**Ca** utilizator pe mobil
**Vreau** să văd și să pot accesa butonul de Deconectare
**Pentru că** acum este ascuns sub bara de navigare din footer
**Acceptance Criteria:**
- [ ] Butonul "Deconectare" este complet vizibil în drawer menu
- [ ] Adăugat padding-bottom suficient pentru a nu fi acoperit de MobileBottomNav
- [ ] Scroll funcționează corect dacă meniul este mai lung decât ecranul
- [ ] npm run typecheck passes
- [ ] Verify in browser mobil: butonul Deconectare este vizibil și clickabil
---
### US-507: Selecție Companie/Perioadă pe Mobil
**Ca** utilizator pe mobil
**Vreau** să pot selecta compania și perioada contabilă
**Pentru că** acum această funcționalitate lipsește complet pe mobil
**Acceptance Criteria:**
- [ ] MobileDrawerMenu sau MobileTopBar include selector companie
- [ ] Selector perioadă contabilă disponibil
- [ ] Selectarea companiei/perioadei actualizează datele pe toate paginile
- [ ] Valorile selectate persistă între sesiuni
- [ ] npm run typecheck passes
- [ ] Verify in browser mobil: pot schimba compania și perioada
---
### US-508: Selector Temă pe Mobil (Dark/Light/Auto)
**Ca** utilizator pe mobil
**Vreau** să pot schimba tema (dark/light/auto)
**Pentru că** acum această opțiune lipsește pe mobil
**Acceptance Criteria:**
- [ ] Opțiune de schimbare temă în MobileDrawerMenu sau Setări
- [ ] Trei opțiuni: Light, Dark, Auto (system)
- [ ] Schimbarea temei se aplică imediat
- [ ] Preferința persistă în localStorage
- [ ] npm run typecheck passes
- [ ] Verify in browser mobil: tema se schimbă corect
---
### US-509: Fix Detailed Invoices - Grupuri Expandabile Desktop
**Ca** utilizator pe desktop
**Vreau** ca grupurile de facturi per client/furnizor să se expandeze la click
**Pentru că** acum funcționează doar pe mobil
**Acceptance Criteria:**
- [ ] Click pe un grup (client/furnizor) expandează/colapsează facturile
- [ ] Indicator vizual pentru expand/collapse (chevron icon)
- [ ] Animație smooth la expand/collapse
- [ ] Comportament identic cu versiunea mobilă
- [ ] npm run typecheck passes
- [ ] Verify in browser desktop: grupurile se extind la click
---
### US-510: Detailed Invoices - Eliminare Filtru Clienți/Furnizori
**Ca** utilizator
**Vreau** ca filtrele din Facturi Detaliate să NU aibă selecția Clienți/Furnizori
**Pentru că** sunt deja pagini separate (`/clients` și `/suppliers`)
**Acceptance Criteria:**
- [ ] Pagina `/reports/detailed-invoices/clients` NU are dropdown Clienți/Furnizori în filtre
- [ ] Pagina `/reports/detailed-invoices/suppliers` NU are dropdown Clienți/Furnizori în filtre
- [ ] Tipul (clienți/furnizori) este determinat automat din URL
- [ ] npm run typecheck passes
- [ ] Verify in browser: filtrul Clienți/Furnizori nu mai apare
---
### US-511: Detailed Invoices - Eliminare Buton Filtru Duplicat
**Ca** utilizator
**Vreau** să am un singur buton de filtre (în header)
**Pentru că** acum există și în header și deasupra tabelului
**Acceptance Criteria:**
- [ ] Butonul de filtre apare DOAR în header (dreapta)
- [ ] Eliminat butonul duplicat de deasupra tabelului
- [ ] Funcționalitatea rămâne identică
- [ ] npm run typecheck passes
- [ ] Verify in browser: un singur buton de filtre
---
### US-512: Detailed Invoices - Fix Overlay Butoane Ascunse
**Ca** utilizator
**Vreau** ca în overlay-ul cu selecții să văd toate butoanele
**Pentru că** acum Reset Filtre și Export sunt ascunse sub footer
**Acceptance Criteria:**
- [ ] Toate butoanele din overlay sunt vizibile
- [ ] Butoanele nu sunt acoperite de footer
- [ ] Scroll funcționează dacă conținutul e mare
- [ ] Z-index corect pentru overlay vs footer
- [ ] npm run typecheck passes
- [ ] Verify in browser: toate butoanele sunt vizibile în overlay
---
### US-513: Analize Scadențe - Eliminare Secțiune Facturi Detaliate
**Ca** utilizator
**Vreau** ca pagina Analize Scadențe să NU conțină secțiunea Facturi Detaliate
**Pentru că** sunt pagini separate
**Acceptance Criteria:**
- [ ] Pagina `/reports/maturity` afișează DOAR analiza scadențelor
- [ ] Secțiunea "Facturi Detaliate" este eliminată complet
- [ ] Link-urile către Facturi Detaliate rămân în meniu
- [ ] npm run typecheck passes
- [ ] Verify in browser: pagina conține doar scadențe
---
### US-514: Fix Spațiu Blank Excesiv Top (Toate Paginile)
**Ca** utilizator
**Vreau** ca paginile să NU aibă spațiu gol mare în partea de sus
**Pentru că** ocupă ecran inutil
**Acceptance Criteria:**
- [ ] Identificat cauza spațiului blank (margin/padding excesiv)
- [ ] Redus spațiul la maximum 16px între header și conținut
- [ ] Toate paginile verificate și corectate
- [ ] Layout-ul rămâne corect pe toate device-urile
- [ ] npm run typecheck passes
- [ ] Verify in browser: spațiul blank este eliminat
---
### US-515: Lista Bonuri - Meniu "Bon Nou/Bulk Upload" Material Design
**Ca** utilizator
**Vreau** ca meniul pentru Bon Nou și Bulk Upload să arate modern, Material Design
**Pentru că** acum arată înghesuit și nu se potrivește cu restul UI-ului
**Acceptance Criteria:**
- [ ] Meniul redesenat în stil Material Design 3
- [ ] Spacing adecvat între opțiuni (min 44px touch targets)
- [ ] Iconițe clare pentru fiecare opțiune
- [ ] Hover/active states vizibile
- [ ] Animații smooth la deschidere/închidere
- [ ] npm run typecheck passes
- [ ] Verify in browser: meniul arată modern și consistent
---
### US-516: Lista Bonuri - Meniu Acțiuni Per Bon Material Design
**Ca** utilizator
**Vreau** ca meniul de acțiuni pentru fiecare bon (⋮) să arate modern
**Pentru că** acum arată înghesuit și inconsistent
**Acceptance Criteria:**
- [ ] Meniul acțiuni (Vizualizare, Editare, Ștergere) redesenat MD3
- [ ] Opțiuni cu iconițe și text clar
- [ ] Touch targets min 44px
- [ ] Divider între acțiuni normale și destructive (Ștergere)
- [ ] npm run typecheck passes
- [ ] Verify in browser: meniul arată modern
---
### US-517: Lista Bonuri Desktop - Dialog Ștergere Material Design
**Ca** utilizator pe desktop
**Vreau** ca dialogul de confirmare ștergere să arate modern
**Pentru că** acum arată înghesuit și vechi
**Acceptance Criteria:**
- [ ] Dialog redesenat în stil Material Design 3
- [ ] Titlu clar: "Șterge bonul?"
- [ ] Mesaj descriptiv cu detalii bon
- [ ] Butoane: "Anulează" (secondary) și "Șterge" (danger)
- [ ] Spacing și padding corespunzătoare
- [ ] npm run typecheck passes
- [ ] Verify in browser: dialogul arată modern
---
### US-518: Creare/Vizualizare/Editare Bon - Butoane Doar Sus
**Ca** utilizator
**Vreau** ca în paginile de creare, vizualizare și editare bon, butoanele să fie DOAR în partea de sus
**Pentru că** să fie consistent și să nu am butoane duplicate
**Acceptance Criteria:**
- [ ] Pagina creare bon: butoane (Salvează, Anulează) doar în header
- [ ] Pagina vizualizare bon: butoane (Editează, Șterge, Înapoi) doar în header
- [ ] Pagina editare bon: butoane (Salvează, Anulează) doar în header
- [ ] Eliminate butoanele din footer/body dacă există
- [ ] Pe mobil: butoanele sunt în MobileTopBar actions
- [ ] npm run typecheck passes
- [ ] Verify in browser: butoane doar în header pe toate cele 3 pagini
---
### US-519: Separare Casă și Bancă în Pagini Distincte
**Ca** utilizator
**Vreau** ca Casă și Bancă să fie pagini separate (nu combinate)
**Pentru că** să pot accesa fiecare raport independent și să am o navigare mai clară
**Acceptance Criteria:**
- [ ] Pagină separată pentru Casă: `/reports/cash`
- [ ] Pagină separată pentru Bancă: `/reports/bank`
- [ ] Fiecare pagină are propriul titlu (Casă / Bancă)
- [ ] Meniul hamburger (desktop și mobil) are intrări separate pentru Casă și Bancă
- [ ] MobileDrawerMenu actualizat cu linkuri separate
- [ ] MobileBottomNav sau navigarea include ambele opțiuni (dacă relevant)
- [ ] Rutele vechi `/reports/cash-bank` redirect către `/reports/cash` sau sunt eliminate
- [ ] Filtrele și exportul funcționează independent pe fiecare pagină
- [ ] npm run typecheck passes
- [ ] Verify in browser desktop: Casă și Bancă sunt pagini separate accesibile din meniu
- [ ] Verify in browser mobil: Casă și Bancă sunt pagini separate în MobileDrawerMenu
---
## 4. Cerințe Funcționale
1. [REQ-001] Toate paginile de rapoarte TREBUIE să aibă header actions: Filter, Reset, Export (dropdown PDF/XLSX)
2. [REQ-002] Exportul TREBUIE să exporte DOAR datele filtrate curent
3. [REQ-003] Meniul hamburger TREBUIE să fie identic între desktop și mobil ca structură
4. [REQ-004] Pe mobil, filtrele TREBUIE să fie în BottomSheet, nu inline
5. [REQ-005] Touch targets TREBUIE să fie minim 44x44px pe mobil
6. [REQ-006] Butoanele de acțiuni (salvare, ștergere, etc.) TREBUIE să fie DOAR în header/top bar
7. [REQ-007] Toate dialogurile și meniurile TREBUIE să urmeze stilul Material Design 3
## 5. Non-Goals (Ce NU facem)
- ❌ Redesign complet al aplicației - doar unificare și fixes
- ❌ Funcționalități noi de business logic - doar UI/UX
- ❌ Modificări la structura bazei de date
- ❌ Noi endpoint-uri API (doar fix-uri la cele existente)
- ❌ Suport pentru alte limbi/i18n
- ❌ Implementare PWA sau funcționalități offline
## 6. Considerații Tehnice
### Stack/Tehnologii
- **Frontend**: Vue 3, PrimeVue, CSS custom cu design tokens
- **Backend**: FastAPI (doar pentru fix export endpoints)
- **Componente existente**: MobileTopBar, MobileBottomNav, MobileDrawerMenu, BottomSheet, MobileSelectionFooter
### Patterns de Urmat
- **Referință design**: `/reports/invoices` (InvoicesView.vue)
- **Mobile actions**: Array în `mobileTopBarActions` computed
- **Filtre mobil**: BottomSheet component
- **Design tokens**: Folosește DOAR variabile CSS din `DESIGN_TOKENS.md`
### Fișiere Cheie
```
src/shared/components/mobile/MobileTopBar.vue
src/shared/components/mobile/MobileDrawerMenu.vue
src/shared/components/mobile/BottomSheet.vue
src/modules/reports/views/InvoicesView.vue (referință)
src/modules/reports/views/DetailedInvoicesView.vue
src/modules/reports/views/MaturityAnalysisView.vue
src/modules/data-entry/views/receipts/ReceiptsListView.vue
src/modules/data-entry/views/receipts/ReceiptCreateView.vue
src/modules/data-entry/views/receipts/ReceiptEditView.vue
src/modules/data-entry/views/receipts/ReceiptDetailView.vue
```
### Dependențe
- PrimeVue components (Button, Menu, Dialog, Dropdown)
- Design tokens CSS variables
- Backend export endpoints existente
### Riscuri Tehnice
- Export endpoints pot avea erori neașteptate - necesită debugging
- Unele pagini pot avea logică complexă de filtrare - atenție la regresii
## 7. Considerații UI/UX
### Layout Pattern (Header Actions)
```
┌─────────────────────────────────────────────────┐
│ [☰/←] Titlu Pagină [🔍] [↻] [⬇️▼] │
│ (centrat) Filter Reset Export │
└─────────────────────────────────────────────────┘
```
### Export Dropdown
```
┌──────────────┐
│ 📄 Export PDF │
│ 📊 Export XLSX│
└──────────────┘
```
### Stări UI
- **Loading**: Skeleton sau spinner în zona de conținut
- **Empty**: Mesaj "Nu există date" cu icon ilustrativ
- **Error**: Toast notification + retry button
- **Success export**: Toast "Exportul a fost descărcat"
### Dark Mode
- Toate componentele noi TREBUIE testate în dark mode
- Folosește design tokens pentru culori (nu hardcoded)
## 8. Ordine Implementare Recomandată
### Faza 1: Fixes Critice (bugs)
1. US-506: Fix MobileDrawerMenu - Deconectare vizibil
2. US-509: Fix Detailed Invoices - Grupuri expandabile desktop
3. US-512: Fix overlay butoane ascunse
4. US-504: Fix Export endpoints backend
### Faza 2: Unificare Header Actions
5. US-501: Header Actions Bar - Rapoarte
6. US-502: Header Actions Bar - Lista Bonuri
7. US-503: BottomSheet Filtre pentru Lista Bonuri
### Faza 3: Cleanup & Eliminări
8. US-510: Eliminare filtru Clienți/Furnizori
9. US-511: Eliminare buton filtru duplicat
10. US-513: Eliminare secțiune Facturi Detaliate din Scadențe
11. US-514: Fix spațiu blank top
### Faza 4: Meniu & Navigare
12. US-505: Meniu hamburger desktop = mobil
13. US-507: Selecție companie/perioadă mobil
14. US-508: Selector temă mobil
### Faza 5: Material Design Styling
15. US-515: Meniu Bon Nou/Bulk Upload MD3
16. US-516: Meniu acțiuni per bon MD3
17. US-517: Dialog ștergere MD3
18. US-518: Butoane doar sus în creare/editare bon
## 9. Success Metrics
- **Consistență UI**: 100% pagini cu același pattern header actions
- **Zero bugs vizuale**: Toate butoanele vizibile, zero overflow
- **Export funcțional**: PDF și XLSX funcționează pe toate paginile
- **Mobile parity**: Toate funcțiile disponibile pe mobil (companie, perioadă, temă)
## 10. Decizii Clarficate
-**PDF Export**: Folosește formatarea existentă de la Facturi/Balanță/Casă și Bancă - doar extinde la celelalte pagini
-**Selecție companie/perioadă mobil**: În MobileDrawerMenu, sub secțiunea profil
-**Tema selector mobil**: În MobileDrawerMenu (lângă alte setări)