diff options
| author | yyamashita <yyamashita@mosquit.one> | 2026-05-11 00:06:52 +0900 |
|---|---|---|
| committer | yyamashita <yyamashita@mosquit.one> | 2026-05-11 00:06:52 +0900 |
| commit | e9e576abd9d6c6030aa4bb290e869890831488ad (patch) | |
| tree | ec521f62ddffda13c30f5c964e01b9daa1b52851 /app/routes/list-by-uuid.tsx | |
| parent | 609dc6a3769d85e1cc4a8f06af58165be86b598c (diff) | |
Add lists feature (band recommendation lists with history)
New lists, list_entries, list_revisions tables; full CRUD routes under /lists; nav link in root.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Diffstat (limited to 'app/routes/list-by-uuid.tsx')
| -rw-r--r-- | app/routes/list-by-uuid.tsx | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/app/routes/list-by-uuid.tsx b/app/routes/list-by-uuid.tsx new file mode 100644 index 0000000..f8c7380 --- /dev/null +++ b/app/routes/list-by-uuid.tsx @@ -0,0 +1,54 @@ +import { data, Link, useLoaderData } from "react-router"; +import type { LoaderFunctionArgs } from "react-router"; +import { getBandListById, getListEntries, getListRevisions } from "~/lib/db.server"; + +export async function loader({ params }: LoaderFunctionArgs) { + const list = getBandListById(params.uuid!); + if (!list) throw data("Not found", { status: 404 }); + const entries = getListEntries(list.id); + const revisions = getListRevisions(list.id); + return { list, entries, latest: revisions[0] ?? null }; +} + +export default function ListDetail() { + const { list, entries, latest } = useLoaderData<typeof loader>(); + + return ( + <main> + <div className="detail-header"> + <div className="detail-info"> + <h1>{list.title}</h1> + {list.description && <p className="detail-desc">{list.description}</p>} + </div> + <div className="detail-actions"> + <Link to={`/lists/of/${list.id}/history`} className="history">履歴</Link> + <Link to={`/lists/of/${list.id}/edit`} className="edit">編集</Link> + </div> + </div> + + {entries.length === 0 ? ( + <p className="muted">エントリがありません。</p> + ) : ( + <ul className="entry-list"> + {entries.map((entry) => ( + <li key={entry.id}> + <div className="entry-band">{entry.band_name}</div> + {entry.note && <div className="entry-note">{entry.note}</div>} + </li> + ))} + </ul> + )} + + <hr /> + <div className="meta"> + <p>/lists/of/{list.id}</p> + <p> + <Link to={`/lists/named/${list.slug}`}>/lists/named/{list.slug}</Link> + </p> + {latest && ( + <p className="updated">最終更新: {latest.created_at} — {latest.message}</p> + )} + </div> + </main> + ); +} |
