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-history.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-history.tsx')
| -rw-r--r-- | app/routes/list-history.tsx | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/app/routes/list-history.tsx b/app/routes/list-history.tsx new file mode 100644 index 0000000..c47614b --- /dev/null +++ b/app/routes/list-history.tsx @@ -0,0 +1,48 @@ +import { data, Link, useLoaderData } from "react-router"; +import type { LoaderFunctionArgs } from "react-router"; +import { getBandListById, 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 revisions = getListRevisions(list.id); + return { list, revisions }; +} + +export default function ListHistory() { + const { list, revisions } = useLoaderData<typeof loader>(); + return ( + <main> + <div className="page-header"> + <Link to={`/lists/of/${list.id}`} className="back">←</Link> + <h1>{list.title} — 編集履歴</h1> + </div> + + {revisions.length === 0 ? ( + <p className="muted">履歴がありません。</p> + ) : ( + <ol className="rev-list"> + {revisions.map((rev, i) => { + let snap: { title?: string; entries?: unknown[] } = {}; + try { snap = JSON.parse(rev.snapshot); } catch { /* ignore */ } + return ( + <li key={rev.id} className="rev"> + <div className="rev-header"> + <div className="rev-main"> + <p className="rev-message">{rev.message}</p> + <p className="rev-time">{rev.created_at} · {rev.ip_address}</p> + </div> + {i === 0 && <span className="rev-latest">最新</span>} + </div> + <div className="rev-snap"> + <p>タイトル: {snap.title ?? "—"}</p> + <p>エントリ数: {snap.entries?.length ?? 0}件</p> + </div> + </li> + ); + })} + </ol> + )} + </main> + ); +} |
