diff options
| author | yyamashita <yyamashita@mosquit.one> | 2026-05-07 10:16:43 +0900 |
|---|---|---|
| committer | yyamashita <yyamashita@mosquit.one> | 2026-05-07 10:16:43 +0900 |
| commit | 0cd5fb770ca9bd3f304d9556a4b33a4ad4f45e7e (patch) | |
| tree | aa316c21d7195689d87669338373d83b0b6ac3fb /app/routes | |
| parent | 538fd636e25595d88a958344d285c0e7cf44e530 (diff) | |
Playwright scraping for FLAT/Pitbar; web UI display-only
- Install Playwright + Chromium; add shared browser singleton (playwright.server.ts)
- Rewrite flat-nishiogikubo scraper: Wix calendar via headless browser,
month navigation via date picker, extracts .WPczEB/.ExCBIq selectors
- Rewrite pitbar-nishiogikubo scraper: freecalend.com via headless browser,
parses cal-{member}-{year}-{month}-{day} cell IDs
- scraper-runner: close shared browser after each run with closeBrowser()
- Remove all scrape trigger buttons from web UI (events index, venues page);
remove /api/scrape and /api/scrape-status from routes.ts
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Diffstat (limited to 'app/routes')
| -rw-r--r-- | app/routes/events._index.tsx | 14 | ||||
| -rw-r--r-- | app/routes/venues.tsx | 41 |
2 files changed, 11 insertions, 44 deletions
diff --git a/app/routes/events._index.tsx b/app/routes/events._index.tsx index 3ff441a..1917ace 100644 --- a/app/routes/events._index.tsx +++ b/app/routes/events._index.tsx @@ -1,4 +1,4 @@ -import { useLoaderData, useSearchParams, Form, Link } from "react-router"; +import { useLoaderData, useSearchParams, Link } from "react-router"; import type { Route } from "./+types/events._index"; import { queryEvents, getVenues } from "~/lib/db.server"; import EventCard from "~/components/EventCard"; @@ -49,16 +49,8 @@ export default function EventsIndex() { </header> <main className="max-w-6xl mx-auto px-4 py-8"> - <div className="mb-6 flex items-center justify-between"> + <div className="mb-6"> <h1 className="text-2xl font-bold">イベント一覧</h1> - <Form method="post" action="/api/scrape"> - <button - type="submit" - className="rounded-md bg-indigo-600 px-4 py-2 text-sm font-medium hover:bg-indigo-500 transition-colors" - > - 情報を更新 - </button> - </Form> </div> <FilterBar venues={venues} defaultDateFrom={date_from} defaultDateTo={date_to} /> @@ -66,7 +58,7 @@ export default function EventsIndex() { {events.length === 0 ? ( <div className="mt-16 text-center text-gray-500"> <p className="text-lg">イベントが見つかりません</p> - <p className="mt-2 text-sm">「情報を更新」ボタンでデータを取得してください。</p> + <p className="mt-2 text-sm">スクレイパーを実行してデータを取得してください: <code>npm run scrape</code></p> </div> ) : ( <div className="mt-6 grid gap-4 sm:grid-cols-2 lg:grid-cols-3"> diff --git a/app/routes/venues.tsx b/app/routes/venues.tsx index affa72a..fca90dd 100644 --- a/app/routes/venues.tsx +++ b/app/routes/venues.tsx @@ -1,18 +1,15 @@ -import { useLoaderData, Link, Form } from "react-router"; +import { useLoaderData, Link } from "react-router"; import type { Route } from "./+types/venues"; import { getVenues, getLastScrapePerVenue, type ScrapeLog } from "~/lib/db.server"; -import { getScraperIds } from "~/lib/venue-meta.server"; export async function loader(_: Route.LoaderArgs) { const venues = getVenues(); - const scraperIds = getScraperIds(); const scrapeStatus = getLastScrapePerVenue(); - return { venues, scraperIds, scrapeStatus }; + return { venues, scrapeStatus }; } export default function Venues() { - const { venues, scraperIds: scraperIdList, scrapeStatus } = useLoaderData<typeof loader>(); - const scraperIds = new Set(scraperIdList); + const { venues, scrapeStatus } = useLoaderData<typeof loader>(); const statusMap = new Map<string, ScrapeLog>(scrapeStatus.map((s) => [s.venue_id, s])); return ( @@ -28,21 +25,11 @@ export default function Venues() { </header> <main className="max-w-4xl mx-auto px-4 py-10"> - <div className="mb-8 flex items-start justify-between gap-4 flex-wrap"> - <div> - <h1 className="text-2xl font-bold">会場一覧</h1> - <p className="mt-1 text-sm text-gray-400"> - 現在 {scraperIdList.length} 会場のスクレイパーが登録されています。 - </p> - </div> - <Form method="post" action="/api/scrape"> - <button - type="submit" - className="rounded-md bg-indigo-600 px-4 py-2 text-sm font-medium hover:bg-indigo-500 transition-colors" - > - 全会場を更新 - </button> - </Form> + <div className="mb-8"> + <h1 className="text-2xl font-bold">会場一覧</h1> + <p className="mt-1 text-sm text-gray-400"> + 現在 {venues.length} 会場が登録されています。 + </p> </div> {venues.length === 0 ? ( @@ -79,18 +66,6 @@ export default function Venues() { <span className="text-xs text-gray-600 whitespace-nowrap">未実行</span> )} - {/* 個別更新ボタン */} - {scraperIds.has(v.id) && ( - <Form method="post" action="/api/scrape"> - <input type="hidden" name="venue_id" value={v.id} /> - <button - type="submit" - className="rounded bg-gray-700 px-3 py-1 text-xs hover:bg-gray-600 transition-colors whitespace-nowrap" - > - 更新 - </button> - </Form> - )} </div> ); })} |
