feat: VAT toggle + offline mode

- Rename Revenue to GrossRevenue, add NetRevenue (excl. VAT)
- Add VAT toggle (Incl/Excl) on Dashboard and Comparison pages
- Add offline mode with localStorage caching (24h validity)
- Add refresh button and offline indicator in nav
- Remove Google Sheets fallback (archived to dataService.legacy.js)
- Add AR/EN translations for new UI elements
This commit is contained in:
fahed
2026-02-04 11:47:42 +03:00
parent afe276541f
commit 9044ab7da3
8 changed files with 477 additions and 280 deletions

View File

@@ -271,38 +271,6 @@ html[dir="rtl"] {
border-color: var(--primary);
}
.nav-label-toggle {
display: flex;
align-items: center;
gap: 6px;
padding: 8px 14px;
border-radius: 8px;
font-size: 0.75rem;
font-weight: 600;
cursor: pointer;
transition: all 0.2s;
background: var(--bg);
border: 1px solid var(--border);
color: var(--text-muted);
margin-left: 8px;
}
.nav-label-toggle:hover {
background: var(--surface);
color: var(--text-primary);
border-color: var(--primary);
}
.nav-label-toggle.active {
background: #10b981;
color: white;
border-color: #10b981;
}
.nav-label-toggle svg {
opacity: 0.8;
}
.nav-link.active svg {
opacity: 1;
}
@@ -341,6 +309,58 @@ html[dir="rtl"] .nav-lang-toggle {
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
}
/* Offline Badge */
.offline-badge {
display: flex;
align-items: center;
gap: 5px;
padding: 6px 12px;
background: #fef3c7;
color: #92400e;
border-radius: 6px;
font-size: 0.75rem;
font-weight: 600;
border: 1px solid #fcd34d;
}
.offline-badge svg {
opacity: 0.8;
}
/* Refresh Button */
.nav-refresh-btn {
display: flex;
align-items: center;
justify-content: center;
width: 36px;
height: 36px;
border-radius: 8px;
cursor: pointer;
transition: all 0.2s ease;
background: transparent;
border: 1px solid var(--border);
color: var(--text-muted);
}
.nav-refresh-btn:hover {
background: var(--surface);
color: var(--text-primary);
border-color: var(--primary);
}
.nav-refresh-btn:active {
transform: scale(0.96);
}
.nav-refresh-btn:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.nav-refresh-btn.refreshing svg {
animation: spin 1s linear infinite;
}
/* Main Content */
.dashboard,
.comparison {
@@ -394,6 +414,18 @@ html[dir="rtl"] .nav-lang-toggle {
color: var(--text-secondary);
}
/* Header Toggles Container (for multiple toggles side by side) */
.header-toggles {
display: flex;
align-items: center;
gap: 24px;
margin-top: 6px;
}
.header-toggles .toggle-with-label {
margin-top: 0;
}
/* Filters - now uses .controls for consistency */
/* Stats Grid */
@@ -870,33 +902,6 @@ table tbody tr:hover {
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.08);
}
/* Data Labels Toggle */
.label-toggle {
display: flex;
align-items: center;
gap: 4px;
border: 2px solid var(--border);
background: var(--surface);
color: var(--text-muted);
padding: 8px 14px;
border-radius: 10px;
font-size: 0.8rem;
font-weight: 500;
cursor: pointer;
transition: all 0.25s ease;
}
.label-toggle:hover {
border-color: var(--primary);
color: var(--text-primary);
}
.label-toggle.active {
background: var(--primary);
border-color: var(--primary);
color: white;
}
.chart-metric-selector button {
border: none;
background: transparent;
@@ -926,13 +931,6 @@ table tbody tr:hover {
margin-bottom: 32px;
}
.chart-selectors-bar {
display: flex;
gap: 8px;
margin-bottom: 16px;
flex-wrap: wrap;
}
/* Inline selectors inside chart cards (mobile) */
.chart-selectors-inline {
display: flex;
@@ -1305,11 +1303,6 @@ table tbody tr:hover {
flex-wrap: wrap;
}
/* Chart selectors bar */
.chart-selectors-bar {
justify-content: center;
}
/* Carousel - overlay arrows on mobile */
.carousel-arrow {
width: 28px;
@@ -1484,10 +1477,6 @@ table tbody tr:hover {
.carousel-dot .dot-label {
font-size: 0.5625rem;
}
.chart-selectors-bar {
gap: 4px;
}
}
/* ========== Slides Builder ========== */