From 74dff2d17dd4fa7b78f52fcd24d8de91858b4bab Mon Sep 17 00:00:00 2001 From: Claude Agent Date: Sun, 1 Mar 2026 08:55:11 +0000 Subject: [PATCH] feat(reports,mobile): add FinancialIndicators page and refactor dashboard layout - Add dedicated FinancialIndicatorsView with its own route - Refactor FinancialIndicatorsCard: simplified collapsible card (no period picker) - Dashboard mobile: reduce swipeable pages from 2 to 1, embed indicators in card-0 - Dashboard desktop: wrap indicators in CollapsibleCard - Update MobileBottomNav defaults: reports-centric nav (Facturi/Banca/Casa/Indicatori) - BankView/CashView: date format DD/MM/YY, remove amount color classes, CSS tweaks Co-Authored-By: Claude Sonnet 4.6 --- src/assets/css/layout/containers.css | 6 +- src/assets/css/vendor/primevue-overrides.css | 19 + .../cards/FinancialIndicatorsCard.vue | 2745 ++--------------- .../dashboard/cards/IndicatorItem.vue | 280 +- src/modules/reports/views/BankView.vue | 61 +- src/modules/reports/views/CashView.vue | 61 +- src/modules/reports/views/DashboardView.vue | 76 +- .../reports/views/DetailedInvoicesView.vue | 45 +- .../reports/views/FinancialIndicatorsView.vue | 1085 +++++++ src/modules/reports/views/InvoicesView.vue | 19 +- .../reports/views/TrialBalanceView.vue | 11 +- src/router/index.js | 6 + .../components/mobile/MobileBottomNav.vue | 16 +- .../components/mobile/MobileDrawerMenu.vue | 5 +- 14 files changed, 1624 insertions(+), 2811 deletions(-) create mode 100644 src/modules/reports/views/FinancialIndicatorsView.vue diff --git a/src/assets/css/layout/containers.css b/src/assets/css/layout/containers.css index 8b1c7d9..ad07a08 100644 --- a/src/assets/css/layout/containers.css +++ b/src/assets/css/layout/containers.css @@ -156,7 +156,7 @@ @media (max-width: 768px) { .app-container, .page-container { - padding: var(--space-md); + padding: var(--space-xs); } /* US-705: Keep main-content padding minimal - app-container handles content spacing */ @@ -171,7 +171,7 @@ .dashboard-container { gap: var(--space-lg); - padding: var(--space-md); + padding: var(--space-xs); } .card-container { @@ -195,7 +195,7 @@ .app-container, .page-container, .dashboard-container { - padding: var(--space-sm); + padding: var(--space-xs); } /* US-705: Keep main-content padding minimal on small screens too */ diff --git a/src/assets/css/vendor/primevue-overrides.css b/src/assets/css/vendor/primevue-overrides.css index 129fb39..1abccb3 100644 --- a/src/assets/css/vendor/primevue-overrides.css +++ b/src/assets/css/vendor/primevue-overrides.css @@ -956,3 +956,22 @@ color: var(--text-color-secondary, #9ca3af) !important; } } + +/* ===== Mobile Layout: Flat Cards (no borders/shadows) ===== */ +/* Applied when parent has .mobile-layout class (isMobile === true). + Removes PrimeVue Card visual frame so content flows as flat list, + consistent with Material Design 3 edge-to-edge pattern. */ +.mobile-layout .p-card { + border: none !important; + box-shadow: none !important; + border-radius: 0 !important; + background: transparent !important; +} + +.mobile-layout .p-card .p-card-body { + padding: var(--space-sm) !important; +} + +.mobile-layout .p-card .p-card-content { + padding: 0 !important; +} diff --git a/src/modules/reports/components/dashboard/cards/FinancialIndicatorsCard.vue b/src/modules/reports/components/dashboard/cards/FinancialIndicatorsCard.vue index 27b34b2..56a4ae4 100644 --- a/src/modules/reports/components/dashboard/cards/FinancialIndicatorsCard.vue +++ b/src/modules/reports/components/dashboard/cards/FinancialIndicatorsCard.vue @@ -1,2542 +1,393 @@ diff --git a/src/modules/reports/components/dashboard/cards/IndicatorItem.vue b/src/modules/reports/components/dashboard/cards/IndicatorItem.vue index cd9d731..27caa53 100644 --- a/src/modules/reports/components/dashboard/cards/IndicatorItem.vue +++ b/src/modules/reports/components/dashboard/cards/IndicatorItem.vue @@ -1,92 +1,77 @@ @@ -94,12 +79,8 @@ diff --git a/src/modules/reports/views/CashView.vue b/src/modules/reports/views/CashView.vue index f572cb9..41e45e2 100644 --- a/src/modules/reports/views/CashView.vue +++ b/src/modules/reports/views/CashView.vue @@ -249,13 +249,11 @@ {{ reg.nume || 'Fără partener' }} -
{{ reg.nume_cont_bancar }} @@ -552,11 +550,12 @@ const formatDate = (dateString) => { return format(new Date(dateString), "dd.MM.yyyy"); }; -// Short date format for mobile cards (DD/MM) +// Short date format for mobile cards (DD/MM/YY) const formatDateShort = (dateString) => { if (!dateString) return ""; const date = new Date(dateString); - return `${String(date.getDate()).padStart(2, "0")}/${String(date.getMonth() + 1).padStart(2, "0")}`; + const year = String(date.getFullYear()).slice(-2); + return `${String(date.getDate()).padStart(2, "0")}/${String(date.getMonth() + 1).padStart(2, "0")}/${year}`; }; // Compact number format @@ -971,8 +970,8 @@ watch( .mobile-layout .register-view { padding-top: calc(56px + var(--space-md)); padding-bottom: calc(56px + var(--space-md)); - padding-left: var(--space-md); - padding-right: var(--space-md); + padding-left: 0; + padding-right: 0; } /* Card Spacing */ @@ -1005,10 +1004,9 @@ watch( .mobile-totals-bar { background: var(--surface-card); - border: 1px solid var(--surface-border); - padding: var(--space-sm) var(--space-md); - margin-bottom: var(--space-md); - border-radius: var(--radius-md); + border-bottom: 1px solid var(--surface-border); + padding: var(--space-sm) var(--space-xs); + margin-bottom: var(--space-sm); } .mobile-totals-grid { @@ -1054,7 +1052,7 @@ watch( display: flex; align-items: center; min-height: 44px; - padding: var(--space-sm) var(--space-md); + padding: var(--space-sm) 0; gap: var(--space-sm); cursor: pointer; } @@ -1064,9 +1062,9 @@ watch( } .compact-date { - font-size: var(--text-xs); + font-size: var(--text-sm); color: var(--text-color-secondary); - min-width: 40px; + min-width: 54px; flex-shrink: 0; } @@ -1083,20 +1081,7 @@ watch( font-weight: var(--font-semibold); font-variant-numeric: tabular-nums; font-size: var(--text-sm); - flex-shrink: 0; -} - -.compact-amount.positive { - color: var(--green-600); -} - -.compact-amount.negative { - color: var(--red-600); -} - -.meta-chevron { - font-size: var(--text-xs); - color: var(--text-color-secondary); + color: var(--text-color); flex-shrink: 0; } @@ -1104,9 +1089,9 @@ watch( display: flex; flex-direction: column; gap: var(--space-xs); - padding: var(--space-xs) var(--space-md) var(--space-sm) calc(40px + var(--space-md) + var(--space-sm)); + padding: var(--space-xs) var(--space-xs) var(--space-sm) calc(54px + var(--space-sm)); background: var(--surface-hover); - font-size: var(--text-xs); + font-size: var(--text-sm); color: var(--text-color-secondary); } @@ -1156,24 +1141,8 @@ watch( Dark Mode Support ================================================ */ -[data-theme="dark"] .compact-amount.positive { - color: var(--green-400); -} - -[data-theme="dark"] .compact-amount.negative { - color: var(--red-400); -} - /* Auto dark mode */ @media (prefers-color-scheme: dark) { - :root:not([data-theme]) .compact-amount.positive { - color: var(--green-400); - } - - :root:not([data-theme]) .compact-amount.negative { - color: var(--red-400); - } - :root:not([data-theme]) .numeric-value.negative { color: var(--red-400); } @@ -1189,7 +1158,7 @@ watch( @media (max-width: 768px) { .register-view { - padding: var(--space-md); + padding: var(--space-xs); } } diff --git a/src/modules/reports/views/DashboardView.vue b/src/modules/reports/views/DashboardView.vue index dd171e3..7c04308 100644 --- a/src/modules/reports/views/DashboardView.vue +++ b/src/modules/reports/views/DashboardView.vue @@ -50,7 +50,7 @@
- + - - @@ -291,22 +286,22 @@
+ + +
- -
- -
- @@ -826,16 +821,6 @@ const handleRefresh = async () => { await loadDashboardData(); }; -// US-014: Handle period change from FinancialIndicatorsCard dropdown -const handleFinancialIndicatorsPeriodChange = async (period) => { - if (!companyStore.selectedCompany || !period) return; - await dashboardStore.loadFinancialIndicators( - companyStore.selectedCompany.id_firma, - period.luna, - period.an, - ); -}; - // Computed property pentru luna curentă - folosește perioada din period selector const currentMonthLabel = computed(() => { // Prioritate: period selector > dashboard current period > loading @@ -856,6 +841,15 @@ const currentMonthLabel = computed(() => { // Computed property pentru luna anterioară - pentru indicatorii financiari // Luna curentă e în lucru, deci folosim luna anterioară pentru date finale +// Summary label for Indicators CollapsibleCard header (desktop) +const indicatorsSummaryLabel = computed(() => { + const d = dashboardStore.financialIndicators.data; + if (!d) return ''; + const marja = d?.profitabilitate?.marja_profit_brut?.value; + if (marja === null || marja === undefined) return ''; + return `${Number(marja).toLocaleString('ro-RO', { minimumFractionDigits: 0, maximumFractionDigits: 0 })}% Marjă`; +}); + const previousPeriodForIndicators = computed(() => { if (!periodStore.selectedPeriod) return null; @@ -1705,10 +1699,7 @@ onUnmounted(() => { } /* US-014: Financial Indicators Section - Desktop Only */ -.financial-indicators-section { - margin-top: var(--space-lg); - width: 100%; -} + /* Mobile Budget Card wrapper (card-6 in SwipeableCards) */ .mobile-budget-card { @@ -1988,11 +1979,7 @@ onUnmounted(() => { box-shadow: none; } -.mobile-kpi-carousel :deep(.financial-indicators-card) { - border: none; - background: transparent; - box-shadow: none; -} +/* FinancialIndicatorsCard now has its own card styling - do NOT strip it */ .mobile-kpi-carousel .mobile-budget-card { border: none; @@ -2031,4 +2018,5 @@ onUnmounted(() => { .solduri-grid-2x2 > * { /* Height auto - only as tall as content needs */ } + diff --git a/src/modules/reports/views/DetailedInvoicesView.vue b/src/modules/reports/views/DetailedInvoicesView.vue index da7dcfb..8ac93b7 100644 --- a/src/modules/reports/views/DetailedInvoicesView.vue +++ b/src/modules/reports/views/DetailedInvoicesView.vue @@ -352,7 +352,6 @@ {{ formatCurrency(group.totalSold) }} -
@@ -590,7 +589,7 @@ const formatDate = (value) => { return date.toLocaleDateString('ro-RO', { day: '2-digit', month: '2-digit', - year: 'numeric' + year: '2-digit' }) } @@ -1455,21 +1454,19 @@ onUnmounted(() => { .mobile-partner-list { display: flex; flex-direction: column; - gap: var(--space-sm); + gap: 0; } .mobile-partner-row { - background: var(--surface-card); - border: 1px solid var(--surface-border); - border-radius: var(--radius-md); - overflow: hidden; + background: transparent; + border-bottom: 1px solid var(--surface-border); } .partner-header { display: flex; justify-content: space-between; align-items: center; - padding: var(--space-sm) var(--space-md); + padding: var(--space-sm) var(--space-xs); cursor: pointer; gap: var(--space-sm); min-height: 44px; @@ -1516,25 +1513,15 @@ onUnmounted(() => { color: var(--text-color); } -.partner-sold.overdue { - color: var(--red-600); -} - -.partner-chevron { - font-size: 12px; - color: var(--text-color-secondary); -} - .partner-invoices { border-top: 1px solid var(--surface-border); - background: var(--surface-hover); } .invoice-line { display: flex; justify-content: space-between; align-items: center; - padding: var(--space-xs) var(--space-md); + padding: var(--space-xs) var(--space-xs); border-bottom: 1px solid var(--surface-border); gap: var(--space-sm); } @@ -1544,24 +1531,20 @@ onUnmounted(() => { } .invoice-ref { - font-size: var(--text-xs); + font-size: var(--text-sm); color: var(--text-color-secondary); flex: 1; min-width: 0; } .invoice-sold { - font-family: var(--font-mono); - font-size: var(--text-xs); font-weight: var(--font-semibold); + font-variant-numeric: tabular-nums; + font-size: var(--text-sm); color: var(--text-color); flex-shrink: 0; } -.invoice-sold.overdue { - color: var(--red-600); -} - /* Empty data state */ .empty-data { display: flex; @@ -1657,11 +1640,6 @@ onUnmounted(() => { background: var(--primary-800); } -[data-theme="dark"] .partner-sold.overdue, -[data-theme="dark"] .invoice-sold.overdue { - color: var(--red-400); -} - @media (prefers-color-scheme: dark) { :root:not([data-theme]) .filter-chip { background: var(--surface-100); @@ -1670,10 +1648,5 @@ onUnmounted(() => { :root:not([data-theme]) .filter-chip.active { background: var(--primary-800); } - - :root:not([data-theme]) .partner-sold.overdue, - :root:not([data-theme]) .invoice-sold.overdue { - color: var(--red-400); - } } diff --git a/src/modules/reports/views/FinancialIndicatorsView.vue b/src/modules/reports/views/FinancialIndicatorsView.vue new file mode 100644 index 0000000..761e8d6 --- /dev/null +++ b/src/modules/reports/views/FinancialIndicatorsView.vue @@ -0,0 +1,1085 @@ + + + + + diff --git a/src/modules/reports/views/InvoicesView.vue b/src/modules/reports/views/InvoicesView.vue index 8c925c2..01e65ef 100644 --- a/src/modules/reports/views/InvoicesView.vue +++ b/src/modules/reports/views/InvoicesView.vue @@ -632,17 +632,17 @@ const formatCompact = (amount) => { const formatDate = (dateString) => { if (!dateString) return ""; try { - return format(new Date(dateString), "dd/MM/yyyy", { locale: ro }); + return format(new Date(dateString), "dd/MM/yy", { locale: ro }); } catch (error) { return dateString; } }; -// Short date format for mobile (DD/MM only) +// Short date format for mobile (DD/MM/YY with year) const formatDateShort = (dateString) => { if (!dateString) return ""; try { - return format(new Date(dateString), "dd/MM", { locale: ro }); + return format(new Date(dateString), "dd/MM/yy", { locale: ro }); } catch (error) { return ""; } @@ -1025,8 +1025,8 @@ watch( .mobile-layout .invoices { padding-top: calc(56px + 48px + var(--space-md)); /* Account for MobileTopBar + tabs */ padding-bottom: calc(56px + var(--space-md)); /* Account for fixed MobileBottomNav */ - padding-left: var(--space-md); - padding-right: var(--space-md); + padding-left: 0; + padding-right: 0; } /* ================================================ @@ -1154,9 +1154,8 @@ watch( .mobile-totals-bar { background: var(--surface-card); border-bottom: 1px solid var(--surface-border); - padding: var(--space-sm) var(--space-md); - margin-bottom: var(--space-md); - border-radius: var(--radius-md); + padding: var(--space-sm) var(--space-xs); + margin-bottom: var(--space-sm); } .mobile-totals-content { @@ -1193,7 +1192,7 @@ watch( align-items: center; border-bottom: 1px solid var(--surface-border); min-height: 44px; - padding: var(--space-sm) var(--space-md); + padding: var(--space-sm) 0; gap: var(--space-sm); } @@ -1346,7 +1345,7 @@ watch( @media (max-width: 768px) { .invoices { - padding: var(--space-md); + padding: var(--space-xs); } .page-title { diff --git a/src/modules/reports/views/TrialBalanceView.vue b/src/modules/reports/views/TrialBalanceView.vue index c8fcdb9..f0ac541 100644 --- a/src/modules/reports/views/TrialBalanceView.vue +++ b/src/modules/reports/views/TrialBalanceView.vue @@ -1057,8 +1057,8 @@ watch( .mobile-layout .trial-balance { padding-top: calc(56px + var(--space-md)); /* Account for fixed MobileTopBar */ padding-bottom: calc(56px + var(--space-md)); /* Account for fixed MobileBottomNav */ - padding-left: var(--space-md); - padding-right: var(--space-md); + padding-left: 0; + padding-right: 0; } /* Card Spacing */ @@ -1088,9 +1088,8 @@ watch( .mobile-totals-bar { background: var(--surface-card); border-bottom: 1px solid var(--surface-border); - padding: var(--space-sm) var(--space-md); - margin-bottom: var(--space-md); - border-radius: var(--radius-md); + padding: var(--space-sm) var(--space-xs); + margin-bottom: var(--space-sm); } .mobile-totals-content { @@ -1142,7 +1141,7 @@ watch( align-items: center; border-bottom: 1px solid var(--surface-border); min-height: 44px; - padding: var(--space-sm) var(--space-md); + padding: var(--space-sm) 0; gap: var(--space-sm); } diff --git a/src/router/index.js b/src/router/index.js index 31484da..5d1c65c 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -73,6 +73,12 @@ const routes = [ component: () => import('@reports/views/MaturityAnalysisView.vue'), meta: { requiresAuth: true, title: 'Analiză Scadențe - ROA2WEB' } }, + { + path: 'financial-indicators', + name: 'FinancialIndicators', + component: () => import('@reports/views/FinancialIndicatorsView.vue'), + meta: { requiresAuth: true, title: 'Indicatori Financiari - ROA2WEB' } + }, { // US-603: Single route for Detailed Invoices with tabs (Clienți/Furnizori) path: 'detailed-invoices', diff --git a/src/shared/components/mobile/MobileBottomNav.vue b/src/shared/components/mobile/MobileBottomNav.vue index 4fc5ba3..6492504 100644 --- a/src/shared/components/mobile/MobileBottomNav.vue +++ b/src/shared/components/mobile/MobileBottomNav.vue @@ -41,11 +41,12 @@ * Events: * - item-click: Emitted when a button item (without `to`) is clicked * - * Default items (4 links): + * Default items (5 links): * - Dashboard (/dashboard) - * - Bonuri (/data-entry) - * - Detalii (/reports/detailed-invoices) - * - Setări (/settings) + * - Facturi (/reports/detailed-invoices) + * - Banca (/reports/bank) + * - Casa (/reports/cash) + * - Indicatori (/reports/financial-indicators) */ defineProps({ @@ -57,9 +58,10 @@ defineProps({ type: Array, default: () => [ { to: '/dashboard', icon: 'pi pi-home', label: 'Dashboard' }, - { to: '/data-entry', icon: 'pi pi-shopping-bag', label: 'Bonuri' }, - { to: '/reports/detailed-invoices', icon: 'pi pi-file-edit', label: 'Detalii' }, - { to: '/settings', icon: 'pi pi-cog', label: 'Setări' } + { to: '/reports/detailed-invoices', icon: 'pi pi-file-edit', label: 'Facturi' }, + { to: '/reports/bank', icon: 'pi pi-building', label: 'Banca' }, + { to: '/reports/cash', icon: 'pi pi-wallet', label: 'Casa' }, + { to: '/reports/financial-indicators', icon: 'pi pi-chart-bar', label: 'Indicatori' } ], validator: (items) => { return Array.isArray(items) && items.every( diff --git a/src/shared/components/mobile/MobileDrawerMenu.vue b/src/shared/components/mobile/MobileDrawerMenu.vue index 7f6d2ee..6131ca9 100644 --- a/src/shared/components/mobile/MobileDrawerMenu.vue +++ b/src/shared/components/mobile/MobileDrawerMenu.vue @@ -724,9 +724,10 @@ const rapoarteItems = [ { to: '/reports/bank', icon: 'pi pi-building', label: 'Bancă', exactMatch: true } ] -// ANALIZE: Scadențe +// ANALIZE: Scadențe, Indicatori Financiari const analizeItems = [ - { to: '/reports/maturity-analysis', icon: 'pi pi-clock', label: 'Scadențe', exactMatch: true } + { to: '/reports/maturity-analysis', icon: 'pi pi-clock', label: 'Scadențe', exactMatch: true }, + { to: '/reports/financial-indicators', icon: 'pi pi-chart-bar', label: 'Indicatori', exactMatch: true } ] // ADMINISTRARE: Setări