summaryrefslogtreecommitdiff
path: root/app/routes/artist-by-uuid.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'app/routes/artist-by-uuid.tsx')
-rw-r--r--app/routes/artist-by-uuid.tsx53
1 files changed, 42 insertions, 11 deletions
diff --git a/app/routes/artist-by-uuid.tsx b/app/routes/artist-by-uuid.tsx
index 6eb06a7..a65525b 100644
--- a/app/routes/artist-by-uuid.tsx
+++ b/app/routes/artist-by-uuid.tsx
@@ -1,18 +1,29 @@
import { data, Link, useLoaderData } from "react-router";
import type { LoaderFunctionArgs } from "react-router";
-import { getArtistBands, getArtistById, getArtistLinks, getArtistRevisions } from "~/lib/db.server";
+import { getArtistById, getArtistLinks, getArtistMembers, getArtistRevisions, type ArtistMemberRow } from "~/lib/db.server";
export async function loader({ params }: LoaderFunctionArgs) {
const artist = getArtistById(params.uuid!);
if (!artist) throw data("Not found", { status: 404 });
const links = getArtistLinks(artist.id);
- const bands = getArtistBands(artist.id);
+ const memberships = getArtistMembers(artist.id);
const revisions = getArtistRevisions(artist.id);
- return { artist, links, bands, latest: revisions[0] ?? null };
+ return { artist, links, memberships, latest: revisions[0] ?? null };
+}
+
+function periodLabel(m: ArtistMemberRow): string | null {
+ if (!m.since && !m.until) return null;
+ const from = m.since || "?";
+ const to = m.until || "現在";
+ return `${from} 〜 ${to}`;
}
export default function ArtistDetail() {
- const { artist, links, bands, latest } = useLoaderData<typeof loader>();
+ const { artist, links, memberships, latest } = useLoaderData<typeof loader>();
+
+ // group by band_id
+ const bandIds = [...new Set(memberships.map((m) => m.band_id))];
+
return (
<main>
<div className="detail-header">
@@ -23,16 +34,36 @@ export default function ArtistDetail() {
</div>
</div>
- {bands.length > 0 && (
+ {bandIds.length > 0 && (
<section>
<h2>バンド</h2>
<ul className="member-list">
- {bands.map((b) => (
- <li key={b.band_id}>
- <Link to={`/bands/of/${b.band_id}`}>{b.band_name}</Link>
- {b.role && <span className="muted">{b.role}</span>}
- </li>
- ))}
+ {bandIds.map((bandId) => {
+ const group = memberships.filter((m) => m.band_id === bandId);
+ const first = group[0];
+ return (
+ <li key={bandId}>
+ <div className="member-main">
+ <Link to={`/bands/of/${bandId}`}>{first.band_name}</Link>
+ {first.role && <span className="muted">{first.role}</span>}
+ </div>
+ {group.some((m) => m.since || m.until || m.note) && (
+ <ul className="period-list">
+ {group.map((m) => {
+ const label = periodLabel(m);
+ if (!label && !m.note) return null;
+ return (
+ <li key={m.id} className="period-item">
+ {label && <span className="period-range">{label}</span>}
+ {m.note && <span className="period-note">{m.note}</span>}
+ </li>
+ );
+ })}
+ </ul>
+ )}
+ </li>
+ );
+ })}
</ul>
</section>
)}