import { data, Link, useLoaderData } from "react-router"; import type { LoaderFunctionArgs } from "react-router"; import { getArtistById, getArtistLinks, getArtistMembers, getArtistRevisions, groupArtistMembers, type BandGroup, } from "~/lib/db.server"; import { formatDuration } from "~/lib/utils"; 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 memberships = getArtistMembers(artist.id); const revisions = getArtistRevisions(artist.id); const grouped = groupArtistMembers(memberships); return { artist, links, grouped, latest: revisions[0] ?? null }; } function periodRange(since: string, until: string): string | null { if (!since && !until) return null; return `${since || "?"} 〜 ${until || "現在"}`; } function BandItem({ group }: { group: BandGroup }) { const roles = [...new Set(group.periods.flatMap((p) => p.role ? p.role.split(", ").filter(Boolean) : [] ))]; const hasPeriodInfo = group.periods.some((p) => p.since || p.until || p.note); return (
  • {group.band_name} {roles.map((r, i) => {r})} {group.duration_months !== null && ( {formatDuration(group.duration_months)} )}
    {hasPeriodInfo && ( )}
  • ); } export default function ArtistDetail() { const { artist, links, grouped, latest } = useLoaderData(); return (

    {artist.name}

    履歴 編集
    {grouped.current.length > 0 && (

    在籍中のバンド

      {grouped.current.map((g) => )}
    )} {grouped.former.length > 0 && (

    元在籍バンド

      {grouped.former.map((g) => )}
    )} {links.length > 0 && (

    リンク

    )}

    /artists/of/{artist.id}

    /artists/named/{artist.slug}

    {latest && (

    最終更新: {latest.created_at} — {latest.message}

    )}
    ); }