diff --git a/src/components/dashboard/RecentCampaigns.jsx b/src/components/dashboard/RecentCampaigns.jsx new file mode 100644 index 0000000..01a4f8c --- /dev/null +++ b/src/components/dashboard/RecentCampaigns.jsx @@ -0,0 +1,185 @@ +import { useEffect } from 'react'; +import { Link } from 'react-router-dom'; +import { ArrowRight, PlusCircle, LayoutGrid } from 'lucide-react'; +import { useAppDispatch, useAppSelector } from '../../store/hooks'; +import { fetchRecentCampaigns } from '../../features/dashboard/dashboardThunks'; +import { + selectRecentCampaigns, + selectDashboardLoading, +} from '../../features/dashboard/dashboardSelectors'; + +// ─── Status badge config ────────────────────────────────────────────────────── +const STATUS_BADGE = { + active: { label: 'Active', className: 'bg-emerald-100 text-emerald-700' }, + completed: { label: 'Completed', className: 'bg-indigo-100 text-indigo-700' }, + pending: { label: 'Pending', className: 'bg-amber-100 text-amber-700' }, + rejected: { label: 'Rejected', className: 'bg-red-100 text-red-700' }, + paused: { label: 'Paused', className: 'bg-slate-100 text-slate-600' }, +}; + +function StatusBadge({ status }) { + const cfg = STATUS_BADGE[status?.toLowerCase()] ?? { + label: status ?? 'Unknown', + className: 'bg-slate-100 text-slate-500', + }; + return ( + + {cfg.label} + + ); +} + +// ─── Progress bar ───────────────────────────────────────────────────────────── +function ProgressBar({ raised, goal }) { + const pct = goal > 0 ? Math.min((raised / goal) * 100, 100) : 0; + return ( +
No campaigns yet
++ You have not created any campaigns. Launch your first one and start + collecting donations. +
+ ++ {campaign.title ?? campaign.name ?? 'Untitled Campaign'} +
+