TypeScript 61.9%
HTML 37.2%
SQL 0.7%
1import type { Metadata } from 'next';2import Link from 'next/link';3import { requireUser } from '@/lib/auth/session';4import { listSavedSearches } from '@/lib/account/queries';5import { deleteSavedSearchAction, toggleSavedSearchNotifyAction } from '@/lib/account/actions';6import { PageHeader, btnDanger, btnGhost } from '@/components/account/page-header';7import { Card, CardHeader, EmptyState, Badge } from '@/components/ui/primitives';8import { fmtRelative } from '@/lib/format';9import { SaveSearchForm } from './save-form';1011export const metadata: Metadata = { title: 'Saved searches', robots: { index: false } };1213export default async function SavedPage({ searchParams }: { searchParams: Promise<Record<string, string | undefined>> }) {14 const sp = await searchParams;15 const u = await requireUser('/saved');16 const rows = await listSavedSearches(u.id);17 return (18 <>19 <PageHeader title="Saved searches" description="Keep your Explore and Search filters one click away. Searches with notifications on are re-run daily; new matches land in your inbox." />20 <div className="grid gap-4 lg:grid-cols-[minmax(0,1fr)_360px]">21 <Card>22 <CardHeader title={`Saved · ${rows.length}`} />23 {rows.length === 0 ? (24 <EmptyState title="No saved searches" description="Run a search, then use “Save this search” — or paste a RareIndex search URL on the right." />25 ) : (26 <ul className="divide-y divide-border">27 {rows.map((s) => (28 <li key={s.id} className="flex items-center justify-between gap-3 px-4 py-2.5 text-sm">29 <div className="min-w-0">30 <Link href={s.url} className="block truncate font-medium hover:underline">31 {s.name}32 </Link>33 <p className="truncate text-[11px] text-subtle">34 {s.url} · saved {fmtRelative(s.createdAt)}35 {s.lastRunAt ? ` · last run ${fmtRelative(s.lastRunAt)} (${s.lastCount ?? 0} results)` : ''}36 </p>37 </div>38 <div className="flex items-center gap-1">39 {s.notify ? <Badge tone="index">notify</Badge> : null}40 <form action={toggleSavedSearchNotifyAction}>41 <input type="hidden" name="id" value={s.id} />42 <button className={btnGhost}>{s.notify ? 'Mute' : 'Notify'}</button>43 </form>44 <form action={deleteSavedSearchAction}>45 <input type="hidden" name="id" value={s.id} />46 <button className={btnDanger}>Delete</button>47 </form>48 </div>49 </li>50 ))}51 </ul>52 )}53 </Card>54 <Card>55 <CardHeader title="Save a search" />56 <div className="p-4">57 <SaveSearchForm initialUrl={sp.url ?? ''} initialName={sp.name ?? ''} />58 </div>59 </Card>60 </div>61 </>62 );63}64