'use client'; import { useAuth } from '@/components/auth/AuthContext'; import { useFindDriverById } from '@/hooks/driver/useFindDriverById'; import { useEffectiveDriverId } from '@/hooks/useEffectiveDriverId'; import { routes } from '@/lib/routing/RouteConfig'; import { DriverViewModel as DriverViewModelClass } from '@/lib/view-models/DriverViewModel'; import { Icon } from '@/ui/Icon'; import { Image } from '@/ui/Image'; import { Link } from '@/ui/Link'; import { Text } from '@/ui/Text'; import { Box } from '@/ui/Box'; import { Group } from '@/ui/Group'; import { Stack } from '@/ui/Stack'; import { Surface } from '@/ui/Surface'; import { UserDropdown, UserDropdownHeader, UserDropdownItem, UserDropdownFooter } from '@/ui/UserDropdown'; import { AnimatePresence, motion } from 'framer-motion'; import { BarChart3, ChevronDown, CreditCard, Handshake, LogOut, Megaphone, Paintbrush, Settings, Shield } from 'lucide-react'; import React, { useEffect, useMemo, useState } from 'react'; // Hook to detect demo user mode based on session function useDemoUserMode(): { isDemo: boolean; demoRole: string | null } { const { session } = useAuth(); const [demoMode, setDemoMode] = useState({ isDemo: false, demoRole: null as string | null }); // Check if this is a demo user useEffect(() => { if (!session?.user) { setDemoMode({ isDemo: false, demoRole: null }); return; } const email = session.user.email?.toLowerCase() || ''; const displayName = session.user.displayName?.toLowerCase() || ''; const primaryDriverId = session.user.primaryDriverId || ''; const role = 'role' in session.user ? (session.user as { role?: string }).role : undefined; // Check if this is a demo user if (email.includes('demo') || displayName.includes('demo') || primaryDriverId.startsWith('demo-')) { // Use role from session if available, otherwise derive from email let roleToUse = role; if (!roleToUse) { if (email.includes('sponsor')) roleToUse = 'sponsor'; else if (email.includes('league-owner') || displayName.includes('owner')) roleToUse = 'league-owner'; else if (email.includes('league-steward') || displayName.includes('steward')) roleToUse = 'league-steward'; else if (email.includes('league-admin') || displayName.includes('admin')) roleToUse = 'league-admin'; else if (email.includes('system-owner') || displayName.includes('system owner')) roleToUse = 'system-owner'; else if (email.includes('super-admin') || displayName.includes('super admin')) roleToUse = 'super-admin'; else roleToUse = 'driver'; } setDemoMode({ isDemo: true, demoRole: roleToUse }); } else { setDemoMode({ isDemo: false, demoRole: null }); } }, [session]); return demoMode; } // Helper to check if user has admin access (Owner or Super Admin) function useHasAdminAccess(): boolean { const { session } = useAuth(); const { isDemo, demoRole } = useDemoUserMode(); // Demo users with system-owner or super-admin roles if (isDemo && (demoRole === 'system-owner' || demoRole === 'super-admin')) { return true; } // Real users - would need role information from session // For now, we'll check if the user has any admin-related capabilities // This can be enhanced when the API includes role information if (!session?.user) return false; // Check for admin-related email patterns as a temporary measure const email = session.user.email?.toLowerCase() || ''; const displayName = session.user.displayName?.toLowerCase() || ''; return email.includes('system-owner') || email.includes('super-admin') || displayName.includes('system owner') || displayName.includes('super admin'); } export function UserPill() { const { session } = useAuth(); const [isMenuOpen, setIsMenuOpen] = useState(false); const { isDemo, demoRole } = useDemoUserMode(); const primaryDriverId = useEffectiveDriverId(); // Use React-Query hook for driver data (only for non-demo users) const { data: driverDto } = useFindDriverById(primaryDriverId || '', { enabled: !!primaryDriverId && !isDemo, }); // Transform DTO to ViewModel const driver = useMemo(() => { if (!driverDto) return null; return new DriverViewModelClass({ ...driverDto, avatarUrl: driverDto.avatarUrl ?? null }); }, [driverDto]); // Close menu when clicking outside useEffect(() => { const handleClickOutside = (e: MouseEvent) => { if (isMenuOpen) { const target = e.target as HTMLElement; if (!target.closest('[data-user-pill]')) { setIsMenuOpen(false); } } }; document.addEventListener('click', handleClickOutside); return () => document.removeEventListener('click', handleClickOutside); }, [isMenuOpen]); // Logout handler for demo users const handleLogout = async () => { try { // Call the logout API await fetch('/api/auth/logout', { method: 'POST' }); // Redirect to home window.location.href = '/'; } catch (error) { console.error('Logout failed:', error); window.location.href = '/'; } }; // Call hooks unconditionally before any returns const hasAdminAccess = useHasAdminAccess(); // Handle unauthenticated users if (!session) { return ( Enter GridPilot ); } // For all authenticated users (demo or regular), show the user pill // Determine what to show in the pill const displayName = driver?.name || session.user.displayName || session.user.email || 'User'; const avatarUrl = session.user.avatarUrl; const roleLabel = isDemo ? ({ 'driver': 'Driver', 'sponsor': 'Sponsor', 'league-owner': 'League Owner', 'league-steward': 'League Steward', 'league-admin': 'League Admin', 'system-owner': 'System Owner', 'super-admin': 'Super Admin', } as Record)[demoRole || 'driver'] : null; const roleIntent = isDemo ? ({ 'driver': 'primary', 'sponsor': 'success', 'league-owner': 'primary', 'league-steward': 'warning', 'league-admin': 'critical', 'system-owner': 'primary', 'super-admin': 'primary', } as Record)[demoRole || 'driver'] : 'low'; return ( setIsMenuOpen((open) => !open)} style={{ display: 'flex', alignItems: 'center', gap: '0.75rem', borderRadius: '9999px', border: `1px solid ${isMenuOpen ? 'var(--ui-color-intent-primary)' : 'var(--ui-color-border-default)'}`, padding: '0.375rem 0.75rem', background: 'var(--ui-color-bg-surface-muted)', cursor: 'pointer' }} > {/* Avatar */} {avatarUrl ? ( {displayName} ) : ( {displayName[0]?.toUpperCase() || 'U'} )} {/* Info */} {displayName} {roleLabel && ( {roleLabel} )} {/* Chevron */} {avatarUrl ? ( {displayName} ) : ( {displayName[0]?.toUpperCase() || 'U'} )} {displayName} {roleLabel && ( {roleLabel} )} {hasAdminAccess && ( setIsMenuOpen(false)} /> )} {isDemo && demoRole === 'sponsor' && ( setIsMenuOpen(false)} /> setIsMenuOpen(false)} /> setIsMenuOpen(false)} /> )} setIsMenuOpen(false)} /> setIsMenuOpen(false)} /> setIsMenuOpen(false)} /> setIsMenuOpen(false)} /> setIsMenuOpen(false)} /> ); }