blob: a4c03b744e499a277a3fad7146d706bbaf5adf9c (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
|
import { Form, Link, useLoaderData } from "react-router";
import type { Route } from "./+types/search";
import { searchAll } from "~/lib/db.server";
export function loader({ request }: Route.LoaderArgs) {
const q = new URL(request.url).searchParams.get("q")?.trim() ?? "";
if (!q) return { q, bands: [], artists: [] };
const { bands, artists } = searchAll(q);
return { q, bands, artists };
}
export default function Search() {
const { q, bands, artists } = useLoaderData<typeof loader>();
const hasResults = bands.length > 0 || artists.length > 0;
return (
<main>
<div className="page-header">
<h1>検索</h1>
</div>
<Form method="get" action="/search" style={{ marginBottom: "1.5rem" }}>
<input
type="search"
name="q"
defaultValue={q}
placeholder="バンド名・アーティスト名で検索"
autoFocus
/>
</Form>
{!q ? (
<p className="muted">検索キーワードを入力してください。</p>
) : !hasResults ? (
<p className="muted">「{q}」に一致する結果が見つかりませんでした。</p>
) : (
<>
{bands.length > 0 && (
<section>
<h2>Bands</h2>
<ul className="band-list">
{bands.map((band) => (
<li key={band.id}>
<Link to={`/bands/of/${band.id}`}>{band.name}</Link>
{band.area && (
<span className="muted" style={{ fontSize: ".75rem" }}>{band.area}</span>
)}
{band.status === "hiatus" && (
<span className="muted" style={{ fontSize: ".75rem" }}>活動休止</span>
)}
</li>
))}
</ul>
</section>
)}
{artists.length > 0 && (
<section>
<h2>Artists</h2>
<ul className="band-list">
{artists.map((artist) => (
<li key={artist.id}>
<Link to={`/artists/of/${artist.id}`}>{artist.name}</Link>
</li>
))}
</ul>
</section>
)}
</>
)}
</main>
);
}
|