import { Globe, Menu, Search as SearchIcon, X } from "lucide-react"; import { useState } from "react"; import { Link, Outlet, useLocation, useNavigate } from "react-router-dom"; import { ArkLogoMark } from "../components/ArkLogoMark"; import { useI18n, type Lang } from "../i18n"; import { adminUiPrefix } from "../adminPaths"; type PublicNavWhich = | "home" | "browseAll" | "categories" | "browseLatest" | "browseRecommended" | "browsePopular" | "favorites" | "wallet" | "about"; function navIsActive( pathname: string, search: string, hash: string, which: PublicNavWhich, ): boolean { const sp = new URLSearchParams(search); switch (which) { case "home": return pathname === "/"; case "browseAll": return pathname === "/browse" && !sp.has("sort"); case "categories": return pathname === "/" && hash === "#categories"; case "browseLatest": return pathname === "/browse" && sp.get("sort") === "latest"; case "browseRecommended": return pathname === "/browse" && sp.get("sort") === "recommended"; case "browsePopular": return pathname === "/browse" && sp.get("sort") === "popular"; case "favorites": return pathname === "/favorites"; case "wallet": return pathname === "/wallet"; case "about": return pathname === "/about"; default: return false; } } function navClassName(active: boolean) { return [ "shrink-0 rounded-sm px-2 py-2 text-[13px] font-medium leading-none whitespace-nowrap no-underline outline-none transition-colors", "focus-visible:ring-2 focus-visible:ring-ark-gold/90 focus-visible:ring-offset-2 focus-visible:ring-offset-ark-bg", active ? "text-ark-gold visited:text-ark-gold" : "text-[#d7d7dc] visited:text-[#d7d7dc] hover:text-ark-gold", ].join(" "); } export function PublicLayout() { const { t, lang, setLang } = useI18n(); const { pathname, search, hash } = useLocation(); const [open, setOpen] = useState(false); const [q, setQ] = useState(""); const nav = useNavigate(); const na = (which: PublicNavWhich) => navIsActive(pathname, search, hash, which); const goSearch = () => { const s = q.trim(); if (!s) return; nav(`/search?q=${encodeURIComponent(s)}`); setOpen(false); }; return (
{/* Single row (md+): logo | scrollable nav (左對齊,可橫向滑動) | 搜尋 + 語言 */}
{t("brand")}
setQ(e.target.value)} onKeyDown={(e) => e.key === "Enter" && goSearch()} placeholder={t("searchPlaceholder")} className="w-24 rounded-md bg-transparent text-sm text-neutral-200 outline-none placeholder:text-[#777985] focus-visible:ring-2 focus-visible:ring-ark-gold/60 focus-visible:ring-offset-2 focus-visible:ring-offset-[#1a1b20] md:w-28 lg:w-44 xl:w-52" />
{open ? (
setQ(e.target.value)} onKeyDown={(e) => e.key === "Enter" && goSearch()} placeholder={t("searchPlaceholder")} className="flex-1 bg-transparent text-sm outline-none placeholder:text-[#777985]" />
setOpen(false)} > {t("home")} setOpen(false)} > {t("all")} setOpen(false)} > {t("categories")} setOpen(false)} > {t("favorites")} setOpen(false)} > {t("latest")} setOpen(false)} > {t("official")} setOpen(false)} > {t("popular")} setOpen(false)} > {t("wallet")} setOpen(false)} > {t("footerAbout")}
) : null}
); } const NAVBAR_ICON_BASE = "/assets/ark-library/navbar"; function BottomNavIcon({ to, label, icon, active, }: { to: string; label: string; icon: "home" | "document" | "heart" | "update"; active: boolean; }) { const src = active ? `${NAVBAR_ICON_BASE}/${icon}-active.svg` : `${NAVBAR_ICON_BASE}/${icon}-inactive.svg`; return ( {label} ); }