Complete EHSAN POC: fix all code review findings
- 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.
This commit is contained in:
@@ -15,6 +15,16 @@ export const en = {
|
||||
back: "Back",
|
||||
confirm: "Confirm",
|
||||
language: "العربية",
|
||||
trackCase: "Track Case",
|
||||
notFound: "Case not found.",
|
||||
noData: "No data available.",
|
||||
currentStep: "Current Step",
|
||||
pleaseWait: "Please wait...",
|
||||
search: "Search",
|
||||
searchPlaceholder: "Search by name, case ID, or description...",
|
||||
allOpportunities: "All Opportunities",
|
||||
featuredCases: "Featured Cases",
|
||||
donate: "Donate",
|
||||
},
|
||||
home: {
|
||||
heroTitle: "Closed Donation Loop POC",
|
||||
@@ -22,8 +32,13 @@ export const en = {
|
||||
totalRequests: "Total Requests",
|
||||
totalCollected: "Total Collected",
|
||||
totalClosed: "Closed Cases",
|
||||
viewOpportunities: "View Opportunities",
|
||||
viewOpportunities: "View All Opportunities",
|
||||
workflowTitle: "Closed Donation Loop Workflow",
|
||||
searchOpportunities: "Search Donation Opportunities",
|
||||
searchLabel: "Find a cause to support",
|
||||
searchButton: "Search",
|
||||
featuredTitle: "Featured Opportunities",
|
||||
noResults: "No opportunities match your search.",
|
||||
},
|
||||
workflow: {
|
||||
step1: "Request Submitted",
|
||||
@@ -85,22 +100,26 @@ export const en = {
|
||||
collected: "Collected",
|
||||
remaining: "Remaining",
|
||||
target: "Target",
|
||||
noOpportunities: "No opportunities are available right now.",
|
||||
verified: "Verified",
|
||||
},
|
||||
donate: {
|
||||
title: "Complete Donation",
|
||||
caseSummary: "Case Summary",
|
||||
donorName: "Donor Name",
|
||||
donorPhone: "Phone Number",
|
||||
donorEmail: "Email (Optional)",
|
||||
amount: "Donation Amount",
|
||||
confirmDonation: "Confirm Donation",
|
||||
successMessage: "Thank you for your donation. May Allah reward you.",
|
||||
caseNotFound: "Case not found or no longer available.",
|
||||
},
|
||||
admin: {
|
||||
title: "Admin Dashboard",
|
||||
caseId: "Case ID",
|
||||
beneficiary: "Beneficiary",
|
||||
status: "Status",
|
||||
currentStep: "Current Step",
|
||||
currentStep: "Step",
|
||||
actions: "Actions",
|
||||
verify: "Verify",
|
||||
publish: "Publish",
|
||||
@@ -109,27 +128,41 @@ export const en = {
|
||||
close: "Close Case",
|
||||
reject: "Reject",
|
||||
rejectionReason: "Rejection Reason",
|
||||
track: "Track",
|
||||
whatsapp: "WhatsApp",
|
||||
noRequests: "No requests found.",
|
||||
needType: "Need Type",
|
||||
amount: "Amount",
|
||||
},
|
||||
track: {
|
||||
title: "Track Case",
|
||||
caseTimeline: "Case Timeline",
|
||||
caseInfo: "Case Information",
|
||||
rejected: "Case Rejected",
|
||||
currentStepLabel: "Current",
|
||||
submitThankYou: "Submit Thank-You Message",
|
||||
},
|
||||
thankYou: {
|
||||
title: "Submit Thank You Message",
|
||||
message: "Thank You Message",
|
||||
submitLabel: "Send Message to Donor",
|
||||
successNote: "Your thank-you message will be sent to the donor via WhatsApp through OpenClaw.",
|
||||
beneficiaryMessageLabel: "Beneficiary Message",
|
||||
},
|
||||
whatsapp: {
|
||||
title: "WhatsApp Log",
|
||||
donor: "Donor",
|
||||
message: "Message",
|
||||
donorPhone: "Phone",
|
||||
message: "WhatsApp Message",
|
||||
beneficiaryMessage: "Beneficiary Message",
|
||||
status: "Status",
|
||||
sentAt: "Sent At",
|
||||
sendViaOpenClaw: "Send via OpenClaw",
|
||||
pending: "Pending",
|
||||
sent: "Sent",
|
||||
failed: "Failed",
|
||||
}
|
||||
noEntries: "No WhatsApp log entries yet.",
|
||||
},
|
||||
};
|
||||
|
||||
export const ar = {
|
||||
@@ -149,6 +182,16 @@ export const ar = {
|
||||
back: "رجوع",
|
||||
confirm: "تأكيد",
|
||||
language: "English",
|
||||
trackCase: "تتبع الحالة",
|
||||
notFound: "الحالة غير موجودة.",
|
||||
noData: "لا توجد بيانات.",
|
||||
currentStep: "الخطوة الحالية",
|
||||
pleaseWait: "يرجى الانتظار...",
|
||||
search: "بحث",
|
||||
searchPlaceholder: "ابحث بالاسم أو رقم الحالة أو الوصف...",
|
||||
allOpportunities: "جميع الفرص",
|
||||
featuredCases: "الحالات المميزة",
|
||||
donate: "تبرع",
|
||||
},
|
||||
home: {
|
||||
heroTitle: "إقفال دورة التبرع",
|
||||
@@ -156,8 +199,13 @@ export const ar = {
|
||||
totalRequests: "إجمالي الطلبات",
|
||||
totalCollected: "إجمالي التبرعات (ريال)",
|
||||
totalClosed: "الحالات المغلقة",
|
||||
viewOpportunities: "استعراض الفرص",
|
||||
viewOpportunities: "عرض جميع الفرص",
|
||||
workflowTitle: "خطوات إقفال دورة التبرع",
|
||||
searchOpportunities: "ابحث في فرص التبرع",
|
||||
searchLabel: "ابحث عن قضية لدعمها",
|
||||
searchButton: "بحث",
|
||||
featuredTitle: "الفرص المميزة",
|
||||
noResults: "لا توجد فرص تطابق بحثك.",
|
||||
},
|
||||
workflow: {
|
||||
step1: "مقدم الطلب",
|
||||
@@ -219,22 +267,26 @@ export const ar = {
|
||||
collected: "المجموع",
|
||||
remaining: "المتبقي",
|
||||
target: "الهدف",
|
||||
noOpportunities: "لا توجد فرص متاحة حالياً.",
|
||||
verified: "موثق",
|
||||
},
|
||||
donate: {
|
||||
title: "إتمام التبرع",
|
||||
caseSummary: "ملخص الحالة",
|
||||
donorName: "اسم المتبرع",
|
||||
donorPhone: "رقم الجوال",
|
||||
donorEmail: "البريد الإلكتروني (اختياري)",
|
||||
amount: "مبلغ التبرع",
|
||||
confirmDonation: "تأكيد التبرع",
|
||||
successMessage: "شكراً لتبرعك. جزاك الله خيراً.",
|
||||
caseNotFound: "الحالة غير موجودة أو لم تعد متاحة.",
|
||||
},
|
||||
admin: {
|
||||
title: "لوحة الإدارة",
|
||||
caseId: "رقم الحالة",
|
||||
beneficiary: "المستفيد",
|
||||
status: "الحالة",
|
||||
currentStep: "الخطوة الحالية",
|
||||
currentStep: "الخطوة",
|
||||
actions: "الإجراءات",
|
||||
verify: "توثيق",
|
||||
publish: "نشر",
|
||||
@@ -243,25 +295,39 @@ export const ar = {
|
||||
close: "إغلاق الحالة",
|
||||
reject: "رفض",
|
||||
rejectionReason: "سبب الرفض",
|
||||
track: "تتبع",
|
||||
whatsapp: "واتساب",
|
||||
noRequests: "لا توجد طلبات.",
|
||||
needType: "نوع الاحتياج",
|
||||
amount: "المبلغ",
|
||||
},
|
||||
track: {
|
||||
title: "تتبع الحالة",
|
||||
caseTimeline: "مسار الحالة",
|
||||
caseInfo: "معلومات الحالة",
|
||||
rejected: "تم رفض الحالة",
|
||||
currentStepLabel: "الحالية",
|
||||
submitThankYou: "تقديم رسالة الشكر",
|
||||
},
|
||||
thankYou: {
|
||||
title: "تقديم رسالة الشكر",
|
||||
message: "رسالة الشكر",
|
||||
submitLabel: "إرسال الرسالة للمتبرع",
|
||||
successNote: "سيتم إرسال رسالة شكرك إلى المتبرع عبر واتساب من خلال OpenClaw.",
|
||||
beneficiaryMessageLabel: "رسالة المستفيد",
|
||||
},
|
||||
whatsapp: {
|
||||
title: "سجل رسائل الواتساب",
|
||||
donor: "المتبرع",
|
||||
message: "الرسالة",
|
||||
donorPhone: "الجوال",
|
||||
message: "رسالة الواتساب",
|
||||
beneficiaryMessage: "رسالة المستفيد",
|
||||
status: "الحالة",
|
||||
sentAt: "وقت الإرسال",
|
||||
sendViaOpenClaw: "إرسال عبر OpenClaw",
|
||||
pending: "قيد الانتظار",
|
||||
sent: "مرسل",
|
||||
failed: "فشل",
|
||||
}
|
||||
noEntries: "لا توجد سجلات واتساب بعد.",
|
||||
},
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user