'use client'; import React, { useState, useMemo } from 'react'; import Link from 'next/link'; import { INITIAL_GROUP_RIDES } from './fixtures'; import { GroupRideSummary } from './types'; import { CreateRideModal } from './create-ride-modal'; import { EditRideModal } from './edit-ride-modal'; import { DeleteConfirmModal } from './delete-confirm-modal'; import { JoinRideModal } from './join-ride-modal'; import { LivePackRadar } from './live-pack-radar'; interface GroupRidesManagementProps { currentUser?: { email?: string | null; displayName?: string | null } | null; onViewShowcase?: () => void; } type ManagementTab = 'my-rides' | 'discover' | 'radar'; type MyRidesFilter = 'all' | 'organized' | 'joined'; export function GroupRidesManagement({ currentUser, onViewShowcase, }: GroupRidesManagementProps) { const [rides, setRides] = useState(INITIAL_GROUP_RIDES); const [activeTab, setActiveTab] = useState('my-rides'); const [myRidesFilter, setMyRidesFilter] = useState('all'); const [searchQuery, setSearchQuery] = useState(''); const [paceFilter, setPaceFilter] = useState('all'); // Modals state const [isCreateModalOpen, setIsCreateModalOpen] = useState(false); const [isJoinModalOpen, setIsJoinModalOpen] = useState(false); const [editingRide, setEditingRide] = useState(null); const [deletingRide, setDeletingRide] = useState(null); const [leavingRide, setLeavingRide] = useState(null); // Toast alert const [activeAlert, setActiveAlert] = useState<{ message: string; type: 'success' | 'info' | 'error'; } | null>(null); const showAlert = (message: string, type: 'success' | 'info' | 'error' = 'success') => { setActiveAlert({ message, type }); setTimeout(() => { setActiveAlert(null); }, 4500); }; // KPIs const myOrganizedRides = useMemo(() => rides.filter((r) => r.isOrganizer), [rides]); const myJoinedRides = useMemo( () => rides.filter((r) => !r.isOrganizer && (r.userStatus === 'joined' || r.userStatus === 'requested')), [rides] ); const myTotalRides = useMemo( () => rides.filter((r) => r.isOrganizer || r.userStatus === 'joined'), [rides] ); // My Rides filtered list const filteredMyRides = useMemo(() => { let list = rides.filter((r) => { if (myRidesFilter === 'organized') return r.isOrganizer; if (myRidesFilter === 'joined') return !r.isOrganizer && (r.userStatus === 'joined' || r.userStatus === 'requested'); return r.isOrganizer || r.userStatus === 'joined' || r.userStatus === 'requested'; }); if (searchQuery.trim()) { const q = searchQuery.toLowerCase(); list = list.filter( (r) => r.title.toLowerCase().includes(q) || r.region.toLowerCase().includes(q) || r.meetingPoint.toLowerCase().includes(q) ); } return list; }, [rides, myRidesFilter, searchQuery]); // Discover Rides filtered list const discoverRides = useMemo(() => { let list = rides; if (paceFilter !== 'all') { list = list.filter((r) => r.paceClassification.toLowerCase().includes(paceFilter.toLowerCase())); } if (searchQuery.trim()) { const q = searchQuery.toLowerCase(); list = list.filter( (r) => r.title.toLowerCase().includes(q) || r.region.toLowerCase().includes(q) || r.leadHandle.toLowerCase().includes(q) ); } return list; }, [rides, paceFilter, searchQuery]); // Handlers for Add, Alter, Remove, Join, Leave const handleCreateRide = (newRide: GroupRideSummary) => { const rideWithOrganizer: GroupRideSummary = { ...newRide, isOrganizer: true, status: 'scheduled', userStatus: 'joined', rideCode: `MS-${Math.floor(1000 + Math.random() * 9000)}`, leadHandle: currentUser?.displayName || currentUser?.email?.split('@')[0] || 'MyHandle', leadAvatarText: (currentUser?.displayName?.[0] || currentUser?.email?.[0] || 'M').toUpperCase(), }; setRides((prev) => [rideWithOrganizer, ...prev]); showAlert(`Created new group ride "${newRide.title}"! Ride Code: ${rideWithOrganizer.rideCode}`, 'success'); }; const handleSaveEditedRide = (updatedRide: GroupRideSummary) => { setRides((prev) => prev.map((r) => (r.id === updatedRide.id ? updatedRide : r))); showAlert(`Updated parameters for "${updatedRide.title}".`, 'success'); }; const handleDeleteRide = () => { if (!deletingRide) return; const title = deletingRide.title; setRides((prev) => prev.filter((r) => r.id !== deletingRide.id)); setDeletingRide(null); showAlert(`Deleted group ride "${title}". Pack telemetry cleared.`, 'info'); }; const handleCancelRide = (ride: GroupRideSummary) => { setRides((prev) => prev.map((r) => (r.id === ride.id ? { ...r, status: 'canceled' } : r)) ); showAlert(`Ride "${ride.title}" status changed to Canceled. Participants notified.`, 'info'); }; const handleLeaveRide = () => { if (!leavingRide) return; const title = leavingRide.title; setRides((prev) => prev.map((r) => { if (r.id !== leavingRide.id) return r; return { ...r, userStatus: 'none', participantCount: Math.max(0, r.participantCount - 1), }; }) ); setLeavingRide(null); showAlert(`Left pack for "${title}". Slot relinquished.`, 'info'); }; const handleRequestSlot = (rideId: string) => { setRides((prev) => prev.map((r) => { if (r.id !== rideId) return r; if (r.participantCount >= r.participantLimit) { showAlert(`Added to waitlist for "${r.title}".`, 'info'); return { ...r, userStatus: 'waitlisted' }; } showAlert(`Joined pack for "${r.title}"! Telemetry stream linked.`, 'success'); return { ...r, userStatus: 'joined', participantCount: r.participantCount + 1, }; }) ); }; const handleJoinSuccess = (code: string, rideTitle: string) => { showAlert(`Synchronized telemetry with "${rideTitle}" (Code: ${code})!`, 'success'); }; const copyRideCode = (code?: string) => { if (!code) return; navigator.clipboard?.writeText(code); showAlert(`Copied ride code "${code}" to clipboard!`, 'success'); }; return (
{/* Dynamic Atmospheric Glow Background Layers */}
{/* Toast Notification Alert */} {activeAlert && (
{activeAlert.type === 'success' ? 'check_circle' : activeAlert.type === 'error' ? 'error' : 'info'} {activeAlert.message}
)} {/* Top Command Bar & Showcase Switch */}
Rider Console Active
• {currentUser?.email ? currentUser.email : 'Rider Account'}
{/* Showcase Mode Link */}
{onViewShowcase ? ( ) : ( visibility Feature Showcase )} person Rider Portal
{/* Header & Quick Action Region */}
groups Squad Management & Telemetry Hub

Group Rides Management

Schedule new pack formations, modify routes, manage roster slots, and monitor live squadron mesh telemetry.

{/* Action Buttons */}
{/* Metrics KPI Cards */}
Active Pack Runs
{myTotalRides.length}
{myOrganizedRides.length} Lead • {myJoinedRides.length} Wingman
Rides Organized
{myOrganizedRides.length}
Road Captain Authority
Squad Formations
{rides.length} Total
In Regional Network
Live Pack Radar
Online
6-Node Telemetry Mesh
{/* Main Navigation Tabs */}
{/* TAB 1: MY PACK RUNS (VIEW, ALTER, REMOVE, LEAVE) */} {activeTab === 'my-rides' && (
{/* Filter Sub-Bar */}
{/* Search input */}
search setSearchQuery(e.target.value)} className="w-full pl-9 pr-3.5 py-1.5 rounded-xl bg-surface-container border border-outline-variant/30 text-xs text-on-surface focus:outline-none focus:ring-1 focus:ring-primary-container" />
{/* Rides List */} {filteredMyRides.length === 0 ? (
sports_motorsports

No group rides in this view

Schedule a new run to lead as Road Captain, or browse the community directory to join an upcoming pack run.

) : (
{filteredMyRides.map((ride) => { const isOrg = Boolean(ride.isOrganizer); const isCanceled = ride.status === 'canceled'; return (
{/* Role & Status Header */}
{isOrg ? ( Road Captain (Organizer) ) : ( Squad Wingman )} {isCanceled && ( Canceled )}
{/* Ride Code Button */} {ride.rideCode && ( )}
{/* Ride Title & Region */}

{ride.title}

location_on {ride.region} • {ride.distance}

{ride.description}

{/* Meeting Point & Schedule */}
schedule {ride.scheduledDate} • {ride.scheduledTime}
flag Rally: {ride.meetingPoint}
group Pack: {ride.participantCount}/{ride.participantLimit} Riders
{/* Management Controls Row (ALTER, REMOVE, CANCEL, LEAVE) */}
{isOrg ? ( <>
{!isCanceled && ( )}
) : ( <> check_circle Pack Slot Active )}
); })}
)}
)} {/* TAB 2: EXPLORE COMMUNITY RUNS (VIEW, SEARCH, REQUEST SLOT) */} {activeTab === 'discover' && (
{/* Filter controls */}
search setSearchQuery(e.target.value)} className="w-full pl-9 pr-3.5 py-1.5 rounded-xl bg-surface-container border border-outline-variant/30 text-xs text-on-surface focus:outline-none focus:ring-1 focus:ring-primary-container" />
{/* Directory Grid */}
{discoverRides.map((ride) => { const isJoined = ride.userStatus === 'joined' || ride.isOrganizer; const isFull = ride.participantCount >= ride.participantLimit; return (
{ride.paceClassification} {ride.scheduledDate} • {ride.scheduledTime}

{ride.title}

{ride.description}

location_on {ride.region}
flag Rally: {ride.meetingPoint}
Lead: {ride.leadHandle} {ride.participantCount}/{ride.participantLimit} Riders
{isJoined ? (
check_circle {ride.isOrganizer ? 'Organized by You' : 'Slot Confirmed'}
) : isFull ? ( ) : ( )}
); })}
)} {/* TAB 3: LIVE SQUAD RADAR COCKPIT */} {activeTab === 'radar' && (
Active Squad Telemetry Stream

Live Formation Radar

Synchronized multi-band telemetry mesh monitoring live squad distance, speed, and lean angle.

)} {/* Modals */} setIsCreateModalOpen(false)} onCreateRide={handleCreateRide} /> setEditingRide(null)} onSaveRide={handleSaveEditedRide} /> setDeletingRide(null)} onConfirm={handleDeleteRide} /> setLeavingRide(null)} onConfirm={handleLeaveRide} /> setIsJoinModalOpen(false)} onJoinSuccess={handleJoinSuccess} />
); }