Files
marketing-app/client/src/components/StatCard.jsx
fahed e76be78498 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>
2026-02-15 15:49:28 +03:00

45 lines
1.8 KiB
JavaScript

export default function StatCard({ icon: Icon, label, value, subtitle, color = 'brand-primary', trend }) {
const accentMap = {
'brand-primary': 'accent-primary',
'brand-secondary': 'accent-secondary',
'brand-tertiary': 'accent-tertiary',
'brand-quaternary': 'accent-quaternary',
}
const iconBgMap = {
'brand-primary': 'bg-indigo-50 text-indigo-600 shadow-lg shadow-indigo-500/20',
'brand-secondary': 'bg-pink-50 text-pink-600 shadow-lg shadow-pink-500/20',
'brand-tertiary': 'bg-amber-50 text-amber-600 shadow-lg shadow-amber-500/20',
'brand-quaternary': 'bg-emerald-50 text-emerald-600 shadow-lg shadow-emerald-500/20',
}
const accentClass = accentMap[color] || 'accent-primary'
return (
<div className={`stat-card-premium ${accentClass} bg-white rounded-xl border border-border p-5 card-hover`}>
<div className="flex items-start justify-between">
<div>
<p className="text-sm font-medium text-text-tertiary">{label}</p>
<p className="text-3xl font-bold text-text-primary mt-1">{value}</p>
{subtitle && (
<p className="text-xs text-text-tertiary mt-1">{subtitle}</p>
)}
</div>
<div className={`w-11 h-11 rounded-xl flex items-center justify-center ${iconBgMap[color] || iconBgMap['brand-primary']}`}>
<Icon className="w-5 h-5" />
</div>
</div>
{trend && (
<div className="mt-3 pt-3 border-t border-border-light">
<div className="flex items-center gap-1">
<span className={`text-xs font-medium ${trend > 0 ? 'text-emerald-600' : 'text-red-500'}`}>
{trend > 0 ? '+' : ''}{trend}%
</span>
<span className="text-xs text-text-tertiary">vs last month</span>
</div>
</div>
)}
</div>
)
}