import { useLoaderData, Link } from "react-router"; import type { Route } from "./+types/venues"; import { getVenues, getLastScrapePerVenue, type ScrapeLog } from "~/lib/db.server"; export async function loader(_: Route.LoaderArgs) { const venues = getVenues(); const scrapeStatus = getLastScrapePerVenue(); return { venues, scrapeStatus }; } export default function Venues() { const { venues, scrapeStatus } = useLoaderData(); const statusMap = new Map(scrapeStatus.map((s) => [s.venue_id, s])); return (
🎸 ライブに行くしかない

会場一覧

現在 {venues.length} 会場が登録されています。

{venues.length === 0 ? (

まだ会場データがありません。「全会場を更新」してください。

) : (
{venues.map((v) => { const log = statusMap.get(v.id); return (
{/* 会場名 + エリア */}
{v.name} {v.area &&

{v.area}

}
{/* イベント件数 */} {v.event_count ?? 0} {/* 最終スクレイプ状態 */} {log ? ( ) : ( 未実行 )}
); })}
)}
); } function ScrapeStatus({ log }: { log: ScrapeLog }) { if (log.status === "running") { return ⟳ 実行中...; } if (log.status === "error") { return ( ✖ エラー ); } const time = log.finished_at?.slice(0, 16).replace("T", " ") ?? ""; return ( ✔ {time} ); }