"use client"; import { useState } from "react"; import { useRouter } from "next/navigation"; import { useAuth } from "@/components/AuthProvider"; import { useTrips } from "@/lib/useTrips"; import { c2api } from "@/lib/c2api"; import type { TripRecord } from "@/lib/types"; function fmtDate(iso: string) { return new Date(`${iso}T12:00:00`).toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric", }); } function TripCard({ trip, isAdmin, onDelete }: { trip: TripRecord; isAdmin: boolean; onDelete: (id: string) => void; }) { const router = useRouter(); const today = new Date().toISOString().slice(0, 10); const upcoming = trip.start_date >= today; const attendeeCount = Object.keys(trip.attendees ?? {}).length; return (
router.push(`/trips/${trip.trip_id}`)} >
{upcoming ? "Upcoming" : "Past"}

{trip.name}

{trip.location}

{fmtDate(trip.start_date)} — {fmtDate(trip.end_date)}

{attendeeCount > 0 && (

{attendeeCount} going

)}
{isAdmin && ( )}
); } function CreateModal({ onClose, onCreate }: { onClose: () => void; onCreate: (body: object) => Promise; }) { const [name, setName] = useState(""); const [location, setLocation] = useState(""); const [start, setStart] = useState(""); const [end, setEnd] = useState(""); const [mapsLink, setMapsLink] = useState(""); const [saving, setSaving] = useState(false); const [error, setError] = useState(null); async function handleSubmit(e: React.FormEvent) { e.preventDefault(); if (end < start) { setError("End date must be on or after start date."); return; } setSaving(true); setError(null); try { await onCreate({ name, location, start_date: start, end_date: end, maps_link: mapsLink || null, }); onClose(); } catch { setError("Failed to create trip."); } finally { setSaving(false); } } return (

New Trip

setName(e.target.value)} placeholder="Road trip to Nashville" className="w-full bg-gray-800 border border-gray-700 rounded-lg px-3 py-2 text-white text-sm focus:outline-none focus:border-indigo-500" />
setLocation(e.target.value)} placeholder="Nashville, TN" className="w-full bg-gray-800 border border-gray-700 rounded-lg px-3 py-2 text-white text-sm focus:outline-none focus:border-indigo-500" />
setStart(e.target.value)} className="w-full bg-gray-800 border border-gray-700 rounded-lg px-3 py-2 text-white text-sm focus:outline-none focus:border-indigo-500" />
setEnd(e.target.value)} min={start} className="w-full bg-gray-800 border border-gray-700 rounded-lg px-3 py-2 text-white text-sm focus:outline-none focus:border-indigo-500" />
setMapsLink(e.target.value)} placeholder="https://maps.google.com/…" className="w-full bg-gray-800 border border-gray-700 rounded-lg px-3 py-2 text-white text-sm focus:outline-none focus:border-indigo-500" />
{error &&

{error}

}
); } export default function TripsPage() { const { isAdmin } = useAuth(); const { trips, loading } = useTrips(); const [showCreate, setShowCreate] = useState(false); const today = new Date().toISOString().slice(0, 10); const upcoming = trips.filter((t) => t.end_date >= today); const past = trips.filter((t) => t.end_date < today); async function handleDelete(id: string) { try { await c2api.deleteTrip(id); } catch (e) { console.error(e); } } return (

Trips

{isAdmin && ( )}
{loading ? (

Loading…

) : ( <> {upcoming.length > 0 && (

Upcoming

{upcoming.map((t) => ( ))}
)} {past.length > 0 && (

Past

{past.map((t) => ( ))}
)} {trips.length === 0 && (

No trips yet.

)} )} {showCreate && ( setShowCreate(false)} onCreate={async (body) => { await c2api.createTrip(body); }} /> )}
); }