import { useEffect, useMemo, useState } from "react"; import { useSearchParams } from "react-router-dom"; import { getJSON, itemsOrEmpty, postJSON, type Resource } from "../api"; import { ResourceCard } from "../components/ResourceCard"; import { ResourceListFooter } from "../components/ResourceListFooter"; import { useI18n } from "../i18n"; import { typeFilterLabel } from "../resourceTypeLabels"; const types = [ "all", "image", "video", "ppt", "pdf", "text", "link", "archive", ] as const; const resourceLangCodes = ["", "zh-TW", "zh-CN", "en"] as const; function resourceLangLabel(t: (k: string) => string, code: string) { if (!code) return t("filterLanguageAll"); if (code === "zh-TW") return t("lang_zh_TW"); if (code === "zh-CN") return t("lang_zh_CN"); return t("lang_en"); } export function SearchPage() { const { t, lang } = useI18n(); const [sp, setSp] = useSearchParams(); const q = sp.get("q") || ""; const sort = sp.get("sort") || "latest"; const type = sp.get("type") || "all"; const resourceLang = sp.get("language") || ""; const page = Math.max(1, parseInt(sp.get("page") || "1", 10) || 1); const limit = 24; const [items, setItems] = useState([]); const [total, setTotal] = useState(0); const [err, setErr] = useState(null); const query = useMemo(() => { const p = new URLSearchParams(); p.set("lang", lang); p.set("limit", String(limit)); p.set("page", String(page)); p.set("sort", sort); if (q) p.set("q", q); if (type && type !== "all") p.set("type", type); if (resourceLang) p.set("language", resourceLang); return p.toString(); }, [lang, q, sort, type, resourceLang, page]); useEffect(() => { setErr(null); if (!q) { setItems([]); setTotal(0); return; } postJSON("/api/search-log", { query: q }).catch(() => {}); getJSON<{ items: Resource[]; total?: number }>(`/api/resources?${query}`) .then((r) => { setItems(itemsOrEmpty(r.items)); setTotal(typeof r.total === "number" ? r.total : 0); }) .catch((e) => setErr(String(e))); }, [query, q]); const setPage = (next: number) => { const n = new URLSearchParams(sp); if (next <= 1) n.delete("page"); else n.set("page", String(next)); setSp(n); }; return (

{t("search")}: {q || "—"}

{q ? ( <>
{( [ ["latest", t("latest")], ["recommended", t("official")], ["popular", t("popular")], ["published", t("sortPublished")], ] as const ).map(([k, label]) => ( ))}
{types.map((tp) => ( ))}
{t("resourceLangFilter")}
{resourceLangCodes.map((code) => ( ))}
) : null} {err ?
{err}
: null} {!q ?

{t("noResults")}

: null} {q && items.length === 0 && !err ? (

{t("noResults")}

) : null}
{items.map((r) => ( ))}
{q ? ( setPage(page - 1)} onNext={() => setPage(page + 1)} /> ) : null}
); }