feat(dashboard): Complete dashboard desktop cleanup and improvements
User Stories Completed: - US-001: Eliminare SolduriCompactCard de pe Desktop - US-002: Eliminare Icoane din Header-ul CollapsibleCard - US-003: Reorganizare TreasuryDualCard - Text Înainte de Grafice - US-004: Reorganizare ClientiBalanceCard - Text Înainte de Grafice - US-005: Reorganizare FurnizoriBalanceCard - Text Înainte de Grafice - US-006: Grafice Colapsabile în TreasuryDualCard - US-007: Grafice Colapsabile în ClientiBalanceCard - US-008: Grafice Colapsabile în FurnizoriBalanceCard - US-009: Grafice Colapsabile în CashFlowMetricCard Additional Improvements: - Add cache metadata display (CacheFooter component) for all dashboard cards - Add @cached decorators to get_monthly_flows and get_indicators_with_sparklines - Fix financial indicators calculations and sparkline sync - Add state reset on company change to prevent stale data - New shared components: CacheFooter.vue, authRedirect.js - Enhanced FinancialIndicatorsCard with sparklines and period selection Squashed from branch: ralph/dashboard-desktop-cleanup (11 commits) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
69
.claude/handover-cleanup-roa2web.md
Normal file
69
.claude/handover-cleanup-roa2web.md
Normal file
@@ -0,0 +1,69 @@
|
||||
# Handover: Curățare Cod ROA2WEB
|
||||
|
||||
## Context
|
||||
|
||||
Am analizat arhitectura ROA2WEB cu 3 agenți de explorare și am identificat 4 acțiuni de curățare cu randament mare și risc minim.
|
||||
|
||||
**Plan detaliat**: `/home/claude/.claude/plans/immutable-chasing-flute.md`
|
||||
|
||||
## Prompt pentru /ralph:prd
|
||||
|
||||
```
|
||||
Implementează curățarea codului ROA2WEB conform planului din /home/claude/.claude/plans/immutable-chasing-flute.md
|
||||
|
||||
Obiective:
|
||||
1. Elimină store duplication - șterge src/modules/reports/stores/sharedStores.js și src/modules/data-entry/stores/sharedStores.js, mută instantierea în App.vue
|
||||
2. Creează factory pentru API services - src/shared/services/createApiService.js și simplifică api.js din module
|
||||
3. Fă dependențele OCR opționale - adaugă variabile în .env (OCR_ENABLE_PADDLEOCR, OCR_ENABLE_TESSERACT), implementează lazy loading în OCR service, mută deps în requirements opțional
|
||||
4. Consolidează CSS design tokens - unifică variables.css, tokens.css, md3-tokens.css într-un singur design-tokens.css
|
||||
|
||||
Constrângeri:
|
||||
- NU schimba arhitectura (layered architecture rămâne)
|
||||
- NU modifica auth middleware, cache decorator, oracle pool
|
||||
- Testează după fiecare modificare: app pornește, login funcționează, dark mode arată corect
|
||||
|
||||
Ordinea execuției:
|
||||
1. [15 min] Store duplication
|
||||
2. [30 min] API factory
|
||||
3. [30 min] OCR dependencies opționale (lazy loading via .env)
|
||||
4. [1 oră] CSS tokens
|
||||
|
||||
Impact așteptat: -150 linii cod duplicat, OCR deps opționale via .env, -2 fișiere CSS, startup mai rapid
|
||||
```
|
||||
|
||||
## Fișiere Cheie de Referință
|
||||
|
||||
### De Șters
|
||||
- `src/modules/reports/stores/sharedStores.js`
|
||||
- `src/modules/data-entry/stores/sharedStores.js`
|
||||
|
||||
### De Creat
|
||||
- `src/shared/services/createApiService.js`
|
||||
- `src/assets/css/core/design-tokens.css` (consolidat)
|
||||
|
||||
### De Modificat
|
||||
- `src/App.vue` - adaugă instantiere stores
|
||||
- `src/modules/reports/services/api.js` - simplifică cu factory
|
||||
- `src/modules/data-entry/services/api.js` - simplifică cu factory
|
||||
- `backend/requirements.txt` - mută paddleocr/tesseract în secțiune opțională (comentate)
|
||||
- `backend/.env` - adaugă `OCR_ENABLE_PADDLEOCR=false` și `OCR_ENABLE_TESSERACT=false`
|
||||
- `backend/modules/data_entry/services/ocr_service.py` - implementează lazy loading pentru OCR engines
|
||||
- `src/assets/css/main.css` - actualizează importuri CSS
|
||||
|
||||
## Verificare Finală
|
||||
|
||||
După implementare, verifică:
|
||||
- [ ] `./start-prod.sh` pornește fără erori
|
||||
- [ ] Login funcționează
|
||||
- [ ] Un raport se încarcă corect
|
||||
- [ ] O chitanță se poate crea
|
||||
- [ ] Dark mode arată corect pe toate paginile
|
||||
- [ ] `pip install -r backend/requirements.txt` reușește
|
||||
- [ ] Cu `OCR_ENABLE_PADDLEOCR=false` - app pornește fără PaddleOCR instalat
|
||||
- [ ] Cu `OCR_ENABLE_PADDLEOCR=true` - OCR fallback funcționează (dacă e instalat)
|
||||
|
||||
## Note
|
||||
|
||||
- Arhitectura actuală (Layered) este potrivită pentru echipa de 1-2 developeri
|
||||
- Nu este nevoie de Vertical Slice sau Feature-Sliced Design
|
||||
- Acțiunile opționale (split receiptStore, simplificare cache) pot fi făcute ulterior
|
||||
253
.claude/plans/immutable-chasing-flute.md
Normal file
253
.claude/plans/immutable-chasing-flute.md
Normal file
@@ -0,0 +1,253 @@
|
||||
# Plan: Curățare Cod ROA2WEB (High ROI, Low Risk)
|
||||
|
||||
## Sumar Executiv
|
||||
|
||||
Arhitectura ROA2WEB este **solidă** pentru o echipă de 1-2 developeri. Nu necesită schimbări arhitecturale.
|
||||
|
||||
Acest plan conține doar **optimizări tactice sigure** cu randament mare.
|
||||
|
||||
---
|
||||
|
||||
## Acțiuni de Curățare (Prioritizate)
|
||||
|
||||
### 1. Elimină Store Duplication ✅
|
||||
**ROI**: ⭐⭐⭐⭐⭐ | **Risc**: Foarte Scăzut | **Efort**: 15 min
|
||||
|
||||
**Problema**: `sharedStores.js` identic în 2 module (42 linii duplicate)
|
||||
|
||||
**Fișiere de șters**:
|
||||
- `src/modules/reports/stores/sharedStores.js`
|
||||
- `src/modules/data-entry/stores/sharedStores.js`
|
||||
|
||||
**Soluție**: Instantiază stores direct în `App.vue`
|
||||
|
||||
```javascript
|
||||
// App.vue
|
||||
import { createAuthStore } from '@shared/stores/auth'
|
||||
import { createCompaniesStore } from '@shared/stores/companies'
|
||||
import { createAccountingPeriodStore } from '@shared/stores/accountingPeriod'
|
||||
import authApi from '@shared/services/authApi'
|
||||
|
||||
const useAuthStore = createAuthStore(authApi)
|
||||
const useCompanyStore = createCompaniesStore(authApi, useAuthStore)
|
||||
const useAccountingPeriodStore = createAccountingPeriodStore(authApi)
|
||||
```
|
||||
|
||||
**Verificare**: App funcționează normal, stores disponibile în componente
|
||||
|
||||
---
|
||||
|
||||
### 2. Factory pentru API Services ✅
|
||||
**ROI**: ⭐⭐⭐⭐ | **Risc**: Scăzut | **Efort**: 30 min
|
||||
|
||||
**Problema**: `api.js` duplicat în module (70% cod identic, 156 linii total)
|
||||
|
||||
**Fișier de creat**: `src/shared/services/createApiService.js`
|
||||
|
||||
```javascript
|
||||
// createApiService.js (~50 linii)
|
||||
import axios from 'axios'
|
||||
|
||||
export function createApiService(basePath, options = {}) {
|
||||
const api = axios.create({
|
||||
baseURL: import.meta.env.BASE_URL + `api/${basePath}`,
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
})
|
||||
|
||||
api.interceptors.request.use(config => {
|
||||
const token = localStorage.getItem('access_token')
|
||||
if (token) config.headers.Authorization = `Bearer ${token}`
|
||||
|
||||
if (options.injectCompany) {
|
||||
// Logic pentru X-Selected-Company header
|
||||
}
|
||||
|
||||
if (config.data instanceof FormData) {
|
||||
delete config.headers['Content-Type']
|
||||
}
|
||||
return config
|
||||
})
|
||||
|
||||
api.interceptors.response.use(
|
||||
response => response,
|
||||
error => {
|
||||
if (error.response?.status === 401) {
|
||||
localStorage.removeItem('access_token')
|
||||
window.location.href = '/login'
|
||||
}
|
||||
return Promise.reject(error)
|
||||
}
|
||||
)
|
||||
|
||||
return api
|
||||
}
|
||||
```
|
||||
|
||||
**Fișiere simplificate** (5 linii fiecare):
|
||||
```javascript
|
||||
// src/modules/reports/services/api.js
|
||||
import { createApiService } from '@shared/services/createApiService'
|
||||
export default createApiService('reports')
|
||||
|
||||
// src/modules/data-entry/services/api.js
|
||||
import { createApiService } from '@shared/services/createApiService'
|
||||
export default createApiService('data-entry', { injectCompany: true })
|
||||
```
|
||||
|
||||
**Verificare**: Login funcționează, API calls returnează date
|
||||
|
||||
---
|
||||
|
||||
### 3. Dependențe OCR Opționale (Lazy Loading) ✅
|
||||
**ROI**: ⭐⭐⭐⭐ | **Risc**: Foarte Scăzut | **Efort**: 30 min
|
||||
|
||||
**Problema**: PaddleOCR + pytesseract se instalează și încarcă mereu, chiar dacă nu sunt folosite
|
||||
|
||||
**Soluție**: Fă-le opționale via `.env` și lazy loading
|
||||
|
||||
**Fișier `.env`** - adaugă:
|
||||
```env
|
||||
# OCR Engines (true = instalează și încarcă, false = skip)
|
||||
OCR_ENABLE_PADDLEOCR=false
|
||||
OCR_ENABLE_TESSERACT=false
|
||||
```
|
||||
|
||||
**Fișier `backend/requirements.txt`** - mută în secțiune opțională:
|
||||
```
|
||||
# Required OCR
|
||||
python-doctr[torch]>=0.8.0
|
||||
|
||||
# Optional OCR (install only if needed)
|
||||
# paddleocr>=2.7.0 # Uncomment if OCR_ENABLE_PADDLEOCR=true
|
||||
# paddlepaddle>=2.5.0 # Uncomment if OCR_ENABLE_PADDLEOCR=true
|
||||
# pytesseract>=0.3.10 # Uncomment if OCR_ENABLE_TESSERACT=true
|
||||
```
|
||||
|
||||
**SAU** creează `requirements-ocr-optional.txt`:
|
||||
```
|
||||
paddleocr>=2.7.0
|
||||
paddlepaddle>=2.5.0
|
||||
pytesseract>=0.3.10
|
||||
```
|
||||
|
||||
**Fișier OCR service** - lazy import:
|
||||
```python
|
||||
# backend/modules/data_entry/services/ocr_service.py
|
||||
import os
|
||||
from functools import lru_cache
|
||||
|
||||
@lru_cache()
|
||||
def get_paddleocr():
|
||||
if os.getenv('OCR_ENABLE_PADDLEOCR', 'false').lower() == 'true':
|
||||
from paddleocr import PaddleOCR
|
||||
return PaddleOCR(use_angle_cls=True, lang='ro')
|
||||
return None
|
||||
|
||||
@lru_cache()
|
||||
def get_tesseract():
|
||||
if os.getenv('OCR_ENABLE_TESSERACT', 'false').lower() == 'true':
|
||||
import pytesseract
|
||||
return pytesseract
|
||||
return None
|
||||
```
|
||||
|
||||
**Beneficiu**:
|
||||
- Păstrează alternativele pentru viitor
|
||||
- Nu se instalează/încarcă dacă nu sunt necesare
|
||||
- Startup mai rapid când sunt dezactivate
|
||||
- ~500MB saved când `false`
|
||||
|
||||
**Verificare**:
|
||||
- Cu `false`: App pornește fără PaddleOCR/Tesseract instalate
|
||||
- Cu `true`: OCR fallback funcționează
|
||||
|
||||
---
|
||||
|
||||
### 4. Consolidare Design Tokens CSS ✅
|
||||
**ROI**: ⭐⭐⭐ | **Risc**: Scăzut | **Efort**: 1 oră
|
||||
|
||||
**Problema**: 3 fișiere cu tokens overlap: `variables.css`, `tokens.css`, `md3-tokens.css`
|
||||
|
||||
**Soluție**: Consolidează în `src/assets/css/core/design-tokens.css`
|
||||
|
||||
**Pași**:
|
||||
1. Creează `design-tokens.css` unificat
|
||||
2. Migrează variabilele din cele 3 fișiere
|
||||
3. Actualizează importurile în `main.css`
|
||||
4. Șterge fișierele vechi
|
||||
|
||||
**Verificare**: Testează light mode ȘI dark mode pe toate paginile
|
||||
|
||||
---
|
||||
|
||||
## Acțiuni Opționale (Dacă Ai Timp)
|
||||
|
||||
### 5. Split receiptStore (Opțional)
|
||||
**ROI**: ⭐⭐⭐ | **Risc**: Mediu | **Efort**: 2-3 ore
|
||||
|
||||
**Problema**: 606 linii într-un singur store
|
||||
|
||||
**Soluție**: Split în 3 stores (receipts, workflow, nomenclatures)
|
||||
|
||||
**De făcut doar dacă**: Lucrezi frecvent pe data-entry module
|
||||
|
||||
---
|
||||
|
||||
### 6. Simplificare Cache (Opțional)
|
||||
**ROI**: ⭐⭐ | **Risc**: Mediu | **Efort**: 2-3 ore
|
||||
|
||||
**Problema**: 7 fișiere cache, unele nefolosite
|
||||
|
||||
**Soluție**: Reduce la 3 fișiere
|
||||
|
||||
**De făcut doar dacă**: Ai nevoie să modifici cache logic
|
||||
|
||||
---
|
||||
|
||||
## Impact Total (Acțiuni 1-4)
|
||||
|
||||
| Metrică | Înainte | După | Diferență |
|
||||
|---------|---------|------|-----------|
|
||||
| Linii cod duplicat | ~200 | ~50 | **-150** |
|
||||
| OCR deps obligatorii | 3 | 0 | **opționale via .env** |
|
||||
| Fișiere CSS tokens | 3 | 1 | **-2** |
|
||||
| Store duplication | 42 linii | 0 | **-42** |
|
||||
| Startup time (OCR off) | ~5s | ~2s | **-3s** |
|
||||
| **Timp total** | - | - | **~2.5 ore** |
|
||||
|
||||
---
|
||||
|
||||
## Ordinea Recomandată
|
||||
|
||||
1. **[15 min]** Elimină store duplication
|
||||
2. **[30 min]** Factory pentru API services
|
||||
3. **[30 min]** OCR dependencies opționale (lazy loading)
|
||||
4. **[1 oră]** Consolidare CSS tokens
|
||||
|
||||
**Total**: ~2.5 ore pentru toate 4 acțiunile principale
|
||||
|
||||
---
|
||||
|
||||
## Verificare Finală
|
||||
|
||||
După fiecare acțiune:
|
||||
- [ ] App pornește fără erori
|
||||
- [ ] Login funcționează
|
||||
- [ ] Un raport se încarcă
|
||||
- [ ] O chitanță se creează
|
||||
- [ ] Dark mode arată corect
|
||||
|
||||
---
|
||||
|
||||
## Ce NU Schimbăm
|
||||
|
||||
- ✅ Arhitectura Layered - potrivită pentru echipa de 1-2 devs
|
||||
- ✅ Module isolation (reports, data-entry, telegram)
|
||||
- ✅ Router/Store Factory patterns
|
||||
- ✅ Auth middleware
|
||||
- ✅ Cache decorator `@cached`
|
||||
- ✅ Oracle pool singleton
|
||||
|
||||
---
|
||||
|
||||
*Plan simplificat: doar curățare cod cu randament mare și risc minim.*
|
||||
96
.claude/rules/financial-indicators.md
Normal file
96
.claude/rules/financial-indicators.md
Normal file
@@ -0,0 +1,96 @@
|
||||
# Claude Rules: Financial Indicators
|
||||
<!-- paths: backend/modules/reports/services/financial_indicators_service.py, backend/modules/reports/services/dashboard_service.py, backend/modules/reports/models/financial_indicators.py -->
|
||||
|
||||
## Surse de Date - OBLIGATORIU
|
||||
|
||||
### Preferință: VBAL (Balanța de Verificare)
|
||||
|
||||
**ÎNTOTDEAUNA** folosește tabelul `VBAL` pentru calculul indicatorilor financiari, NU `vbalanta_parteneri`.
|
||||
|
||||
| Indicator | Tabel | Conturi | Coloane |
|
||||
|-----------|-------|---------|---------|
|
||||
| Vânzări/Cifra Afaceri | VBAL | 70x | TOTCRED - TOTDEB(709) |
|
||||
| Cheltuieli | VBAL | 6x | TOTDEB - TOTCRED(609) |
|
||||
| Încasări clienți | VBAL | 4111, 461 | RULCRED (lunar), TOTCRED (YTD) |
|
||||
| Plăți furnizori | VBAL | 401, 404, 462 | RULDEB (lunar), TOTDEB (YTD) |
|
||||
| Solduri bilanțiere | VBAL | diverse | SOLDDEB, SOLDCRED |
|
||||
|
||||
### Excepție: ACT (Registru Jurnal)
|
||||
|
||||
Pentru **Achiziții YTD** se folosește tabelul `ACT` deoarece captează și achizițiile directe pe cheltuieli (6x = 4x):
|
||||
|
||||
```sql
|
||||
-- Achiziții totale (stocuri + cheltuieli directe)
|
||||
SELECT SUM(CASE WHEN (SCD LIKE '3%' OR SCD LIKE '6%')
|
||||
AND (SCC LIKE '4%' OR SCC LIKE '46%')
|
||||
THEN SUMA ELSE 0 END)
|
||||
FROM ACT WHERE STERS = 0
|
||||
```
|
||||
|
||||
## Structura VBAL
|
||||
|
||||
```sql
|
||||
SELECT
|
||||
cont, -- Cont contabil (ex: '4111', '701')
|
||||
solddeb1, -- Sold debitor la 1 ianuarie
|
||||
soldcred1, -- Sold creditor la 1 ianuarie
|
||||
ruldeb, -- Rulaj DEBIT luna curentă
|
||||
rulcred, -- Rulaj CREDIT luna curentă
|
||||
totdeb, -- Total DEBIT YTD (de la 1 ianuarie)
|
||||
totcred, -- Total CREDIT YTD (de la 1 ianuarie)
|
||||
solddeb, -- Sold final debitor
|
||||
soldcred -- Sold final creditor
|
||||
FROM {schema}.VBAL
|
||||
WHERE AN = :an AND LUNA = :luna
|
||||
```
|
||||
|
||||
### Când să folosești fiecare coloană:
|
||||
|
||||
| Nevoie | Coloană | Exemplu |
|
||||
|--------|---------|---------|
|
||||
| Valoare lunară | `RULDEB`, `RULCRED` | Încasări luna curentă |
|
||||
| Valoare YTD | `TOTDEB`, `TOTCRED` | Cifra de Afaceri YTD |
|
||||
| Sold curent | `SOLDDEB`, `SOLDCRED` | Sold clienți |
|
||||
| Sold început an | `SOLDDEB1`, `SOLDCRED1` | Active la 1 ianuarie |
|
||||
|
||||
## TVA în Indicatori
|
||||
|
||||
### Cu TVA (fluxuri de numerar reale):
|
||||
- ✅ Cash Flow (încasări/plăți)
|
||||
- ✅ Solduri clienți/furnizori
|
||||
- ✅ DSO, DPO (zile încasare/plată)
|
||||
|
||||
### Fără TVA (indicatori economici):
|
||||
- ✅ Cifra de Afaceri (Clasa 7)
|
||||
- ✅ Cheltuieli (Clasa 6)
|
||||
- ✅ Profit Brut
|
||||
- ✅ Achiziții (din ACT)
|
||||
|
||||
## Pattern-uri de Cod
|
||||
|
||||
### Query VBAL cu agregare pe conturi:
|
||||
|
||||
```python
|
||||
query = f"""
|
||||
SELECT
|
||||
NVL(SUM(CASE WHEN CONT LIKE '70%' THEN TOTCRED ELSE 0 END), 0) -
|
||||
NVL(SUM(CASE WHEN CONT = '709' THEN TOTDEB ELSE 0 END), 0) as cifra_afaceri
|
||||
FROM {schema}.VBAL
|
||||
WHERE AN = :an AND LUNA = :luna
|
||||
"""
|
||||
```
|
||||
|
||||
### Cache decorator:
|
||||
|
||||
```python
|
||||
@staticmethod
|
||||
@cached(cache_type='fin_indicator_name', key_params=['company_id', 'luna', 'an'])
|
||||
async def get_indicator(...):
|
||||
...
|
||||
```
|
||||
|
||||
## NU folosi
|
||||
|
||||
- ❌ `vbalanta_parteneri` pentru calcule agregate (doar pentru rapoarte pe parteneri)
|
||||
- ❌ `SOLDDEB`/`SOLDCRED` pentru Clasa 6/7 (conturile se închid lunar, sold=0)
|
||||
- ❌ Hardcodare valori TVA (19%, 9%) în formule
|
||||
@@ -1,627 +0,0 @@
|
||||
# Frontend Style Audit - Handover Document
|
||||
|
||||
**Data:** 2025-01-06
|
||||
**Sesiune:** Audit CSS cu Playwright
|
||||
**Status:** ✅ COMPLETAT (2025-01-06)
|
||||
|
||||
## ✅ REZUMAT FINAL
|
||||
|
||||
### Ce s-a implementat:
|
||||
1. **Theme Toggle Button** - Buton în header cu 3 stări (auto/light/dark)
|
||||
2. **CSS Dark Mode Variables** - `variables.css` cu `[data-theme="dark"]` și media query
|
||||
3. **PrimeVue Overrides Centralizate** - Toate `:deep()` mutate în `vendor/primevue-overrides.css`
|
||||
4. **Design Tokens** - Înlocuite ~500+ culori hardcodate cu variabile CSS
|
||||
|
||||
### Fișiere modificate:
|
||||
- `src/shared/components/layout/AppHeader.vue` - Theme toggle button
|
||||
- `src/assets/css/core/variables.css` - Dark mode variables
|
||||
- `src/shared/styles/layout/header.css` - Theme toggle styles
|
||||
- `src/assets/css/vendor/primevue-overrides.css` - PrimeVue centralized overrides
|
||||
- `src/modules/data-entry/views/receipts/ReceiptsListView.vue`
|
||||
- `src/modules/data-entry/views/receipts/ReceiptCreateView.vue`
|
||||
- `src/modules/data-entry/components/ocr/OCRPreview.vue`
|
||||
- `src/modules/data-entry/components/ocr/OCRUploadZone.vue`
|
||||
- `src/modules/reports/views/InvoicesView.vue`
|
||||
- `src/modules/data-entry/views/OCRMetricsView.vue`
|
||||
- `src/modules/reports/components/dashboard/DetailedDataTable.vue`
|
||||
- `src/modules/reports/views/ServerLogsView.vue`
|
||||
- `src/modules/reports/views/TelegramView.vue`
|
||||
|
||||
### Teste Playwright (screenshot-uri în `.playwright-mcp/`):
|
||||
- `test-dashboard-light-mode.png` ✅
|
||||
- `test-dashboard-dark-mode.png` ✅
|
||||
- `test-receipts-list-dark-mode.png` ✅
|
||||
- `test-receipt-create-dark-mode.png` ✅
|
||||
|
||||
---
|
||||
|
||||
---
|
||||
|
||||
## Context
|
||||
|
||||
Utilizatorul a raportat probleme de stil pe diverse pagini:
|
||||
- Pagini care nu respectă tema sistemului
|
||||
- Fundal alb cu text gri/alb care nu se vede
|
||||
- Header-ul nu este vizibil din cauza schemei de culori
|
||||
- Pagini neunitare ca stil pe mobil vs desktop
|
||||
|
||||
Am folosit **Playwright MCP** pentru a testa vizual toate paginile la rezoluții desktop (1920x1080) și mobil (375x812), apoi am analizat codul sursă pentru a identifica problemele CSS.
|
||||
|
||||
**Credențiale folosite pentru testare:**
|
||||
- Username: `MARIUS M`
|
||||
- Password: `PAROLA9911`
|
||||
- Firma: `ROMFAST SRL`
|
||||
|
||||
---
|
||||
|
||||
## Rezultate Audit Vizual (Playwright)
|
||||
|
||||
### Screenshot-uri salvate în `.playwright-mcp/`:
|
||||
- `desktop-home-1920x1080.png` - Dashboard desktop
|
||||
- `desktop-invoices-1920x1080.png` - Facturi desktop
|
||||
- `desktop-trial-balance-1920x1080.png` - Balanță verificare desktop
|
||||
- `desktop-data-entry-list-1920x1080.png` - Lista bonuri desktop
|
||||
- `desktop-data-entry-create-1920x1080.png` - Formular bon desktop
|
||||
- `mobile-dashboard-375x812.png` - Dashboard mobil
|
||||
- `mobile-invoices-375x812.png` - Facturi mobil
|
||||
- `mobile-data-entry-list-375x812.png` - Lista bonuri mobil
|
||||
- `mobile-data-entry-create-375x812.png` - Formular bon mobil
|
||||
|
||||
### Concluzii vizuale:
|
||||
- ✅ Header-ul este vizibil pe toate paginile (desktop și mobil)
|
||||
- ✅ Textul este lizibil - nu am găsit probleme majore de contrast
|
||||
- ✅ Meniul hamburger funcționează pe mobil
|
||||
- ✅ Formularele și tabelele sunt vizibile
|
||||
- ⚠️ Stilurile sunt inconsistente (culori hardcodate vs design tokens)
|
||||
|
||||
---
|
||||
|
||||
## 🌓 Analiză Dark Mode / Light Mode
|
||||
|
||||
### Status Actual Dark Mode
|
||||
|
||||
| Aspect | Status | Detalii |
|
||||
|--------|--------|---------|
|
||||
| **CSS Variables** | ✅ Parțial implementat | `variables.css` are `@media (prefers-color-scheme: dark)` |
|
||||
| **PrimeVue Theme** | ❌ Light Only | Folosește `saga-blue` (doar light mode) |
|
||||
| **Componente Custom** | ❌ Nu suportă | Culori hardcodate nu se adaptează |
|
||||
|
||||
### Configurație Dark Mode în Cod
|
||||
|
||||
**Fișier:** `src/assets/css/core/variables.css` (liniile 156-184)
|
||||
```css
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--color-text: #f9fafb;
|
||||
--color-bg: #111827;
|
||||
--color-bg-secondary: #1f2937;
|
||||
--surface-50: #020617;
|
||||
/* ... alte variabile */
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**PrimeVue Theme:** `src/main.js` (linia 42)
|
||||
```javascript
|
||||
import 'primevue/resources/themes/saga-blue/theme.css' // LIGHT ONLY!
|
||||
```
|
||||
|
||||
### Screenshot-uri Dark Mode (Playwright Test)
|
||||
|
||||
Salvate în `.playwright-mcp/`:
|
||||
- `dark-mode-dashboard.png` - ✅ Dashboard arată bine
|
||||
- `dark-mode-receipts-list.png` - ✅ Lista bonuri OK (cu eroare API)
|
||||
- `dark-mode-receipt-create.png` - ❌ **PROBLEMĂ CRITICĂ** - Formular cu fundal ALB!
|
||||
- `dark-mode-invoices.png` - ⚠️ Card cu fundal mai deschis
|
||||
|
||||
### 🔴 PROBLEME CRITICE DARK MODE
|
||||
|
||||
#### 1. Formularul Bon Nou - Fundal Alb pe Dark Mode
|
||||
**Fișier:** `src/modules/data-entry/views/receipts/ReceiptCreateView.vue`
|
||||
|
||||
**Problema:** Card-ul formularului are `background: white` hardcodat care NU se adaptează la dark mode.
|
||||
|
||||
**Screenshot:** Vezi `dark-mode-receipt-create.png` - formularul are fundal complet alb pe pagină dark.
|
||||
|
||||
**Corecție necesară:**
|
||||
```css
|
||||
/* ❌ GREȘIT */
|
||||
.form-card {
|
||||
background: white;
|
||||
}
|
||||
|
||||
/* ✅ CORECT */
|
||||
.form-card {
|
||||
background: var(--surface-card, var(--color-bg));
|
||||
}
|
||||
```
|
||||
|
||||
#### 2. OCR Upload Zone - Fundal Hardcodat
|
||||
**Fișier:** `src/modules/data-entry/components/ocr/OCRUploadZone.vue`
|
||||
|
||||
**Problema:** Zona de upload are culori hardcodate (#f8fafc, #cbd5e1).
|
||||
|
||||
#### 3. PrimeVue Components - Nu Suportă Dark Mode
|
||||
**Cauza:** Tema `saga-blue` este DOAR pentru light mode.
|
||||
|
||||
**Soluții posibile:**
|
||||
1. **Schimbă tema** la `lara-dark-blue` sau `aura-dark-blue` pentru dark mode
|
||||
2. **Folosește theme switching** cu două teme (light + dark)
|
||||
3. **Override PrimeVue variables** în `primevue-overrides.css`
|
||||
|
||||
### Componente Afectate de Dark Mode
|
||||
|
||||
| Componentă | Problemă | Severitate |
|
||||
|------------|----------|------------|
|
||||
| `ReceiptCreateView.vue` | Fundal alb hardcodat | 🔴 CRITIC |
|
||||
| `OCRUploadZone.vue` | Culori hardcodate pe dropzone | 🔴 CRITIC |
|
||||
| `OCRPreview.vue` | Fundal alb pe card results | 🔴 CRITIC |
|
||||
| `ReceiptsListView.vue` | Card-uri cu fundal alb | 🟡 MEDIU |
|
||||
| `InvoicesView.vue` | Table background hardcodat | 🟡 MEDIU |
|
||||
| `DetailedDataTable.vue` | `background: #ffffff` | 🟡 MEDIU |
|
||||
|
||||
### Strategia Recomandată pentru Dark Mode
|
||||
|
||||
**Opțiunea 1 - Quick Fix (Recomandat pentru acum):**
|
||||
1. Înlocuiește toate `background: white` / `#ffffff` cu `var(--surface-card)`
|
||||
2. Înlocuiește culori text hardcodate cu `var(--text-color)`
|
||||
3. CSS variables se vor adapta automat la `prefers-color-scheme: dark`
|
||||
|
||||
**Opțiunea 2 - Full Dark Mode Support (Viitor):**
|
||||
1. Adaugă theme switcher în UI
|
||||
2. Schimbă PrimeVue theme dinamic (`saga-blue` ↔ `lara-dark-blue`)
|
||||
3. Salvează preferința user în localStorage
|
||||
|
||||
### Testare Dark Mode cu Playwright
|
||||
|
||||
Pentru a testa dark mode, folosește:
|
||||
```javascript
|
||||
// Activează dark mode în Playwright
|
||||
await page.emulateMedia({ colorScheme: 'dark' });
|
||||
|
||||
// Ia screenshot
|
||||
await page.screenshot({ path: 'dark-mode-test.png' });
|
||||
```
|
||||
|
||||
Sau în tool MCP:
|
||||
```
|
||||
mcp__plugin_playwright_playwright__browser_run_code
|
||||
code: "async (page) => { await page.emulateMedia({ colorScheme: 'dark' }); }"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Probleme Identificate în Cod
|
||||
|
||||
### 1. Culori Hardcodate (~500+ instanțe) - CRITIC
|
||||
|
||||
| Fișier | Probleme | Severitate |
|
||||
|--------|----------|------------|
|
||||
| `src/modules/data-entry/components/ocr/OCRPreview.vue` | ~80 culori hardcodate | 🔴 CRITIC |
|
||||
| `src/modules/data-entry/views/receipts/ReceiptCreateView.vue` | ~100+ culori hardcodate | 🔴 CRITIC |
|
||||
| `src/modules/data-entry/views/receipts/ReceiptsListView.vue` | ~50+ culori hardcodate | 🔴 CRITIC |
|
||||
| `src/modules/data-entry/views/OCRMetricsView.vue` | ~70+ culori hardcodate | 🔴 CRITIC |
|
||||
| `src/modules/reports/components/dashboard/cards/MaturityAndDetailsCard.vue` | ~100+ culori | 🟡 MEDIU |
|
||||
| `src/modules/reports/components/dashboard/cards/ClientsFurnizoriBalanceCard.vue` | ~50+ culori | 🟡 MEDIU |
|
||||
| `src/modules/data-entry/components/ocr/OCRUploadZone.vue` | ~30+ culori | 🟡 MEDIU |
|
||||
| `src/modules/data-entry/components/ocr/OCRConfidenceIndicator.vue` | ~10 culori | 🟢 MINOR |
|
||||
|
||||
**Exemple de cod problematic:**
|
||||
```css
|
||||
/* ❌ GREȘIT - culori hardcodate */
|
||||
background: #f8fafc;
|
||||
color: #64748b;
|
||||
border: 1px solid #e2e8f0;
|
||||
background: #dcfce7;
|
||||
color: #166534;
|
||||
|
||||
/* ✅ CORECT - design tokens */
|
||||
background: var(--surface-ground);
|
||||
color: var(--text-color-secondary);
|
||||
border: 1px solid var(--surface-border);
|
||||
background: var(--green-100);
|
||||
color: var(--green-800);
|
||||
```
|
||||
|
||||
### 2. Utilizare `:deep()` - ÎNCĂLCARE REGULI CSS (22 instanțe)
|
||||
|
||||
Conform `docs/CSS_PATTERNS.md`, `:deep()` nu trebuie folosit în componente. Override-urile PrimeVue trebuie mutate în `src/assets/css/vendor/`.
|
||||
|
||||
| Fișier | Linii cu `:deep()` |
|
||||
|--------|-------------------|
|
||||
| `src/modules/reports/views/InvoicesView.vue` | 882, 886, 890, 894 |
|
||||
| `src/modules/data-entry/views/receipts/ReceiptCreateView.vue` | 2715, 2720, 2724, 2729, 2738, 2743, 2775, 2779, 2962-2964 |
|
||||
| `src/modules/data-entry/views/receipts/ReceiptsListView.vue` | 1071, 1076, 1081, 1386 |
|
||||
| `src/modules/data-entry/components/ocr/OCRUploadZone.vue` | 525, 531 |
|
||||
| `src/modules/data-entry/components/ocr/OCRPreview.vue` | 726 |
|
||||
|
||||
### 3. `background: white` / `#ffffff` hardcodat (12 instanțe)
|
||||
|
||||
```
|
||||
src/modules/reports/views/ServerLogsView.vue:346 - background: #ffffff
|
||||
src/modules/reports/views/TelegramView.vue:285 - background: white
|
||||
src/modules/reports/components/dashboard/DetailedDataTable.vue - 3 instanțe (#ffffff)
|
||||
src/modules/data-entry/components/ocr/OCRPreview.vue:687 - background: white
|
||||
src/modules/data-entry/views/OCRMetricsView.vue - 3 instanțe (white)
|
||||
src/modules/data-entry/views/receipts/ReceiptCreateView.vue - 2 instanțe (#fff3e0)
|
||||
src/modules/data-entry/views/receipts/ReceiptsListView.vue:1100 - background: white
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Mapping Culori Hardcodate → Design Tokens
|
||||
|
||||
| Hardcoded | Design Token | Utilizare |
|
||||
|-----------|--------------|-----------|
|
||||
| `#ffffff`, `white` | `var(--surface-card)` | Fundal carduri |
|
||||
| `#f8fafc`, `#f8f9fa` | `var(--surface-ground)` | Fundal pagină |
|
||||
| `#f1f5f9` | `var(--surface-hover)` | Hover state |
|
||||
| `#e2e8f0`, `#e5e7eb` | `var(--surface-border)` | Borduri |
|
||||
| `#64748b`, `#6b7280` | `var(--text-color-secondary)` | Text secundar |
|
||||
| `#1e293b`, `#111827`, `#334155` | `var(--text-color)` | Text principal |
|
||||
| `#94a3b8`, `#9ca3af` | `var(--text-color-secondary)` | Text muted |
|
||||
| `#22c55e`, `#16a34a` | `var(--green-500)`, `var(--green-600)` | Success |
|
||||
| `#dcfce7`, `#d1fae5` | `var(--green-100)` | Success background |
|
||||
| `#166534`, `#15803d` | `var(--green-800)`, `var(--green-700)` | Success dark |
|
||||
| `#ef4444`, `#dc2626` | `var(--red-500)`, `var(--red-600)` | Error/Danger |
|
||||
| `#fee2e2`, `#fecaca` | `var(--red-100)` | Error background |
|
||||
| `#991b1b`, `#b91c1c` | `var(--red-800)`, `var(--red-700)` | Error dark |
|
||||
| `#f59e0b`, `#d97706` | `var(--yellow-500)`, `var(--yellow-600)` | Warning |
|
||||
| `#fef3c7`, `#fef9c3` | `var(--yellow-100)` | Warning background |
|
||||
| `#92400e`, `#854d0e` | `var(--yellow-800)` | Warning dark |
|
||||
| `#3b82f6`, `#2563eb` | `var(--primary-500)`, `var(--primary-600)` | Primary |
|
||||
| `#dbeafe`, `#e0e7ff` | `var(--primary-100)` | Primary background |
|
||||
| `#1e40af`, `#1d4ed8` | `var(--primary-800)`, `var(--primary-700)` | Primary dark |
|
||||
| `#667eea` | `var(--primary-400)` | Primary light |
|
||||
| `#6366f1` | `var(--primary-500)` | Indigo/Primary |
|
||||
|
||||
---
|
||||
|
||||
## Plan de Acțiune
|
||||
|
||||
### ✅ COMPLETAT - Theme Toggle & Dark Mode Infrastructure
|
||||
|
||||
| Task | Status | Detalii |
|
||||
|------|--------|---------|
|
||||
| Theme Toggle Button | ✅ DONE | `AppHeader.vue:39-47` - buton 3 stări (auto/light/dark) |
|
||||
| Dark Mode CSS Variables | ✅ DONE | `variables.css:223-373` - `[data-theme="dark"]` + media query |
|
||||
| Theme Toggle Styles | ✅ DONE | `header.css:135-169` - stiluri + gradient variant |
|
||||
|
||||
### Prioritate 1 - CRITICĂ (Impact mare, folosite frecvent)
|
||||
|
||||
#### 1.1. `ReceiptsListView.vue` (~50 corecții)
|
||||
- [x] Înlocuiește `background: white` → `var(--surface-card)` ✅
|
||||
- [x] Înlocuiește `#f8fafc` → `var(--surface-ground)` ✅
|
||||
- [x] Înlocuiește `#e2e8f0` → `var(--surface-border)` ✅
|
||||
- [x] Înlocuiește `#64748b` → `var(--text-color-secondary)` ✅
|
||||
- [x] Înlocuiește `#1e293b` → `var(--text-color)` ✅
|
||||
- [x] Mută `:deep()` CSS în `vendor/primevue-overrides.css` ✅
|
||||
|
||||
#### 1.2. `ReceiptCreateView.vue` (~100 corecții)
|
||||
- [x] Înlocuiește toate culorile hardcodate conform mapping-ului ✅
|
||||
- [x] Mută `:deep()` CSS (12 instanțe) în `vendor/primevue-overrides.css` ✅
|
||||
|
||||
#### 1.3. `OCRPreview.vue` (~80 corecții)
|
||||
- [x] Înlocuiește toate culorile green (#f0fdf4, #dcfce7, #86efac, #166534) ✅
|
||||
- [x] Înlocuiește toate culorile slate (#f8fafc, #e2e8f0, #64748b) ✅
|
||||
- [x] Mută `:deep()` (1 instanță) în `vendor/primevue-overrides.css` ✅
|
||||
|
||||
### Prioritate 2 - MEDIE (Impact moderat)
|
||||
|
||||
#### 2.1. `OCRMetricsView.vue` (~70 corecții)
|
||||
- [x] Fix 3x `background: white` → `var(--surface-card)` ✅
|
||||
|
||||
#### 2.2. `OCRUploadZone.vue` (~30 corecții)
|
||||
- [x] Înlocuiește culorile pentru drop zone și states ✅
|
||||
- [x] Mută `:deep()` (2 instanțe) în `vendor/primevue-overrides.css` ✅
|
||||
|
||||
#### 2.3. `InvoicesView.vue` (4 corecții)
|
||||
- [x] Mută `:deep()` în `vendor/primevue-overrides.css` ✅
|
||||
|
||||
### Prioritate 3 - JOASĂ (Dashboard cards)
|
||||
|
||||
- [x] `DetailedDataTable.vue` - 3x `background: white` → `var(--surface-card)` ✅
|
||||
- [x] `ServerLogsView.vue` - 1x `background: white` → `var(--surface-card)` ✅
|
||||
- [x] `TelegramView.vue` - 1x `background: white` → `var(--surface-card)` ✅
|
||||
|
||||
### ⏳ Rămase pentru viitor (P3 - opțional)
|
||||
- [ ] `MaturityAndDetailsCard.vue` - audit culori hardcodate
|
||||
- [ ] `ClientsFurnizoriBalanceCard.vue` - audit culori hardcodate
|
||||
- [ ] Alte carduri din `src/modules/reports/components/dashboard/cards/`
|
||||
|
||||
---
|
||||
|
||||
## Testare cu Playwright MCP
|
||||
|
||||
### Pregătire Mediu
|
||||
|
||||
```bash
|
||||
# 1. Pornește aplicația
|
||||
./start-prod.sh
|
||||
|
||||
# 2. Așteaptă până serviciile sunt active
|
||||
# - Backend: http://localhost:8000
|
||||
# - Frontend: http://localhost:3000
|
||||
```
|
||||
|
||||
### Workflow Testare după Corecții
|
||||
|
||||
După fiecare fișier corectat, execută următorii pași cu Playwright MCP:
|
||||
|
||||
#### Pas 1: Login și Navigare
|
||||
|
||||
```
|
||||
# Folosește tool-urile MCP în ordine:
|
||||
|
||||
1. mcp__plugin_playwright_playwright__browser_navigate
|
||||
url: "http://localhost:3000"
|
||||
|
||||
2. mcp__plugin_playwright_playwright__browser_snapshot
|
||||
# Verifică că pagina login s-a încărcat
|
||||
|
||||
3. mcp__plugin_playwright_playwright__browser_type
|
||||
element: "Username input field"
|
||||
ref: [ref din snapshot pentru input username]
|
||||
text: "MARIUS M"
|
||||
|
||||
4. mcp__plugin_playwright_playwright__browser_type
|
||||
element: "Password input field"
|
||||
ref: [ref din snapshot pentru input password]
|
||||
text: "PAROLA9911"
|
||||
submit: true
|
||||
|
||||
5. mcp__plugin_playwright_playwright__browser_wait_for
|
||||
time: 2 # Așteaptă 2 secunde pentru login
|
||||
|
||||
6. mcp__plugin_playwright_playwright__browser_snapshot
|
||||
# Verifică că ești logat (ar trebui să vezi Dashboard)
|
||||
```
|
||||
|
||||
#### Pas 2: Testare Desktop (1920x1080)
|
||||
|
||||
```
|
||||
1. mcp__plugin_playwright_playwright__browser_resize
|
||||
width: 1920
|
||||
height: 1080
|
||||
|
||||
2. # Pentru fiecare pagină modificată:
|
||||
|
||||
# Lista Bonuri
|
||||
mcp__plugin_playwright_playwright__browser_navigate
|
||||
url: "http://localhost:3000/data-entry"
|
||||
|
||||
mcp__plugin_playwright_playwright__browser_take_screenshot
|
||||
filename: "test-receipts-list-desktop.png"
|
||||
|
||||
# Formular Bon Nou
|
||||
mcp__plugin_playwright_playwright__browser_navigate
|
||||
url: "http://localhost:3000/data-entry/create"
|
||||
|
||||
mcp__plugin_playwright_playwright__browser_take_screenshot
|
||||
filename: "test-receipt-create-desktop.png"
|
||||
|
||||
# Dashboard
|
||||
mcp__plugin_playwright_playwright__browser_navigate
|
||||
url: "http://localhost:3000/reports/dashboard"
|
||||
|
||||
mcp__plugin_playwright_playwright__browser_take_screenshot
|
||||
filename: "test-dashboard-desktop.png"
|
||||
|
||||
# Facturi
|
||||
mcp__plugin_playwright_playwright__browser_navigate
|
||||
url: "http://localhost:3000/reports/invoices"
|
||||
|
||||
mcp__plugin_playwright_playwright__browser_take_screenshot
|
||||
filename: "test-invoices-desktop.png"
|
||||
```
|
||||
|
||||
#### Pas 3: Testare Mobile (375x812)
|
||||
|
||||
```
|
||||
1. mcp__plugin_playwright_playwright__browser_resize
|
||||
width: 375
|
||||
height: 812
|
||||
|
||||
2. # Repetă pentru aceleași pagini:
|
||||
|
||||
mcp__plugin_playwright_playwright__browser_navigate
|
||||
url: "http://localhost:3000/data-entry"
|
||||
|
||||
mcp__plugin_playwright_playwright__browser_take_screenshot
|
||||
filename: "test-receipts-list-mobile.png"
|
||||
|
||||
mcp__plugin_playwright_playwright__browser_navigate
|
||||
url: "http://localhost:3000/data-entry/create"
|
||||
|
||||
mcp__plugin_playwright_playwright__browser_take_screenshot
|
||||
filename: "test-receipt-create-mobile.png"
|
||||
|
||||
# etc.
|
||||
```
|
||||
|
||||
#### Pas 4: Verificare Vizuală
|
||||
|
||||
După capturarea screenshot-urilor, citește-le cu tool-ul Read:
|
||||
|
||||
```
|
||||
Read file_path: "/workspace/roa2web/.playwright-mcp/test-receipts-list-desktop.png"
|
||||
Read file_path: "/workspace/roa2web/.playwright-mcp/test-receipts-list-mobile.png"
|
||||
```
|
||||
|
||||
### Checklist Verificare Vizuală
|
||||
|
||||
Pentru fiecare screenshot, verifică:
|
||||
|
||||
| Element | Ce să verifici | ✓/✗ |
|
||||
|---------|----------------|-----|
|
||||
| **Header** | Vizibil, logo ROA2WEB citibil, meniu hamburger pe mobil | |
|
||||
| **Text principal** | Contrast suficient, citibil pe fundal | |
|
||||
| **Text secundar** | Vizibil dar mai subtle decât cel principal | |
|
||||
| **Butoane** | Culori corecte (primary=albastru, success=verde, danger=roșu) | |
|
||||
| **Carduri** | Fundal diferențiat de background pagină | |
|
||||
| **Borduri** | Vizibile dar subtile | |
|
||||
| **Badge-uri status** | Culori distincte per status (CIORNĂ=albastru, APROBAT=verde, etc.) | |
|
||||
| **Formulare** | Input-uri vizibile, labels citibile | |
|
||||
| **Tabele** | Alternare rânduri vizibilă, header distinct | |
|
||||
|
||||
### Pagini de Testat
|
||||
|
||||
| URL | Fișiere Afectate | Prioritate |
|
||||
|-----|------------------|------------|
|
||||
| `/data-entry` | ReceiptsListView.vue | P1 |
|
||||
| `/data-entry/create` | ReceiptCreateView.vue, OCRPreview.vue, OCRUploadZone.vue | P1 |
|
||||
| `/data-entry/edit/:id` | ReceiptCreateView.vue (same component) | P1 |
|
||||
| `/reports/dashboard` | Dashboard cards | P3 |
|
||||
| `/reports/invoices` | InvoicesView.vue | P2 |
|
||||
| `/reports/trial-balance` | TrialBalanceView.vue | P3 |
|
||||
| `/reports/bank-cash` | BankCashView.vue | P3 |
|
||||
|
||||
### Comparare Before/After
|
||||
|
||||
Screenshot-urile BEFORE sunt deja salvate în `.playwright-mcp/`:
|
||||
- `desktop-data-entry-list-1920x1080.png`
|
||||
- `desktop-data-entry-create-1920x1080.png`
|
||||
- `mobile-data-entry-list-375x812.png`
|
||||
- `mobile-data-entry-create-375x812.png`
|
||||
|
||||
După corecții, compară vizual cu cele noi pentru a te asigura că:
|
||||
1. Nu s-au pierdut stiluri
|
||||
2. Contrastul s-a îmbunătățit sau a rămas la fel
|
||||
3. Layout-ul este identic
|
||||
|
||||
### Script Automatizat Testare
|
||||
|
||||
Pentru testare rapidă, poți folosi acest flow:
|
||||
|
||||
```javascript
|
||||
// Pseudo-cod pentru testare completă
|
||||
async function testAllPages() {
|
||||
// Login
|
||||
await navigate('http://localhost:3000')
|
||||
await login('MARIUS M', 'PAROLA9911')
|
||||
|
||||
const pages = [
|
||||
'/data-entry',
|
||||
'/data-entry/create',
|
||||
'/reports/dashboard',
|
||||
'/reports/invoices',
|
||||
'/reports/trial-balance'
|
||||
]
|
||||
|
||||
// Desktop
|
||||
await resize(1920, 1080)
|
||||
for (const page of pages) {
|
||||
await navigate(`http://localhost:3000${page}`)
|
||||
await screenshot(`after-desktop-${page.replace(/\//g, '-')}.png`)
|
||||
}
|
||||
|
||||
// Mobile
|
||||
await resize(375, 812)
|
||||
for (const page of pages) {
|
||||
await navigate(`http://localhost:3000${page}`)
|
||||
await screenshot(`after-mobile-${page.replace(/\//g, '-')}.png`)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Troubleshooting Playwright
|
||||
|
||||
| Problemă | Soluție |
|
||||
|----------|---------|
|
||||
| Browser not installed | `mcp__plugin_playwright_playwright__browser_install` |
|
||||
| Timeout la navigate | Crește timeout sau verifică că serverul rulează |
|
||||
| Element not found | Fă `browser_snapshot` și verifică ref-urile disponibile |
|
||||
| Screenshot gol/alb | Așteaptă cu `browser_wait_for` înainte de screenshot |
|
||||
|
||||
---
|
||||
|
||||
## Documentație Relevantă
|
||||
|
||||
Înainte de a începe corecțiile, citește:
|
||||
1. `docs/CSS_PATTERNS.md` - Toate pattern-urile CSS aprobate
|
||||
2. `docs/DESIGN_TOKENS.md` - Lista completă de design tokens
|
||||
3. `docs/ONBOARDING_CSS.md` - Quick start pentru CSS system
|
||||
|
||||
---
|
||||
|
||||
## Comenzi Utile
|
||||
|
||||
```bash
|
||||
# Pornește mediul de dezvoltare
|
||||
./start-prod.sh
|
||||
|
||||
# Verifică modificările vizual
|
||||
# Navighează la http://localhost:3000
|
||||
|
||||
# Găsește toate culorile hardcodate într-un fișier
|
||||
grep -n "#[0-9a-fA-F]\{6\}" src/modules/data-entry/views/receipts/ReceiptsListView.vue
|
||||
|
||||
# Găsește toate utilizările :deep()
|
||||
grep -rn ":deep(" src/modules/
|
||||
|
||||
# Verifică că nu ai introdus noi hardcodate colors
|
||||
grep -rn "#[0-9a-fA-F]\{6\}" src/modules/ --include="*.vue" | wc -l
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Note pentru Sesiunea Următoare
|
||||
|
||||
1. **Nu modifica logica JavaScript** - doar CSS/stiluri
|
||||
2. **Testează pe mobil după fiecare fișier** - folosește Playwright sau DevTools
|
||||
3. **Commitează incremental** - un fișier per commit pentru ușurință la review
|
||||
4. **Verifică dark mode** dacă există - design tokens sunt compatibile
|
||||
|
||||
---
|
||||
|
||||
## Estimare Efort
|
||||
|
||||
| Prioritate | Fișiere | Corecții | Testare Playwright | Total |
|
||||
|------------|---------|----------|-------------------|-------|
|
||||
| P1 - Critică | 3 fișiere | ~2-3 ore | ~30 min | ~3 ore |
|
||||
| P2 - Medie | 3 fișiere | ~1-2 ore | ~20 min | ~2 ore |
|
||||
| P3 - Joasă | 5+ fișiere | ~2-3 ore | ~30 min | ~3 ore |
|
||||
| **TOTAL** | ~11 fișiere | ~5-8 ore | ~1.5 ore | **~7-10 ore** |
|
||||
|
||||
---
|
||||
|
||||
## Quick Start pentru Sesiunea Următoare
|
||||
|
||||
```bash
|
||||
# 1. Citește acest document
|
||||
cat .claude/sessions/2025-01-06_frontend-style-audit.md
|
||||
|
||||
# 2. Pornește mediul
|
||||
./start-prod.sh
|
||||
|
||||
# 3. Începe cu primul fișier din P1
|
||||
# Fișier: src/modules/data-entry/views/receipts/ReceiptsListView.vue
|
||||
|
||||
# 4. După corecții, testează cu Playwright MCP
|
||||
# - Navigare: http://localhost:3000/data-entry
|
||||
# - Screenshot desktop (1920x1080)
|
||||
# - Screenshot mobile (375x812)
|
||||
# - Compară cu before screenshots din .playwright-mcp/
|
||||
|
||||
# 5. Commit incremental
|
||||
git add src/modules/data-entry/views/receipts/ReceiptsListView.vue
|
||||
git commit -m "refactor(css): Replace hardcoded colors with design tokens in ReceiptsListView"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Fișiere Relevante
|
||||
|
||||
```
|
||||
.claude/sessions/2025-01-06_frontend-style-audit.md # Acest document
|
||||
.playwright-mcp/ # Screenshot-uri BEFORE
|
||||
docs/CSS_PATTERNS.md # Pattern-uri CSS aprobate
|
||||
docs/DESIGN_TOKENS.md # Design tokens disponibile
|
||||
src/assets/css/vendor/ # Locație pentru :deep() overrides
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**Creat de:** Claude Code (Opus 4.5)
|
||||
**Data:** 2025-01-06
|
||||
**Pentru:** Handover către sesiune nouă
|
||||
Reference in New Issue
Block a user