'use client'; import { useEffectiveDriverId } from '@/hooks/useEffectiveDriverId'; import { AlertCircle, AlertTriangle, Award, Bell, BellRing, Building2, ChevronDown, ChevronUp, LogIn, LogOut, MessageSquare, Shield, TrendingUp, User, Vote, Wrench, X, } from 'lucide-react'; import { useRouter } from 'next/navigation'; import { useEffect, useState } from 'react'; type DemoNotificationType = 'protest_filed' | 'defense_requested' | 'vote_required' | 'race_performance_summary' | 'race_final_results'; type DemoUrgency = 'silent' | 'toast' | 'modal'; interface NotificationOption { type: DemoNotificationType; label: string; description: string; icon: typeof Bell; color: string; } interface UrgencyOption { urgency: DemoUrgency; label: string; description: string; icon: typeof Bell; } const notificationOptions: NotificationOption[] = [ { type: 'protest_filed', label: 'Protest Against You', description: 'A protest was filed against you', icon: AlertTriangle, color: 'text-red-400', }, { type: 'defense_requested', label: 'Defense Requested', description: 'A steward requests your defense', icon: Shield, color: 'text-warning-amber', }, { type: 'vote_required', label: 'Vote Required', description: 'You need to vote on a protest', icon: Vote, color: 'text-primary-blue', }, { type: 'race_performance_summary', label: 'Race Performance Summary', description: 'Immediate results after main race', icon: TrendingUp, color: 'text-primary-blue', }, { type: 'race_final_results', label: 'Race Final Results', description: 'Final results after stewarding closes', icon: Award, color: 'text-warning-amber', }, ]; const urgencyOptions: UrgencyOption[] = [ { urgency: 'silent', label: 'Silent', description: 'Only shows in notification center', icon: Bell, }, { urgency: 'toast', label: 'Toast', description: 'Shows a temporary popup', icon: BellRing, }, { urgency: 'modal', label: 'Modal', description: 'Shows blocking modal (may require response)', icon: AlertCircle, }, ]; type LoginMode = 'none' | 'driver' | 'sponsor'; export default function DevToolbar() { const router = useRouter(); const [isExpanded, setIsExpanded] = useState(false); const [isMinimized, setIsMinimized] = useState(false); const [selectedType, setSelectedType] = useState('protest_filed'); const [selectedUrgency, setSelectedUrgency] = useState('toast'); const [sending, setSending] = useState(false); const [lastSent, setLastSent] = useState(null); const [loginMode, setLoginMode] = useState('none'); const [loggingIn, setLoggingIn] = useState(false); const currentDriverId = useEffectiveDriverId(); // Sync login mode with actual cookie state on mount useEffect(() => { if (typeof document !== 'undefined') { const cookies = document.cookie.split(';'); const demoModeCookie = cookies.find(c => c.trim().startsWith('gridpilot_demo_mode=')); if (demoModeCookie) { const value = demoModeCookie.split('=')[1]?.trim(); if (value === 'sponsor') { setLoginMode('sponsor'); } else if (value === 'driver') { setLoginMode('driver'); } else { setLoginMode('none'); } } else { // Default to driver mode if no cookie (for demo purposes) setLoginMode('driver'); } } }, []); const handleLoginAsDriver = async () => { setLoggingIn(true); try { // Demo: Set cookie to indicate driver mode document.cookie = 'gridpilot_demo_mode=driver; path=/; max-age=86400'; setLoginMode('driver'); // Refresh to update all components that depend on demo mode window.location.reload(); } finally { setLoggingIn(false); } }; const handleLoginAsSponsor = async () => { setLoggingIn(true); try { // Demo: Set cookie to indicate sponsor mode document.cookie = 'gridpilot_demo_mode=sponsor; path=/; max-age=86400'; setLoginMode('sponsor'); // Navigate to sponsor dashboard window.location.href = '/sponsor/dashboard'; } finally { setLoggingIn(false); } }; const handleLogout = async () => { setLoggingIn(true); try { // Demo: Clear demo mode cookie document.cookie = 'gridpilot_demo_mode=; path=/; max-age=0'; setLoginMode('none'); // Refresh to update all components window.location.href = '/'; } finally { setLoggingIn(false); } }; // Only show in development if (process.env.NODE_ENV === 'production') { return null; } // const handleSendNotification = async () => { // setSending(true); // try { // const sendNotification = getSendNotificationUseCase(); // const raceRepository = getRaceRepository(); // const leagueRepository = getLeagueRepository(); // const [allRaces, allLeagues] = await Promise.all([ // raceRepository.findAll(), // leagueRepository.findAll(), // ]); // const completedRaces = allRaces.filter((race) => race.status === 'completed'); // const scheduledRaces = allRaces.filter((race) => race.status === 'scheduled'); // const primaryRace = completedRaces[0] ?? allRaces[0]; // const secondaryRace = scheduledRaces[0] ?? allRaces[1] ?? primaryRace; // const primaryLeague = allLeagues[0]; // const notificationDeadline = // selectedUrgency === 'modal' // ? new Date(Date.now() + 48 * 60 * 60 * 1000) // : undefined; // let title: string; // let body: string; // let notificationType: 'protest_filed' | 'protest_defense_requested' | 'protest_vote_required' | 'race_performance_summary' | 'race_final_results'; // let actionUrl: string; // switch (selectedType) { // case 'protest_filed': { // const raceId = primaryRace?.id; // title = '🚨 Protest Filed Against You'; // body = // 'A protest has been filed against you for unsafe rejoining during a recent race. Please review the incident details.'; // notificationType = 'protest_filed'; // actionUrl = raceId ? `/races/${raceId}/stewarding` : '/races'; // break; // } // case 'defense_requested': { // const raceId = secondaryRace?.id ?? primaryRace?.id; // title = '⚖️ Defense Requested'; // body = // 'A steward has requested your defense regarding a recent incident. Please provide your side of the story within 48 hours.'; // notificationType = 'protest_defense_requested'; // actionUrl = raceId ? `/races/${raceId}/stewarding` : '/races'; // break; // } // case 'vote_required': { // const leagueId = primaryLeague?.id; // title = '🗳️ Your Vote Required'; // body = // 'As a league steward, you are required to vote on an open protest. Please review the case and cast your vote.'; // notificationType = 'protest_vote_required'; // actionUrl = leagueId ? `/leagues/${leagueId}/stewarding` : '/leagues'; // break; // } // case 'race_performance_summary': { // const raceId = primaryRace?.id; // const leagueId = primaryLeague?.id; // title = '🏁 Race Complete: Performance Summary'; // body = // 'Your Monza Grand Prix race is finished! You finished P1 with 0 incidents. Provisional rating: +25 points. View full results and standings.'; // notificationType = 'race_performance_summary'; // actionUrl = raceId ? `/races/${raceId}` : '/races'; // break; // } // case 'race_final_results': { // const leagueId = primaryLeague?.id; // title = '🏆 Final Results: Monza Grand Prix'; // body = // 'Stewarding is now closed. Your final result: P1 (+25 rating). No penalties were applied. View championship standings.'; // notificationType = 'race_final_results'; // actionUrl = leagueId ? `/leagues/${leagueId}/standings` : '/leagues'; // break; // } // } // const actions = // selectedUrgency === 'modal' // ? selectedType.startsWith('race_') // ? [ // { label: selectedType === 'race_performance_summary' ? '🏁 View Race Results' : '🏆 View Standings', type: 'primary' as const, href: actionUrl, actionId: 'view' }, // { label: '🎉 Share Achievement', type: 'secondary' as const, actionId: 'share' }, // ] // : [ // { label: 'View Protest', type: 'primary' as const, href: actionUrl, actionId: 'view' }, // { label: 'Dismiss', type: 'secondary' as const, actionId: 'dismiss' }, // ] // : []; // await sendNotification.execute({ // recipientId: currentDriverId, // type: notificationType, // title, // body, // actionUrl, // urgency: selectedUrgency as NotificationUrgency, // requiresResponse: selectedUrgency === 'modal' && !selectedType.startsWith('race_'), // actions, // data: { // ...(selectedType.startsWith('protest_') ? { // protestId: `demo-protest-${Date.now()}`, // } : {}), // ...(selectedType.startsWith('race_') ? { // raceEventId: `demo-race-event-${Date.now()}`, // sessionId: `demo-session-${Date.now()}`, // position: 1, // positionChange: 0, // incidents: 0, // provisionalRatingChange: 25, // finalRatingChange: 25, // hadPenaltiesApplied: false, // } : {}), // raceId: primaryRace?.id ?? '', // leagueId: primaryLeague?.id ?? '', // ...(notificationDeadline && selectedType.startsWith('protest_') ? { deadline: notificationDeadline } : {}), // }, // }); // setLastSent(`${selectedType}-${selectedUrgency}`); // setTimeout(() => setLastSent(null), 3000); // } catch (error) { // console.error('Failed to send demo notification:', error); // } finally { // setSending(false); // } // }; if (isMinimized) { return ( ); } return (
{/* Header */}
Dev Toolbar DEMO
{/* Content */} {isExpanded && (
{/* Notification Type Section */}
Notification Type
{notificationOptions.map((option) => { const Icon = option.icon; const isSelected = selectedType === option.type; return ( ); })}
{/* Urgency Section */}
Urgency Level
{urgencyOptions.map((option) => { const Icon = option.icon; const isSelected = selectedUrgency === option.urgency; return ( ); })}

{urgencyOptions.find(o => o.urgency === selectedUrgency)?.description}

{/* Send Button */} {/* Info */}

Silent: Notification center only
Toast: Temporary popup (auto-dismisses)
Modal: Blocking popup (may require action)

{/* Login Section */}
Demo Login
{loginMode !== 'none' && ( )}

Switch between driver and sponsor views for demo purposes.

)} {/* Collapsed state hint */} {!isExpanded && (
Click ↑ to expand dev tools
)}
); }