'use client'; import React, { useState, useEffect } from 'react'; interface JoinRideModalProps { isOpen: boolean; onClose: () => void; onJoinSuccess: (code: string) => Promise<{ title: string; lead: string; status: 'joined' | 'requested' }>; } export function JoinRideModal({ isOpen, onClose, onJoinSuccess }: JoinRideModalProps) { const [code, setCode] = useState(''); const [errorMsg, setErrorMsg] = useState(null); const [successInfo, setSuccessInfo] = useState<{ title: string; lead: string; status: 'joined' | 'requested' } | null>(null); const [isSubmitting, setIsSubmitting] = useState(false); // Reset state when modal is opened/closed useEffect(() => { if (isOpen) { setCode(''); setErrorMsg(null); setSuccessInfo(null); setIsSubmitting(false); } }, [isOpen]); // Handle ESC key press useEffect(() => { const handleKeyDown = (e: KeyboardEvent) => { if (e.key === 'Escape' && isOpen) { onClose(); } }; window.addEventListener('keydown', handleKeyDown); return () => window.removeEventListener('keydown', handleKeyDown); }, [isOpen, onClose]); if (!isOpen) return null; const handleCodeChange = (e: React.ChangeEvent) => { const raw = e.target.value.toUpperCase().replace(/[^A-Z0-9_-]/g, ''); setCode(raw); if (errorMsg) setErrorMsg(null); }; const processCode = async (rideCode: string) => { const cleanCode = rideCode.trim().toUpperCase(); if (!cleanCode || cleanCode.length < 4) { setErrorMsg('Please enter a valid ride code (at least 4 characters).'); return; } setIsSubmitting(true); setErrorMsg(null); try { setSuccessInfo(await onJoinSuccess(cleanCode)); } catch (error) { setErrorMsg(error instanceof Error ? error.message : 'Could not join this ride.'); } finally { setIsSubmitting(false); } }; const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); void processCode(code); }; return (
{ if (e.target === e.currentTarget) onClose(); }} >
{/* Header */}
qr_code_scanner

Join Pack Formation

{/* Success State */} {successInfo ? (
check_circle
{successInfo.status === 'joined' ? 'Ride Joined' : 'Request Sent'}

{successInfo.title}

Ride lead: {successInfo.lead}. {successInfo.status === 'joined' ? ' You are on the rider list.' : ' The organizer must approve your request.'}

) : ( /* Input / Scanner Flow */

Enter the ride code to find a public group ride and join or request a slot.

{/* Error Message */} {errorMsg && (
error {errorMsg}
)} {/* Code Input */}
{/* Submit Button */}
)}
); }