From 0c2ef37622ebd3d17402947c817e595d3619f251 Mon Sep 17 00:00:00 2001 From: Replit Agent Date: Fri, 5 Jun 2026 20:23:22 +0000 Subject: [PATCH] Add EHSAN favicon and localized browser tab titles (Task #21) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The browser tab previously showed a generic placeholder favicon and the English title "EHSAN Closed Donation Loop". Per the reference, the tab now shows the EHSAN logo mark and an Arabic platform title. Changes: - Favicon: copied the existing EHSAN logo (src/assets/ehsan-logo.png) to public/favicon.png and pointed index.html at %BASE_URL%favicon.png (base-path safe; verified it serves 200 image/png). - Static head: index.html and OG/Twitter titles + description now use the Arabic platform name "منصة إحسان". - Per-page titles: added a DocumentTitle component (src/hooks/useDocumentTitle.ts) rendered in the Router that sets document.title to "<page name> - <platform>" based on the current wouter path and active language, reading from a new translations.meta section (AR + EN). Home reads "الصفحة الرئيسية - منصة إحسان"; switches with language. Approach note: titles are centralized in the router rather than edited into each page file, keeping it DRY while covering all main routes. Verified: tsc clean; e2e confirmed titles on /, /opportunities, /cart and English fallback ("Home - EHSAN Platform"), plus favicon load. --- artifacts/ehsan-poc/index.html | 14 ++++---- artifacts/ehsan-poc/public/favicon.png | Bin 0 -> 1798 bytes artifacts/ehsan-poc/src/App.tsx | 2 ++ .../ehsan-poc/src/hooks/useDocumentTitle.ts | 33 ++++++++++++++++++ .../ehsan-poc/src/lib/i18n/translations.ts | 32 +++++++++++++++++ 5 files changed, 74 insertions(+), 7 deletions(-) create mode 100644 artifacts/ehsan-poc/public/favicon.png create mode 100644 artifacts/ehsan-poc/src/hooks/useDocumentTitle.ts diff --git a/artifacts/ehsan-poc/index.html b/artifacts/ehsan-poc/index.html index 359e252..88c4873 100644 --- a/artifacts/ehsan-poc/index.html +++ b/artifacts/ehsan-poc/index.html @@ -3,16 +3,16 @@ <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1" /> - <title>EHSAN Closed Donation Loop - + منصة إحسان + - - + + - - - + + + diff --git a/artifacts/ehsan-poc/public/favicon.png b/artifacts/ehsan-poc/public/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..7a0556434148e184336b8bddaa7ff8239bf5ffcb GIT binary patch literal 1798 zcmZvdc~BG97RE0kP{JNi3Jr)(YlGl3@(4%-3CNNNff%AdMH#_x<^P0|_PGJZ*0Md5@z|8^Rzq%H89)MH?01G4lP;~&< z(l7TO^#(w14IfGjoOwC3xw$#?QcDnB`nWW`X!xG&rH1>h6x~|GRY*Z03*_p=l+9?k zatX+0fovvME(MtkaDge)YCr}9Wau7~+&&55Fwp!eu2cfp40LT3x~dA$>3~iHR63y0 zK_U$#&}6DfaE1oRw1&sS_~!aTMIVSu8Jd~upHgk-eZ8H>DIDm-U+1H9D?n_@(DW4k zdcAgO(T1B=AnQeEmxC{;+*@MBi>dHybvEZxZO)~IH`FP#nu7biGNl?sQn?~=ctb6Y zUkl~1p=oTzlm-weAc7(rQ{(Dt2Q?Zfi)F=RS+Q6OjV83F2Axq3@DvbE;oj`V)zsum zr1?^5XhpSU3d1smDH~OT&}0yj%)QZ_CzcGVCoPf~mPw3|(yF{J2|BGDV3N7lyK~!n z%*izK)3m|olShgw(X3Jskc7>zG$W;$#nG_&6$2BKvJo}+T6gXpaqit7(-^Ah3F^SO zns-}_$tpLAq?knML>*A7G2fK)L}H$(JEx@!5|M07&?(6{B3VAB4$dqa7*ppocLk-F z8iywthb76Mse>{~vzxlIn>vk-BpP88K01;pA63bps)9Hrft(Wg6IFI&XCS*o&zH)* zDn`@FHFLj69*%oQSQqFvLoYrgI6!Z6%U-RnFs5UoSpb+1{x9@~X)UL9O(QlI7ihF# zXkcaU?7Hl&+bVq}Ho%VM%JJ57wY?j9sTDG-!FL)Jz_0s)#1 zh2RK8q}_euF>IKnd-PC{fbA9s|EzV7_TZ)O<9!4VO`GBcir}>@rs=Ey2#=9>;YDFF z^X@Yo%u)SAp~U%BJO5UK13gdZFK}*cb@p!+DsH6mP>=?`$G@pHcwvD4mdqbiKimCm z$5I%+ueG->{NTxPbZnfE5j|VJyDTH^bSy%*D0_&ua2M>(WZQi^#l+(Gv0xv3)2M^u z)xOQO3A6OVK-f|kzeInvCtf5C8_>wOs4r^xe5s-D72^tg9+`Z-yt?}SxP^@cdnz3@ z8wZ`wy{w6mSGx!={y-UN*1+g3u*mtJNQixPG$|xYPC8V3LQFWtoP2waq)l@{%D`<` zI&b+omSW3Vg1%bzQM`p7m5h`}&Bu5e_R8{$^~X}ngpKj8<_^2lwvH4<$L@c8aL-Q{ zeOoF^&4YzOZipH#z_s{9^>K{cucN!%iLF66f_;{?5M1DRpMRJRtt-U1@^#xv; zj2eG2+v_;}<5b_fGEvEg1+3x7&CzX;cRSqgzOj519D{WF{k`#TQEv=k7ZO^7r_FfZ zHlIOViC-%gH3xwuFSN={0vsONnMA(4oA^yOsi^0hoiBpuX09Vc5qy` zfSrqIHXE|lq7kzzxk+#Qe(zta!yk-xgzT1|^}p~G>7nRybHES&xRSTwc%s!{C}T`< z8`3l2B$^Y<**qz@w7PuYOU=5A5{5^laz1%k`%9}5dAugEjQ__dEGplO{9(f3^@oY= z)34?4;hJ4uJoE0y~jPX0hXRAH?5>xOt%5_y5JfE2DnXF#sDF7SQHT G%K8(SswqSO literal 0 HcmV?d00001 diff --git a/artifacts/ehsan-poc/src/App.tsx b/artifacts/ehsan-poc/src/App.tsx index 0769406..af10961 100644 --- a/artifacts/ehsan-poc/src/App.tsx +++ b/artifacts/ehsan-poc/src/App.tsx @@ -6,6 +6,7 @@ import { LanguageProvider } from "./contexts/LanguageContext"; import { CartProvider } from "./contexts/CartContext"; import { AuthProvider, useAuth } from "./contexts/AuthContext"; import { AppLayout } from "./components/layout/AppLayout"; +import { DocumentTitle } from "./hooks/useDocumentTitle"; import NotFound from "@/pages/not-found"; import { ComponentType } from "react"; @@ -37,6 +38,7 @@ function Protected({ component: Component }: { component: ComponentType }) function Router() { return ( + diff --git a/artifacts/ehsan-poc/src/hooks/useDocumentTitle.ts b/artifacts/ehsan-poc/src/hooks/useDocumentTitle.ts new file mode 100644 index 0000000..df9d9d3 --- /dev/null +++ b/artifacts/ehsan-poc/src/hooks/useDocumentTitle.ts @@ -0,0 +1,33 @@ +import { useEffect } from "react"; +import { useLocation } from "wouter"; +import { useLanguage } from "../contexts/LanguageContext"; + +function pageNameForPath(path: string, meta: Record): string { + if (path === "/" || path === "") return meta.home; + if (path.startsWith("/opportunities")) return meta.opportunities; + if (path.startsWith("/cart")) return meta.cart; + if (path.startsWith("/about")) return meta.about; + if (path.startsWith("/track")) return meta.track; + if (path.startsWith("/donate")) return meta.donate; + if (path.startsWith("/request")) return meta.request; + if (path.startsWith("/waqf")) return meta.waqf; + if (path.startsWith("/baraem")) return meta.baraem; + if (path.startsWith("/admin")) return meta.admin; + if (path.startsWith("/whatsapp-log")) return meta.whatsappLog; + if (path.startsWith("/thank-you")) return meta.thankYou; + if (path.startsWith("/login")) return meta.login; + return ""; +} + +export function DocumentTitle() { + const [location] = useLocation(); + const { t } = useLanguage(); + + useEffect(() => { + const meta = t.meta as Record; + const name = pageNameForPath(location, meta); + document.title = name ? `${name} - ${meta.platform}` : meta.platform; + }, [location, t]); + + return null; +} diff --git a/artifacts/ehsan-poc/src/lib/i18n/translations.ts b/artifacts/ehsan-poc/src/lib/i18n/translations.ts index 76f633a..9d7fcbf 100644 --- a/artifacts/ehsan-poc/src/lib/i18n/translations.ts +++ b/artifacts/ehsan-poc/src/lib/i18n/translations.ts @@ -1,4 +1,20 @@ export const en = { + meta: { + platform: "EHSAN Platform", + home: "Home", + opportunities: "Donation Opportunities", + cart: "Your Donation Cart", + about: "About EHSAN", + track: "Track Case", + donate: "Complete Donation", + request: "Request Support", + waqf: "Endowment", + baraem: "EHSAN Buds", + admin: "Admin Dashboard", + whatsappLog: "WhatsApp Log", + thankYou: "Submit Thank You", + login: "Login", + }, common: { ehsan: "EHSAN", home: "Home", @@ -400,6 +416,22 @@ export const en = { }; export const ar = { + meta: { + platform: "منصة إحسان", + home: "الصفحة الرئيسية", + opportunities: "فرص التبرع", + cart: "سلة تبرعاتك", + about: "عن إحسان", + track: "تتبع الحالة", + donate: "إتمام التبرع", + request: "طلب دعم", + waqf: "الوقف", + baraem: "براعم إحسان", + admin: "لوحة الإدارة", + whatsappLog: "سجل واتساب", + thankYou: "إرسال شكر", + login: "تسجيل الدخول", + }, common: { ehsan: "إحسان", home: "الرئيسية",