import { useLoaderData, useSearchParams, Link } from "react-router"; import type { Route } from "./+types/events._index"; import { queryEvents, getVenues, type CapacityRange } from "~/lib/db.server"; import EventCard from "~/components/EventCard"; import EventListRow from "~/components/EventListRow"; import FilterBar from "~/components/FilterBar"; function defaultWindow() { const today = new Date(); today.setHours(0, 0, 0, 0); const end = new Date(today); end.setDate(end.getDate() + 35); return { from: today.toISOString().slice(0, 10), to: end.toISOString().slice(0, 10), }; } export async function loader({ request }: Route.LoaderArgs) { const url = new URL(request.url); const { from: defaultFrom, to: defaultTo } = defaultWindow(); const date_from = url.searchParams.get("date_from") ?? defaultFrom; const date_to = url.searchParams.get("date_to") ?? defaultTo; const venue_id = url.searchParams.get("venue_id") ?? undefined; const keyword = url.searchParams.get("keyword") ?? undefined; const capacity_range = (url.searchParams.get("capacity_range") ?? undefined) as CapacityRange | undefined; const page = Math.max(1, parseInt(url.searchParams.get("page") ?? "1", 10)); const limit = 30; const offset = (page - 1) * limit; const events = queryEvents({ date_from, date_to, venue_id, keyword, capacity_range, limit, offset }); const venues = getVenues(); return { events, venues, page, hasMore: events.length === limit, date_from, date_to }; } export default function EventsIndex() { const { events, venues, page, hasMore, date_from, date_to } = useLoaderData(); const [searchParams, setSearchParams] = useSearchParams(); const view = (searchParams.get("view") ?? "card") as "card" | "list"; function switchView(next: "card" | "list") { const next_params = new URLSearchParams(searchParams); next_params.set("view", next); next_params.delete("page"); setSearchParams(next_params, { preventScrollReset: true }); } return (
🎸 ライブに行くしかない

イベント一覧

{events.length === 0 ? (

イベントが見つかりません

スクレイパーを実行してデータを取得してください: npm run scrape

) : view === "list" ? (
{events.map((event) => ( ))}
) : (
{events.map((event) => ( ))}
)}
{page > 1 && ( ← 前のページ )} {hasMore && ( 次のページ → )}
); } function buildPageParams(params: URLSearchParams, page: number): string { const next = new URLSearchParams(params); next.set("page", String(page)); return next.toString(); }