import React, { useState, useEffect } from 'react'; import { Avatar, Box, Menu, MenuItem, Typography, Tooltip, Chip, Divider, IconButton, CircularProgress } from '@mui/material'; import { useUser, useClerk } from '@clerk/clerk-react'; import { useSubscription } from '../../contexts/SubscriptionContext'; import SystemStatusIndicator from '../ContentPlanningDashboard/components/SystemStatusIndicator'; import UsageDashboard from './UsageDashboard'; import { isFeatureOnlyMode } from '../../utils/demoMode'; import { apiClient, isBackendCooldownActive, logBackendCooldownSkipOnce, } from '../../api/client'; import { saveNavigationState } from '../../utils/navigationState'; import { Refresh as RefreshIcon } from '@mui/icons-material'; interface UserBadgeProps { colorMode?: 'light' | 'dark'; } const UserBadge: React.FC = ({ colorMode = 'light' }) => { const { user, isSignedIn } = useUser(); const { signOut } = useClerk(); const { subscription, refreshSubscription, loading } = useSubscription(); const [anchorEl, setAnchorEl] = React.useState(null); const [systemStatus, setSystemStatus] = useState<'healthy' | 'warning' | 'critical' | 'unknown'>('unknown'); const [isRefreshing, setIsRefreshing] = useState(false); const open = Boolean(anchorEl); const initials = React.useMemo(() => { const first = user?.firstName?.[0] || ''; const last = user?.lastName?.[0] || ''; return (first + last || user?.username?.[0] || user?.primaryEmailAddress?.emailAddress?.[0] || '?').toUpperCase(); }, [user]); // Fetch system status for status bulb useEffect(() => { // Skip system status checks in feature-limited mode (endpoint not available) if (isFeatureOnlyMode()) { setSystemStatus('unknown'); return; } const fetchSystemStatus = async () => { if (isBackendCooldownActive()) { logBackendCooldownSkipOnce('UserBadge'); return; } try { const response = await apiClient.get('/api/content-planning/monitoring/lightweight-stats'); const result = response.data; if (result.status === 'success' && result.data) { setSystemStatus(result.data.status || 'unknown'); } } catch (err) { // Silently fail for system status to avoid console noise setSystemStatus('unknown'); } }; fetchSystemStatus(); // Refresh every 120 seconds (2 minutes) to reduce load and avoid timeouts const interval = setInterval(fetchSystemStatus, 120000); return () => clearInterval(interval); }, []); if (!isSignedIn) return null; // Get status bulb color const getStatusBulbColor = () => { switch (systemStatus) { case 'healthy': return '#4caf50'; // Green case 'warning': return '#ff9800'; // Orange case 'critical': return '#f44336'; // Red default: return '#757575'; // Gray for unknown } }; // Get plan display info const getPlanColor = () => { const plan = subscription?.plan?.toLowerCase() || 'free'; switch (plan) { case 'free': return '#4caf50'; case 'basic': return '#2196f3'; case 'pro': return '#9c27b0'; case 'enterprise': return '#ff9800'; default: return '#757575'; } }; const getPlanLabel = () => { if (!subscription?.plan) return 'Free'; const plan = subscription.plan.toLowerCase(); if (plan === 'free') return 'Free'; if (plan === 'basic') return 'Basic'; if (plan === 'pro') return 'Pro'; if (plan === 'enterprise') return 'Enterprise'; return subscription.plan.charAt(0).toUpperCase() + subscription.plan.slice(1); }; const handleOpen = (e: React.MouseEvent) => setAnchorEl(e.currentTarget); const handleClose = () => setAnchorEl(null); const handleRefreshPlan = async () => { setIsRefreshing(true); try { await refreshSubscription(); } catch (err) { console.error('Failed to refresh subscription:', err); } finally { setIsRefreshing(false); } }; const handleSignOut = async () => { try { await signOut(); } finally { window.location.assign('/'); } }; return ( {/* Subscription Plan Chip */} {initials} {/* Status Bulb */} {/* User Info Header */} {user?.fullName || user?.username || 'User'} {user?.primaryEmailAddress?.emailAddress} {/* Subscription Info */} Current Plan {(isRefreshing || loading) ? : } {/* System Status Indicator */} e.stopPropagation()} > System Health *': { transform: 'scale(0.85)' } }}> {/* Usage Dashboard */} e.stopPropagation()} > Usage Statistics { handleClose(); saveNavigationState(window.location.pathname); sessionStorage.setItem('pending_subscription_change', 'true'); window.location.href = '/pricing'; }} sx={{ mx: 1, borderRadius: 1, background: 'linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%)', color: '#ffffff', fontWeight: 600, mb: 0.5, '&:hover': { background: 'linear-gradient(135deg, #4f46e5 0%, #7c3aed 100%)', boxShadow: '0 2px 8px rgba(99,102,241,0.4)' } }}> Manage Subscription { handleClose(); window.location.href = '/billing'; }} sx={{ mx: 1, borderRadius: 1, background: 'linear-gradient(135deg, #06b6d4 0%, #3b82f6 100%)', color: '#ffffff', fontWeight: 600, '&:hover': { background: 'linear-gradient(135deg, #0891b2 0%, #2563eb 100%)', boxShadow: '0 2px 8px rgba(6,182,212,0.4)' } }}> View Costing Details Sign out ); }; export default UserBadge;