Dashboard fix, expense system, currency settings, visual upgrade

- Fix Dashboard stat card: show "Budget Remaining" instead of "Budget Spent"
  with correct remaining value accounting for campaign allocations
- Add expense system: budget entries now have income/expense type with
  server-side split, per-campaign and per-project expense tracking,
  colored amounts, type filters, and summary bar in Budgets page
- Add configurable currency in Settings (SAR ⃁ default, supports 10
  currencies) replacing all hardcoded SAR references across the app
- Replace PiggyBank icon with Landmark (culturally appropriate for KSA)
- Visual upgrade: mesh background, gradient text, premium stat cards with
  accent bars, section-card containers, sidebar active glow
- UX polish: consistent text-2xl headers, skeleton loaders for Finance
  and Budgets pages
- Finance page: expenses column in campaign/project breakdown tables,
  ROI accounts for expenses, expense stat card

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
fahed
2026-02-15 15:49:28 +03:00
parent f3e6fc848d
commit e76be78498
17 changed files with 2817 additions and 1379 deletions
+79
View File
@@ -172,6 +172,15 @@ textarea {
animation: spin 1s linear infinite;
}
@keyframes slide-in-right {
from { transform: translateX(100%); }
to { transform: translateX(0); }
}
.animate-slide-in-right {
animation: slide-in-right 0.25s ease-out;
}
/* Stagger children */
.stagger-children > * {
opacity: 0;
@@ -217,6 +226,76 @@ textarea {
opacity: 1;
}
/* Mesh background - subtle radial gradients */
.bg-mesh {
background-color: #f8fafc;
background-image:
radial-gradient(at 20% 20%, rgba(79, 70, 229, 0.04) 0, transparent 50%),
radial-gradient(at 80% 40%, rgba(219, 39, 119, 0.03) 0, transparent 50%),
radial-gradient(at 40% 80%, rgba(5, 150, 105, 0.03) 0, transparent 50%);
}
/* Gradient text */
.text-gradient {
background: linear-gradient(135deg, var(--color-brand-primary) 0%, #7c3aed 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
/* Premium stat card - always-visible gradient top bar */
.stat-card-premium {
position: relative;
overflow: hidden;
}
.stat-card-premium::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 3px;
opacity: 1;
}
.stat-card-premium.accent-primary::before {
background: linear-gradient(90deg, #4f46e5, #7c3aed);
}
.stat-card-premium.accent-secondary::before {
background: linear-gradient(90deg, #db2777, #ec4899);
}
.stat-card-premium.accent-tertiary::before {
background: linear-gradient(90deg, #f59e0b, #fbbf24);
}
.stat-card-premium.accent-quaternary::before {
background: linear-gradient(90deg, #059669, #34d399);
}
/* Section card - premium container */
.section-card {
background: white;
border: 1px solid var(--color-border);
border-radius: 1rem;
overflow: hidden;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04);
transition: box-shadow 0.3s ease;
}
.section-card:hover {
box-shadow: 0 4px 20px -4px rgba(0, 0, 0, 0.08);
}
.section-card-header {
padding: 1rem 1.25rem;
border-bottom: 1px solid var(--color-border);
background: linear-gradient(180deg, rgba(249, 250, 251, 0.5) 0%, white 100%);
}
/* Sidebar active glow */
.sidebar-active-glow {
box-shadow: inset 3px 0 0 rgba(129, 140, 248, 0.8);
}
[dir="rtl"] .sidebar-active-glow {
box-shadow: inset -3px 0 0 rgba(129, 140, 248, 0.8);
}
/* Refined button styles */
button {
border-radius: 0.625rem;