diff options
Diffstat (limited to 'app/components')
| -rw-r--r-- | app/components/EventListRow.tsx | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/app/components/EventListRow.tsx b/app/components/EventListRow.tsx new file mode 100644 index 0000000..24f5f59 --- /dev/null +++ b/app/components/EventListRow.tsx @@ -0,0 +1,65 @@ +import { Link } from "react-router"; +import type { Event } from "~/lib/db.server"; + +interface Props { + event: Event; +} + +export default function EventListRow({ event }: Props) { + const formattedDate = formatDate(event.date); + const timeLabel = buildTimeLabel(event.open_time, event.start_time); + + return ( + <Link + to={`/events/${event.id}`} + className="group flex items-center gap-3 rounded-lg px-4 py-3 bg-gray-800/40 border border-gray-700/30 hover:border-indigo-500/50 hover:bg-gray-800/70 transition-all text-sm" + > + {/* Date */} + <span className="w-32 shrink-0 text-xs text-gray-400 tabular-nums"> + {formattedDate} + {timeLabel && ( + <span className="block text-gray-600 text-[11px]">{timeLabel}</span> + )} + </span> + + {/* Venue */} + <span className="w-28 shrink-0 truncate rounded-full bg-gray-700/60 px-2 py-0.5 text-xs text-gray-300"> + {event.venue_name} + {event.venue_area ? `(${event.venue_area})` : ""} + </span> + + {/* Title + artist */} + <span className="flex-1 min-w-0"> + <span className="block truncate font-medium text-gray-100 group-hover:text-indigo-300 transition-colors"> + {event.title} + </span> + {event.artist && ( + <span className="block truncate text-xs text-indigo-300/80"> + {event.artist} + </span> + )} + </span> + + {/* Price */} + {event.price ? ( + <span className="shrink-0 text-xs text-emerald-400">¥{event.price}</span> + ) : ( + <span className="shrink-0 w-16" /> + )} + </Link> + ); +} + +function formatDate(iso: string): string { + const [y, m, d] = iso.split("-"); + const days = ["日", "月", "火", "水", "木", "金", "土"]; + const dayIdx = new Date(`${iso}T00:00:00`).getDay(); + return `${y}/${m}/${d}(${days[dayIdx]})`; +} + +function buildTimeLabel(open: string | null, start: string | null): string { + const parts: string[] = []; + if (open) parts.push(`OPEN ${open}`); + if (start) parts.push(`START ${start}`); + return parts.join(" / "); +} |
