Follow-up tweaks so the EHSAN POC matches the official ehsan.sa site.
- Font: switched from Tajawal to IBM Plex Sans Arabic (index.html +
index.css). ehsan.sa's exact webfont couldn't be auto-detected (site
blocks scraping; no Wayback snapshot), so picked the closest official
match.
- Home hero: replaced the gray search-box hero with a full-bleed green
branded banner (badge, title, subtitle, two CTAs, decorative leaf SVGs),
matching ehsan.sa. Moved the search bar above the featured opportunities
grid (with an sr-only label for accessibility).
- Currency: replaced the legacy "﷼" glyph everywhere with the new official
Saudi Riyal symbol via a reusable <Riyal /> component that masks a
processed PNG (src/assets/riyal.png) colored with currentColor; marked
aria-hidden since the adjacent number conveys the value. Applied across
home stats, OpportunityCard, donate, track, admin, request.
- Added AR+EN translation keys heroBadge/heroBrowse.
Verified: tsc clean, no console errors, screenshots confirm hero, font, and
riyal symbol render correctly. Code review fixes applied (search label,
decorative riyal aria, removed unused key).
- API routes: explicit return types on all Express handlers (fixes TS7030),
`beneficiaryName` now accepted and stored in /thank-you route per OpenAPI spec.
- Home page: added search bar (filters by case ID, description, name) +
Featured Opportunities section with live cards, progress bars, and Donate buttons.
- Opportunities page: added need-type filter pill bar (all 8 types + "All Types")
with active state highlighting; empty state respects selected filter.
- i18n: expanded translations with all previously hardcoded strings
(trackCase, notFound, noData, currentStep, search, searchPlaceholder,
featuredTitle, noResults, donate.caseSummary, donate.caseNotFound,
admin.noRequests, admin.needType, admin.amount, admin.track, admin.whatsapp,
track.caseInfo, track.rejected, track.currentStepLabel, track.submitThankYou,
thankYou.successNote, thankYou.beneficiaryMessageLabel,
whatsapp.donorPhone, whatsapp.beneficiaryMessage, whatsapp.noEntries,
opportunities.noOpportunities, opportunities.verified).
All pages now use t.* — zero hardcoded English UI strings.
- TypeScript: both frontend (tsc --noEmit) and API server build are clean.