const { useState, useEffect } = React; const W = window.WK; const { A, LOGO, tri, BRAND, L, SLIDES, WHY, PROCESS, ORDER, SERVICES, FAQ, SERVICE_FAQ, CMS, getStore, setStore, pk, resolveImg, Ic, PageHero, Flowchart, PaymentMethods, OnlineBooking, OfficialChannels, ShareButtons, ContactForm, Footer, FloatingWidget, Button, Badge, ServiceCard, BlogCard, CaseStudyCard, TestimonialCard, AdvantageCard, Accordion, Input, Textarea, Select, Label } = W; const { useRef } = React; /* ---------------- Header (with services dropdown) ---------------- */ function Header({ lang, setLang, t, page, go }) { const [open, setOpen] = useState(false); const langs = [["en","EN"],["zh_TW","繁"],["zh_CN","简"]]; const isSvc = page === "services" || page.startsWith("svc:"); const link = (key, label, active) => ( {e.preventDefault();go(key);}} style={{ fontSize:14, fontWeight:500, color: active ? "hsl(var(--primary))":"hsl(var(--foreground))", borderBottom: active ? "2px solid hsl(var(--primary))":"2px solid transparent", paddingBottom:4, whiteSpace:"nowrap" }}>{label} ); return (
Fr8ightgo("home")} />
{langs.map(([code,label]) => ( ))}
); } /* ---------------- Home ---------------- */ function Hero({ t, lang, go }) { const [i, setI] = useState(0); useEffect(() => { const id = setInterval(()=>setI(p=>(p+1)%SLIDES.length), 6000); return ()=>clearInterval(id); }, []); const s = SLIDES[i]; return (
{SLIDES.map((sl,idx)=>( ))}

{tri(lang,s.title.en,s.title.zh_TW,s.title.zh_CN)}

{tri(lang,s.desc.en,s.desc.zh_TW,s.desc.zh_CN)}

{SLIDES.map((_,idx)=>(
); } function ServicesOverview({ t, lang, go }) { return (
{tri(lang,"Our Expertise","我們的專業","我们的专业")}

{tri(lang,"Our core services","核心業務","核心业务")}

{SERVICES.map((s)=>go("svc:"+s.key)} />)}
); } function WhyCard({ w, lang }) { return (
{w.n}

{tri(lang,w.t.en,w.t.zh_TW,w.t.zh_CN)}

{tri(lang,w.d.en,w.d.zh_TW,w.d.zh_CN)}

); } function WhyChooseUs({ t, lang }) { return (
{t.whyEyebrow}

{t.whyTitle}

{WHY.slice(0,2).map((w)=>)}
{WHY.slice(2).map((w)=>)}
); } function ProcessSection({ t, lang }) { return (
{t.procEyebrow}

{t.procTitle}

); } function CasesRow({ t, lang, go }) { const items = casesData(lang).slice(0,3); return (
{tri(lang,"Proven Results","實際成果","实际成果")}

{tri(lang,"Recent case studies","近期案例","近期案例")}

{items.map((c,i)=>go("cases")} />)}
); } function testimonialsData(lang) { return (getStore().reviews || []).filter(r=>r.status==="published").map(r=>({ rating: r.rating, name: pk(lang,r.name), company: pk(lang,r.company), feedback: pk(lang,r.feedback), })); } function TestimonialsRow({ lang }) { const all = testimonialsData(lang); const [page, setPage] = useState(0); const per = 3; const pages = Math.ceil(all.length / per); const items = all.slice(page*per, page*per+per); return (
{tri(lang,"Client Voices","客戶評價","客户评价")}

{tri(lang,"Trusted by shippers across the GBA","深受大灣區託運人信賴","深受大湾区托运人信赖")}

{items.map((v,i)=>)}
{Array.from({length:pages}).map((_,i)=>(
); } function CTABand({ t, go }) { return (

{t.ready}

{t.readyDesc}

); } function AboutHome({ t, lang, go }) { const pg = getStore().page || {}; return (
{tri(lang,"About
{tri(lang,"About Us","關於我們","关于我们")}

{pk(lang,pg.aboutTitle) || tri(lang,"Redefining logistics across every border","跨越每個邊界,重新定義物流","跨越每个边界,重新定义物流")}

{pk(lang,pg.aboutText)}

{pk(lang,pg.aboutText2)}

); } function HomePage({ t, lang, go }) { return ( ); } /* ---------------- Services overview page ---------------- */ function ServicesPage({ t, lang, go }) { return (
{SERVICES.map((s)=>(
go("svc:"+s.key)} />
))}
); } /* ---------------- Service detail (2nd level) ---------------- */ function ServiceDetailPage({ svcKey, t, lang, go }) { const s = SERVICES.find(x=>x.key===svcKey) || SERVICES[0]; const title = tri(lang,s.title.en,s.title.zh_TW,s.title.zh_CN); return ( {/* breadcrumb + inner services */}
{e.preventDefault();go("services");}} style={{ color:"hsl(var(--primary))" }}>{t.services} / {title}
{tri(lang,"What's included","服務內容","服务内容")}

{tri(lang,"Services under this category","此類別下的業務","此类别下的业务")}

{s.sub.map((b,i)=>( ))}
{/* Moving-only: new self-service feature */} {s.key==="moving" && (
QR
{tri(lang,"NEW FEATURE","全新功能","全新功能")}

{tri(lang,"Mainland moving orders now support online self-service booking","內地搬家訂單現已支援線上自助下單","内地搬家订单现已支持在线自助下单")}

{tri(lang,"Place mainland moving orders easily through our official WeChat account. Scan the QR code to enter our smart booking system, get an instant quote and track your moving progress in real time.","您現在可以直接透過我們的官方微信公眾號輕鬆下達內地搬家訂單。掃描二維碼進入我們的智能預訂系統,獲取即時報價並實時追蹤您的搬家進度。","您现在可以直接通过我们的官方微信公众号轻松下达内地搬家订单。扫描二维码进入我们的智能预订系统,获取即时报价并实时追踪您的搬家进度。")}

)}
{t.procEyebrow}

{t.procTitle}

{t.faq}

({ question:tri(lang,f.q.en,f.q.zh_TW,f.q.zh_CN), answer:tri(lang,f.a.en,f.a.zh_TW,f.a.zh_CN) }))} />
); } /* ---------------- Cases ---------------- */ function casesData(lang) { return (getStore().cases || []).filter(c=>c.status==="published").map(c=>({ client: pk(lang,c.client), location: pk(lang,c.location), tag: pk(lang,c.tag), teaser: pk(lang,c.teaser), image: resolveImg(c.img), })); } function CasesPage({ t, lang, go }) { const all = casesData(lang); const [page, setPage] = useState(0); const per = 6; const pages = Math.ceil(all.length / per); const items = all.slice(page*per, page*per+per); return (
{items.map((c,i)=>( go("contact")} /> ))}
{pages>1 && (
{Array.from({length:pages}).map((_,i)=>( ))}
)}
); } /* ---------------- About ---------------- */ function AboutPage({ t, lang, go }) { const stats = [ [tri(lang,"15+ Years","15+ 年","15+ 年"), tri(lang,"Experience","經驗","经验"), "M12 6v6l4 2M12 2a10 10 0 1 0 0 20 10 10 0 0 0 0-20Z"], ["10,000+", tri(lang,"Customers served","服務客戶","服务客户"), "M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2M9 11a4 4 0 1 0 0-8 4 4 0 0 0 0 8ZM23 21v-2a4 4 0 0 0-3-3.87M16 3.13a4 4 0 0 1 0 7.75"], ["500+", tri(lang,"Cities covered","覆蓋城市","覆盖城市"), "M12 2a10 10 0 1 0 0 20 10 10 0 0 0 0-20ZM2 12h20M12 2a15 15 0 0 1 0 20 15 15 0 0 1 0-20Z"], ["200+", tri(lang,"Professional team","專業團隊","专业团队"), "M16 20V4a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v16M2 9h20v11a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1z"], ]; const checks = [ tri(lang,"15+ years of experience","15 年以上經驗","15 年以上经验"), tri(lang,"10,000+ satisfied customers","10,000+ 滿意客戶","10,000+ 满意客户"), tri(lang,"500+ cities covered","覆蓋 500+ 城市","覆盖 500+ 城市"), tri(lang,"200+ professional team","200+ 專業團隊","200+ 专业团队"), tri(lang,"24/7 customer support","24/7 全天候客服","24/7 全天候客服"), tri(lang,"Transparent pricing & full insurance","價格透明與全面保險","价格透明与全面保险"), ]; const philosophy = WHY.slice(0,4); return (
{stats.map((s,i)=>(
{s[0]}
{s[1]}
))}

{tri(lang,"Fr8ight — your cross-border logistics expert","Fr8ight – 您的跨境物流專家","Fr8ight – 您的跨境物流专家")}

{tri(lang,"With over 15 years of professional service, Fr8ight has become the logistics partner of choice connecting Hong Kong and the Mainland. We are committed to seamless, safe and efficient transport solutions for individuals and enterprises alike.","憑藉超過 15 年的專業服務經驗,Fr8ight 已成為連接香港與內地的首選物流合作夥伴。我們致力於為個人及企業客戶提供無縫、安全且高效的運輸解決方案。","凭借超过 15 年的专业服务经验,Fr8ight 已成为连接香港与内地的首选物流合作伙伴。我们致力于为个人及企业客户提供无缝、安全且高效的运输解决方案。")}

{checks.map((c,i)=>(
{c}
))}
{tri(lang,"Our Philosophy","我們的理念","我们的理念")}

{tri(lang,"What we stand for","我們的堅持","我们的坚持")}

{philosophy.map((w)=>(

{tri(lang,w.t.en,w.t.zh_TW,w.t.zh_CN)}

{tri(lang,w.d.en,w.d.zh_TW,w.d.zh_CN)}

))}
{tri(lang,"How to Order","下單流程","下单流程")}

{tri(lang,"Five steps to ship","五步完成託運","五步完成托运")}

({t:o}))} lang={lang} />
); } /* ---------------- Blog ---------------- */ function postsData(lang) { return (getStore().posts || []).filter(p=>p.status==="published").map(p=>({ category: pk(lang,p.cat), date: p.date, author: pk(lang,p.author), image: resolveImg(p.img), title: pk(lang,p.title), excerpt: pk(lang,p.excerpt), content: pk(lang,p.content), })); } function BlogPage({ t, lang, go }) { const all = postsData(lang); const [page, setPage] = useState(0); const per = 6; const pages = Math.ceil(all.length / per); const items = all.slice(page*per, page*per+per); return (
{items.map((p,i)=>( go("article:"+(page*per+i))} /> ))}
{pages>1 && (
{Array.from({length:pages}).map((_,i)=>( ))}
)}
); } function ArticlePage({ idx, t, lang, go }) { const posts = postsData(lang); const p = posts[idx] || posts[0]; const paras = [ p.excerpt, tri(lang,"At Fr8ight we combine cross-border expertise with a dedicated operations team so every shipment is handled with care from pickup to final delivery.","在 Fr8ight,我們結合跨境專業與專屬營運團隊,讓每一票貨從取件到最終配送都得到細心處理。","在 Fr8ight,我们结合跨境专业与专属运营团队,让每一票货从取件到最终配送都得到细心处理。"), tri(lang,"Have a shipment in mind? Talk to our team for a tailored quote and a clear, transparent plan with no hidden surcharges.","有貨要寄?聯絡我們的團隊獲取客製化報價,以及清晰透明、無隱藏收費的方案。","有货要寄?联系我们的团队获取定制化报价,以及清晰透明、无隐藏收费的方案。"), ]; return (
{e.preventDefault();go("blog");}} style={{ fontSize:14, color:"hsl(var(--primary))" }}>{tri(lang,"← Back to Blog","← 返回部落格","← 返回博客")}
{p.category}

{p.title}

{p.author}·{p.date}
{paras.map((para,i)=>(

{para}

))}

{tri(lang,"Related articles","相關文章","相关文章")}

{posts.filter((_,i)=>i!==idx).slice(0,3).map((rp,i)=>{ const realIdx=posts.indexOf(rp); return go("article:"+realIdx)} />; })}
); } /* ---------------- Contact ---------------- */ function ContactPage({ t, lang }) { const pg = getStore().page || {}; const info = [ [tri(lang,"Office","門市地址","门市地址"), tri(lang,BRAND.addr.en,BRAND.addr.zh_TW,BRAND.addr.zh_CN)], ["WhatsApp", pg.whatsapp || BRAND.whatsapp], [tri(lang,"Phone","電話","电话"), pg.phone || BRAND.phone], ["Email", pg.email || BRAND.email], [tri(lang,"Hours","營業時間","营业时间"), tri(lang,BRAND.hours.en,BRAND.hours.zh_TW,BRAND.hours.zh_CN)], ["Facebook / Instagram", BRAND.facebook.replace("www.facebook.com/","fb: ")+" · IG: "+BRAND.instagram], [tri(lang,"Xiaohongshu (RED)","小紅書","小红书"), BRAND.xhs], ]; return (
{info.map((r,i)=>(
{r[0]}
{r[1]}
))}
); } /* ---------------- App router ---------------- */ function App() { const [lang, setLang] = useState("en"); const [page, setPage] = useState("home"); const [, setVer] = useState(0); useEffect(() => { // Visitors with no local edits get the published content.json (if uploaded next to this page). if (CMS && !CMS.hasLocal()) { CMS.fetchPublished((j) => { if (j) { setStore(j); setVer(v=>v+1); } }); } }, []); const t = L[lang]; const go = (p) => { setPage(p); window.scrollTo(0, 0); }; let body; if (page === "home") body = ; else if (page === "services") body = ; else if (page.startsWith("svc:")) body = ; else if (page === "cases") body = ; else if (page === "about") body = ; else if (page === "blog") body = ; else if (page.startsWith("article:")) body = ; else if (page === "contact") body = ; return (
{body}