From b8d24d292d99c8da285092ce923b5e2b546d8f45 Mon Sep 17 00:00:00 2001 From: yyamashita Date: Sat, 9 May 2026 00:27:19 +0900 Subject: Implement band/artist management with version history Full CRUD for bands and artists: UUID + slug URLs, dynamic link editor, band-artist associations with roles, per-edit revision snapshots (message + IP). Add README and CLAUDE.md. Co-Authored-By: Claude Sonnet 4.6 --- app/routes/band-by-uuid.tsx | 108 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 app/routes/band-by-uuid.tsx (limited to 'app/routes/band-by-uuid.tsx') diff --git a/app/routes/band-by-uuid.tsx b/app/routes/band-by-uuid.tsx new file mode 100644 index 0000000..c55472e --- /dev/null +++ b/app/routes/band-by-uuid.tsx @@ -0,0 +1,108 @@ +import { data, Link, useLoaderData } from "react-router"; +import type { LoaderFunctionArgs } from "react-router"; +import { + getBandById, + getBandLinks, + getBandArtists, + getBandRevisions, +} from "~/lib/db.server"; + +export async function loader({ params }: LoaderFunctionArgs) { + const band = getBandById(params.uuid!); + if (!band) throw data("Not found", { status: 404 }); + const links = getBandLinks(band.id); + const artists = getBandArtists(band.id); + const revisions = getBandRevisions(band.id); + return { band, links, artists, latest: revisions[0] ?? null }; +} + +export default function BandDetail() { + const { band, links, artists, latest } = useLoaderData(); + return ( +
+
+
+

{band.name}

+ {band.area &&

{band.area}

} +
+
+ + 履歴 + + + 編集 + +
+
+ + {artists.length > 0 && ( +
+

+ メンバー +

+
    + {artists.map((a) => ( +
  • + + {a.artist_name} + + {a.role && ( + {a.role} + )} +
  • + ))} +
+
+ )} + + {links.length > 0 && ( +
+

+ リンク +

+ +
+ )} + +
+
+

/bands/of/{band.id}

+

+ + /bands/named/{band.slug} + +

+ {latest && ( +

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

+ )} +
+
+ ); +} -- cgit v1.2.3