EHSAN official look & auth (Task #5)

Reskin the EHSAN POC to match ehsan.sa and gate the admin area behind a
simple POC login.

- Official header: cropped EHSAN logo, nav (الرئيسية/الوقف/فرص التبرع/
  خدماتنا dropdown→طلب دعم/عن إحسان/براعم إحسان), login/cart/search icons,
  language toggle, mobile menu. Functional items link; rest are visual-only.
- Colors: green primary tuned + orange accent token added in index.css.
- Auth: AuthContext (localStorage, admin/admin) + login page; /admin and
  /whatsapp-log now behind a Protected wrapper redirecting to /login.
- Redesigned OpportunityCard (photo, green progress bar with %, category
  badge, تم جمع/المبلغ المتبقي columns, inline donate button + amount),
  used on home and opportunities pages.
- Two-step donate page (التفاصيل → الدفع): step indicator, presets
  100/50/10, custom amount (prefilled via ?amount=), "تبرع عن أهلك"
  checkbox, donor form (phone min 10 for OpenClaw loop).
- 8 need-type card images added; needImages helper maps need→image.
- Seed: added published opportunities (req-012..017) with partial progress
  to showcase cards; one kept near-full for an easy closed-loop demo.

Deviation (from code review): donate handler now ACCUMULATES collectedAmount
and clamps to target, validates finite/positive amount, and only advances to
the closed-loop pipeline when a case is fully funded (previously overwrote
and force-advanced — broke partial-progress cases). Donate buttons kept green
to match the reference; orange is an accent only.
This commit is contained in:
Replit Agent
2026-06-05 17:45:17 +00:00
parent 4db9f09195
commit 5d40b0d3c2
28 changed files with 1177 additions and 324 deletions
@@ -1,5 +1,6 @@
import { ReactNode } from "react";
import { Header } from "./Header";
import ehsanLogo from "../../assets/ehsan-logo.png";
export function AppLayout({ children }: { children: ReactNode }) {
return (
@@ -9,8 +10,11 @@ export function AppLayout({ children }: { children: ReactNode }) {
{children}
</main>
<footer className="border-t bg-white mt-auto py-8">
<div className="container mx-auto px-4 text-center text-sm text-muted-foreground">
EHSAN POC &copy; {new Date().getFullYear()}
<div className="container mx-auto px-4 flex flex-col items-center gap-3 text-center">
<img src={ehsanLogo} alt="EHSAN" className="h-9 w-auto object-contain" />
<p className="text-sm text-muted-foreground">
EHSAN POC &copy; {new Date().getFullYear()}
</p>
</div>
</footer>
</div>