diff options
| author | yyamashita <yyamashita@hetzner.yyamashita.com> | 2026-09-26 00:19:53 +0900 |
|---|---|---|
| committer | yyamashita <yyamashita@hetzner.yyamashita.com> | 2026-09-26 00:19:53 +0900 |
| commit | 874749df46cc291ca61f2f98092ccabfdeffbf16 (patch) | |
| tree | e4cb53b5bfa23974e7935eb2616e0e005954f782 /app/routes/events.by-date.tsx | |
| parent | 999b7a3133fccc3f120ac5ae24c02bb38a4ecce9 (diff) | |
Single-user auth: any registered passkey logs in as the owner. First
registration needs a one-time token that the app writes to
data/registration-token when no passkey exists yet; once logged in,
more passkeys can be added without a token.
Logged in, /favorites manages a list of terms (e.g. band names).
Events whose title or artist contains a term (NFKC + case-insensitive)
get a ★, and the event list gains an "お気に入りのみ" filter.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'app/routes/events.by-date.tsx')
| -rw-r--r-- | app/routes/events.by-date.tsx | 8 |
1 files changed, 7 insertions, 1 deletions
diff --git a/app/routes/events.by-date.tsx b/app/routes/events.by-date.tsx index ee4a873..5c7876f 100644 --- a/app/routes/events.by-date.tsx +++ b/app/routes/events.by-date.tsx @@ -2,6 +2,7 @@ import { useLoaderData, useSearchParams, Link, Form } from "react-router"; import { queryEvents, getVenues, type CapacityRange } from "~/lib/db.server"; import type { Event } from "~/lib/db.server"; import { useVenueFilter } from "~/lib/venue-filter"; +import { isLoggedIn } from "~/lib/auth.server"; function todayJst(): string { // JST = UTC+9 @@ -38,7 +39,10 @@ export async function loader({ request }: { request: Request }) { const capacity_range = (url.searchParams.get("capacity_range") ?? undefined) as CapacityRange | undefined; const area = url.searchParams.get("area") ?? undefined; - const events = queryEvents({ date_from: date, date_to: date, keyword, venue_id, capacity_range, area, limit: 500 }); + const events = queryEvents({ + date_from: date, date_to: date, keyword, venue_id, capacity_range, area, + with_favorites: isLoggedIn(request), limit: 500, + }); const venues = getVenues(); const areas = [...new Set(venues.filter((v) => v.area).map((v) => v.area as string))].sort(); @@ -89,6 +93,7 @@ export default function EventsByDate() { <Link to="/events" className="hover:text-white transition-colors">イベント</Link> <Link to="/events/by-date" className="text-white">日付別</Link> <Link to="/venues" className="hover:text-white transition-colors">会場一覧</Link> + <Link to="/favorites" className="hover:text-white transition-colors">★ お気に入り</Link> </nav> </header> @@ -265,6 +270,7 @@ function VenueEventRow({ event }: { event: Event }) { {/* Title + artist */} <span className="flex-1 min-w-0"> <span className="block truncate text-sm font-medium text-gray-100 group-hover:text-indigo-300 transition-colors"> + {event.is_favorite ? <span className="text-amber-400" title="お気に入り">★ </span> : null} {event.title} </span> {event.artist && ( |
