From d371d63c19638148e95620d9f948466ff8f456af Mon Sep 17 00:00:00 2001 From: Replit Agent Date: Fri, 5 Jun 2026 18:20:34 +0000 Subject: [PATCH] Replace home hero with animated EHSAN banner carousel MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task #6: On artifacts/ehsan-poc home page, replaced the green text hero with an auto-rotating, looping carousel of the four official ehsan.sa banner images (Zakat, recurring/dawri, Waqf, gift) imported via @assets. - Auto-advances every 5s, loops, and respects prefers-reduced-motion. - Clickable dot indicators plus an accessible pause/play toggle (WCAG 2.2.2) on a translucent backdrop pill. - Bottom gradient scrim keeps the white CTA + controls readable on all four banner backgrounds. - Removed the overlay heading, subtitle, and the "طلب دعم" button per the user; kept the "تصفّح الفرص" CTA linking to /opportunities. - Added common.pause / common.play i18n keys (AR + EN) for the toggle. Banners use alt="" (decorative) since the functional CTA is separately labeled. Verified with tsc --noEmit and home-page screenshots (RTL). --- .../ehsan-poc/src/lib/i18n/translations.ts | 4 + artifacts/ehsan-poc/src/pages/home.tsx | 137 ++++++++++-------- 2 files changed, 82 insertions(+), 59 deletions(-) diff --git a/artifacts/ehsan-poc/src/lib/i18n/translations.ts b/artifacts/ehsan-poc/src/lib/i18n/translations.ts index 6411713..1a11d33 100644 --- a/artifacts/ehsan-poc/src/lib/i18n/translations.ts +++ b/artifacts/ehsan-poc/src/lib/i18n/translations.ts @@ -28,6 +28,8 @@ export const en = { login: "Login", logout: "Logout", cart: "Cart", + pause: "Pause slideshow", + play: "Play slideshow", }, nav: { home: "Home", @@ -238,6 +240,8 @@ export const ar = { login: "تسجيل الدخول", logout: "تسجيل الخروج", cart: "السلة", + pause: "إيقاف العرض", + play: "تشغيل العرض", }, nav: { home: "الرئيسية", diff --git a/artifacts/ehsan-poc/src/pages/home.tsx b/artifacts/ehsan-poc/src/pages/home.tsx index 284d4fc..9ddef42 100644 --- a/artifacts/ehsan-poc/src/pages/home.tsx +++ b/artifacts/ehsan-poc/src/pages/home.tsx @@ -1,4 +1,4 @@ -import { useState } from "react"; +import { useState, useEffect } from "react"; import { useLanguage } from "../contexts/LanguageContext"; import { useGetStats, useListPublishedRequests } from "@workspace/api-client-react"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; @@ -8,13 +8,30 @@ import { Skeleton } from "@/components/ui/skeleton"; import { OpportunityCard } from "../components/OpportunityCard"; import { Riyal } from "@/components/Riyal"; import { Link } from "wouter"; -import { Search } from "lucide-react"; +import { Search, Pause, Play } from "lucide-react"; +import zakatBanner from "@assets/zakatbanarWEB_1780682994527.png"; +import dawriBanner from "@assets/dawribanarWEB_1780682998494.png"; +import waqfBanner from "@assets/waqfbanerWEB_1780683002610.png"; +import giftBanner from "@assets/giftbanarWEB_1780683006569.png"; + +const HERO_BANNERS = [zakatBanner, dawriBanner, waqfBanner, giftBanner]; export default function Home() { const { t } = useLanguage(); const { data: stats, isLoading: statsLoading } = useGetStats(); const { data: published, isLoading: pubLoading } = useListPublishedRequests(); const [query, setQuery] = useState(""); + const [slide, setSlide] = useState(0); + const [paused, setPaused] = useState(false); + + useEffect(() => { + const reduce = window.matchMedia?.("(prefers-reduced-motion: reduce)").matches; + if (reduce || paused) return; + const id = setInterval(() => { + setSlide((s) => (s + 1) % HERO_BANNERS.length); + }, 5000); + return () => clearInterval(id); + }, [paused]); const filtered = (published || []).filter((r) => { if (!query.trim()) return true; @@ -28,64 +45,66 @@ export default function Home() { return ( <> - {/* Hero — official EHSAN green banner */} -
-
- {/* decorative leaves (visual only) */} - - + {/* Hero — auto-rotating banner carousel */} +
+
+ {HERO_BANNERS.map((src, i) => ( + + ))} -
-
- - {t.home.heroBadge} - -

- {t.home.heroTitle} -

-

- {t.home.heroSubtitle} -

-
- - - - - - + {/* bottom scrim keeps the CTA + dots readable over any banner */} +
+ +
+ + + + +
+ +
+ {HERO_BANNERS.map((_, i) => ( +