72 lines
2.3 KiB
TypeScript
72 lines
2.3 KiB
TypeScript
"use client";
|
|
|
|
import { Suspense, useEffect, useState } from "react";
|
|
import { useTranslations } from "next-intl";
|
|
import { useRouter, usePathname } from "@/i18n/navigation";
|
|
import { useSearchParams } from "next/navigation";
|
|
|
|
function HeaderCatalogSearchInner() {
|
|
const t = useTranslations("nav");
|
|
const router = useRouter();
|
|
const pathname = usePathname();
|
|
const searchParams = useSearchParams();
|
|
const qParam = pathname === "/catalog" ? (searchParams.get("q") ?? "") : "";
|
|
const [q, setQ] = useState(qParam);
|
|
|
|
useEffect(() => {
|
|
setQ(qParam);
|
|
}, [qParam]);
|
|
|
|
function onSubmit(e: React.FormEvent) {
|
|
e.preventDefault();
|
|
const trimmed = q.trim();
|
|
const params = new URLSearchParams();
|
|
if (trimmed) params.set("q", trimmed);
|
|
router.push(`/catalog${params.toString() ? `?${params.toString()}` : ""}`);
|
|
}
|
|
|
|
return (
|
|
<form
|
|
onSubmit={onSubmit}
|
|
className="relative hidden w-full max-w-xl md:block"
|
|
role="search"
|
|
>
|
|
<label htmlFor="header-catalog-search" className="sr-only">
|
|
{t("searchAria")}
|
|
</label>
|
|
<input
|
|
id="header-catalog-search"
|
|
type="search"
|
|
enterKeyHint="search"
|
|
value={q}
|
|
onChange={(e) => setQ(e.target.value)}
|
|
placeholder={t("searchPlaceholder")}
|
|
className="w-full rounded-full border border-neutral-200 bg-neutral-50 py-2.5 pl-11 pr-4 text-sm text-neutral-900 shadow-inner shadow-neutral-200/40 outline-none ring-blue-600/0 transition placeholder:text-neutral-400 focus:border-blue-600 focus:bg-white focus:ring-2 focus:ring-blue-600/20"
|
|
/>
|
|
<span
|
|
className="pointer-events-none absolute left-3.5 top-1/2 -translate-y-1/2 text-neutral-400"
|
|
aria-hidden
|
|
>
|
|
<svg className="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={1.75}>
|
|
<path strokeLinecap="round" strokeLinejoin="round" d="m21 21-4.34-4.34M11 18a7 7 0 1 1 0-14 7 7 0 0 1 0 14Z" />
|
|
</svg>
|
|
</span>
|
|
</form>
|
|
);
|
|
}
|
|
|
|
export function HeaderCatalogSearch() {
|
|
return (
|
|
<Suspense
|
|
fallback={
|
|
<div
|
|
className="hidden h-10 w-full max-w-xl rounded-full bg-neutral-100 md:block"
|
|
aria-hidden
|
|
/>
|
|
}
|
|
>
|
|
<HeaderCatalogSearchInner />
|
|
</Suspense>
|
|
);
|
|
}
|