45 lines
1.6 KiB
TypeScript
45 lines
1.6 KiB
TypeScript
import { Search as SearchIcon } from "lucide-react";
|
|
import { searchCovers } from "@/lib/db/queries";
|
|
import { MasonryGrid } from "@/components/grid/MasonryGrid";
|
|
import { RegisterVisible } from "@/components/select/RegisterVisible";
|
|
|
|
export const dynamic = "force-dynamic";
|
|
|
|
export default async function SearchPage({
|
|
searchParams,
|
|
}: {
|
|
searchParams: Promise<{ q?: string | string[] }>;
|
|
}) {
|
|
const { q } = await searchParams;
|
|
const query = (Array.isArray(q) ? q[0] ?? "" : q ?? "").trim();
|
|
const items = query ? searchCovers(query) : [];
|
|
|
|
return (
|
|
<div className="max-w-[1600px] mx-auto px-6 py-6 fade-in">
|
|
<div className="mb-6 flex items-center gap-3">
|
|
<SearchIcon className="w-6 h-6 text-[var(--color-cyan)]" />
|
|
<div>
|
|
<h1 className="text-2xl font-semibold tracking-tight">
|
|
{query ? <>Results for <span className="text-gradient-accent">{query}</span></> : "Search"}
|
|
</h1>
|
|
<p className="text-sm text-[var(--color-fg-dim)] mt-0.5">
|
|
{query ? `${items.length} match${items.length === 1 ? "" : "es"}` : "Type a code, title, director or notes phrase in the top bar."}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
{query && items.length === 0 && (
|
|
<div className="glass rounded-2xl p-card text-center text-[var(--color-fg-dim)]">
|
|
No covers match. Try a shorter or different query.
|
|
</div>
|
|
)}
|
|
{items.length > 0 && (
|
|
<>
|
|
<RegisterVisible ids={items.map((i) => i.id)} />
|
|
<MasonryGrid images={items} />
|
|
</>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|