'use client'; import React from 'react'; import Link from 'next/link'; import { useParams, useSearchParams } from 'next/navigation'; import { ClubUpcomingRide, UserPortalPermissions } from './types'; import { EmptyState } from './empty-state'; interface UpcomingRidesSectionProps { rides: ClubUpcomingRide[]; permissions: UserPortalPermissions; clubId?: string; onPlanRide?: () => void; onManageRide?: (rideId: string) => void; onViewRoster?: (rideId: string) => void; onViewRoute?: (routeId?: string) => void; } export function ClubRideCard({ ride, permissions, clubId, onManageRide, onViewRoster, onViewRoute, }: { ride: ClubUpcomingRide; permissions: UserPortalPermissions; clubId?: string; onManageRide?: (rideId: string) => void; onViewRoster?: (rideId: string) => void; onViewRoute?: (routeId?: string) => void; }) { const params = useParams(); const targetClubId = clubId || (typeof params?.clubId === 'string' ? params.clubId : ''); const capacityPercent = ride.capacity ? Math.min(100, Math.round((ride.confirmedCount / ride.capacity) * 100)) : 75; return (
{/* Top Metadata Row */}
{ride.scheduledStartAt} • Ride ID: {ride.rideIdentifier}

{ride.title}

{ride.paceClassification}
{/* Attributes Row */}
Straight-line distance
{ride.distanceMiles ? `${ride.distanceMiles} mi` : '--'}
Duration
{ride.durationString ?? '--'}
Pace Classification
{ride.paceClassification}
{/* Roster & Road Captain Details */}
Riders: {ride.confirmedCount} going {ride.pendingCount > 0 ? ( {ride.pendingCount} requests pending ) : ride.capacity ? ( {Math.max(0, ride.capacity - ride.confirmedCount)} open spots ) : null}
{/* Section 15: Verbatim Live Location Privacy Policy Notice */}
info Live location is shared only with eligible ride participants while sharing is enabled. Club membership alone never grants access to rider location.
{/* Actions: Disabled until backend club-ride management ships */}
{permissions.canPlanRides ? ( ) : ( )}
); } export function UpcomingRidesSection({ rides, permissions, clubId, onPlanRide, onManageRide, onViewRoster, onViewRoute, }: UpcomingRidesSectionProps) { const params = useParams(); const searchParams = useSearchParams(); const isDemo = searchParams?.get('preview') === 'demo'; const queryParam = isDemo ? '?preview=demo' : ''; const targetClubId = clubId || (typeof params?.clubId === 'string' ? params.clubId : ''); return (

Upcoming Club Rides

Scheduled Club Rides, routes, participants, and ride assignments.

{rides.length > 0 && ( Full Ride Schedule arrow_forward )}
{rides.length === 0 ? ( ) : (
{rides.map((ride) => ( ))}
)}
); }