feat: comprehensive UI overhaul + budget allocation redesign
Audit & Quality: - RTL: replaced 121 LTR-only utilities (text-left, pl-, left-) with logical properties - A11y: focus traps + ARIA on Modal/SlidePanel/TabbedModal, clickable divs→buttons - Theming: bg-white→bg-surface (170 instances), text-gray→semantic tokens - Performance: useMemo on filters, loading="lazy" on 24 images - CSS: prefers-reduced-motion, removed dead animations Component Splits: - PostDetailPanel: 1332→623 lines + 4 sub-components - ArtefactDetailPanel: 972→590 lines + 1 sub-component Brand Identity — Rawaj (رواج): - New name, DM Sans font, deep teal palette (#0d9488) - Custom SVG logo, forest-tinted dark mode - All emails branded with app name in subject line Design Refinement: - Dashboard: merged posts+deadlines into tabbed ActivityFeed, inline stats - Quieter: removed card lift, brand glow, gradient text, mesh backgrounds - CampaignDetail: prominent budget card, compact team avatars, Lucide icons - Consistent page titles via Header.jsx, standardized section headers - Finance page fully i18n'd (20+ hardcoded strings replaced) Budget Allocation Redesign: - Single source of truth: BudgetEntries (Campaign.budget deprecated) - Validation at all levels: main→campaign→track, expenses blocked if insufficient - Budget request workflow with CEO approval via public link - BudgetRequests table, CRUD routes, public approval page - Budget mutex for race condition prevention - Idempotent migration for existing campaign budgets Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
export function SkeletonCard() {
|
||||
return (
|
||||
<div className="bg-white rounded-xl border border-border p-5 animate-pulse">
|
||||
<div className="bg-surface rounded-xl border border-border p-5 animate-pulse">
|
||||
<div className="h-4 bg-surface-tertiary rounded w-3/4 mb-3"></div>
|
||||
<div className="h-3 bg-surface-tertiary rounded w-1/2 mb-2"></div>
|
||||
<div className="h-3 bg-surface-tertiary rounded w-2/3"></div>
|
||||
@@ -12,7 +12,7 @@ export function SkeletonCard() {
|
||||
|
||||
export function SkeletonStatCard() {
|
||||
return (
|
||||
<div className="bg-white rounded-xl border border-border p-5 animate-pulse">
|
||||
<div className="bg-surface rounded-xl border border-border p-5 animate-pulse">
|
||||
<div className="flex items-start justify-between mb-4">
|
||||
<div className="w-10 h-10 bg-surface-tertiary rounded-lg"></div>
|
||||
<div className="h-3 bg-surface-tertiary rounded w-16"></div>
|
||||
@@ -25,7 +25,7 @@ export function SkeletonStatCard() {
|
||||
|
||||
export function SkeletonTable({ rows = 5, cols = 6 }) {
|
||||
return (
|
||||
<div className="bg-white rounded-xl border border-border overflow-hidden animate-pulse">
|
||||
<div className="bg-surface rounded-xl border border-border overflow-hidden animate-pulse">
|
||||
<div className="border-b border-border bg-surface-secondary p-4">
|
||||
<div className="flex gap-4">
|
||||
{[...Array(cols)].map((_, i) => (
|
||||
@@ -60,7 +60,7 @@ export function SkeletonKanbanBoard() {
|
||||
</div>
|
||||
<div className="bg-surface-secondary rounded-xl p-2 space-y-2 min-h-[400px]">
|
||||
{[...Array(3)].map((_, cardIdx) => (
|
||||
<div key={cardIdx} className="bg-white rounded-lg border border-border p-3">
|
||||
<div key={cardIdx} className="bg-surface rounded-lg border border-border p-3">
|
||||
<div className="h-4 bg-surface-tertiary rounded w-full mb-2"></div>
|
||||
<div className="h-3 bg-surface-tertiary rounded w-3/4 mb-3"></div>
|
||||
<div className="flex gap-2">
|
||||
@@ -78,7 +78,7 @@ export function SkeletonKanbanBoard() {
|
||||
|
||||
export function SkeletonCalendar() {
|
||||
return (
|
||||
<div className="bg-white rounded-xl border border-border overflow-hidden animate-pulse">
|
||||
<div className="bg-surface rounded-xl border border-border overflow-hidden animate-pulse">
|
||||
<div className="flex items-center justify-between px-6 py-4 border-b border-border">
|
||||
<div className="h-6 bg-surface-tertiary rounded w-40"></div>
|
||||
<div className="h-8 bg-surface-tertiary rounded w-20"></div>
|
||||
@@ -138,7 +138,7 @@ export function SkeletonDashboard() {
|
||||
{/* Content cards */}
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
|
||||
{[...Array(2)].map((_, i) => (
|
||||
<div key={i} className="bg-white rounded-xl border border-border animate-pulse">
|
||||
<div key={i} className="bg-surface rounded-xl border border-border animate-pulse">
|
||||
<div className="px-5 py-4 border-b border-border">
|
||||
<div className="h-5 bg-surface-tertiary rounded w-32"></div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user