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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
|
import { Link, useLoaderData } from "react-router";
import { listBands, listArtists, listBandLists, listRecentBands, listRecentArtists } from "~/lib/db.server";
export function loader() {
return {
bandCount: listBands().length,
artistCount: listArtists().length,
listCount: listBandLists().length,
recentBands: listRecentBands(8),
recentArtists: listRecentArtists(8),
};
}
export default function Home() {
const { bandCount, artistCount, listCount, recentBands, recentArtists } = useLoaderData<typeof loader>();
return (
<main>
<div style={{ marginBottom: "2.5rem" }}>
<h1 style={{ fontSize: "2rem", fontWeight: 700, color: "#f9fafb", marginBottom: ".5rem" }}>
whois.band
</h1>
<p className="muted">バンドとアーティストの情報管理サイト</p>
</div>
<div style={{ display: "flex", flexDirection: "column", gap: "1px", background: "#1f2937", border: "1px solid #1f2937", borderRadius: "6px", overflow: "hidden", marginBottom: "2.5rem" }}>
<SectionRow to="/bands" label="Bands" count={bandCount} newTo="/bands/new" />
<SectionRow to="/artists" label="Artists" count={artistCount} newTo="/artists/new" />
<SectionRow to="/lists" label="Lists" count={listCount} newTo="/lists/new" />
</div>
<div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: "2rem" }}>
<RecentSection title="最近追加されたバンド" viewAllTo="/bands">
{recentBands.length === 0 ? (
<p className="muted" style={{ fontSize: ".875rem" }}>まだありません</p>
) : (
<ul className="band-list">
{recentBands.map((band) => (
<li key={band.id}>
<Link to={`/bands/of/${band.id}`}>{band.name}</Link>
{band.status === "hiatus" && (
<span className="muted" style={{ fontSize: ".75rem" }}>活動休止</span>
)}
</li>
))}
</ul>
)}
</RecentSection>
<RecentSection title="最近追加されたアーティスト" viewAllTo="/artists">
{recentArtists.length === 0 ? (
<p className="muted" style={{ fontSize: ".875rem" }}>まだありません</p>
) : (
<ul className="band-list">
{recentArtists.map((artist) => (
<li key={artist.id}>
<Link to={`/artists/of/${artist.id}`}>{artist.name}</Link>
</li>
))}
</ul>
)}
</RecentSection>
</div>
</main>
);
}
function SectionRow({
to,
label,
count,
newTo,
}: {
to: string;
label: string;
count: number;
newTo: string;
}) {
return (
<div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", padding: ".875rem 1.25rem", background: "#0f1117" }}>
<div style={{ display: "flex", alignItems: "baseline", gap: "1rem" }}>
<Link to={to} style={{ fontWeight: 600, fontSize: "1rem", color: "#e5e7eb" }}>
{label}
</Link>
<span className="muted" style={{ fontSize: ".8rem" }}>{count}件</span>
</div>
<Link to={newTo} className="btn" style={{ fontSize: ".8rem" }}>
+ 追加
</Link>
</div>
);
}
function RecentSection({
title,
viewAllTo,
children,
}: {
title: string;
viewAllTo: string;
children: React.ReactNode;
}) {
return (
<section style={{ marginBottom: 0 }}>
<div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: ".75rem" }}>
<h2 style={{ margin: 0 }}>{title}</h2>
<Link to={viewAllTo} className="muted" style={{ fontSize: ".75rem" }}>すべて見る</Link>
</div>
{children}
</section>
);
}
|