feat(mobile-fixes-phase4): Complete US-401 - Fix Layout Principal - Ascundere Header Desktop pe Mobil

Implemented by Ralph autonomous loop.
Iteration: 1

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Claude Agent
2026-01-12 18:45:30 +00:00
parent ac2966c629
commit 65eff42312
4 changed files with 311 additions and 1226 deletions

View File

@@ -1,7 +1,7 @@
{
"projectName": "mobile-fixes-phase3",
"projectName": "mobile-fixes-phase4",
"branchName": "ralph/unified-mobile-md",
"description": "Corectări navigare mobilă: footer restructurat, tab-uri Clienți/Furnizori, FAB pe Bonuri, hamburger grupat",
"description": "Fix layout mobil: ascundere header desktop, butoane filter/export vizibile, MobileDrawerMenu cu ANALIZE, persistență bonuri cu eroare",
"cssRules": {
"documentation": [
"docs/ONBOARDING_CSS.md",
@@ -16,7 +16,8 @@
"NICIODATĂ :deep() în componente (PrimeVue → vendor/)",
"Mobile: toate paginile folosesc MobileTopBar + MobileBottomNav",
"Mobile: filtrele se pun în BottomSheet, NU inline",
"Mobile: tab-uri pentru switch Clienți/Furnizori"
"Mobile: v-if='isMobile' pentru componente mobile-only",
"Desktop: v-if='!isMobile' pentru componente desktop-only"
],
"mobileLayoutTokens": {
"topBarHeight": "56px",
@@ -28,189 +29,133 @@
},
"userStories": [
{
"id": "US-307",
"title": "Restructurare Footer Nav (4 butoane noi)",
"description": "Ca utilizator mobil vreau footer navigation cu: Dashboard | Bonuri | Facturi | Setări",
"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",
"priority": 1,
"acceptanceCriteria": [
"MobileBottomNav cu 4 butoane: Dashboard, Bonuri, Facturi, Setări",
"Dashboard: icon pi-home, route /dashboard",
"Bonuri: icon pi-receipt, route /data-entry",
"Facturi: icon pi-file-edit, route /reports/invoices",
"Setări: icon pi-cog, route /settings",
"Active state corect pe fiecare pagină",
"Ștergere link Upload din footer (mutat în FAB)",
"npm run build passes"
"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",
"npm run build passes",
"Verify in browser (375x667): Header desktop cu 'Selectare perioada' și 'AXN' NU este vizibil"
],
"passes": true,
"notes": "Completed in iteration 1"
},
{
"id": "US-308",
"title": "Actualizare Hamburger Menu - Grupat pe Categorii",
"description": "Ca utilizator mobil vreau meniul hamburger organizat pe categorii clare",
"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",
"priority": 2,
"acceptanceCriteria": [
"MobileDrawerMenu.vue restructurat cu secțiuni vizuale",
"Secțiune PRINCIPALE: Dashboard → /dashboard, Bonuri → /data-entry",
"Secțiune RAPOARTE: Facturi → /reports/invoices, Balanță → /reports/trial-balance, Casa și Banca → /reports/bank-cash",
"Secțiune ANALIZE: Scadențe → /reports/maturity-analysis, Facturi Detaliate → /reports/detailed-invoices",
"Secțiune ADMINISTRARE: Setări → /settings",
"Separatori vizuali între secțiuni",
"Header cu logo, Footer cu profil utilizator și logout",
"npm run build passes"
"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"
],
"passes": true,
"notes": "Completed in iteration 2"
"passes": false,
"notes": "Depinde de US-401 - butoanele există dar sunt acoperite de header-ul desktop"
},
{
"id": "US-304",
"title": "Tab-uri Clienți/Furnizori în Facturi",
"description": "Ca utilizator vreau pagina Facturi să aibă tab-uri pentru Clienți și Furnizori",
"id": "US-403",
"title": "Fix MobileDrawerMenu - Secțiunea ANALIZE Vizibilă",
"description": "Ca utilizator mobil vreau să văd secțiunea ANALIZE în hamburger menu",
"priority": 3,
"acceptanceCriteria": [
"InvoicesView.vue modificat cu tab-uri: Clienți | Furnizori",
"Tab-uri sub MobileTopBar (design Material, full-width)",
"Switch între tab-uri păstrează filtrele active",
"Default: primul tab activ (Clienți)",
"URL query param pentru tab activ (?tab=suppliers)",
"MobileTopBar cu title Facturi",
"MobileBottomNav activ (Facturi highlighted)",
"npm run build passes"
"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ă"
],
"passes": true,
"notes": "Completed in iteration 1"
"passes": false,
"notes": "Depinde de US-401 - hamburger-ul deschidea sidebar-ul desktop"
},
{
"id": "US-305",
"title": "Tab-uri Clienți/Furnizori în Scadențe",
"description": "Ca utilizator vreau pagina Scadențe să aibă tab-uri pentru Clienți și Furnizori",
"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",
"priority": 4,
"acceptanceCriteria": [
"MaturityAnalysisView.vue modificat cu tab-uri: Clienți | Furnizori",
"Tab-uri sub MobileTopBar (design Material, full-width)",
"Switch între tab-uri păstrează filtrele active",
"Default: primul tab activ (Clienți)",
"URL query param pentru tab activ (?tab=suppliers)",
"MobileTopBar cu title Scadențe și buton ← Înapoi",
"MobileBottomNav activ",
"npm run build passes"
"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",
"npm run build passes",
"Verify in browser (375x667): Conținutul începe imediat sub MobileTopBar, fără gap de ~120px"
],
"passes": true,
"notes": "Completed in iteration 2"
"passes": false,
"notes": "Depinde de US-401 - spațiul era ocupat de header-ul desktop ascuns incorect"
},
{
"id": "US-301",
"title": "Buton Înapoi în Creare/Editare/Vizualizare Bon",
"description": "Ca utilizator mobil vreau buton ← Înapoi în MobileTopBar pe pagina de bon",
"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",
"priority": 5,
"acceptanceCriteria": [
"ReceiptCreateUnifiedView.vue are MobileTopBar cu showBack=true",
"Click pe ← navighează la /data-entry (lista bonuri)",
"Funcționează în toate modurile: create, edit, view",
"Verify in browser: butonul apare și funcționează",
"Î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"
],
"passes": true,
"notes": "Completed in iteration 3"
"passes": false,
"notes": ""
},
{
"id": "US-302",
"title": "Footer Nav pe toate Paginile de Setări",
"description": "Ca utilizator mobil vreau MobileBottomNav pe toate paginile din secțiunea Setări",
"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'",
"priority": 6,
"acceptanceCriteria": [
"OCRMetricsView.vue include MobileBottomNav cu Setări activ",
"CacheStatsView.vue include MobileBottomNav cu Setări activ",
"ServerLogsView.vue include MobileBottomNav cu Setări activ",
"TelegramAdminView.vue include MobileBottomNav cu Setări activ (dacă există)",
"SettingsHubView.vue include MobileBottomNav cu Setări activ",
"npm run build passes"
"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",
"npm run build passes",
"Verify in browser (375x667): Bon cu eroare arată 'Eroare' nu 'În procesare'"
],
"passes": true,
"notes": "Completed in iteration 4"
"passes": false,
"notes": "Depinde de US-405 - bonurile failed trebuie să fie în listă mai întâi"
},
{
"id": "US-303",
"title": "FAB pe Pagina Bonuri (Mutare Upload)",
"description": "Ca utilizator mobil vreau funcția Upload să fie în butonul FAB (+) pe pagina Bonuri",
"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",
"priority": 7,
"acceptanceCriteria": [
"ReceiptsListView.vue are buton FAB (+) în colțul dreapta-jos",
"Click pe FAB deschide meniu popup: Bon Nou | Upload Bulk",
"FAB poziționat deasupra MobileBottomNav (bottom: 72px)",
"Bon Nou navighează la /data-entry/receipts/new",
"Upload Bulk navighează la /data-entry/bulk-upload",
"FAB vizibil doar pe mobil (isMobile)",
"npm run build passes"
"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",
"npm run build passes",
"Verify in browser: Editează bon cu eroare → Salvează → Statusul nu mai arată eroare"
],
"passes": true,
"notes": "Completed in iteration 5"
"passes": false,
"notes": ""
},
{
"id": "US-306",
"title": "Restaurare Butoane Export și Filtrare pe Rapoarte",
"description": "Ca utilizator mobil vreau butoane de export și filtrare pe toate rapoartele",
"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",
"priority": 8,
"acceptanceCriteria": [
"InvoicesView.vue: buton Export (pi-download) și Filtrare (pi-filter) în MobileTopBar actions",
"TrialBalanceView.vue: buton Export și Filtrare în MobileTopBar actions",
"BankCashRegisterView.vue: buton Export și Filtrare în MobileTopBar actions",
"ReceiptsListView.vue: buton Export și Filtrare în MobileTopBar actions",
"MaturityAnalysisView.vue: buton Export și Filtrare în MobileTopBar actions",
"Click pe Filtrare deschide BottomSheet cu filtrele paginii",
"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"
],
"passes": true,
"notes": "Completed in iteration 6"
},
{
"id": "US-309",
"title": "Cleanup Dashboard Mobile",
"description": "Ca utilizator mobil vreau Dashboard-ul să afișeze doar KPIs fără quick-links",
"priority": 9,
"acceptanceCriteria": [
"DashboardView.vue pe mobil: ștergere quick-link cards dacă există",
"Doar SwipeableCards cu KPIs pe mobil",
"Desktop rămâne neschimbat",
"MobileTopBar cu title Dashboard",
"MobileBottomNav cu Dashboard activ",
"npm run build passes"
],
"passes": true,
"notes": "Completed in iteration 7"
},
{
"id": "US-310",
"title": "Actualizare Router cu Modificările",
"description": "Ca developer vreau router-ul actualizat pentru a funcționa cu noile pagini",
"priority": 10,
"acceptanceCriteria": [
"Rută /reports/invoices → InvoicesView funcțională",
"Rută /reports/maturity-analysis → MaturityAnalysisView funcțională",
"Rutele existente păstrate: /reports/trial-balance, /reports/bank-cash, /reports/detailed-invoices",
"Cleanup rute nefolosite dacă există",
"Toate rutele lazy loaded",
"npm run build passes"
],
"passes": true,
"notes": "Completed in iteration 8"
},
{
"id": "US-311",
"title": "Actualizare Documentație MOBILE_PATTERNS.md",
"description": "Ca developer viitor vreau documentația actualizată cu modificările din Phase 3",
"priority": 11,
"acceptanceCriteria": [
"Secțiune actualizată: Footer Navigation (Dashboard, Bonuri, Facturi, Setări)",
"Secțiune nouă: FAB Pattern pentru acțiuni contextuale",
"Secțiune nouă: Tab Pattern pentru switch Clienți/Furnizori",
"Secțiune actualizată: Hamburger Menu grupat pe categorii",
"Diagrame ASCII actualizate cu noua structură navigare",
"npm run build passes"
],
"passes": true,
"notes": "Completed in iteration 9"
"passes": false,
"notes": ""
}
]
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,8 +1,8 @@
<template>
<div id="app">
<!-- Header -->
<!-- Desktop Header - hidden on mobile (viewport < 768px) -->
<AppHeader
v-if="authStore.isAuthenticated"
v-if="authStore.isAuthenticated && !isMobile"
title="ROA2WEB"
brand-link="/reports/dashboard"
:menu-open="menuOpen"
@@ -15,9 +15,9 @@
@period-changed="handlePeriodChanged"
/>
<!-- Slide Menu -->
<!-- Desktop Slide Menu - hidden on mobile (viewport < 768px) -->
<SlideMenu
v-if="authStore.isAuthenticated"
v-if="authStore.isAuthenticated && !isMobile"
:is-open="menuOpen"
:menu-items="enabledMenuItems"
:current-user="authStore.currentUser"
@@ -25,8 +25,8 @@
@logout="handleLogout"
/>
<!-- Main Content -->
<main class="main-content" :class="{ 'with-navbar': authStore.isAuthenticated }">
<!-- Main Content - with-navbar only on desktop when authenticated -->
<main class="main-content" :class="{ 'with-navbar': authStore.isAuthenticated && !isMobile }">
<router-view />
</main>
@@ -37,7 +37,7 @@
</template>
<script setup>
import { ref, computed, onMounted, watch } from 'vue'
import { ref, computed, onMounted, onUnmounted, watch } from 'vue'
import { useRouter } from 'vue-router'
import AppHeader from '@shared/components/layout/AppHeader.vue'
import SlideMenu from '@shared/components/layout/SlideMenu.vue'
@@ -52,6 +52,14 @@ import axios from 'axios'
const router = useRouter()
// Mobile detection - reactive with resize listener
const windowWidth = ref(typeof window !== 'undefined' ? window.innerWidth : 1024)
const isMobile = computed(() => windowWidth.value < 768)
const handleResize = () => {
windowWidth.value = window.innerWidth
}
// API service for auth and shared endpoints (unified backend)
const authApi = axios.create({
baseURL: import.meta.env.BASE_URL + 'api',
@@ -101,6 +109,9 @@ watch(
// Initialize auth and load companies on mount
onMounted(async () => {
// Add resize listener for mobile detection
window.addEventListener('resize', handleResize)
console.log('[App] Mounted - initializing auth...')
await authStore.initializeAuth()
console.log('[App] Auth initialized, isAuthenticated:', authStore.isAuthenticated)
@@ -116,6 +127,11 @@ onMounted(async () => {
}
})
// Cleanup resize listener
onUnmounted(() => {
window.removeEventListener('resize', handleResize)
})
// Event handlers
const handleCompanyChanged = async (company) => {
console.log('[App] Company changed:', company)

View File

@@ -0,0 +1,188 @@
# PRD: Mobile Fixes Phase 4 - Layout & State Issues
## 1. Introducere
După completarea Phase 3 (11/11 stories), au fost identificate probleme critice în modul mobil prin testare Playwright. Cauza principală este că layout-ul desktop (AppHeader + sidebar) rămâne vizibil pe viewport mobil, acoperind componentele mobile (MobileTopBar, MobileDrawerMenu). În plus, există probleme cu persistența bonurilor cu eroare la upload.
## 2. Obiective
### Obiectiv Principal
- Corectarea layout-ului mobil pentru a afișa DOAR componentele mobile pe viewport < 768px
### Obiective Secundare
- Restaurarea corectă a bonurilor cu eroare după refresh
- Permiterea editării bonurilor cu eroare pentru corectare
### Metrici de Succes
- Playwright test: Header desktop ASCUNS pe viewport 375px
- Playwright test: MobileTopBar cu butoane filter/export VIZIBILE
- Playwright test: MobileDrawerMenu afișează secțiunea ANALIZE
- Playwright test: Bonuri cu eroare rămân vizibile după refresh
## 3. User Stories
### US-401: Fix Layout Principal - Ascundere Header Desktop pe Mobil
**Ca** utilizator mobil
**Vreau** văd doar MobileTopBar și MobileBottomNav
**Pentru că** header-ul desktop ocupă spațiu și acoperă butoanele mobile
**Acceptance Criteria:**
- [ ] AppHeader.vue are `v-if="!isMobile"` pentru a se ascunde pe mobil
- [ ] Sidebar-ul desktop (navigation cu Rapoarte/Introduceri Date/Sistem) este ascuns pe mobil
- [ ] MobileTopBar este singurul header vizibil pe viewport < 768px
- [ ] Nu există suprapunere între header desktop și MobileTopBar
- [ ] npm run build passes
- [ ] Verify in browser (375x667): Header desktop NU este vizibil
### US-402: Fix MobileTopBar - Butoane Filter/Export Vizibile
**Ca** utilizator mobil pe pagina Facturi/Bonuri
**Vreau** văd butoanele de filtrare și export în header
**Pentru că** acum sunt ascunse/acoperite de header-ul desktop
**Acceptance Criteria:**
- [ ] Pe InvoicesView.vue, butoanele Filter/Refresh/Export sunt vizibile în MobileTopBar
- [ ] Pe ReceiptsListView.vue, butoanele Filter/Export/More sunt vizibile în MobileTopBar
- [ ] Click pe butonul Filter deschide BottomSheet cu filtre
- [ ] Click pe butonul Export declanșează descărcarea
- [ ] npm run build passes
- [ ] Verify in browser (375x667): Butoanele sunt vizibile și funcționale pe pagina Facturi
### US-403: Fix MobileDrawerMenu - Secțiunea ANALIZE Vizibilă
**Ca** utilizator mobil
**Vreau** văd secțiunea ANALIZE în hamburger menu
**Pentru că** acum se deschide sidebar-ul desktop în loc de MobileDrawerMenu
**Acceptance Criteria:**
- [ ] 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, Facturi Detaliate
- [ ] Link-urile din ANALIZE navighează corect
- [ ] npm run build passes
- [ ] Verify in browser (375x667): Click pe Meniu apare drawer cu secțiunea ANALIZE
### US-404: Fix Spațiu Blank - Padding Corect pentru Mobile
**Ca** utilizator mobil
**Vreau** ca paginile nu aibă spațiu blank excesiv în partea de sus
**Pentru că** acum există ~120px spațiu gol unde ar fi header-ul desktop
**Acceptance Criteria:**
- [ ] Paginile de rapoarte au padding-top corect pentru MobileTopBar (56px)
- [ ] Nu există spațiu blank între MobileTopBar și conținut
- [ ] Tab-urile Clienți/Furnizori sunt imediat sub MobileTopBar
- [ ] npm run build passes
- [ ] Verify in browser (375x667): Nu există spațiu blank excesiv pe pagina Facturi
### US-405: Fix batchProgressStore - Restaurare Joburi Failed
**Ca** utilizator care a uploadat bonuri cu erori OCR
**Vreau** ca bonurile cu eroare rămână vizibile după refresh
**Pentru că** acum dispar și nu pot fi editate
**Acceptance Criteria:**
- [ ] `restoreJobsFromBatch()` în batchProgressStore.js include joburi cu status 'failed'
- [ ] Batch-ul NU este șters din localStorage dacă are joburi failed
- [ ] După refresh, bonurile cu eroare sunt afișate cu status vizual "Eroare"
- [ ] `unifiedItems` computed include joburile failed pentru afișare
- [ ] npm run build passes
- [ ] Verify in browser: Upload bon cu eroare Refresh Bonul cu eroare rămâne vizibil
### US-406: Fix UI Bonuri cu Eroare - Afișare Corectă pe Mobil
**Ca** utilizator mobil
**Vreau** văd clar un bon are eroare (nu "în procesare")
**Pentru că** acum bonurile failed arată ca și cum ar fi încă în procesare
**Acceptance Criteria:**
- [ ] Bonurile cu status 'failed' afișează chip/badge "Eroare" (roșu)
- [ ] NU afișează "În procesare" pentru bonuri failed
- [ ] Mesajul de eroare este vizibil (truncat dacă e prea lung)
- [ ] npm run build passes
- [ ] Verify in browser (375x667): Bon cu eroare arată "Eroare" nu "În procesare"
### US-407: Fix Editare Bonuri cu Eroare
**Ca** utilizator care are un bon cu eroare OCR
**Vreau** pot edita bonul pentru a corecta erorile manual
**Pentru că** acum nu pot salva modificările sau re-trimite pe workflow
**Acceptance Criteria:**
- [ ] Click pe bon cu eroare deschide formularul de editare
- [ ] La salvare, `processing_status` este resetat la NULL
- [ ] După salvare, bonul poate fi trimis pe workflow (Submit for Approval)
- [ ] Backend endpoint PATCH /receipts/{id} resetează processing_status
- [ ] npm run build passes
- [ ] Verify in browser: Editează bon cu eroare Salvează Poate fi trimis pe workflow
### US-408: Verificare Finală cu Playwright
**Ca** developer
**Vreau** verificare automată a tuturor fix-urilor
**Pentru că** trebuie confirmate toate scenariile înainte de merge
**Acceptance Criteria:**
- [ ] Test 1: Viewport 375x667 Header desktop ASCUNS
- [ ] Test 2: Viewport 375x667 MobileTopBar cu butoane VIZIBILE
- [ ] Test 3: Click Meniu MobileDrawerMenu cu ANALIZE
- [ ] Test 4: Pagina Facturi Tab-uri + butoane imediat vizibile (fără blank)
- [ ] Test 5: Upload bon cu eroare Arată "Eroare" nu "În procesare"
- [ ] Test 6: Refresh Bonul cu eroare rămâne
- [ ] npm run build passes
## 4. Cerințe Funcționale
1. [REQ-001] Pe viewport < 768px, AppHeader și sidebar desktop trebuie ascunse complet
2. [REQ-002] MobileTopBar trebuie fie singurul header vizibil pe mobil
3. [REQ-003] MobileDrawerMenu trebuie se deschidă la click pe butonul Meniu din MobileTopBar
4. [REQ-004] Butoanele actions din MobileTopBar trebuie fie vizibile și funcționale
5. [REQ-005] batchProgressStore trebuie restaureze și afișeze joburi cu status 'failed'
6. [REQ-006] Editarea unui bon cu eroare trebuie reseteze processing_status pentru re-workflow
## 5. Non-Goals (Ce NU facem)
- NU modificăm layout-ul desktop (rămâne neschimbat)
- NU adăugăm funcționalități noi (doar fix-uri)
- NU modificăm stilurile cardurilor de bonuri
- NU schimbăm structura hamburger menu (doar ne asigurăm se deschide corect)
## 6. Considerații Tehnice
### Stack/Tehnologii
- Vue 3 Composition API
- PrimeVue components
- Pinia stores (batchProgressStore)
- CSS media queries / v-if cu isMobile computed
### Patterns de Urmat
- `isMobile` computed bazat pe `window.innerWidth < 768`
- `v-if="!isMobile"` pentru componente desktop-only
- `v-if="isMobile"` pentru componente mobile-only
### Fișiere Cheie de Modificat
| Fișier | Modificare |
|--------|------------|
| `src/App.vue` sau layout component | v-if pentru AppHeader/sidebar |
| `src/shared/components/layout/AppHeader.vue` | Verificare isMobile |
| `src/modules/reports/views/InvoicesView.vue` | CSS padding-top |
| `src/modules/data-entry/views/ReceiptsListView.vue` | CSS padding-top |
| `src/stores/batchProgressStore.js` | Include 'failed' în restore |
| `backend/modules/data_entry/routers/receipts.py` | Reset processing_status |
### Riscuri Tehnice
- Modificarea layout-ului principal poate afecta toate paginile - testare completă necesară
- isMobile computed trebuie fie reactiv la resize
## 7. Considerații UI/UX
- Mobile layout trebuie fie curat, fără suprapuneri
- Butoanele touch target minim 48px
- Feedback vizual clar pentru starea bonurilor (Eroare vs În procesare)
- Tranziție smooth pentru MobileDrawerMenu
## 8. Success Metrics
- 100% teste Playwright trec
- 0 suprapuneri vizuale pe viewport mobil
- Bonuri cu eroare persistent după refresh
- Timp de încărcare pagină neschimbat
## 9. Open Questions
- [x] Cauza exactă a problemei? Header desktop nu este ascuns pe mobil (confirmat prin Playwright)
- [x] isMobile computed există? Trebuie verificat în layout principal
- [ ] Există alte pagini afectate de layout? De verificat după fix