@propknot/shared-ui 1.0.14 → 1.0.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/utils/notificationTypes.js","../src/index.js","../src/components/Navigation/Navbar.js","../src/contexts/AuthContext.js","../src/services/api.js","../src/contexts/NotificationContext.js","../src/contexts/ThemeContext.js","../src/utils/colorExtractor.js","../src/utils/themeContrast.js","../src/components/Layout/PageLayout.js","../src/components/Layout/PageHeader.js","../src/components/Layout/AuthLayout.js","../src/components/Layout/TenantLayout.js","../src/contexts/TenantThemeContext.js","../src/components/UI/LoadingSpinner.js","../src/components/UI/ModernCard.js","../src/components/Notifications/NotificationManager.js","../src/components/Notifications/NotificationBell.js","../src/components/ErrorBoundary/ErrorBoundary.js","../src/contexts/SocketContext.js","../src/hooks/useNotifications.js","../src/hooks/useUnifiedNotifications.js","../src/utils/unifiedNotifications.js","../src/hooks/useAccessibleColors.js","../src/hooks/useContrastText.js","../src/utils/notificationHelpers.js","../src/utils/notifications.js","../src/utils/pushNotifications.js","../src/utils/tenantAuth.js"],"sourcesContent":["/**\r\n * Shared notification types and constants\r\n * This file is used by both frontend and backend to ensure consistency\r\n */\r\n\r\n// Notification types enum\r\nconst NOTIFICATION_TYPES = {\r\n // Toast notification types (UI feedback)\r\n SUCCESS: 'success',\r\n ERROR: 'error',\r\n WARNING: 'warning',\r\n INFO: 'info',\r\n LOADING: 'loading',\r\n \r\n // Ticket/issue notification types\r\n TICKET_CREATED: 'ticket_created',\r\n TICKET_UPDATED: 'ticket_updated',\r\n TICKET_ASSIGNED: 'ticket_assigned',\r\n TICKET_RESOLVED: 'ticket_resolved',\r\n TICKET_COMMENTED: 'ticket_commented',\r\n TICKET_STATUS_CHANGED: 'ticket_status_changed',\r\n \r\n // Messaging notification types\r\n MESSAGE_RECEIVED: 'message_received',\r\n MENTION_RECEIVED: 'mention_received',\r\n \r\n // System notification types\r\n SYSTEM_ALERT: 'system_alert',\r\n MAINTENANCE_SCHEDULED: 'maintenance_scheduled',\r\n \r\n // Tenant-specific types\r\n LEASE_EXPIRING: 'lease_expiring',\r\n PAYMENT_DUE: 'payment_due',\r\n PAYMENT_OVERDUE: 'payment_overdue',\r\n \r\n // Property-specific types\r\n PROPERTY_UPDATED: 'property_updated',\r\n APPLIANCE_MAINTENANCE_DUE: 'appliance_maintenance_due'\r\n};\r\n\r\n// Notification channels enum\r\nconst NOTIFICATION_CHANNELS = {\r\n TOAST: 'toast', // In-app toast notifications\r\n BROWSER: 'browser', // Browser notifications\r\n PUSH: 'push', // Push notifications (service worker)\r\n DATABASE: 'database', // Persistent database notifications\r\n SOCKET: 'socket', // Real-time socket notifications\r\n EMAIL: 'email', // Email notifications\r\n SMS: 'sms', // SMS notifications\r\n SOUND: 'sound' // Audio notifications\r\n};\r\n\r\n// Priority levels\r\nconst PRIORITY_LEVELS = {\r\n LOW: 'low',\r\n NORMAL: 'normal',\r\n HIGH: 'high',\r\n URGENT: 'urgent'\r\n};\r\n\r\n// Notification status\r\nconst NOTIFICATION_STATUS = {\r\n UNREAD: 'unread',\r\n READ: 'read',\r\n DISMISSED: 'dismissed',\r\n ARCHIVED: 'archived'\r\n};\r\n\r\n// Default channel configurations for different notification types\r\nconst DEFAULT_CHANNEL_CONFIGS = {\r\n [NOTIFICATION_TYPES.SUCCESS]: [NOTIFICATION_CHANNELS.TOAST],\r\n [NOTIFICATION_TYPES.ERROR]: [NOTIFICATION_CHANNELS.TOAST, NOTIFICATION_CHANNELS.BROWSER],\r\n [NOTIFICATION_TYPES.WARNING]: [NOTIFICATION_CHANNELS.TOAST],\r\n [NOTIFICATION_TYPES.INFO]: [NOTIFICATION_CHANNELS.TOAST],\r\n \r\n [NOTIFICATION_TYPES.TICKET_CREATED]: [\r\n NOTIFICATION_CHANNELS.DATABASE,\r\n NOTIFICATION_CHANNELS.SOCKET,\r\n NOTIFICATION_CHANNELS.PUSH\r\n ],\r\n [NOTIFICATION_TYPES.TICKET_UPDATED]: [\r\n NOTIFICATION_CHANNELS.DATABASE,\r\n NOTIFICATION_CHANNELS.SOCKET,\r\n NOTIFICATION_CHANNELS.TOAST\r\n ],\r\n [NOTIFICATION_TYPES.TICKET_ASSIGNED]: [\r\n NOTIFICATION_CHANNELS.DATABASE,\r\n NOTIFICATION_CHANNELS.SOCKET,\r\n NOTIFICATION_CHANNELS.PUSH\r\n ],\r\n [NOTIFICATION_TYPES.TICKET_RESOLVED]: [\r\n NOTIFICATION_CHANNELS.DATABASE,\r\n NOTIFICATION_CHANNELS.SOCKET,\r\n NOTIFICATION_CHANNELS.PUSH\r\n ],\r\n [NOTIFICATION_TYPES.TICKET_COMMENTED]: [\r\n NOTIFICATION_CHANNELS.DATABASE,\r\n NOTIFICATION_CHANNELS.SOCKET\r\n ],\r\n \r\n [NOTIFICATION_TYPES.MESSAGE_RECEIVED]: [\r\n NOTIFICATION_CHANNELS.BROWSER,\r\n NOTIFICATION_CHANNELS.SOUND,\r\n NOTIFICATION_CHANNELS.SOCKET\r\n ],\r\n \r\n [NOTIFICATION_TYPES.SYSTEM_ALERT]: [\r\n NOTIFICATION_CHANNELS.DATABASE,\r\n NOTIFICATION_CHANNELS.PUSH,\r\n NOTIFICATION_CHANNELS.BROWSER\r\n ],\r\n \r\n [NOTIFICATION_TYPES.PAYMENT_OVERDUE]: [\r\n NOTIFICATION_CHANNELS.DATABASE,\r\n NOTIFICATION_CHANNELS.PUSH,\r\n NOTIFICATION_CHANNELS.EMAIL\r\n ]\r\n};\r\n\r\n// Default priority mapping\r\nconst DEFAULT_PRIORITY_MAPPING = {\r\n [NOTIFICATION_TYPES.SUCCESS]: PRIORITY_LEVELS.LOW,\r\n [NOTIFICATION_TYPES.ERROR]: PRIORITY_LEVELS.HIGH,\r\n [NOTIFICATION_TYPES.WARNING]: PRIORITY_LEVELS.NORMAL,\r\n [NOTIFICATION_TYPES.INFO]: PRIORITY_LEVELS.LOW,\r\n \r\n [NOTIFICATION_TYPES.TICKET_CREATED]: PRIORITY_LEVELS.NORMAL,\r\n [NOTIFICATION_TYPES.TICKET_UPDATED]: PRIORITY_LEVELS.LOW,\r\n [NOTIFICATION_TYPES.TICKET_ASSIGNED]: PRIORITY_LEVELS.NORMAL,\r\n [NOTIFICATION_TYPES.TICKET_RESOLVED]: PRIORITY_LEVELS.NORMAL,\r\n [NOTIFICATION_TYPES.TICKET_COMMENTED]: PRIORITY_LEVELS.LOW,\r\n \r\n [NOTIFICATION_TYPES.MESSAGE_RECEIVED]: PRIORITY_LEVELS.NORMAL,\r\n [NOTIFICATION_TYPES.SYSTEM_ALERT]: PRIORITY_LEVELS.HIGH,\r\n [NOTIFICATION_TYPES.PAYMENT_OVERDUE]: PRIORITY_LEVELS.URGENT,\r\n [NOTIFICATION_TYPES.LEASE_EXPIRING]: PRIORITY_LEVELS.HIGH\r\n};\r\n\r\n// Notification icons mapping\r\nconst NOTIFICATION_ICONS = {\r\n [NOTIFICATION_TYPES.SUCCESS]: '✅',\r\n [NOTIFICATION_TYPES.ERROR]: '❌',\r\n [NOTIFICATION_TYPES.WARNING]: '⚠️',\r\n [NOTIFICATION_TYPES.INFO]: 'ℹ️',\r\n \r\n [NOTIFICATION_TYPES.TICKET_CREATED]: '📋',\r\n [NOTIFICATION_TYPES.TICKET_UPDATED]: '🔄',\r\n [NOTIFICATION_TYPES.TICKET_ASSIGNED]: '👤',\r\n [NOTIFICATION_TYPES.TICKET_RESOLVED]: '✅',\r\n [NOTIFICATION_TYPES.TICKET_COMMENTED]: '💬',\r\n \r\n [NOTIFICATION_TYPES.MESSAGE_RECEIVED]: '💬',\r\n [NOTIFICATION_TYPES.SYSTEM_ALERT]: '🚨',\r\n [NOTIFICATION_TYPES.PAYMENT_OVERDUE]: '💰',\r\n [NOTIFICATION_TYPES.LEASE_EXPIRING]: '📅'\r\n};\r\n\r\n// Helper functions\r\nfunction getDefaultChannels(notificationType) {\r\n return DEFAULT_CHANNEL_CONFIGS[notificationType] || [NOTIFICATION_CHANNELS.TOAST];\r\n}\r\n\r\nfunction getDefaultPriority(notificationType) {\r\n return DEFAULT_PRIORITY_MAPPING[notificationType] || PRIORITY_LEVELS.NORMAL;\r\n}\r\n\r\nconst getNotificationIcon = (notificationType) => {\r\n return NOTIFICATION_ICONS[notificationType] || 'ℹ️';\r\n};\r\n\r\nconst isHighPriorityType = (notificationType) => {\r\n const priority = getDefaultPriority(notificationType);\r\n return [PRIORITY_LEVELS.HIGH, PRIORITY_LEVELS.URGENT].includes(priority);\r\n};\r\n\r\nconst shouldPlaySound = (notificationType) => {\r\n const channels = getDefaultChannels(notificationType);\r\n return channels.includes(NOTIFICATION_CHANNELS.SOUND) || \r\n [NOTIFICATION_TYPES.MESSAGE_RECEIVED, NOTIFICATION_TYPES.SYSTEM_ALERT].includes(notificationType);\r\n};\r\n\r\n// CommonJS export (works for both Node.js backend and React frontend with build tools)\r\nmodule.exports = {\r\n NOTIFICATION_TYPES,\r\n NOTIFICATION_CHANNELS,\r\n PRIORITY_LEVELS,\r\n NOTIFICATION_STATUS,\r\n DEFAULT_CHANNEL_CONFIGS,\r\n DEFAULT_PRIORITY_MAPPING,\r\n NOTIFICATION_ICONS,\r\n getDefaultChannels,\r\n getDefaultPriority,\r\n getNotificationIcon,\r\n isHighPriorityType,\r\n shouldPlaySound\r\n};","export * from './components/Navigation';\r\nexport * from './components/Layout';\r\nexport * from './components/UI';\r\nexport * from './components/Notifications';\r\nexport * from './components/ErrorBoundary';\r\n\r\nexport * from './contexts/AuthContext';\r\nexport * from './contexts/NotificationContext';\r\nexport * from './contexts/SocketContext';\r\nexport * from './contexts/ThemeContext';\r\nexport * from './contexts/TenantThemeContext';\r\n\r\n// useAuth is exported from AuthContext\r\n// useSocket is exported from SocketContext\r\nexport { useAuth } from './contexts/AuthContext';\r\nexport { useSocket } from './contexts/SocketContext';\r\nexport * from './hooks/useNotifications';\r\nexport * from './hooks/useUnifiedNotifications';\r\nexport * from './hooks/useAccessibleColors';\r\nexport * from './hooks/useContrastText';\r\n\r\nexport * from './services/api';\r\n// export * from './services/auth'; // TODO: services/auth does not exist yet\r\n// export * from './services/socket'; // TODO: services/socket does not exist yet\r\n\r\nexport * from './utils/colorExtractor';\r\nexport * from './utils/notificationHelpers';\r\nexport * from './utils/notifications';\r\nexport {\r\n showMessageNotification,\r\n requestNotificationPermission,\r\n hasNotificationPermission,\r\n isNotificationSupported\r\n} from './utils/notifications';\r\nexport * from './utils/pushNotifications';\r\nexport {\r\n subscribeToPushNotifications,\r\n unsubscribeFromPushNotifications,\r\n isPushNotificationSupported,\r\n isPushSubscribed,\r\n sendTestNotification,\r\n showLocalNotification\r\n} from './utils/pushNotifications';\r\nexport * from './utils/tenantAuth';\r\nexport * from './utils/themeContrast';\r\nexport * from './utils/unifiedNotifications';\r\n","import React, { useState, useEffect } from 'react';\r\nimport {\r\n AppBar,\r\n Toolbar,\r\n Button,\r\n IconButton,\r\n Typography,\r\n Badge,\r\n Box,\r\n Drawer,\r\n List,\r\n ListItem,\r\n ListItemText,\r\n ListItemIcon,\r\n Menu,\r\n MenuItem,\r\n useMediaQuery,\r\n useTheme,\r\n Stack,\r\n Divider,\r\n Avatar\r\n} from '@mui/material';\r\nimport {\r\n Dashboard as MdDashboard,\r\n ReportProblem as MdReportProblem,\r\n Work as MdWork,\r\n Engineering as MdEngineering,\r\n Home as MdHome,\r\n People as MdPeople,\r\n AccountCircle as MdAccountCircle,\r\n Menu as MdMenu,\r\n Notifications as MdNotifications,\r\n Settings as MdSettings,\r\n Message as MdMessage,\r\n Psychology as MdPsychology,\r\n Business as MdBusiness,\r\n Support as MdSupport,\r\n KeyboardArrowDown as MdKeyboardArrowDown,\r\n Inventory as MdInventory,\r\n Schedule as MdSchedule,\r\n Construction as MdConstruction,\r\n} from '@mui/icons-material';\r\nimport { useNavigate, useLocation } from 'react-router-dom';\r\nimport { useAuth } from '../../contexts/AuthContext';\r\nimport { useNotification } from '../../contexts/NotificationContext';\r\nimport { useCustomTheme } from '../../contexts/ThemeContext';\r\nimport api from '../../services/api';\r\nimport { extractColorsFromImage, isColorDark, getAccessibleTextColor, getContrastRatio } from '../../utils/colorExtractor';\r\n\r\n// Enhanced Navbar with Dynamic Tenant Banner Color Theming\r\n// This component now uses the property manager's chosen tenant banner color \r\n// (from preferredBrandingColor) to create sophisticated gradients and hover effects\r\n\r\nconst Navbar = () => {\r\n const [mobileOpen, setMobileOpen] = useState(false);\r\n const [userMenuAnchor, setUserMenuAnchor] = useState(null);\r\n const [notificationMenuAnchor, setNotificationMenuAnchor] = useState(null);\r\n const [recentTickets, setRecentTickets] = useState([]);\r\n const [logoColors, setLogoColors] = useState(null);\r\n const [operationsMenuAnchor, setOperationsMenuAnchor] = useState(null);\r\n const [managementMenuAnchor, setManagementMenuAnchor] = useState(null);\r\n const navigate = useNavigate();\r\n const location = useLocation();\r\n const { user, companyBranding, logout } = useAuth();\r\n const { isDarkMode } = useCustomTheme();\r\n const { notifications, removeNotification, clearAllNotifications } = useNotification();\r\n const theme = useTheme();\r\n const isMobile = useMediaQuery(theme.breakpoints.down('md'));\r\n const isTablet = useMediaQuery(theme.breakpoints.down('lg'));\r\n const isSmallScreen = useMediaQuery(theme.breakpoints.down('sm'));\r\n\r\n // Helper function to get effective branding (company branding for employees)\r\n const getEffectiveBranding = () => {\r\n if ((user?.role === 'maintenance' || user?.role === 'property_manager') && companyBranding) {\r\n return companyBranding;\r\n }\r\n return {\r\n companyName: user?.companyName || '',\r\n companyLogo: user?.companyLogo || null,\r\n preferredBrandingColor: user?.preferredBrandingColor || 0\r\n };\r\n };\r\n\r\n // Fetch recent notifications\r\n useEffect(() => {\r\n const fetchNotifications = async () => {\r\n try {\r\n // Check if we're in the tenant portal based on the current path\r\n const isTenantPortal = location.pathname.startsWith('/tenant');\r\n const endpoint = isTenantPortal ? '/tenant-portal/notifications/unread' : '/notifications/unread';\r\n \r\n const response = await api.get(endpoint);\r\n const notifications = response.data.notifications || [];\r\n \r\n if (notifications.length > 0) {\r\n const formattedNotifications = notifications.map(notif => ({\r\n id: notif._id,\r\n notificationId: notif._id, // Add this for marking as read\r\n title: notif.title,\r\n message: notif.message,\r\n time: new Date(notif.createdAt).toLocaleString(),\r\n type: notif.type,\r\n ticketId: notif.ticketId,\r\n ticketNumber: notif.ticketNumber,\r\n actionUrl: notif.actionUrl,\r\n priority: notif.priority,\r\n read: notif.read\r\n }));\r\n setRecentTickets(formattedNotifications);\r\n }\r\n } catch (error) {\r\n console.error('Error fetching notifications:', error);\r\n }\r\n };\r\n\r\n if (user) {\r\n fetchNotifications();\r\n const interval = setInterval(fetchNotifications, 30000);\r\n return () => clearInterval(interval);\r\n }\r\n }, [user]);\r\n\r\n // Extract colors from logo when user logo changes\r\n useEffect(() => {\r\n const extractLogoColors = async () => {\r\n const effectiveBranding = getEffectiveBranding();\r\n if (effectiveBranding.companyLogo) {\r\n try {\r\n const baseURL = api.defaults.baseURL.replace('/api', '');\r\n const logoUrl = `${baseURL}/uploads/logos/${effectiveBranding.companyLogo}`;\r\n const colors = await extractColorsFromImage(logoUrl);\r\n setLogoColors(colors);\r\n } catch (error) {\r\n console.error('Error extracting logo colors:', error);\r\n setLogoColors(null);\r\n }\r\n } else {\r\n setLogoColors(null);\r\n }\r\n };\r\n\r\n extractLogoColors();\r\n }, [user?.companyLogo, companyBranding]);\r\n\r\n const handleDrawerToggle = () => {\r\n setMobileOpen(!mobileOpen);\r\n };\r\n\r\n const handleNavigate = (path) => {\r\n navigate(path);\r\n setMobileOpen(false);\r\n };\r\n\r\n const handleUserMenuClick = (event) => {\r\n setUserMenuAnchor(event.currentTarget);\r\n };\r\n\r\n const handleUserMenuClose = () => {\r\n setUserMenuAnchor(null);\r\n };\r\n\r\n const handleNotificationMenuClick = (event) => {\r\n setNotificationMenuAnchor(event.currentTarget);\r\n };\r\n\r\n const handleNotificationMenuClose = () => {\r\n setNotificationMenuAnchor(null);\r\n };\r\n\r\n const handleOperationsMenuClick = (event) => {\r\n setOperationsMenuAnchor(event.currentTarget);\r\n };\r\n\r\n const handleOperationsMenuClose = () => {\r\n setOperationsMenuAnchor(null);\r\n };\r\n\r\n const handleManagementMenuClick = (event) => {\r\n setManagementMenuAnchor(event.currentTarget);\r\n };\r\n\r\n const handleManagementMenuClose = () => {\r\n setManagementMenuAnchor(null);\r\n };\r\n\r\n const markNotificationAsRead = async (notificationId) => {\r\n try {\r\n // Check if we're in the tenant portal based on the current path\r\n const isTenantPortal = location.pathname.startsWith('/tenant');\r\n \r\n if (isTenantPortal) {\r\n // Use tenant portal endpoint\r\n await api.put(`/tenant-portal/notifications/${notificationId}/read`);\r\n } else {\r\n // Use property manager endpoint\r\n await api.put(`/notifications/${notificationId}/read`);\r\n }\r\n } catch (error) {\r\n console.error('Error marking notification as read:', error);\r\n // Fallback: try the other endpoint if the first one fails\r\n try {\r\n const isTenantPortal = location.pathname.startsWith('/tenant');\r\n if (isTenantPortal) {\r\n await api.put(`/notifications/${notificationId}/read`);\r\n } else {\r\n await api.put(`/tenant-portal/notifications/${notificationId}/read`);\r\n }\r\n } catch (fallbackError) {\r\n console.error('Fallback also failed:', fallbackError);\r\n }\r\n }\r\n };\r\n\r\n const handleLogout = () => {\r\n logout();\r\n handleUserMenuClose();\r\n };\r\n\r\n // Categorized navigation structure\r\n const navigationCategories = {\r\n operations: {\r\n label: 'Operations',\r\n icon: MdSupport,\r\n items: [\r\n { path: '/tickets', label: 'Tickets', icon: MdReportProblem },\r\n { path: '/work-orders', label: 'Work Orders', icon: MdWork, featureRequired: 'maintenanceModule' },\r\n { path: '/maintenance-schedules', label: 'Maintenance Schedules', icon: MdSchedule, roles: ['property_manager', 'owner', 'admin'], featureRequired: 'maintenanceModule' },\r\n { path: '/renovations', label: 'Renovations', icon: MdConstruction, roles: ['property_manager', 'owner', 'admin'], featureRequired: 'renovationsModule' },\r\n { path: '/ai-training', label: 'AI Training', icon: MdPsychology, roles: ['owner', 'property_manager', 'admin'], featureRequired: 'aiAssistant' },\r\n ]\r\n },\r\n management: {\r\n label: 'Management',\r\n icon: MdBusiness,\r\n items: [\r\n { path: '/properties', label: 'Properties', icon: MdHome, roles: ['property_manager', 'owner', 'admin'] },\r\n { path: '/tenants', label: 'Tenants', icon: MdPeople, roles: ['property_manager', 'owner', 'admin'] },\r\n { path: '/workers', label: 'Workers', icon: MdEngineering, roles: ['property_manager', 'owner', 'admin'], featureRequired: 'workersModule' },\r\n { path: '/property-managers', label: 'Property Managers', icon: MdBusiness, roles: ['owner', 'admin'] },\r\n { path: '/inventory', label: 'Inventory', icon: MdInventory, roles: ['property_manager', 'owner', 'admin'], featureRequired: 'inventoryModule' },\r\n ]\r\n }\r\n };\r\n\r\n // Standalone items that don't fit in categories\r\n const standaloneItems = [\r\n { path: '/dashboard', label: 'Dashboard', icon: MdDashboard },\r\n ];\r\n\r\n const notificationCount = recentTickets.length;\r\n\r\n // Generate lighter and darker color variations\r\n const lightenColor = (hex, amount) => {\r\n const num = parseInt(hex.replace(\"#\", \"\"), 16);\r\n const r = Math.min(255, (num >> 16) + Math.round(255 * amount));\r\n const g = Math.min(255, (num >> 8 & 0x00FF) + Math.round(255 * amount));\r\n const b = Math.min(255, (num & 0x0000FF) + Math.round(255 * amount));\r\n return `#${((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1)}`;\r\n };\r\n\r\n const darkenColor = (hex, amount) => {\r\n const num = parseInt(hex.replace(\"#\", \"\"), 16);\r\n const r = Math.max(0, (num >> 16) - Math.round(255 * amount));\r\n const g = Math.max(0, (num >> 8 & 0x00FF) - Math.round(255 * amount));\r\n const b = Math.max(0, (num & 0x0000FF) - Math.round(255 * amount));\r\n return `#${((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1)}`;\r\n };\r\n\r\n // Generate dynamic navbar styles based on property manager's chosen tenant banner color\r\n const getNavbarStyles = () => {\r\n if (!logoColors || !logoColors.topColors) {\r\n // Default Material-UI theme colors\r\n return {\r\n backgroundColor: theme.palette.primary.main,\r\n color: theme.palette.primary.contrastText\r\n };\r\n }\r\n\r\n // Get the property manager's chosen tenant banner color\r\n const effectiveBranding = getEffectiveBranding();\r\n const chosenColorIndex = effectiveBranding.preferredBrandingColor || 0;\r\n const chosenColor = logoColors.topColors?.[chosenColorIndex];\r\n const tenantBannerColor = chosenColor?.hex || logoColors.primaryHex || '#1976d2';\r\n \r\n // Create sophisticated gradient using the tenant banner color\r\n const lightVariant = lightenColor(tenantBannerColor, 0.3);\r\n const darkVariant = darkenColor(tenantBannerColor, 0.2);\r\n \r\n // Create gradient based on mode\r\n const gradientStart = isDarkMode ? darkVariant : lightVariant;\r\n const gradientEnd = tenantBannerColor;\r\n \r\n // Get accessible text color for the primary banner color\r\n const textColor = getAccessibleTextColor(tenantBannerColor, {\r\n preferredLight: '#ffffff',\r\n preferredDark: '#000000',\r\n fallbackLight: '#f8fafc',\r\n fallbackDark: '#1e293b'\r\n });\r\n \r\n return {\r\n background: `linear-gradient(135deg, ${gradientStart} 0%, ${gradientEnd} 70%, ${darkVariant} 100%)`,\r\n color: textColor,\r\n boxShadow: `0 4px 20px ${tenantBannerColor}40, 0 2px 10px ${tenantBannerColor}20`,\r\n borderBottom: `1px solid ${tenantBannerColor}30`\r\n };\r\n };\r\n\r\n // Generate button hover styles using tenant banner color\r\n const getButtonHoverStyles = () => {\r\n if (!logoColors || !logoColors.topColors) {\r\n return {\r\n backgroundColor: 'rgba(255, 255, 255, 0.2)'\r\n };\r\n }\r\n\r\n // Get the property manager's chosen tenant banner color\r\n const effectiveBranding = getEffectiveBranding();\r\n const chosenColorIndex = effectiveBranding.preferredBrandingColor || 0;\r\n const chosenColor = logoColors.topColors?.[chosenColorIndex];\r\n const tenantBannerColor = chosenColor?.hex || logoColors.primaryHex || '#1976d2';\r\n\r\n // Create sophisticated hover effect with the tenant banner color\r\n const hoverColor = isDarkMode ? lightenColor(tenantBannerColor, 0.1) : darkenColor(tenantBannerColor, 0.1);\r\n \r\n return {\r\n backgroundColor: `${hoverColor}60`,\r\n backdropFilter: 'blur(10px)',\r\n border: `1px solid ${tenantBannerColor}30`\r\n };\r\n };\r\n\r\n // Get the tenant banner color and appropriate text color for UI elements\r\n const getTenantBannerColorStyles = () => {\r\n if (!logoColors || !logoColors.topColors) {\r\n // Fallback to theme colors when no logo colors are available\r\n const fallbackColor = isDarkMode ? '#ffffff' : theme.palette.primary.main;\r\n return {\r\n color: getAccessibleTextColor(fallbackColor),\r\n tenantBannerColor: fallbackColor\r\n };\r\n }\r\n\r\n // Get the property manager's chosen tenant banner color\r\n const effectiveBranding = getEffectiveBranding();\r\n const chosenColorIndex = effectiveBranding.preferredBrandingColor || 0;\r\n const chosenColor = logoColors.topColors?.[chosenColorIndex];\r\n const tenantBannerColor = chosenColor?.hex || logoColors.primaryHex || '#1976d2';\r\n\r\n // Get accessible text color for the tenant banner color\r\n const textColor = getAccessibleTextColor(tenantBannerColor, {\r\n preferredLight: '#ffffff',\r\n preferredDark: '#000000',\r\n fallbackLight: '#f8fafc',\r\n fallbackDark: '#1e293b'\r\n });\r\n\r\n return {\r\n color: textColor,\r\n tenantBannerColor: tenantBannerColor\r\n };\r\n };\r\n\r\n // Enhanced notification icon styling consistent with navbar text elements\r\n const getNotificationIconStyles = () => {\r\n // Get the same text color used by other navbar elements\r\n const { color: navbarTextColor } = getNavbarStyles();\r\n const buttonHoverStyles = getButtonHoverStyles();\r\n \r\n return {\r\n color: navbarTextColor,\r\n backgroundColor: 'rgba(255, 255, 255, 0.08)',\r\n backdropFilter: 'blur(10px)',\r\n border: '1px solid rgba(255, 255, 255, 0.15)',\r\n boxShadow: '0 2px 8px rgba(0, 0, 0, 0.15), inset 0 1px 0 rgba(255, 255, 255, 0.1)',\r\n transition: 'all 0.2s cubic-bezier(0.4, 0, 0.2, 1)',\r\n '&:hover': {\r\n ...buttonHoverStyles,\r\n transform: 'translateY(-1px)',\r\n boxShadow: '0 4px 12px rgba(0, 0, 0, 0.2), inset 0 1px 0 rgba(255, 255, 255, 0.2)',\r\n },\r\n '& .MuiSvgIcon-root': {\r\n fontSize: '1.5rem',\r\n filter: 'drop-shadow(0 1px 2px rgba(0, 0, 0, 0.2))'\r\n }\r\n };\r\n };\r\n\r\n const drawer = (\r\n <Box onClick={handleDrawerToggle} sx={{ textAlign: 'center' }}>\r\n <Box sx={{ my: 2, display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 1 }}>\r\n <Box\r\n component=\"img\"\r\n src=\"/images/propman-logo-new.png\"\r\n alt=\"PropMan Logo\"\r\n sx={{\r\n height: 32,\r\n width: 'auto',\r\n maxWidth: '80px'\r\n }}\r\n />\r\n <Typography variant=\"h6\">\r\n {getEffectiveBranding().companyName ? `${getEffectiveBranding().companyName} Management` : 'Property AI'}\r\n </Typography>\r\n </Box>\r\n <Divider />\r\n <List>\r\n {/* Standalone items */}\r\n {standaloneItems.map((item) => {\r\n const IconComponent = item.icon;\r\n return (\r\n <ListItem\r\n key={item.path}\r\n disablePadding\r\n onClick={() => handleNavigate(item.path)}\r\n sx={{\r\n backgroundColor: location.pathname === item.path ?\r\n theme.palette.action.selected : 'transparent'\r\n }}\r\n >\r\n <ListItemIcon sx={{ justifyContent: 'center' }}>\r\n <IconComponent />\r\n </ListItemIcon>\r\n <ListItemText primary={item.label} />\r\n </ListItem>\r\n );\r\n })}\r\n\r\n {/* Operations category */}\r\n <ListItem sx={{ py: 1 }}>\r\n <ListItemIcon sx={{ justifyContent: 'center' }}>\r\n <MdSupport />\r\n </ListItemIcon>\r\n <ListItemText\r\n primary=\"Operations\"\r\n sx={{\r\n '& .MuiListItemText-primary': {\r\n fontWeight: 'bold',\r\n fontSize: '0.9rem',\r\n color: theme.palette.text.secondary\r\n }\r\n }}\r\n />\r\n </ListItem>\r\n {navigationCategories.operations.items\r\n .filter(item => {\r\n // Check role permission\r\n if (item.roles && !item.roles.includes(user?.role)) return false;\r\n // Check feature flag if required\r\n if (item.featureRequired && user?.enabledFeatures?.[item.featureRequired] === false) return false;\r\n return true;\r\n })\r\n .map((item) => {\r\n const IconComponent = item.icon;\r\n return (\r\n <ListItem\r\n key={item.path}\r\n disablePadding\r\n onClick={() => handleNavigate(item.path)}\r\n sx={{\r\n backgroundColor: location.pathname === item.path ?\r\n theme.palette.action.selected : 'transparent',\r\n pl: 4\r\n }}\r\n >\r\n <ListItemIcon sx={{ justifyContent: 'center', minWidth: 40 }}>\r\n <IconComponent fontSize=\"small\" />\r\n </ListItemIcon>\r\n <ListItemText primary={item.label} />\r\n </ListItem>\r\n );\r\n })}\r\n\r\n {/* Management category - only for property managers, companies and admins */}\r\n {(user?.role === 'property_manager' || user?.role === 'owner' || user?.role === 'admin') && (\r\n <>\r\n <ListItem sx={{ py: 1 }}>\r\n <ListItemIcon sx={{ justifyContent: 'center' }}>\r\n <MdBusiness />\r\n </ListItemIcon>\r\n <ListItemText\r\n primary=\"Management\"\r\n sx={{\r\n '& .MuiListItemText-primary': {\r\n fontWeight: 'bold',\r\n fontSize: '0.9rem',\r\n color: theme.palette.text.secondary\r\n }\r\n }}\r\n />\r\n </ListItem>\r\n {navigationCategories.management.items\r\n .filter(item => {\r\n // Check role permission\r\n if (item.roles && !item.roles.includes(user?.role)) return false;\r\n // Check feature flag if required\r\n if (item.featureRequired && user?.enabledFeatures?.[item.featureRequired] === false) return false;\r\n return true;\r\n })\r\n .map((item) => {\r\n const IconComponent = item.icon;\r\n return (\r\n <ListItem\r\n key={item.path}\r\n disablePadding\r\n onClick={() => handleNavigate(item.path)}\r\n sx={{\r\n backgroundColor: location.pathname === item.path ?\r\n theme.palette.action.selected : 'transparent',\r\n pl: 4\r\n }}\r\n >\r\n <ListItemIcon sx={{ justifyContent: 'center', minWidth: 40 }}>\r\n <IconComponent fontSize=\"small\" />\r\n </ListItemIcon>\r\n <ListItemText primary={item.label} />\r\n </ListItem>\r\n );\r\n })}\r\n </>\r\n )}\r\n </List>\r\n </Box>\r\n );\r\n\r\n return (\r\n <>\r\n <AppBar\r\n position=\"static\"\r\n data-testid=\"navbar\"\r\n sx={{\r\n borderRadius: '0 0 20px 20px',\r\n ...getNavbarStyles(),\r\n transition: 'all 0.3s cubic-bezier(0.4, 0, 0.2, 1)',\r\n backdrop: 'saturate(180%) blur(20px)',\r\n border: isDarkMode ? '1px solid rgba(255, 255, 255, 0.1)' : '1px solid rgba(0, 0, 0, 0.1)',\r\n borderTop: 'none'\r\n }}\r\n >\r\n <Toolbar>\r\n {isMobile && (\r\n <IconButton\r\n color=\"inherit\"\r\n aria-label=\"open drawer\"\r\n edge=\"start\"\r\n onClick={handleDrawerToggle}\r\n sx={{\r\n color: getNavbarStyles().color\r\n }}\r\n >\r\n <MdMenu />\r\n </IconButton>\r\n )}\r\n \r\n <Box \r\n sx={{ \r\n display: 'flex', \r\n alignItems: 'center', \r\n gap: 1,\r\n flexGrow: isMobile ? 1 : 0,\r\n mr: isMobile ? 0 : 4\r\n }}\r\n >\r\n <Box\r\n component=\"img\"\r\n src=\"/images/propman-logo-new.png\"\r\n alt=\"PropMan Logo\"\r\n sx={{\r\n height: 40,\r\n width: 'auto',\r\n maxWidth: '100px',\r\n cursor: 'pointer'\r\n }}\r\n onClick={() => navigate('/dashboard')}\r\n />\r\n <Typography\r\n variant=\"h6\"\r\n component=\"div\"\r\n sx={{\r\n cursor: 'pointer',\r\n color: getNavbarStyles().color,\r\n whiteSpace: 'nowrap',\r\n overflow: 'hidden',\r\n textOverflow: 'ellipsis',\r\n maxWidth: isTablet ? '200px' : 'none'\r\n }}\r\n onClick={() => navigate('/dashboard')}\r\n >\r\n {getEffectiveBranding().companyName ? (\r\n isSmallScreen\r\n ? getEffectiveBranding().companyName.length > 15\r\n ? `${getEffectiveBranding().companyName.substring(0, 15)}...`\r\n : getEffectiveBranding().companyName\r\n : isTablet\r\n ? `${getEffectiveBranding().companyName} Mgmt`\r\n : `${getEffectiveBranding().companyName} Management`\r\n ) : (\r\n isSmallScreen\r\n ? 'PropAI'\r\n : isTablet\r\n ? 'Property AI'\r\n : 'Property Management AI'\r\n )}\r\n </Typography>\r\n </Box>\r\n\r\n {!isMobile && (\r\n <Stack direction=\"row\" spacing={isTablet ? 0.5 : 1} sx={{ flexGrow: 1 }}>\r\n {/* Standalone items */}\r\n {standaloneItems.map((item) => {\r\n const IconComponent = item.icon;\r\n const isActive = location.pathname === item.path;\r\n\r\n if (isTablet) {\r\n return (\r\n <IconButton\r\n key={item.path}\r\n color=\"inherit\"\r\n onClick={() => navigate(item.path)}\r\n title={item.label}\r\n sx={{\r\n backgroundColor: isActive ? 'rgba(255, 255, 255, 0.15)' : 'transparent',\r\n borderRadius: '12px',\r\n padding: '8px',\r\n transition: 'all 0.2s cubic-bezier(0.4, 0, 0.2, 1)',\r\n '&:hover': {\r\n ...getButtonHoverStyles(),\r\n transform: 'translateY(-1px)',\r\n boxShadow: '0 4px 12px rgba(0, 0, 0, 0.15)'\r\n }\r\n }}\r\n >\r\n <IconComponent />\r\n </IconButton>\r\n );\r\n }\r\n\r\n return (\r\n <Button\r\n key={item.path}\r\n color=\"inherit\"\r\n onClick={() => navigate(item.path)}\r\n startIcon={<IconComponent />}\r\n sx={{\r\n backgroundColor: isActive ? 'rgba(255, 255, 255, 0.15)' : 'transparent',\r\n borderRadius: '16px',\r\n padding: '8px 16px',\r\n minHeight: '44px',\r\n transition: 'all 0.2s cubic-bezier(0.4, 0, 0.2, 1)',\r\n '&:hover': {\r\n ...getButtonHoverStyles(),\r\n transform: 'translateY(-1px)',\r\n boxShadow: '0 4px 12px rgba(0, 0, 0, 0.15)'\r\n }\r\n }}\r\n >\r\n {item.label}\r\n </Button>\r\n );\r\n })}\r\n\r\n {/* Operations dropdown */}\r\n <Box>\r\n <Button\r\n color=\"inherit\"\r\n onClick={handleOperationsMenuClick}\r\n endIcon={<MdKeyboardArrowDown />}\r\n startIcon={!isTablet ? <MdSupport /> : null}\r\n sx={{\r\n backgroundColor: navigationCategories.operations.items.some(item =>\r\n location.pathname === item.path && (!item.roles || item.roles.includes(user?.role))\r\n ) ? 'rgba(255, 255, 255, 0.15)' : 'transparent',\r\n borderRadius: isTablet ? '12px' : '16px',\r\n padding: isTablet ? '8px' : '8px 16px',\r\n minHeight: '44px',\r\n transition: 'all 0.2s cubic-bezier(0.4, 0, 0.2, 1)',\r\n '&:hover': {\r\n ...getButtonHoverStyles(),\r\n transform: 'translateY(-1px)',\r\n boxShadow: '0 4px 12px rgba(0, 0, 0, 0.15)'\r\n }\r\n }}\r\n >\r\n {isTablet ? <MdSupport /> : navigationCategories.operations.label}\r\n </Button>\r\n <Menu\r\n anchorEl={operationsMenuAnchor}\r\n open={Boolean(operationsMenuAnchor)}\r\n onClose={handleOperationsMenuClose}\r\n PaperProps={{\r\n sx: {\r\n borderRadius: '16px',\r\n minWidth: 180,\r\n mt: 1,\r\n boxShadow: '0 8px 32px rgba(0, 0, 0, 0.15)'\r\n }\r\n }}\r\n >\r\n {navigationCategories.operations.items\r\n .filter(item => {\r\n // Check role permission\r\n if (item.roles && !item.roles.includes(user?.role)) return false;\r\n // Check feature flag if required\r\n if (item.featureRequired && user?.enabledFeatures?.[item.featureRequired] === false) return false;\r\n return true;\r\n })\r\n .map((item) => {\r\n const IconComponent = item.icon;\r\n return (\r\n <MenuItem\r\n key={item.path}\r\n onClick={() => {\r\n navigate(item.path);\r\n handleOperationsMenuClose();\r\n }}\r\n sx={{\r\n borderRadius: '12px',\r\n margin: '4px 8px',\r\n backgroundColor: location.pathname === item.path ? 'rgba(0, 0, 0, 0.04)' : 'transparent'\r\n }}\r\n >\r\n <IconComponent sx={{ mr: 2, fontSize: '1.2rem' }} />\r\n {item.label}\r\n </MenuItem>\r\n );\r\n })}\r\n </Menu>\r\n </Box>\r\n\r\n {/* Management dropdown - only for property managers, companies and admins */}\r\n {(user?.role === 'property_manager' || user?.role === 'owner' || user?.role === 'admin') && (\r\n <Box>\r\n <Button\r\n color=\"inherit\"\r\n onClick={handleManagementMenuClick}\r\n endIcon={<MdKeyboardArrowDown />}\r\n startIcon={!isTablet ? <MdBusiness /> : null}\r\n sx={{\r\n backgroundColor: navigationCategories.management.items.some(item =>\r\n location.pathname === item.path && (!item.roles || item.roles.includes(user?.role))\r\n ) ? 'rgba(255, 255, 255, 0.15)' : 'transparent',\r\n borderRadius: isTablet ? '12px' : '16px',\r\n padding: isTablet ? '8px' : '8px 16px',\r\n minHeight: '44px',\r\n transition: 'all 0.2s cubic-bezier(0.4, 0, 0.2, 1)',\r\n '&:hover': {\r\n ...getButtonHoverStyles(),\r\n transform: 'translateY(-1px)',\r\n boxShadow: '0 4px 12px rgba(0, 0, 0, 0.15)'\r\n }\r\n }}\r\n >\r\n {isTablet ? <MdBusiness /> : navigationCategories.management.label}\r\n </Button>\r\n <Menu\r\n anchorEl={managementMenuAnchor}\r\n open={Boolean(managementMenuAnchor)}\r\n onClose={handleManagementMenuClose}\r\n PaperProps={{\r\n sx: {\r\n borderRadius: '16px',\r\n minWidth: 180,\r\n mt: 1,\r\n boxShadow: '0 8px 32px rgba(0, 0, 0, 0.15)'\r\n }\r\n }}\r\n >\r\n {navigationCategories.management.items\r\n .filter(item => {\r\n // Check role permission\r\n if (item.roles && !item.roles.includes(user?.role)) return false;\r\n // Check feature flag if required\r\n if (item.featureRequired && user?.enabledFeatures?.[item.featureRequired] === false) return false;\r\n return true;\r\n })\r\n .map((item) => {\r\n const IconComponent = item.icon;\r\n return (\r\n <MenuItem\r\n key={item.path}\r\n onClick={() => {\r\n navigate(item.path);\r\n handleManagementMenuClose();\r\n }}\r\n sx={{\r\n borderRadius: '12px',\r\n margin: '4px 8px',\r\n backgroundColor: location.pathname === item.path ? 'rgba(0, 0, 0, 0.04)' : 'transparent'\r\n }}\r\n >\r\n <IconComponent sx={{ mr: 2, fontSize: '1.2rem' }} />\r\n {item.label}\r\n </MenuItem>\r\n );\r\n })}\r\n </Menu>\r\n </Box>\r\n )}\r\n </Stack>\r\n )}\r\n\r\n <Stack direction=\"row\" spacing={isTablet ? 0.5 : 1} alignItems=\"center\">\r\n {/* Messages Button - for property managers, admins, owners, and workers */}\r\n {(user?.role === 'property_manager' || user?.role === 'admin' || user?.role === 'owner' || user?.role === 'maintenance') && (\r\n <IconButton\r\n onClick={() => navigate('/messages')}\r\n aria-label=\"Messages\"\r\n sx={{\r\n borderRadius: '16px',\r\n padding: '12px',\r\n ...getNotificationIconStyles()\r\n }}\r\n >\r\n <MdMessage />\r\n </IconButton>\r\n )}\r\n\r\n {/* Notifications */}\r\n <IconButton\r\n onClick={handleNotificationMenuClick}\r\n aria-label={`${notificationCount} new notifications`}\r\n aria-describedby=\"notification-menu\"\r\n sx={{\r\n borderRadius: '16px',\r\n padding: '12px',\r\n ...getNotificationIconStyles(),\r\n // Add subtle glow when there are notifications\r\n ...(notificationCount > 0 && {\r\n boxShadow: `${getNotificationIconStyles().boxShadow}, 0 0 20px rgba(255, 23, 68, 0.2)`\r\n }),\r\n '&:hover': {\r\n ...getNotificationIconStyles()['&:hover'],\r\n // Enhanced glow on hover when there are notifications\r\n ...(notificationCount > 0 && {\r\n boxShadow: `${getNotificationIconStyles()['&:hover'].boxShadow}, 0 0 30px rgba(255, 23, 68, 0.3)`\r\n })\r\n }\r\n }}\r\n >\r\n <Badge\r\n badgeContent={notificationCount}\r\n color=\"error\"\r\n sx={{\r\n '& .MuiBadge-badge': {\r\n backgroundColor: '#ff1744',\r\n color: '#ffffff',\r\n fontWeight: 'bold',\r\n fontSize: '0.75rem',\r\n minWidth: '20px',\r\n height: '20px',\r\n border: '2px solid #ffffff',\r\n boxShadow: '0 3px 8px rgba(255, 23, 68, 0.4), 0 1px 3px rgba(0, 0, 0, 0.3)',\r\n animation: notificationCount > 0 ? 'pulse 2s infinite' : 'none',\r\n '@keyframes pulse': {\r\n '0%': {\r\n transform: 'scale(1)',\r\n boxShadow: '0 3px 8px rgba(255, 23, 68, 0.4), 0 1px 3px rgba(0, 0, 0, 0.3)'\r\n },\r\n '50%': {\r\n transform: 'scale(1.1)',\r\n boxShadow: '0 4px 12px rgba(255, 23, 68, 0.6), 0 2px 6px rgba(0, 0, 0, 0.4)'\r\n },\r\n '100%': {\r\n transform: 'scale(1)',\r\n boxShadow: '0 3px 8px rgba(255, 23, 68, 0.4), 0 1px 3px rgba(0, 0, 0, 0.3)'\r\n }\r\n }\r\n }\r\n }}\r\n >\r\n <MdNotifications />\r\n </Badge>\r\n </IconButton>\r\n\r\n <Menu\r\n id=\"notification-menu\"\r\n anchorEl={notificationMenuAnchor}\r\n open={Boolean(notificationMenuAnchor)}\r\n onClose={handleNotificationMenuClose}\r\n PaperProps={{\r\n sx: {\r\n borderRadius: '16px',\r\n maxWidth: 400,\r\n minWidth: 300,\r\n mt: 1,\r\n maxHeight: 400,\r\n boxShadow: '0 8px 32px rgba(0, 0, 0, 0.15)'\r\n }\r\n }}\r\n >\r\n {recentTickets.length === 0 ? (\r\n <MenuItem sx={{ borderRadius: '12px', justifyContent: 'center' }}>\r\n <Typography variant=\"body2\" color=\"text.secondary\">\r\n No new notifications\r\n </Typography>\r\n </MenuItem>\r\n ) : (\r\n recentTickets.map((ticket) => (\r\n <MenuItem \r\n key={ticket.id}\r\n onClick={async () => {\r\n // Mark notification as read\r\n if (ticket.notificationId) {\r\n await markNotificationAsRead(ticket.notificationId);\r\n // Remove from local state\r\n setRecentTickets(prev => prev.filter(item => item.id !== ticket.id));\r\n }\r\n \r\n // Navigate to the ticket\r\n if (ticket.actionUrl) {\r\n navigate(ticket.actionUrl);\r\n } else if (ticket.ticketId) {\r\n navigate(`/tickets/${ticket.ticketId}`);\r\n }\r\n handleNotificationMenuClose();\r\n }}\r\n sx={{ \r\n borderRadius: '12px',\r\n flexDirection: 'column',\r\n alignItems: 'flex-start',\r\n whiteSpace: 'normal',\r\n py: 1.5\r\n }}\r\n >\r\n <Typography variant=\"body2\" fontWeight=\"medium\">\r\n {ticket.title}\r\n </Typography>\r\n <Typography variant=\"caption\" color=\"text.secondary\" sx={{ mt: 0.5 }}>\r\n {ticket.message}\r\n </Typography>\r\n <Typography variant=\"caption\" color=\"text.secondary\" sx={{ mt: 0.5 }}>\r\n {ticket.time}\r\n </Typography>\r\n </MenuItem>\r\n ))\r\n )}\r\n <Divider />\r\n <MenuItem \r\n onClick={() => {\r\n navigate('/notifications');\r\n handleNotificationMenuClose();\r\n }}\r\n sx={{ borderRadius: '12px', justifyContent: 'center' }}\r\n >\r\n <Typography variant=\"body2\" color=\"primary.main\">\r\n View All Notifications\r\n </Typography>\r\n </MenuItem>\r\n </Menu>\r\n\r\n {/* User Name - hide on tablet and smaller */}\r\n {!isMobile && !isTablet && (\r\n <Typography\r\n variant=\"body2\"\r\n sx={{\r\n color: getTenantBannerColorStyles().color,\r\n whiteSpace: 'nowrap'\r\n }}\r\n >\r\n {user?.firstName} {user?.lastName}\r\n </Typography>\r\n )}\r\n\r\n {/* User Menu */}\r\n <IconButton\r\n onClick={handleUserMenuClick}\r\n sx={{\r\n borderRadius: '16px',\r\n padding: '8px',\r\n // Use consistent navbar text color\r\n color: getNavbarStyles().color,\r\n backgroundColor: 'rgba(255, 255, 255, 0.08)',\r\n backdropFilter: 'blur(8px)',\r\n border: '1px solid rgba(255, 255, 255, 0.15)',\r\n transition: 'all 0.2s cubic-bezier(0.4, 0, 0.2, 1)',\r\n '&:hover': {\r\n ...getButtonHoverStyles(),\r\n transform: 'translateY(-1px)',\r\n boxShadow: '0 4px 12px rgba(0, 0, 0, 0.15)'\r\n },\r\n '& .MuiSvgIcon-root': {\r\n filter: 'drop-shadow(0 1px 2px rgba(0, 0, 0, 0.2))',\r\n fontSize: '1.8rem'\r\n }\r\n }}\r\n >\r\n {getEffectiveBranding().companyLogo ? (\r\n <Avatar\r\n src={`${api.defaults.baseURL.replace('/api', '')}/uploads/logos/${getEffectiveBranding().companyLogo}`}\r\n sx={{\r\n width: 32,\r\n height: 32,\r\n border: '2px solid rgba(255, 255, 255, 0.8)',\r\n boxShadow: '0 2px 8px rgba(0, 0, 0, 0.15)'\r\n }}\r\n />\r\n ) : (\r\n <MdAccountCircle />\r\n )}\r\n </IconButton>\r\n \r\n <Menu\r\n anchorEl={userMenuAnchor}\r\n open={Boolean(userMenuAnchor)}\r\n onClose={handleUserMenuClose}\r\n PaperProps={{\r\n sx: {\r\n borderRadius: '16px',\r\n minWidth: 150,\r\n mt: 1\r\n }\r\n }}\r\n >\r\n <MenuItem\r\n onClick={() => {\r\n navigate('/settings');\r\n handleUserMenuClose();\r\n }}\r\n sx={{ borderRadius: '12px' }}\r\n >\r\n Settings\r\n </MenuItem>\r\n <Divider />\r\n <MenuItem\r\n onClick={handleLogout}\r\n sx={{ borderRadius: '12px' }}\r\n data-testid=\"logout-button\"\r\n >\r\n Logout\r\n </MenuItem>\r\n </Menu>\r\n </Stack>\r\n </Toolbar>\r\n </AppBar>\r\n\r\n {/* Mobile Drawer */}\r\n <Drawer\r\n variant=\"temporary\"\r\n open={mobileOpen}\r\n onClose={handleDrawerToggle}\r\n ModalProps={{\r\n keepMounted: true, // Better open performance on mobile\r\n }}\r\n sx={{\r\n display: { xs: 'block', md: 'none' },\r\n '& .MuiDrawer-paper': { \r\n boxSizing: 'border-box', \r\n width: 300,\r\n borderRadius: '0 16px 16px 0'\r\n },\r\n }}\r\n >\r\n {drawer}\r\n </Drawer>\r\n </>\r\n );\r\n};\r\n\r\nexport default Navbar;","import React, { createContext, useContext, useState, useEffect } from 'react';\r\nimport api from '../services/api';\r\n\r\nconst AuthContext = createContext();\r\n\r\nexport const useAuth = () => {\r\n const context = useContext(AuthContext);\r\n if (!context) {\r\n throw new Error('useAuth must be used within AuthProvider');\r\n }\r\n return context;\r\n};\r\n\r\nexport const AuthProvider = ({ children }) => {\r\n const [user, setUser] = useState(null);\r\n const [companyBranding, setCompanyBranding] = useState(null);\r\n const [isLoading, setIsLoading] = useState(true);\r\n const [needsOnboarding, setNeedsOnboarding] = useState(false);\r\n\r\n useEffect(() => {\r\n const token = localStorage.getItem('token');\r\n \r\n // Comprehensive token validation\r\n const isValidToken = token && \r\n token !== 'null' && \r\n token !== 'undefined' && \r\n token !== '' &&\r\n token.length > 20 && \r\n token.split('.').length === 3; // JWT should have 3 parts\r\n \r\n if (isValidToken) {\r\n api.defaults.headers.common['Authorization'] = `Bearer ${token}`;\r\n fetchUser();\r\n } else {\r\n // Clear any invalid tokens\r\n localStorage.removeItem('token');\r\n delete api.defaults.headers.common['Authorization'];\r\n setUser(null);\r\n setIsLoading(false);\r\n }\r\n }, []);\r\n\r\n const fetchUser = async () => {\r\n try {\r\n const response = await api.get('/auth/me');\r\n \r\n // Normalize user object to ensure consistent ID field\r\n const normalizedUser = {\r\n ...response.data.user,\r\n id: response.data.user._id || response.data.user.id,\r\n enabledFeatures: response.data.user.enabledFeatures || {\r\n workersModule: true,\r\n inventoryModule: true,\r\n advancedAnalytics: false,\r\n aiAssistant: true\r\n }\r\n };\r\n\r\n setUser(normalizedUser);\r\n\r\n // Check if owner needs to complete onboarding\r\n const isOwnerRole = ['owner', 'admin', 'super_admin'].includes(normalizedUser.role);\r\n const hasNoCompany = !normalizedUser.company;\r\n setNeedsOnboarding(isOwnerRole && hasNoCompany);\r\n\r\n // If user is a property manager or maintenance worker, fetch company branding\r\n if (normalizedUser.role === 'property_manager' || normalizedUser.role === 'maintenance') {\r\n try {\r\n const brandingResponse = await api.get('/auth/company-branding');\r\n setCompanyBranding(brandingResponse.data.branding);\r\n } catch (brandingError) {\r\n console.warn('Failed to fetch company branding:', brandingError);\r\n setCompanyBranding(null);\r\n }\r\n } else {\r\n setCompanyBranding(null);\r\n }\r\n } catch (error) {\r\n console.error('Failed to fetch user:', error);\r\n // Clear any invalid/malformed tokens\r\n localStorage.removeItem('token');\r\n delete api.defaults.headers.common['Authorization'];\r\n setUser(null);\r\n setNeedsOnboarding(false);\r\n } finally {\r\n setIsLoading(false);\r\n }\r\n };\r\n\r\n const login = async (email, password) => {\r\n try {\r\n const response = await api.post('/auth/login', { email, password });\r\n const { token, user } = response.data;\r\n\r\n localStorage.setItem('token', token);\r\n api.defaults.headers.common['Authorization'] = `Bearer ${token}`;\r\n setUser(user);\r\n\r\n return { success: true };\r\n } catch (error) {\r\n console.error('Login failed:', error);\r\n return {\r\n success: false,\r\n error: error.response?.data?.message || 'Login failed'\r\n };\r\n }\r\n };\r\n\r\n const logout = () => {\r\n localStorage.removeItem('token');\r\n delete api.defaults.headers.common['Authorization'];\r\n setUser(null);\r\n setCompanyBranding(null);\r\n setNeedsOnboarding(false);\r\n };\r\n\r\n const refreshUser = async () => {\r\n await fetchUser();\r\n };\r\n\r\n const updateUser = (updatedUser) => {\r\n setUser(updatedUser);\r\n };\r\n\r\n const completeOnboarding = async (companyData) => {\r\n try {\r\n const response = await api.post('/companies/onboard', companyData);\r\n\r\n if (response.data.success) {\r\n // Update user with new company association\r\n setUser(response.data.data.user);\r\n setNeedsOnboarding(false);\r\n return { success: true, data: response.data.data };\r\n }\r\n\r\n return { success: false, error: 'Onboarding failed' };\r\n } catch (error) {\r\n console.error('Onboarding failed:', error);\r\n return {\r\n success: false,\r\n error: error.response?.data?.error?.message || 'Onboarding failed'\r\n };\r\n }\r\n };\r\n\r\n const value = {\r\n user,\r\n isAuthenticated: !!user,\r\n companyBranding,\r\n managerBranding: companyBranding, // Keep old name for backward compatibility\r\n needsOnboarding,\r\n login,\r\n logout,\r\n refreshUser,\r\n updateUser,\r\n completeOnboarding,\r\n isLoading\r\n };\r\n\r\n return (\r\n <AuthContext.Provider value={value}>\r\n {children}\r\n </AuthContext.Provider>\r\n );\r\n};","import axios from 'axios';\r\n\r\n// Auto-detect the correct API URL based on current window location\r\nconst getApiUrl = () => {\r\n // If we have an environment variable, use it\r\n if (process.env.REACT_APP_API_URL) {\r\n return process.env.REACT_APP_API_URL;\r\n }\r\n\r\n // Otherwise, auto-detect based on current hostname\r\n const hostname = window.location.hostname;\r\n const port = hostname === 'localhost' ? '5000' : '5000'; // Always use 5000 for API\r\n return `http://${hostname}:${port}/api`;\r\n};\r\n\r\nconst apiUrl = getApiUrl();\r\n\r\nconst api = axios.create({\r\n baseURL: apiUrl,\r\n timeout: 10000,\r\n});\r\n\r\napi.interceptors.response.use(\r\n (response) => response,\r\n (error) => {\r\n if (error.response?.status === 401) {\r\n localStorage.removeItem('token');\r\n delete api.defaults.headers.common['Authorization'];\r\n window.location.href = '/login';\r\n }\r\n return Promise.reject(error);\r\n }\r\n);\r\n\r\nexport { api };\r\nexport default api;","import React, { createContext, useContext, useState, useCallback } from 'react';\r\n\r\nconst NotificationContext = createContext();\r\n\r\nexport const useNotification = () => {\r\n const context = useContext(NotificationContext);\r\n if (!context) {\r\n throw new Error('useNotification must be used within a NotificationProvider');\r\n }\r\n return context;\r\n};\r\n\r\nexport const NotificationProvider = ({ children }) => {\r\n const [notifications, setNotifications] = useState([]);\r\n const [nextId, setNextId] = useState(1);\r\n\r\n const addNotification = useCallback((notification) => {\r\n try {\r\n const id = nextId;\r\n setNextId(prev => prev + 1);\r\n\r\n const newNotification = {\r\n id,\r\n type: 'info', // 'success', 'error', 'warning', 'info'\r\n title: '',\r\n message: '',\r\n duration: 5000, // Auto-hide duration in ms (0 for persistent)\r\n actions: [], // Custom action buttons\r\n dismissible: true,\r\n persistent: false,\r\n timestamp: new Date(),\r\n ...notification\r\n };\r\n\r\n // Validate required fields\r\n if (!newNotification.message) {\r\n console.warn('Notification missing message:', notification);\r\n return null;\r\n }\r\n\r\n setNotifications(prev => Array.isArray(prev) ? [...prev, newNotification] : [newNotification]);\r\n\r\n // Auto-hide notification if duration is set\r\n if (newNotification.duration > 0) {\r\n setTimeout(() => {\r\n removeNotification(id);\r\n }, newNotification.duration);\r\n }\r\n\r\n return id;\r\n } catch (error) {\r\n console.error('Error adding notification:', error);\r\n return null;\r\n }\r\n }, [nextId]);\r\n\r\n const removeNotification = useCallback((id) => {\r\n try {\r\n setNotifications(prev => Array.isArray(prev) ? prev.filter(notification => notification && notification.id !== id) : []);\r\n } catch (error) {\r\n console.error('Error removing notification:', error);\r\n }\r\n }, []);\r\n\r\n const clearAllNotifications = useCallback(() => {\r\n setNotifications([]);\r\n }, []);\r\n\r\n const updateNotification = useCallback((id, updates) => {\r\n setNotifications(prev => \r\n prev.map(notification => \r\n notification.id === id \r\n ? { ...notification, ...updates }\r\n : notification\r\n )\r\n );\r\n }, []);\r\n\r\n // Convenience methods for common notification types\r\n const showSuccess = useCallback((message, options = {}) => {\r\n return addNotification({\r\n type: 'success',\r\n message,\r\n duration: 4000,\r\n ...options\r\n });\r\n }, [addNotification]);\r\n\r\n const showError = useCallback((message, options = {}) => {\r\n return addNotification({\r\n type: 'error',\r\n message,\r\n duration: 7000,\r\n ...options\r\n });\r\n }, [addNotification]);\r\n\r\n const showWarning = useCallback((message, options = {}) => {\r\n return addNotification({\r\n type: 'warning',\r\n message,\r\n duration: 5000,\r\n ...options\r\n });\r\n }, [addNotification]);\r\n\r\n const showInfo = useCallback((message, options = {}) => {\r\n return addNotification({\r\n type: 'info',\r\n message,\r\n duration: 5000,\r\n ...options\r\n });\r\n }, [addNotification]);\r\n\r\n const showLoading = useCallback((message, options = {}) => {\r\n return addNotification({\r\n type: 'info',\r\n message,\r\n persistent: true,\r\n dismissible: false,\r\n duration: 0,\r\n ...options\r\n });\r\n }, [addNotification]);\r\n\r\n // Progress notification for long operations\r\n const showProgress = useCallback((message, progress = 0, options = {}) => {\r\n return addNotification({\r\n type: 'info',\r\n message,\r\n progress,\r\n persistent: true,\r\n dismissible: false,\r\n duration: 0,\r\n ...options\r\n });\r\n }, [addNotification]);\r\n\r\n const updateProgress = useCallback((id, progress, message) => {\r\n updateNotification(id, { \r\n progress,\r\n ...(message && { message })\r\n });\r\n }, [updateNotification]);\r\n\r\n // Action notification with custom buttons\r\n const showAction = useCallback((message, actions, options = {}) => {\r\n return addNotification({\r\n type: 'info',\r\n message,\r\n actions,\r\n persistent: true,\r\n duration: 0,\r\n ...options\r\n });\r\n }, [addNotification]);\r\n\r\n const value = {\r\n notifications,\r\n addNotification,\r\n removeNotification,\r\n clearAllNotifications,\r\n updateNotification,\r\n showSuccess,\r\n showError,\r\n showWarning,\r\n showInfo,\r\n showLoading,\r\n showProgress,\r\n updateProgress,\r\n showAction\r\n };\r\n\r\n return (\r\n <NotificationContext.Provider value={value}>\r\n {children}\r\n </NotificationContext.Provider>\r\n );\r\n};\r\n\r\nexport default NotificationContext;","import React, { createContext, useContext, useState, useEffect } from 'react';\r\nimport { createTheme, ThemeProvider } from '@mui/material/styles';\r\nimport CssBaseline from '@mui/material/CssBaseline';\r\nimport api from '../services/api';\r\nimport { useAuth } from './AuthContext';\r\nimport { createContrastEnhancedComponents } from '../utils/themeContrast';\r\n\r\nconst ThemeContext = createContext();\r\n\r\nexport const useCustomTheme = () => {\r\n const context = useContext(ThemeContext);\r\n if (!context) {\r\n throw new Error('useCustomTheme must be used within a CustomThemeProvider');\r\n }\r\n return context;\r\n};\r\n\r\n// Light theme configuration with modern design\r\nconst baseLightTheme = {\r\n palette: {\r\n mode: 'light',\r\n primary: {\r\n main: '#2563eb', // Modern blue\r\n light: '#3b82f6',\r\n dark: '#1d4ed8',\r\n contrastText: '#ffffff',\r\n },\r\n secondary: {\r\n main: '#7c3aed', // Modern purple\r\n light: '#8b5cf6',\r\n dark: '#6d28d9',\r\n contrastText: '#ffffff',\r\n },\r\n success: {\r\n main: '#10b981', // Modern green\r\n light: '#34d399',\r\n dark: '#059669',\r\n },\r\n warning: {\r\n main: '#f59e0b', // Modern amber\r\n light: '#fbbf24',\r\n dark: '#d97706',\r\n },\r\n error: {\r\n main: '#ef4444', // Modern red\r\n light: '#f87171',\r\n dark: '#dc2626',\r\n },\r\n background: {\r\n default: '#f8fafc', // Subtle gray background\r\n paper: '#ffffff',\r\n },\r\n text: {\r\n primary: '#0f172a', // Rich dark blue-gray\r\n secondary: '#64748b', // Modern gray\r\n },\r\n divider: '#e2e8f0',\r\n grey: {\r\n 50: '#f8fafc',\r\n 100: '#f1f5f9',\r\n 200: '#e2e8f0',\r\n 300: '#cbd5e1',\r\n 400: '#94a3b8',\r\n 500: '#64748b',\r\n 600: '#475569',\r\n 700: '#334155',\r\n 800: '#1e293b',\r\n 900: '#0f172a',\r\n },\r\n },\r\n typography: {\r\n fontFamily: '\"Inter\", \"SF Pro Display\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", \"Roboto\", sans-serif',\r\n h1: {\r\n fontWeight: 800,\r\n letterSpacing: '-0.025em',\r\n fontSize: '2.25rem',\r\n lineHeight: 1.2,\r\n },\r\n h2: {\r\n fontWeight: 700,\r\n letterSpacing: '-0.025em',\r\n fontSize: '1.875rem',\r\n lineHeight: 1.25,\r\n },\r\n h3: {\r\n fontWeight: 600,\r\n letterSpacing: '-0.025em',\r\n fontSize: '1.5rem',\r\n lineHeight: 1.3,\r\n },\r\n h4: {\r\n fontWeight: 600,\r\n fontSize: '1.25rem',\r\n lineHeight: 1.4,\r\n '@media (max-width:600px)': {\r\n fontSize: '1.125rem',\r\n },\r\n },\r\n h5: {\r\n fontWeight: 600,\r\n fontSize: '1.125rem',\r\n lineHeight: 1.5,\r\n },\r\n h6: {\r\n fontWeight: 600,\r\n fontSize: '1rem',\r\n lineHeight: 1.5,\r\n '@media (max-width:600px)': {\r\n fontSize: '0.875rem',\r\n },\r\n },\r\n body1: {\r\n fontSize: '1rem',\r\n lineHeight: 1.6,\r\n color: '#334155',\r\n },\r\n body2: {\r\n fontSize: '0.875rem',\r\n lineHeight: 1.5,\r\n color: '#64748b',\r\n },\r\n button: {\r\n fontWeight: 500,\r\n letterSpacing: '0.025em',\r\n textTransform: 'none',\r\n },\r\n caption: {\r\n fontSize: '0.75rem',\r\n lineHeight: 1.4,\r\n color: '#94a3b8',\r\n },\r\n },\r\n shape: {\r\n borderRadius: 12, // More modern rounded corners\r\n },\r\n breakpoints: {\r\n values: {\r\n xs: 0,\r\n sm: 640,\r\n md: 768,\r\n lg: 1024,\r\n xl: 1280,\r\n },\r\n },\r\n components: {\r\n MuiCssBaseline: {\r\n styleOverrides: {\r\n '@global': {\r\n '@keyframes pulse': {\r\n '0%, 100%': {\r\n opacity: 1,\r\n },\r\n '50%': {\r\n opacity: 0.5,\r\n },\r\n },\r\n '@keyframes spin': {\r\n from: {\r\n transform: 'rotate(0deg)',\r\n },\r\n to: {\r\n transform: 'rotate(360deg)',\r\n },\r\n },\r\n '@keyframes fadeIn': {\r\n from: {\r\n opacity: 0,\r\n transform: 'translateY(10px)',\r\n },\r\n to: {\r\n opacity: 1,\r\n transform: 'translateY(0)',\r\n },\r\n },\r\n '@keyframes slideInRight': {\r\n from: {\r\n opacity: 0,\r\n transform: 'translateX(20px)',\r\n },\r\n to: {\r\n opacity: 1,\r\n transform: 'translateX(0)',\r\n },\r\n },\r\n '@keyframes bounce': {\r\n '0%, 20%, 53%, 80%, 100%': {\r\n transform: 'translate3d(0,0,0)',\r\n },\r\n '40%, 43%': {\r\n transform: 'translate3d(0, -8px, 0)',\r\n },\r\n '70%': {\r\n transform: 'translate3d(0, -4px, 0)',\r\n },\r\n '90%': {\r\n transform: 'translate3d(0, -2px, 0)',\r\n },\r\n },\r\n },\r\n },\r\n },\r\n MuiCard: {\r\n styleOverrides: {\r\n root: {\r\n borderRadius: 16,\r\n boxShadow: '0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)',\r\n transition: 'all 0.2s cubic-bezier(0.4, 0, 0.2, 1)',\r\n '&:hover': {\r\n boxShadow: '0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)',\r\n transform: 'translateY(-2px)',\r\n },\r\n },\r\n },\r\n },\r\n MuiButton: {\r\n styleOverrides: {\r\n root: {\r\n borderRadius: 12,\r\n textTransform: 'none',\r\n fontWeight: 500,\r\n padding: '10px 24px',\r\n boxShadow: 'none',\r\n '&:hover': {\r\n boxShadow: '0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)',\r\n },\r\n },\r\n contained: {\r\n '&:hover': {\r\n boxShadow: '0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)',\r\n },\r\n },\r\n outlined: {\r\n borderWidth: 2,\r\n '&:hover': {\r\n borderWidth: 2,\r\n },\r\n },\r\n },\r\n },\r\n MuiPaper: {\r\n styleOverrides: {\r\n root: {\r\n borderRadius: 16,\r\n boxShadow: '0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)',\r\n },\r\n elevation1: {\r\n boxShadow: '0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)',\r\n },\r\n elevation2: {\r\n boxShadow: '0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)',\r\n },\r\n elevation3: {\r\n boxShadow: '0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)',\r\n },\r\n },\r\n },\r\n MuiTextField: {\r\n styleOverrides: {\r\n root: {\r\n '& .MuiOutlinedInput-root': {\r\n borderRadius: 12,\r\n '& fieldset': {\r\n borderColor: '#e2e8f0',\r\n },\r\n '&:hover fieldset': {\r\n borderColor: '#cbd5e1',\r\n },\r\n '&.Mui-focused fieldset': {\r\n borderWidth: 2,\r\n borderColor: '#2563eb',\r\n },\r\n },\r\n },\r\n },\r\n },\r\n MuiChip: {\r\n styleOverrides: {\r\n root: {\r\n borderRadius: 8,\r\n fontWeight: 500,\r\n },\r\n },\r\n },\r\n MuiAppBar: {\r\n styleOverrides: {\r\n root: {\r\n borderRadius: '0 0 16px 16px',\r\n boxShadow: '0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)',\r\n },\r\n },\r\n },\r\n },\r\n};\r\n\r\n// Dark theme configuration with modern design\r\nconst baseDarkTheme = {\r\n palette: {\r\n mode: 'dark',\r\n primary: {\r\n main: '#3b82f6', // Modern blue for dark mode\r\n light: '#60a5fa',\r\n dark: '#2563eb',\r\n contrastText: '#ffffff',\r\n },\r\n secondary: {\r\n main: '#8b5cf6', // Modern purple for dark mode\r\n light: '#a78bfa',\r\n dark: '#7c3aed',\r\n contrastText: '#ffffff',\r\n },\r\n success: {\r\n main: '#34d399', // Modern green for dark mode\r\n light: '#6ee7b7',\r\n dark: '#10b981',\r\n },\r\n warning: {\r\n main: '#fbbf24', // Modern amber for dark mode\r\n light: '#fcd34d',\r\n dark: '#f59e0b',\r\n },\r\n error: {\r\n main: '#f87171', // Modern red for dark mode\r\n light: '#fca5a5',\r\n dark: '#ef4444',\r\n },\r\n background: {\r\n default: '#0f172a', // Rich dark blue-gray\r\n paper: '#1e293b',\r\n },\r\n text: {\r\n primary: '#f8fafc',\r\n secondary: '#cbd5e1',\r\n },\r\n divider: '#334155',\r\n grey: {\r\n 50: '#0f172a',\r\n 100: '#1e293b',\r\n 200: '#334155',\r\n 300: '#475569',\r\n 400: '#64748b',\r\n 500: '#94a3b8',\r\n 600: '#cbd5e1',\r\n 700: '#e2e8f0',\r\n 800: '#f1f5f9',\r\n 900: '#f8fafc',\r\n },\r\n },\r\n typography: {\r\n fontFamily: '\"Inter\", \"SF Pro Display\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", \"Roboto\", sans-serif',\r\n h1: {\r\n fontWeight: 800,\r\n letterSpacing: '-0.025em',\r\n fontSize: '2.25rem',\r\n lineHeight: 1.2,\r\n },\r\n h2: {\r\n fontWeight: 700,\r\n letterSpacing: '-0.025em',\r\n fontSize: '1.875rem',\r\n lineHeight: 1.25,\r\n },\r\n h3: {\r\n fontWeight: 600,\r\n letterSpacing: '-0.025em',\r\n fontSize: '1.5rem',\r\n lineHeight: 1.3,\r\n },\r\n h4: {\r\n fontWeight: 600,\r\n fontSize: '1.25rem',\r\n lineHeight: 1.4,\r\n '@media (max-width:600px)': {\r\n fontSize: '1.125rem',\r\n },\r\n },\r\n h5: {\r\n fontWeight: 600,\r\n fontSize: '1.125rem',\r\n lineHeight: 1.5,\r\n },\r\n h6: {\r\n fontWeight: 600,\r\n fontSize: '1rem',\r\n lineHeight: 1.5,\r\n '@media (max-width:600px)': {\r\n fontSize: '0.875rem',\r\n },\r\n },\r\n body1: {\r\n fontSize: '1rem',\r\n lineHeight: 1.6,\r\n color: '#e2e8f0', // Lighter text for better contrast on dark backgrounds\r\n },\r\n body2: {\r\n fontSize: '0.875rem',\r\n lineHeight: 1.5,\r\n color: '#cbd5e1', // Improved contrast from #94a3b8\r\n },\r\n button: {\r\n fontWeight: 500,\r\n letterSpacing: '0.025em',\r\n textTransform: 'none',\r\n },\r\n caption: {\r\n fontSize: '0.75rem',\r\n lineHeight: 1.4,\r\n color: '#94a3b8', // Improved contrast from #64748b\r\n },\r\n },\r\n shape: {\r\n borderRadius: 12,\r\n },\r\n breakpoints: {\r\n values: {\r\n xs: 0,\r\n sm: 640,\r\n md: 768,\r\n lg: 1024,\r\n xl: 1280,\r\n },\r\n },\r\n components: {\r\n MuiCssBaseline: {\r\n styleOverrides: {\r\n '@global': {\r\n '@keyframes pulse': {\r\n '0%, 100%': {\r\n opacity: 1,\r\n },\r\n '50%': {\r\n opacity: 0.5,\r\n },\r\n },\r\n '@keyframes spin': {\r\n from: {\r\n transform: 'rotate(0deg)',\r\n },\r\n to: {\r\n transform: 'rotate(360deg)',\r\n },\r\n },\r\n '@keyframes fadeIn': {\r\n from: {\r\n opacity: 0,\r\n transform: 'translateY(10px)',\r\n },\r\n to: {\r\n opacity: 1,\r\n transform: 'translateY(0)',\r\n },\r\n },\r\n '@keyframes slideInRight': {\r\n from: {\r\n opacity: 0,\r\n transform: 'translateX(20px)',\r\n },\r\n to: {\r\n opacity: 1,\r\n transform: 'translateX(0)',\r\n },\r\n },\r\n '@keyframes bounce': {\r\n '0%, 20%, 53%, 80%, 100%': {\r\n transform: 'translate3d(0,0,0)',\r\n },\r\n '40%, 43%': {\r\n transform: 'translate3d(0, -8px, 0)',\r\n },\r\n '70%': {\r\n transform: 'translate3d(0, -4px, 0)',\r\n },\r\n '90%': {\r\n transform: 'translate3d(0, -2px, 0)',\r\n },\r\n },\r\n },\r\n },\r\n },\r\n MuiCard: {\r\n styleOverrides: {\r\n root: {\r\n backgroundColor: '#1e293b',\r\n borderRadius: 16,\r\n border: '1px solid #334155',\r\n boxShadow: '0 4px 6px -1px rgb(0 0 0 / 0.3), 0 2px 4px -2px rgb(0 0 0 / 0.3)',\r\n transition: 'all 0.2s cubic-bezier(0.4, 0, 0.2, 1)',\r\n '&:hover': {\r\n boxShadow: '0 20px 25px -5px rgb(0 0 0 / 0.4), 0 8px 10px -6px rgb(0 0 0 / 0.4)',\r\n transform: 'translateY(-2px)',\r\n borderColor: '#475569',\r\n },\r\n },\r\n },\r\n },\r\n MuiButton: {\r\n styleOverrides: {\r\n root: {\r\n borderRadius: 12,\r\n textTransform: 'none',\r\n fontWeight: 500,\r\n padding: '10px 24px',\r\n boxShadow: 'none',\r\n '&:hover': {\r\n boxShadow: '0 4px 6px -1px rgb(0 0 0 / 0.3), 0 2px 4px -2px rgb(0 0 0 / 0.3)',\r\n },\r\n },\r\n contained: {\r\n '&:hover': {\r\n boxShadow: '0 10px 15px -3px rgb(0 0 0 / 0.3), 0 4px 6px -4px rgb(0 0 0 / 0.3)',\r\n },\r\n },\r\n outlined: {\r\n borderWidth: 2,\r\n '&:hover': {\r\n borderWidth: 2,\r\n },\r\n },\r\n },\r\n },\r\n MuiPaper: {\r\n styleOverrides: {\r\n root: {\r\n backgroundColor: '#1e293b',\r\n borderRadius: 16,\r\n border: '1px solid #334155',\r\n boxShadow: '0 4px 6px -1px rgb(0 0 0 / 0.3), 0 2px 4px -2px rgb(0 0 0 / 0.3)',\r\n },\r\n elevation1: {\r\n boxShadow: '0 1px 3px 0 rgb(0 0 0 / 0.3), 0 1px 2px -1px rgb(0 0 0 / 0.3)',\r\n },\r\n elevation2: {\r\n boxShadow: '0 4px 6px -1px rgb(0 0 0 / 0.3), 0 2px 4px -2px rgb(0 0 0 / 0.3)',\r\n },\r\n elevation3: {\r\n boxShadow: '0 10px 15px -3px rgb(0 0 0 / 0.3), 0 4px 6px -4px rgb(0 0 0 / 0.3)',\r\n },\r\n },\r\n },\r\n MuiTextField: {\r\n styleOverrides: {\r\n root: {\r\n '& .MuiOutlinedInput-root': {\r\n borderRadius: 12,\r\n '& fieldset': {\r\n borderColor: '#475569',\r\n },\r\n '&:hover fieldset': {\r\n borderColor: '#64748b',\r\n },\r\n '&.Mui-focused fieldset': {\r\n borderWidth: 2,\r\n borderColor: '#3b82f6',\r\n },\r\n },\r\n },\r\n },\r\n },\r\n MuiChip: {\r\n styleOverrides: {\r\n root: {\r\n borderRadius: 8,\r\n fontWeight: 500,\r\n backgroundColor: '#334155',\r\n color: '#f8fafc',\r\n },\r\n },\r\n },\r\n MuiAppBar: {\r\n styleOverrides: {\r\n root: {\r\n backgroundColor: '#1e293b',\r\n borderRadius: '0 0 16px 16px',\r\n border: '1px solid #334155',\r\n borderTop: 'none',\r\n boxShadow: '0 4px 6px -1px rgb(0 0 0 / 0.3), 0 2px 4px -2px rgb(0 0 0 / 0.3)',\r\n },\r\n },\r\n },\r\n },\r\n};\r\n\r\n// Create enhanced themes with better contrast\r\nconst createEnhancedTheme = (baseTheme) => {\r\n const theme = createTheme(baseTheme);\r\n const enhancedComponents = createContrastEnhancedComponents(theme);\r\n \r\n return createTheme({\r\n ...baseTheme,\r\n components: {\r\n ...baseTheme.components,\r\n ...enhancedComponents\r\n }\r\n });\r\n};\r\n\r\nconst lightTheme = createEnhancedTheme(baseLightTheme);\r\nconst darkTheme = createEnhancedTheme(baseDarkTheme);\r\n\r\nexport const CustomThemeProvider = ({ children }) => {\r\n const [currentTheme, setCurrentTheme] = useState('light');\r\n const [loading, setLoading] = useState(false);\r\n const { user, companyBranding } = useAuth();\r\n\r\n // Check if running in embedded mode\r\n const isEmbedded = new URLSearchParams(window.location.search).get('embedded') === 'true';\r\n\r\n // All authenticated users can modify their theme preference\r\n const canModifyTheme = Boolean(user && (user.role === 'admin' || user.role === 'owner' || user.role === 'property_manager' || user.role === 'maintenance'));\r\n\r\n // Listen for theme changes from parent in embedded mode\r\n useEffect(() => {\r\n if (!isEmbedded) return;\r\n\r\n const handleMessage = (event) => {\r\n // Only accept messages from localhost (development)\r\n if (!event.origin.startsWith('http://localhost:')) return;\r\n\r\n const { type, theme } = event.data;\r\n\r\n if (type === 'THEME_CHANGE' && theme && ['light', 'dark'].includes(theme)) {\r\n // In embedded mode, directly set theme without API call or permission check\r\n setCurrentTheme(theme);\r\n }\r\n };\r\n\r\n window.addEventListener('message', handleMessage);\r\n\r\n // Request current theme from parent\r\n if (window.parent !== window) {\r\n window.parent.postMessage({ type: 'REQUEST_THEME' }, '*');\r\n }\r\n\r\n return () => window.removeEventListener('message', handleMessage);\r\n }, [isEmbedded]);\r\n\r\n // Load theme preference when user changes\r\n useEffect(() => {\r\n // Skip auto-loading theme in embedded mode (wait for parent to send theme)\r\n if (isEmbedded) return;\r\n\r\n if (user && canModifyTheme) {\r\n // All authenticated users use their own theme preference\r\n const themeToUse = user.themePreference || 'light';\r\n setCurrentTheme(themeToUse);\r\n } else {\r\n // Not authenticated - use light theme\r\n setCurrentTheme('light');\r\n }\r\n }, [user, canModifyTheme, isEmbedded]);\r\n\r\n const toggleTheme = async () => {\r\n if (!canModifyTheme) return;\r\n\r\n const newTheme = currentTheme === 'light' ? 'dark' : 'light';\r\n setCurrentTheme(newTheme);\r\n\r\n try {\r\n await api.put('/users/me', { themePreference: newTheme });\r\n } catch (error) {\r\n console.error('Failed to save theme preference:', error);\r\n // Revert on error\r\n setCurrentTheme(currentTheme);\r\n }\r\n };\r\n\r\n const setTheme = async (themeKey) => {\r\n if (!canModifyTheme || !['light', 'dark'].includes(themeKey)) return;\r\n\r\n setCurrentTheme(themeKey);\r\n\r\n try {\r\n await api.put('/users/me', { themePreference: themeKey });\r\n } catch (error) {\r\n console.error('Failed to save theme preference:', error);\r\n // Revert on error\r\n setCurrentTheme(currentTheme);\r\n }\r\n };\r\n\r\n const resetTheme = async () => {\r\n if (!canModifyTheme) return;\r\n\r\n setCurrentTheme('light');\r\n\r\n try {\r\n await api.put('/users/me', { themePreference: 'light' });\r\n } catch (error) {\r\n console.error('Failed to save theme preference:', error);\r\n // Revert on error\r\n setCurrentTheme(currentTheme);\r\n }\r\n };\r\n\r\n // Helper function to get effective branding color\r\n const getEffectiveBrandingColor = () => {\r\n if ((user?.role === 'maintenance' || user?.role === 'property_manager') && companyBranding) {\r\n return companyBranding.preferredBrandingColor || 0;\r\n }\r\n return user?.preferredBrandingColor || 0;\r\n };\r\n\r\n // Use current theme for authenticated users, light theme for login pages\r\n const effectiveTheme = user ? currentTheme : 'light';\r\n const themeObject = effectiveTheme === 'dark' ? darkTheme : lightTheme;\r\n const isDarkMode = effectiveTheme === 'dark';\r\n const effectiveBrandingColor = getEffectiveBrandingColor();\r\n\r\n const value = {\r\n currentThemeKey: effectiveTheme,\r\n theme: themeObject,\r\n isDarkMode,\r\n setTheme,\r\n toggleTheme,\r\n resetTheme,\r\n canModifyTheme,\r\n loading,\r\n isTenantMode: false, // No tenant theming\r\n effectiveBrandingColor,\r\n };\r\n\r\n return (\r\n <ThemeContext.Provider value={value}>\r\n <ThemeProvider theme={themeObject}>\r\n <CssBaseline />\r\n {children}\r\n </ThemeProvider>\r\n </ThemeContext.Provider>\r\n );\r\n};","/**\r\n * Color extraction utility for analyzing logo images and generating color schemes\r\n */\r\n\r\n/**\r\n * Extract dominant colors from an image URL\r\n * @param {string} imageUrl - URL of the image to analyze\r\n * @returns {Promise<Object>} Object containing primary, secondary, and accent colors\r\n */\r\nexport const extractColorsFromImage = (imageUrl) => {\r\n return new Promise((resolve, reject) => {\r\n const img = new Image();\r\n img.crossOrigin = 'Anonymous';\r\n \r\n img.onload = () => {\r\n try {\r\n const canvas = document.createElement('canvas');\r\n const ctx = canvas.getContext('2d');\r\n \r\n // Set canvas size to match image\r\n canvas.width = img.width;\r\n canvas.height = img.height;\r\n \r\n // Draw image to canvas\r\n ctx.drawImage(img, 0, 0);\r\n \r\n // Get image data\r\n const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);\r\n const data = imageData.data;\r\n \r\n // Extract colors using color quantization\r\n const colors = extractDominantColors(data);\r\n \r\n // Generate color scheme\r\n const colorScheme = generateColorScheme(colors);\r\n \r\n resolve(colorScheme);\r\n } catch (error) {\r\n reject(error);\r\n }\r\n };\r\n \r\n img.onerror = () => {\r\n reject(new Error('Failed to load image'));\r\n };\r\n \r\n img.src = imageUrl;\r\n });\r\n};\r\n\r\n/**\r\n * Extract dominant colors from image data using simple color quantization\r\n * @param {Uint8ClampedArray} data - Image pixel data\r\n * @returns {Array} Array of dominant colors in RGB format\r\n */\r\nconst extractDominantColors = (data) => {\r\n const colorCounts = {};\r\n const step = 4; // Skip pixels for performance\r\n \r\n // Count color occurrences (simplified to reduce similar colors)\r\n for (let i = 0; i < data.length; i += 4 * step) {\r\n const r = Math.floor(data[i] / 32) * 32; // Quantize to reduce similar colors\r\n const g = Math.floor(data[i + 1] / 32) * 32;\r\n const b = Math.floor(data[i + 2] / 32) * 32;\r\n const a = data[i + 3];\r\n \r\n // Skip transparent or very light pixels\r\n if (a < 128 || (r > 200 && g > 200 && b > 200)) continue;\r\n \r\n const colorKey = `${r},${g},${b}`;\r\n colorCounts[colorKey] = (colorCounts[colorKey] || 0) + 1;\r\n }\r\n \r\n // Sort colors by frequency and return top colors\r\n const sortedColors = Object.entries(colorCounts)\r\n .sort(([,a], [,b]) => b - a)\r\n .slice(0, 5)\r\n .map(([color]) => {\r\n const [r, g, b] = color.split(',').map(Number);\r\n return { r, g, b };\r\n });\r\n \r\n return sortedColors;\r\n};\r\n\r\n/**\r\n * Generate a cohesive color scheme from dominant colors\r\n * @param {Array} dominantColors - Array of dominant colors\r\n * @returns {Object} Color scheme object\r\n */\r\nconst generateColorScheme = (dominantColors) => {\r\n if (dominantColors.length === 0) {\r\n // Fallback to default colors\r\n return {\r\n primary: '#1976d2',\r\n secondary: '#dc004e',\r\n accent: '#9c27b0',\r\n light: '#bbdefb',\r\n dark: '#0d47a1'\r\n };\r\n }\r\n \r\n const primary = dominantColors[0];\r\n const secondary = dominantColors[1] || primary;\r\n \r\n // Convert to hex and generate variations\r\n const primaryHex = rgbToHex(primary.r, primary.g, primary.b);\r\n const secondaryHex = rgbToHex(secondary.r, secondary.g, secondary.b);\r\n \r\n // Generate lighter and darker variations\r\n const lightVariation = lightenColor(primaryHex, 0.3);\r\n const darkVariation = darkenColor(primaryHex, 0.3);\r\n \r\n // Generate accent color (complementary or triadic)\r\n const accentHex = generateAccentColor(primary);\r\n \r\n // Get top 4 dominant colors for user selection\r\n const topColors = dominantColors.slice(0, 4).map((color, index) => ({\r\n id: index,\r\n rgb: color,\r\n hex: rgbToHex(color.r, color.g, color.b),\r\n name: `Color ${index + 1}`\r\n }));\r\n\r\n return {\r\n primary: primary,\r\n secondary: secondary,\r\n accent: hexToRgb(accentHex),\r\n light: hexToRgb(lightVariation),\r\n dark: hexToRgb(darkVariation),\r\n // Also include hex versions for CSS use\r\n primaryHex: primaryHex,\r\n secondaryHex: secondaryHex,\r\n accentHex: accentHex,\r\n // Top 4 prominent colors for selection\r\n topColors: topColors\r\n };\r\n};\r\n\r\n/**\r\n * Convert RGB to hex\r\n */\r\nexport const rgbToHex = (r, g, b) => {\r\n return \"#\" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);\r\n};\r\n\r\n/**\r\n * Convert hex to RGB object\r\n */\r\nconst hexToRgb = (hex) => {\r\n const num = parseInt(hex.replace(\"#\", \"\"), 16);\r\n return {\r\n r: num >> 16,\r\n g: (num >> 8 & 0x00FF),\r\n b: num & 0x0000FF\r\n };\r\n};\r\n\r\n/**\r\n * Lighten a hex color\r\n */\r\nexport const lightenColor = (hex, amount) => {\r\n const num = parseInt(hex.replace(\"#\", \"\"), 16);\r\n const r = Math.min(255, (num >> 16) + Math.round(255 * amount));\r\n const g = Math.min(255, (num >> 8 & 0x00FF) + Math.round(255 * amount));\r\n const b = Math.min(255, (num & 0x0000FF) + Math.round(255 * amount));\r\n return rgbToHex(r, g, b);\r\n};\r\n\r\n/**\r\n * Darken a hex color\r\n */\r\nexport const darkenColor = (hex, amount) => {\r\n const num = parseInt(hex.replace(\"#\", \"\"), 16);\r\n const r = Math.max(0, (num >> 16) - Math.round(255 * amount));\r\n const g = Math.max(0, (num >> 8 & 0x00FF) - Math.round(255 * amount));\r\n const b = Math.max(0, (num & 0x0000FF) - Math.round(255 * amount));\r\n return rgbToHex(r, g, b);\r\n};\r\n\r\n/**\r\n * Generate accent color (simple complementary color)\r\n */\r\nconst generateAccentColor = (rgb) => {\r\n // Simple complementary color calculation\r\n const complementaryR = 255 - rgb.r;\r\n const complementaryG = 255 - rgb.g;\r\n const complementaryB = 255 - rgb.b;\r\n \r\n return rgbToHex(complementaryR, complementaryG, complementaryB);\r\n};\r\n\r\n/**\r\n * Check if a color is dark or light (for text contrast)\r\n */\r\nexport const isColorDark = (hex) => {\r\n const num = parseInt(hex.replace(\"#\", \"\"), 16);\r\n const r = (num >> 16);\r\n const g = (num >> 8 & 0x00FF);\r\n const b = (num & 0x0000FF);\r\n \r\n // Calculate luminance\r\n const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255;\r\n return luminance < 0.5;\r\n};\r\n\r\n/**\r\n * Calculate relative luminance according to WCAG 2.1\r\n * @param {string} hex - Hex color code\r\n * @returns {number} Relative luminance (0-1)\r\n */\r\nexport const getRelativeLuminance = (hex) => {\r\n const num = parseInt(hex.replace(\"#\", \"\"), 16);\r\n const r = (num >> 16) / 255;\r\n const g = (num >> 8 & 0x00FF) / 255;\r\n const b = (num & 0x0000FF) / 255;\r\n\r\n // Apply gamma correction\r\n const toLinear = (c) => {\r\n return c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);\r\n };\r\n\r\n const rLinear = toLinear(r);\r\n const gLinear = toLinear(g);\r\n const bLinear = toLinear(b);\r\n\r\n return 0.2126 * rLinear + 0.7152 * gLinear + 0.0722 * bLinear;\r\n};\r\n\r\n/**\r\n * Calculate contrast ratio between two colors according to WCAG 2.1\r\n * @param {string} color1 - First hex color\r\n * @param {string} color2 - Second hex color\r\n * @returns {number} Contrast ratio (1-21)\r\n */\r\nexport const getContrastRatio = (color1, color2) => {\r\n const luminance1 = getRelativeLuminance(color1);\r\n const luminance2 = getRelativeLuminance(color2);\r\n \r\n const lighter = Math.max(luminance1, luminance2);\r\n const darker = Math.min(luminance1, luminance2);\r\n \r\n return (lighter + 0.05) / (darker + 0.05);\r\n};\r\n\r\n/**\r\n * Get the best contrast text color for a given background\r\n * @param {string} backgroundColor - Background color in hex\r\n * @param {string} lightColor - Light text color (default: white)\r\n * @param {string} darkColor - Dark text color (default: black)\r\n * @returns {string} Best contrasting text color\r\n */\r\nexport const getBestContrastText = (backgroundColor, lightColor = '#ffffff', darkColor = '#000000') => {\r\n const lightContrast = getContrastRatio(backgroundColor, lightColor);\r\n const darkContrast = getContrastRatio(backgroundColor, darkColor);\r\n \r\n return lightContrast > darkContrast ? lightColor : darkColor;\r\n};\r\n\r\n/**\r\n * Check if color combination meets WCAG AA standard (4.5:1)\r\n * @param {string} backgroundColor - Background color\r\n * @param {string} textColor - Text color\r\n * @returns {boolean} Whether combination meets WCAG AA\r\n */\r\nexport const meetsWCAGAA = (backgroundColor, textColor) => {\r\n return getContrastRatio(backgroundColor, textColor) >= 4.5;\r\n};\r\n\r\n/**\r\n * Check if color combination meets WCAG AAA standard (7:1)\r\n * @param {string} backgroundColor - Background color\r\n * @param {string} textColor - Text color\r\n * @returns {boolean} Whether combination meets WCAG AAA\r\n */\r\nexport const meetsWCAGAAA = (backgroundColor, textColor) => {\r\n return getContrastRatio(backgroundColor, textColor) >= 7;\r\n};\r\n\r\n/**\r\n * Get accessible text color with fallback options\r\n * @param {string} backgroundColor - Background color\r\n * @param {Object} options - Options for text colors and standards\r\n * @returns {string} Accessible text color\r\n */\r\nexport const getAccessibleTextColor = (backgroundColor, options = {}) => {\r\n const {\r\n preferredLight = '#ffffff',\r\n preferredDark = '#000000',\r\n fallbackLight = '#f8fafc',\r\n fallbackDark = '#1e293b',\r\n standard = 'AA' // 'AA' or 'AAA'\r\n } = options;\r\n\r\n const requiredRatio = standard === 'AAA' ? 7 : 4.5;\r\n \r\n // Try preferred colors first\r\n if (getContrastRatio(backgroundColor, preferredLight) >= requiredRatio) {\r\n return preferredLight;\r\n }\r\n \r\n if (getContrastRatio(backgroundColor, preferredDark) >= requiredRatio) {\r\n return preferredDark;\r\n }\r\n \r\n // Try fallback colors\r\n if (getContrastRatio(backgroundColor, fallbackLight) >= requiredRatio) {\r\n return fallbackLight;\r\n }\r\n \r\n if (getContrastRatio(backgroundColor, fallbackDark) >= requiredRatio) {\r\n return fallbackDark;\r\n }\r\n \r\n // Last resort: return the color with better contrast\r\n return getBestContrastText(backgroundColor, preferredLight, preferredDark);\r\n};","import { getAccessibleTextColor, getContrastRatio, meetsWCAGAA } from './colorExtractor';\r\n\r\n/**\r\n * Enhanced theme contrast utilities for Material-UI components\r\n * Ensures all components meet WCAG accessibility standards\r\n */\r\n\r\n/**\r\n * Get enhanced button colors with proper contrast\r\n * @param {string} backgroundColor - Background color of the button\r\n * @param {string} mode - Theme mode ('light' or 'dark')\r\n * @returns {Object} Button color configuration\r\n */\r\nexport const getButtonContrastColors = (backgroundColor, mode = 'light') => {\r\n const textColor = getAccessibleTextColor(backgroundColor);\r\n const contrast = getContrastRatio(backgroundColor, textColor);\r\n \r\n return {\r\n color: textColor,\r\n backgroundColor,\r\n contrastRatio: contrast,\r\n isAccessible: meetsWCAGAA(backgroundColor, textColor),\r\n // Hover state with adjusted opacity\r\n '&:hover': {\r\n backgroundColor: mode === 'dark' ? \r\n `${backgroundColor}dd` : // Slightly transparent in dark mode\r\n `${backgroundColor}e6`, // Slightly transparent in light mode\r\n color: textColor\r\n }\r\n };\r\n};\r\n\r\n/**\r\n * Get enhanced chip colors with proper contrast\r\n * @param {string} backgroundColor - Background color of the chip\r\n * @param {string} variant - Chip variant ('filled', 'outlined')\r\n * @returns {Object} Chip color configuration\r\n */\r\nexport const getChipContrastColors = (backgroundColor, variant = 'filled') => {\r\n if (variant === 'outlined') {\r\n return {\r\n borderColor: backgroundColor,\r\n color: backgroundColor,\r\n '&:hover': {\r\n backgroundColor: `${backgroundColor}20`,\r\n color: backgroundColor\r\n }\r\n };\r\n }\r\n \r\n const textColor = getAccessibleTextColor(backgroundColor);\r\n return {\r\n backgroundColor,\r\n color: textColor,\r\n '&:hover': {\r\n backgroundColor: `${backgroundColor}dd`,\r\n color: textColor\r\n }\r\n };\r\n};\r\n\r\n/**\r\n * Get enhanced card colors with proper contrast\r\n * @param {string} backgroundColor - Background color of the card\r\n * @param {boolean} isDarkMode - Whether dark mode is active\r\n * @returns {Object} Card styling with proper text contrast\r\n */\r\nexport const getCardContrastColors = (backgroundColor, isDarkMode = false) => {\r\n const textColor = getAccessibleTextColor(backgroundColor, {\r\n preferredLight: isDarkMode ? '#f8fafc' : '#ffffff',\r\n preferredDark: isDarkMode ? '#1e293b' : '#000000',\r\n fallbackLight: isDarkMode ? '#e2e8f0' : '#f8fafc',\r\n fallbackDark: isDarkMode ? '#334155' : '#1e293b'\r\n });\r\n \r\n return {\r\n backgroundColor,\r\n color: textColor,\r\n '& .MuiTypography-root': {\r\n color: textColor\r\n },\r\n '& .MuiTypography-body2': {\r\n color: `${textColor}cc` // Slightly transparent for secondary text\r\n },\r\n '& .MuiTypography-caption': {\r\n color: `${textColor}99` // More transparent for caption text\r\n }\r\n };\r\n};\r\n\r\n/**\r\n * Get enhanced gradient text color for complex backgrounds\r\n * @param {Array} gradientColors - Array of hex colors in the gradient\r\n * @param {Object} options - Text color options\r\n * @returns {string} Best contrast text color for gradient\r\n */\r\nexport const getGradientContrastColor = (gradientColors, options = {}) => {\r\n // Calculate contrast for each color and pick the best overall option\r\n const contrasts = gradientColors.map(color => {\r\n const lightContrast = getContrastRatio(color, '#ffffff');\r\n const darkContrast = getContrastRatio(color, '#000000');\r\n return { color, lightContrast, darkContrast };\r\n });\r\n \r\n // Use the color that provides the minimum acceptable contrast across all gradient colors\r\n const minLightContrast = Math.min(...contrasts.map(c => c.lightContrast));\r\n const minDarkContrast = Math.min(...contrasts.map(c => c.darkContrast));\r\n \r\n if (minLightContrast >= 4.5) {\r\n return options.preferredLight || '#ffffff';\r\n } else if (minDarkContrast >= 4.5) {\r\n return options.preferredDark || '#000000';\r\n } else {\r\n // If neither meets standards, use the better of the two\r\n return minLightContrast > minDarkContrast ? \r\n (options.preferredLight || '#ffffff') : \r\n (options.preferredDark || '#000000');\r\n }\r\n};\r\n\r\n/**\r\n * Get enhanced status colors with proper contrast\r\n * @param {string} status - Status type ('success', 'warning', 'error', 'info')\r\n * @param {string} variant - Color variant ('main', 'light', 'dark')\r\n * @param {Object} theme - MUI theme object\r\n * @returns {Object} Status styling with proper contrast\r\n */\r\nexport const getStatusContrastColors = (status, variant = 'main', theme) => {\r\n const backgroundColor = theme.palette[status][variant];\r\n const textColor = getAccessibleTextColor(backgroundColor);\r\n \r\n return {\r\n backgroundColor,\r\n color: textColor,\r\n borderColor: backgroundColor,\r\n '&:hover': {\r\n backgroundColor: theme.palette[status].dark,\r\n color: getAccessibleTextColor(theme.palette[status].dark)\r\n }\r\n };\r\n};\r\n\r\n/**\r\n * Create enhanced theme component overrides with better contrast\r\n * @param {Object} theme - Base MUI theme\r\n * @returns {Object} Component overrides with enhanced contrast\r\n */\r\nexport const createContrastEnhancedComponents = (theme) => {\r\n const isDark = theme.palette.mode === 'dark';\r\n \r\n return {\r\n // Enhanced Button components\r\n MuiButton: {\r\n styleOverrides: {\r\n containedPrimary: getButtonContrastColors(theme.palette.primary.main, theme.palette.mode),\r\n containedSecondary: getButtonContrastColors(theme.palette.secondary.main, theme.palette.mode),\r\n containedSuccess: getButtonContrastColors(theme.palette.success.main, theme.palette.mode),\r\n containedWarning: getButtonContrastColors(theme.palette.warning.main, theme.palette.mode),\r\n containedError: getButtonContrastColors(theme.palette.error.main, theme.palette.mode),\r\n }\r\n },\r\n \r\n // Enhanced Chip components\r\n MuiChip: {\r\n styleOverrides: {\r\n filledPrimary: getChipContrastColors(theme.palette.primary.main),\r\n filledSecondary: getChipContrastColors(theme.palette.secondary.main),\r\n filledSuccess: getChipContrastColors(theme.palette.success.main),\r\n filledWarning: getChipContrastColors(theme.palette.warning.main),\r\n filledError: getChipContrastColors(theme.palette.error.main),\r\n }\r\n },\r\n \r\n // Enhanced Alert components\r\n MuiAlert: {\r\n styleOverrides: {\r\n filledSuccess: getStatusContrastColors('success', 'main', theme),\r\n filledWarning: getStatusContrastColors('warning', 'main', theme),\r\n filledError: getStatusContrastColors('error', 'main', theme),\r\n filledInfo: getStatusContrastColors('info', 'main', theme),\r\n }\r\n },\r\n \r\n // Enhanced Badge components\r\n MuiBadge: {\r\n styleOverrides: {\r\n colorPrimary: {\r\n backgroundColor: theme.palette.primary.main,\r\n color: getAccessibleTextColor(theme.palette.primary.main)\r\n },\r\n colorSecondary: {\r\n backgroundColor: theme.palette.secondary.main,\r\n color: getAccessibleTextColor(theme.palette.secondary.main)\r\n },\r\n colorError: {\r\n backgroundColor: theme.palette.error.main,\r\n color: getAccessibleTextColor(theme.palette.error.main)\r\n }\r\n }\r\n },\r\n \r\n // Enhanced Avatar components\r\n MuiAvatar: {\r\n styleOverrides: {\r\n colorDefault: {\r\n backgroundColor: theme.palette.primary.main,\r\n color: getAccessibleTextColor(theme.palette.primary.main)\r\n }\r\n }\r\n },\r\n \r\n // Enhanced Fab components\r\n MuiFab: {\r\n styleOverrides: {\r\n primary: getButtonContrastColors(theme.palette.primary.main, theme.palette.mode),\r\n secondary: getButtonContrastColors(theme.palette.secondary.main, theme.palette.mode),\r\n }\r\n }\r\n };\r\n};\r\n\r\n/**\r\n * Validate theme colors for accessibility compliance\r\n * @param {Object} theme - MUI theme object\r\n * @returns {Object} Accessibility report\r\n */\r\nexport const validateThemeAccessibility = (theme) => {\r\n const report = {\r\n compliant: true,\r\n issues: [],\r\n recommendations: []\r\n };\r\n \r\n // Check primary colors\r\n const primaryContrast = getContrastRatio(theme.palette.primary.main, theme.palette.primary.contrastText);\r\n if (!meetsWCAGAA(theme.palette.primary.main, theme.palette.primary.contrastText)) {\r\n report.compliant = false;\r\n report.issues.push({\r\n component: 'Primary color',\r\n current: `${primaryContrast.toFixed(1)}:1`,\r\n required: '4.5:1',\r\n recommendation: `Use ${getAccessibleTextColor(theme.palette.primary.main)} as contrast text`\r\n });\r\n }\r\n \r\n // Check secondary colors\r\n const secondaryContrast = getContrastRatio(theme.palette.secondary.main, theme.palette.secondary.contrastText);\r\n if (!meetsWCAGAA(theme.palette.secondary.main, theme.palette.secondary.contrastText)) {\r\n report.compliant = false;\r\n report.issues.push({\r\n component: 'Secondary color',\r\n current: `${secondaryContrast.toFixed(1)}:1`,\r\n required: '4.5:1',\r\n recommendation: `Use ${getAccessibleTextColor(theme.palette.secondary.main)} as contrast text`\r\n });\r\n }\r\n \r\n return report;\r\n};","import React from 'react';\r\nimport { Box } from '@mui/material';\r\nimport { useCustomTheme } from '../../contexts/ThemeContext';\r\n\r\nconst PageLayout = ({ children, maxWidth = \"1400px\", padding = { xs: 2, sm: 3, md: 4 } }) => {\r\n const { isDarkMode } = useCustomTheme();\r\n\r\n return (\r\n <Box\r\n sx={{\r\n minHeight: 'calc(100vh - 64px)', // Account for navbar height\r\n background: isDarkMode \r\n ? 'linear-gradient(135deg, rgba(59, 130, 246, 0.03) 0%, rgba(139, 92, 246, 0.03) 100%)'\r\n : 'linear-gradient(135deg, rgba(37, 99, 235, 0.02) 0%, rgba(124, 58, 237, 0.02) 100%)',\r\n p: padding\r\n }}\r\n >\r\n <Box\r\n sx={{\r\n maxWidth: maxWidth,\r\n margin: '0 auto',\r\n width: '100%'\r\n }}\r\n >\r\n {children}\r\n </Box>\r\n </Box>\r\n );\r\n};\r\n\r\nexport default PageLayout;","import React from 'react';\r\nimport {\r\n Box,\r\n Typography,\r\n Stack,\r\n Breadcrumbs,\r\n Link,\r\n useMediaQuery,\r\n useTheme\r\n} from '@mui/material';\r\nimport { useNavigate, useLocation } from 'react-router-dom';\r\nimport { useCustomTheme } from '../../contexts/ThemeContext';\r\n\r\nconst PageHeader = ({\r\n title,\r\n subtitle,\r\n children, // Action buttons go here\r\n breadcrumbs = [],\r\n marginBottom = { xs: 3, sm: 4, md: 6 }\r\n}) => {\r\n const navigate = useNavigate();\r\n const location = useLocation();\r\n const theme = useTheme();\r\n const { isDarkMode } = useCustomTheme();\r\n const isMobile = useMediaQuery(theme.breakpoints.down('sm'));\r\n\r\n const handleBreadcrumbClick = (path) => {\r\n if (path) {\r\n navigate(path);\r\n }\r\n };\r\n\r\n return (\r\n <Box sx={{ mb: marginBottom }}>\r\n {/* Breadcrumbs */}\r\n {breadcrumbs.length > 0 && (\r\n <Breadcrumbs\r\n aria-label=\"breadcrumb\"\r\n sx={{ \r\n mb: 2,\r\n '& .MuiBreadcrumbs-separator': {\r\n color: 'text.secondary',\r\n opacity: 0.6\r\n }\r\n }}\r\n >\r\n {breadcrumbs.map((breadcrumb, index) => {\r\n const isLast = index === breadcrumbs.length - 1;\r\n return isLast ? (\r\n <Typography\r\n key={breadcrumb.label}\r\n component=\"span\"\r\n color=\"text.primary\"\r\n sx={{ \r\n fontWeight: 500,\r\n fontSize: '0.875rem'\r\n }}\r\n >\r\n {breadcrumb.label}\r\n </Typography>\r\n ) : (\r\n <Link\r\n key={breadcrumb.label}\r\n color=\"inherit\"\r\n href=\"#\"\r\n onClick={(e) => {\r\n e.preventDefault();\r\n handleBreadcrumbClick(breadcrumb.path);\r\n }}\r\n sx={{ \r\n textDecoration: 'none',\r\n fontSize: '0.875rem',\r\n fontWeight: 400,\r\n '&:hover': {\r\n textDecoration: 'underline',\r\n color: 'primary.main'\r\n }\r\n }}\r\n >\r\n {breadcrumb.label}\r\n </Link>\r\n );\r\n })}\r\n </Breadcrumbs>\r\n )}\r\n\r\n {/* Header Content */}\r\n <Box\r\n display=\"flex\"\r\n justifyContent=\"space-between\"\r\n alignItems={isMobile ? 'flex-start' : 'center'}\r\n flexDirection={isMobile ? 'column' : 'row'}\r\n gap={isMobile ? 2 : 0}\r\n >\r\n {/* Title and Subtitle */}\r\n <Box sx={{ flex: 1 }}>\r\n <Typography\r\n variant=\"h2\"\r\n component=\"h1\"\r\n data-testid=\"dashboard-title\"\r\n sx={{\r\n fontWeight: 800,\r\n background: isDarkMode\r\n ? 'linear-gradient(135deg, #60a5fa 0%, #a78bfa 100%)'\r\n : 'linear-gradient(135deg, #2563eb 0%, #7c3aed 100%)',\r\n WebkitBackgroundClip: 'text',\r\n WebkitTextFillColor: 'transparent',\r\n backgroundClip: 'text',\r\n fontSize: {\r\n xs: '1.75rem',\r\n sm: '2.25rem',\r\n md: '2.5rem'\r\n },\r\n lineHeight: 1.2,\r\n mb: subtitle ? 0.5 : 0\r\n }}\r\n >\r\n {title}\r\n </Typography>\r\n \r\n {subtitle && (\r\n <Typography\r\n variant=\"body1\"\r\n color=\"text.secondary\"\r\n sx={{\r\n fontSize: {\r\n xs: '0.875rem',\r\n sm: '1rem'\r\n },\r\n fontWeight: 400,\r\n maxWidth: '600px'\r\n }}\r\n >\r\n {subtitle}\r\n </Typography>\r\n )}\r\n </Box>\r\n\r\n {/* Action Buttons */}\r\n {children && (\r\n <Box\r\n sx={{\r\n flexShrink: 0,\r\n width: isMobile ? '100%' : 'auto'\r\n }}\r\n >\r\n <Stack\r\n direction={isMobile ? 'column' : 'row'}\r\n spacing={1.5}\r\n sx={{\r\n '& > *': {\r\n minWidth: isMobile ? '100%' : 'auto'\r\n }\r\n }}\r\n >\r\n {children}\r\n </Stack>\r\n </Box>\r\n )}\r\n </Box>\r\n </Box>\r\n );\r\n};\r\n\r\nexport default PageHeader;","import React from 'react';\r\nimport {\r\n Container,\r\n Box,\r\n Paper,\r\n Typography,\r\n Stack\r\n} from '@mui/material';\r\nimport { useCustomTheme } from '../../contexts/ThemeContext';\r\n\r\nconst AuthLayout = ({ \r\n children, \r\n title, \r\n subtitle,\r\n maxWidth = \"sm\",\r\n showLogo = true\r\n}) => {\r\n const { isDarkMode } = useCustomTheme();\r\n\r\n return (\r\n <Box\r\n sx={{\r\n minHeight: '100vh',\r\n display: 'flex',\r\n alignItems: 'center',\r\n background: isDarkMode\r\n ? 'linear-gradient(135deg, rgba(59, 130, 246, 0.08) 0%, rgba(139, 92, 246, 0.08) 100%)'\r\n : 'linear-gradient(135deg, rgba(37, 99, 235, 0.05) 0%, rgba(124, 58, 237, 0.05) 100%)',\r\n py: { xs: 2, sm: 4 }\r\n }}\r\n >\r\n <Container maxWidth={maxWidth}>\r\n <Box\r\n display=\"flex\"\r\n flexDirection=\"column\"\r\n alignItems=\"center\"\r\n px={{ xs: 1, sm: 0 }}\r\n >\r\n {/* Logo/Brand Section */}\r\n {showLogo && (\r\n <Box sx={{ mb: 4, textAlign: 'center' }}>\r\n <Typography\r\n variant=\"h4\"\r\n component=\"h1\"\r\n sx={{\r\n fontWeight: 800,\r\n background: isDarkMode\r\n ? 'linear-gradient(135deg, #60a5fa 0%, #a78bfa 100%)'\r\n : 'linear-gradient(135deg, #2563eb 0%, #7c3aed 100%)',\r\n WebkitBackgroundClip: 'text',\r\n WebkitTextFillColor: 'transparent',\r\n backgroundClip: 'text',\r\n mb: 1\r\n }}\r\n >\r\n PropertyManager AI\r\n </Typography>\r\n <Typography\r\n variant=\"body2\"\r\n color=\"text.secondary\"\r\n sx={{ fontWeight: 500 }}\r\n >\r\n Intelligent Property Management Solutions\r\n </Typography>\r\n </Box>\r\n )}\r\n\r\n <Paper\r\n elevation={6}\r\n sx={{\r\n p: { xs: 3, sm: 4, md: 5 },\r\n width: '100%',\r\n maxWidth: 480,\r\n borderRadius: 3,\r\n background: isDarkMode\r\n ? 'rgba(17, 25, 40, 0.95)'\r\n : 'rgba(255, 255, 255, 0.95)',\r\n backdropFilter: 'blur(10px)',\r\n border: isDarkMode\r\n ? '1px solid rgba(59, 130, 246, 0.1)'\r\n : '1px solid rgba(37, 99, 235, 0.1)',\r\n boxShadow: isDarkMode\r\n ? '0 20px 25px -5px rgba(0, 0, 0, 0.4), 0 10px 10px -5px rgba(0, 0, 0, 0.2)'\r\n : '0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)'\r\n }}\r\n >\r\n {/* Form Header */}\r\n {(title || subtitle) && (\r\n <Box sx={{ mb: 3, textAlign: 'center' }}>\r\n {title && (\r\n <Typography\r\n variant=\"h5\"\r\n component=\"h2\"\r\n sx={{\r\n fontWeight: 700,\r\n mb: subtitle ? 1 : 0,\r\n color: 'text.primary'\r\n }}\r\n >\r\n {title}\r\n </Typography>\r\n )}\r\n {subtitle && (\r\n <Typography\r\n variant=\"body2\"\r\n color=\"text.secondary\"\r\n sx={{ fontWeight: 400 }}\r\n >\r\n {subtitle}\r\n </Typography>\r\n )}\r\n </Box>\r\n )}\r\n\r\n {/* Form Content */}\r\n {children}\r\n </Paper>\r\n </Box>\r\n </Container>\r\n </Box>\r\n );\r\n};\r\n\r\nexport default AuthLayout;","import React from 'react';\r\nimport { Box, CircularProgress, Typography, Stack } from '@mui/material';\r\nimport { TenantThemeProvider, useTenantTheme } from '../../contexts/TenantThemeContext';\r\n\r\n// Loading component that uses the theme context\r\nconst TenantContent = ({ children }) => {\r\n const { isThemeLoading } = useTenantTheme();\r\n\r\n if (isThemeLoading) {\r\n return (\r\n <Box\r\n sx={{\r\n minHeight: '100vh',\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n backgroundColor: 'background.default'\r\n }}\r\n >\r\n <Stack \r\n spacing={3} \r\n alignItems=\"center\"\r\n sx={{\r\n textAlign: 'center'\r\n }}\r\n >\r\n <CircularProgress \r\n size={60}\r\n thickness={4}\r\n sx={{\r\n color: 'primary.main',\r\n '& .MuiCircularProgress-circle': {\r\n strokeLinecap: 'round',\r\n },\r\n }}\r\n />\r\n <Typography \r\n variant=\"h6\" \r\n color=\"text.secondary\"\r\n sx={{ \r\n fontWeight: 500,\r\n letterSpacing: 0.5\r\n }}\r\n >\r\n Loading your personalized experience...\r\n </Typography>\r\n </Stack>\r\n </Box>\r\n );\r\n }\r\n\r\n return (\r\n <Box\r\n sx={{\r\n minHeight: '100vh',\r\n backgroundColor: 'background.default',\r\n transition: 'all 0.3s ease-in-out'\r\n }}\r\n >\r\n {children}\r\n </Box>\r\n );\r\n};\r\n\r\nconst TenantLayout = ({ children }) => {\r\n return (\r\n <TenantThemeProvider>\r\n <TenantContent>\r\n {children}\r\n </TenantContent>\r\n </TenantThemeProvider>\r\n );\r\n};\r\n\r\nexport default TenantLayout;","import React, { createContext, useContext, useState, useEffect } from 'react';\r\nimport { createTheme, ThemeProvider } from '@mui/material/styles';\r\nimport { extractColorsFromImage, getAccessibleTextColor } from '../utils/colorExtractor';\r\nimport api from '../services/api';\r\n\r\nconst TenantThemeContext = createContext();\r\n\r\nexport const useTenantTheme = () => {\r\n const context = useContext(TenantThemeContext);\r\n if (!context) {\r\n throw new Error('useTenantTheme must be used within a TenantThemeProvider');\r\n }\r\n return context;\r\n};\r\n\r\nexport const TenantThemeProvider = ({ children }) => {\r\n const [brandingColors, setBrandingColors] = useState(null);\r\n const [theme, setTheme] = useState(createDefaultTheme());\r\n const [isThemeLoading, setIsThemeLoading] = useState(true);\r\n const [darkMode, setDarkMode] = useState(() => {\r\n // Load dark mode preference from localStorage\r\n const saved = localStorage.getItem('tenantDarkMode');\r\n return saved === 'true';\r\n });\r\n\r\n // Create default theme\r\n function createDefaultTheme(isDark = false) {\r\n return createTheme({\r\n palette: {\r\n mode: isDark ? 'dark' : 'light',\r\n primary: {\r\n main: '#1976d2',\r\n light: '#42a5f5',\r\n dark: '#1565c0',\r\n },\r\n secondary: {\r\n main: '#9c27b0',\r\n },\r\n },\r\n });\r\n }\r\n\r\n // Create theme with branding colors\r\n const createBrandedTheme = (colorScheme, selectedColorIndex = 0, isDark = false) => {\r\n if (!colorScheme?.topColors?.[selectedColorIndex]) {\r\n return createDefaultTheme(isDark);\r\n }\r\n\r\n const selectedColor = colorScheme.topColors[selectedColorIndex];\r\n const primaryHex = selectedColor.hex;\r\n\r\n // Generate lighter and darker variations\r\n const lightenColor = (hex, amount) => {\r\n const num = parseInt(hex.replace(\"#\", \"\"), 16);\r\n const r = Math.min(255, (num >> 16) + Math.round(255 * amount));\r\n const g = Math.min(255, (num >> 8 & 0x00FF) + Math.round(255 * amount));\r\n const b = Math.min(255, (num & 0x0000FF) + Math.round(255 * amount));\r\n return `#${((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1)}`;\r\n };\r\n\r\n const darkenColor = (hex, amount) => {\r\n const num = parseInt(hex.replace(\"#\", \"\"), 16);\r\n const r = Math.max(0, (num >> 16) - Math.round(255 * amount));\r\n const g = Math.max(0, (num >> 8 & 0x00FF) - Math.round(255 * amount));\r\n const b = Math.max(0, (num & 0x0000FF) - Math.round(255 * amount));\r\n return `#${((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1)}`;\r\n };\r\n\r\n const lightVariant = lightenColor(primaryHex, 0.2);\r\n const darkVariant = darkenColor(primaryHex, 0.2);\r\n\r\n // Get secondary color from available colors or generate one\r\n const secondaryColor = colorScheme.topColors[1]?.hex || colorScheme.accentHex || '#9c27b0';\r\n\r\n return createTheme({\r\n palette: {\r\n mode: isDark ? 'dark' : 'light',\r\n primary: {\r\n main: primaryHex,\r\n light: lightVariant,\r\n dark: darkVariant,\r\n contrastText: getAccessibleTextColor(primaryHex),\r\n },\r\n secondary: {\r\n main: secondaryColor,\r\n },\r\n },\r\n components: {\r\n // Customize button styles\r\n MuiButton: {\r\n styleOverrides: {\r\n root: {\r\n borderRadius: '8px',\r\n textTransform: 'none',\r\n fontWeight: 500,\r\n },\r\n contained: {\r\n boxShadow: `0 2px 8px ${primaryHex}40`,\r\n '&:hover': {\r\n boxShadow: `0 4px 12px ${primaryHex}60`,\r\n },\r\n },\r\n },\r\n },\r\n // Customize fab styles\r\n MuiFab: {\r\n styleOverrides: {\r\n root: {\r\n boxShadow: `0 4px 12px ${primaryHex}40`,\r\n '&:hover': {\r\n boxShadow: `0 6px 16px ${primaryHex}60`,\r\n },\r\n },\r\n },\r\n },\r\n // Customize chip styles\r\n MuiChip: {\r\n styleOverrides: {\r\n root: {\r\n borderRadius: '6px',\r\n },\r\n colorPrimary: {\r\n backgroundColor: primaryHex,\r\n color: getAccessibleTextColor(primaryHex),\r\n },\r\n },\r\n },\r\n // Customize icon button styles\r\n MuiIconButton: {\r\n styleOverrides: {\r\n colorPrimary: {\r\n color: primaryHex,\r\n '&:hover': {\r\n backgroundColor: `${primaryHex}20`,\r\n },\r\n },\r\n },\r\n },\r\n // Customize progress indicators\r\n MuiLinearProgress: {\r\n styleOverrides: {\r\n colorPrimary: {\r\n backgroundColor: `${primaryHex}30`,\r\n '& .MuiLinearProgress-bar': {\r\n backgroundColor: primaryHex,\r\n },\r\n },\r\n },\r\n },\r\n MuiCircularProgress: {\r\n styleOverrides: {\r\n colorPrimary: {\r\n color: primaryHex,\r\n },\r\n },\r\n },\r\n // Customize tabs\r\n MuiTab: {\r\n styleOverrides: {\r\n root: {\r\n textTransform: 'none',\r\n fontWeight: 500,\r\n '&.Mui-selected': {\r\n color: primaryHex,\r\n },\r\n },\r\n },\r\n },\r\n MuiTabs: {\r\n styleOverrides: {\r\n indicator: {\r\n backgroundColor: primaryHex,\r\n },\r\n },\r\n },\r\n },\r\n });\r\n };\r\n\r\n // Fetch company data and create branded theme\r\n const initializeBrandedTheme = async () => {\r\n try {\r\n // Get company data from tenant portal API\r\n const response = await api.get('/tenant-portal/company-info');\r\n const company = response.data;\r\n \r\n // Optimization: Check if custom branding is needed before processing\r\n if (!company.companyLogo && !company.preferredBrandingColor) {\r\n // No custom branding, use default theme\r\n setBrandingColors({\r\n colorScheme: null,\r\n selectedColor: null,\r\n hasCustomBranding: false\r\n });\r\n setIsThemeLoading(false);\r\n return;\r\n }\r\n\r\n if (company.companyLogo) {\r\n const logoUrl = `${api.defaults.baseURL.replace('/api', '')}/uploads/logos/${company.companyLogo}`;\r\n const colorScheme = await extractColorsFromImage(logoUrl);\r\n \r\n setBrandingColors({\r\n colorScheme,\r\n selectedIndex: company.preferredBrandingColor || 0,\r\n company\r\n });\r\n \r\n // Create and apply the branded theme\r\n const brandedTheme = createBrandedTheme(colorScheme, company.preferredBrandingColor || 0, darkMode);\r\n setTheme(brandedTheme);\r\n } else {\r\n // No custom branding, use default theme\r\n setTheme(createDefaultTheme(darkMode));\r\n }\r\n } catch (error) {\r\n console.warn('[TENANT THEME] Could not initialize branded theme:', error);\r\n // Keep default theme on error\r\n setTheme(createDefaultTheme(darkMode));\r\n } finally {\r\n // Theme initialization complete\r\n setIsThemeLoading(false);\r\n }\r\n };\r\n\r\n // Toggle dark mode\r\n const toggleDarkMode = () => {\r\n const newDarkMode = !darkMode;\r\n setDarkMode(newDarkMode);\r\n localStorage.setItem('tenantDarkMode', newDarkMode.toString());\r\n\r\n // Re-create theme with new mode\r\n if (brandingColors?.colorScheme) {\r\n const brandedTheme = createBrandedTheme(\r\n brandingColors.colorScheme,\r\n brandingColors.selectedIndex || 0,\r\n newDarkMode\r\n );\r\n setTheme(brandedTheme);\r\n } else {\r\n setTheme(createDefaultTheme(newDarkMode));\r\n }\r\n };\r\n\r\n // Initialize theme when component mounts\r\n useEffect(() => {\r\n const token = localStorage.getItem('tenantToken');\r\n const tenantData = localStorage.getItem('tenantData');\r\n \r\n // Only initialize theme if we have both token and tenant data\r\n if (token && tenantData) {\r\n try {\r\n api.defaults.headers.common['Authorization'] = `Bearer ${token}`;\r\n initializeBrandedTheme();\r\n } catch (error) {\r\n console.warn('[TENANT THEME] Could not initialize theme:', error);\r\n setIsThemeLoading(false);\r\n }\r\n } else {\r\n // No tenant authentication, stop loading immediately\r\n setIsThemeLoading(false);\r\n }\r\n }, []);\r\n\r\n // Re-apply theme when dark mode changes\r\n useEffect(() => {\r\n if (!isThemeLoading) {\r\n if (brandingColors?.colorScheme) {\r\n const brandedTheme = createBrandedTheme(\r\n brandingColors.colorScheme,\r\n brandingColors.selectedIndex || 0,\r\n darkMode\r\n );\r\n setTheme(brandedTheme);\r\n } else {\r\n setTheme(createDefaultTheme(darkMode));\r\n }\r\n }\r\n }, [darkMode]);\r\n\r\n const contextValue = {\r\n theme,\r\n brandingColors,\r\n initializeBrandedTheme,\r\n isThemeLoading,\r\n darkMode,\r\n toggleDarkMode,\r\n };\r\n\r\n return (\r\n <TenantThemeContext.Provider value={contextValue}>\r\n <ThemeProvider theme={theme}>\r\n {children}\r\n </ThemeProvider>\r\n </TenantThemeContext.Provider>\r\n );\r\n};\r\n\r\nexport default TenantThemeProvider;","import React from 'react';\r\nimport { Box, CircularProgress, Typography } from '@mui/material';\r\n\r\nconst LoadingSpinner = ({ message = 'Loading...' }) => {\r\n return (\r\n <Box\r\n display=\"flex\"\r\n flexDirection=\"column\"\r\n justifyContent=\"center\"\r\n alignItems=\"center\"\r\n minHeight=\"100vh\"\r\n gap={3}\r\n sx={{\r\n background: 'linear-gradient(135deg, rgba(37, 99, 235, 0.02) 0%, rgba(124, 58, 237, 0.02) 100%)'\r\n }}\r\n >\r\n <Box\r\n sx={{\r\n position: 'relative',\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center'\r\n }}\r\n >\r\n <CircularProgress \r\n size={60} \r\n thickness={3}\r\n sx={{\r\n color: 'primary.main'\r\n }}\r\n />\r\n </Box>\r\n <Typography \r\n variant=\"h6\" \r\n sx={{\r\n color: 'text.primary',\r\n fontWeight: 500,\r\n textAlign: 'center'\r\n }}\r\n >\r\n {message}\r\n </Typography>\r\n </Box>\r\n );\r\n};\r\n\r\nexport default LoadingSpinner;","import React from 'react';\r\nimport { Card, CardContent, Box, useTheme } from '@mui/material';\r\nimport { useCustomTheme } from '../../contexts/ThemeContext';\r\n\r\nconst ModernCard = ({ \r\n children, \r\n hover = true, \r\n gradient = false, \r\n sx = {},\r\n elevation = 1,\r\n ...props \r\n}) => {\r\n const theme = useTheme();\r\n const { isDarkMode } = useCustomTheme();\r\n\r\n const baseStyles = {\r\n borderRadius: '20px',\r\n border: isDarkMode ? '1px solid rgba(255, 255, 255, 0.1)' : '1px solid rgba(0, 0, 0, 0.08)',\r\n background: gradient \r\n ? isDarkMode\r\n ? 'linear-gradient(135deg, #1e293b 0%, #334155 100%)'\r\n : 'linear-gradient(135deg, #ffffff 0%, #f8fafc 100%)'\r\n : isDarkMode \r\n ? '#1e293b' \r\n : '#ffffff',\r\n boxShadow: isDarkMode\r\n ? '0 4px 6px -1px rgba(0, 0, 0, 0.3), 0 2px 4px -2px rgba(0, 0, 0, 0.3)'\r\n : '0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px -1px rgba(0, 0, 0, 0.1)',\r\n transition: 'all 0.2s cubic-bezier(0.4, 0, 0.2, 1)',\r\n ...(hover && {\r\n '&:hover': {\r\n transform: 'translateY(-4px)',\r\n boxShadow: isDarkMode\r\n ? '0 20px 25px -5px rgba(0, 0, 0, 0.4), 0 8px 10px -6px rgba(0, 0, 0, 0.4)'\r\n : '0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.1)',\r\n borderColor: isDarkMode ? 'rgba(255, 255, 255, 0.2)' : 'rgba(37, 99, 235, 0.2)'\r\n }\r\n }),\r\n ...sx\r\n };\r\n\r\n return (\r\n <Card \r\n elevation={0}\r\n sx={baseStyles}\r\n {...props}\r\n >\r\n {children}\r\n </Card>\r\n );\r\n};\r\n\r\nconst ModernCardContent = ({ children, sx = {}, ...props }) => {\r\n return (\r\n <CardContent \r\n sx={{\r\n padding: '24px',\r\n '&:last-child': {\r\n paddingBottom: '24px'\r\n },\r\n ...sx\r\n }}\r\n {...props}\r\n >\r\n {children}\r\n </CardContent>\r\n );\r\n};\r\n\r\nModernCard.Content = ModernCardContent;\r\n\r\nexport default ModernCard;","import React from 'react';\r\nimport {\r\n Box,\r\n Snackbar,\r\n Alert,\r\n AlertTitle,\r\n IconButton,\r\n Button,\r\n LinearProgress,\r\n Typography,\r\n Slide,\r\n Fade,\r\n Stack,\r\n Paper,\r\n Chip\r\n} from '@mui/material';\r\nimport {\r\n Close,\r\n CheckCircle,\r\n Error,\r\n Warning,\r\n Info,\r\n CloudUpload,\r\n Refresh\r\n} from '@mui/icons-material';\r\nimport { useNotification } from '../../contexts/NotificationContext';\r\nimport { format } from 'date-fns';\r\n\r\nconst NotificationItem = ({ notification, onClose, onAction }) => {\r\n if (!notification) {\r\n return null;\r\n }\r\n\r\n const getSeverityIcon = (type) => {\r\n const icons = {\r\n success: <CheckCircle />,\r\n error: <Error />,\r\n warning: <Warning />,\r\n info: <Info />\r\n };\r\n return icons[type] || <Info />;\r\n };\r\n\r\n const handleActionClick = (action) => {\r\n if (action && action.onClick) {\r\n action.onClick();\r\n }\r\n if (action && action.closeAfter !== false && onClose) {\r\n onClose();\r\n }\r\n };\r\n\r\n const safeOnClose = () => {\r\n if (onClose) {\r\n onClose();\r\n }\r\n };\r\n\r\n return (\r\n <Alert\r\n severity={notification.type}\r\n icon={getSeverityIcon(notification.type)}\r\n action={\r\n <Box display=\"flex\" alignItems=\"center\" gap={1}>\r\n {/* Custom action buttons */}\r\n {notification.actions?.map((action, index) => (\r\n <Button\r\n key={index}\r\n size=\"small\"\r\n variant={action.variant || 'text'}\r\n color={action.color || 'inherit'}\r\n startIcon={action.icon}\r\n onClick={() => handleActionClick(action)}\r\n sx={{ \r\n minWidth: 'auto',\r\n fontSize: '0.75rem',\r\n px: 1\r\n }}\r\n >\r\n {action.label}\r\n </Button>\r\n ))}\r\n \r\n {/* Progress indicator */}\r\n {typeof notification.progress === 'number' && (\r\n <Box sx={{ minWidth: 120 }}>\r\n <LinearProgress \r\n variant=\"determinate\" \r\n value={notification.progress}\r\n sx={{ height: 6, borderRadius: 3 }}\r\n />\r\n <Typography variant=\"caption\" sx={{ fontSize: '0.7rem' }}>\r\n {Math.round(notification.progress)}%\r\n </Typography>\r\n </Box>\r\n )}\r\n \r\n {/* Timestamp */}\r\n {notification.timestamp && (\r\n <Chip\r\n label={(() => {\r\n try {\r\n return format(new Date(notification.timestamp), 'HH:mm:ss');\r\n } catch (e) {\r\n return new Date().toLocaleTimeString();\r\n }\r\n })()}\r\n size=\"small\"\r\n variant=\"outlined\"\r\n sx={{ \r\n height: 20,\r\n fontSize: '0.65rem',\r\n opacity: 0.7\r\n }}\r\n />\r\n )}\r\n\r\n {/* Close button */}\r\n {notification.dismissible && (\r\n <IconButton\r\n size=\"small\"\r\n onClick={safeOnClose}\r\n sx={{ ml: 1 }}\r\n >\r\n <Close fontSize=\"small\" />\r\n </IconButton>\r\n )}\r\n </Box>\r\n }\r\n sx={{\r\n mb: 1,\r\n alignItems: 'flex-start',\r\n '& .MuiAlert-message': {\r\n width: '100%'\r\n }\r\n }}\r\n >\r\n {notification.title && (\r\n <AlertTitle sx={{ fontSize: '0.875rem', mb: 0.5 }}>\r\n {notification.title}\r\n </AlertTitle>\r\n )}\r\n <Typography variant=\"body2\" sx={{ fontSize: '0.8rem' }}>\r\n {notification.message}\r\n </Typography>\r\n </Alert>\r\n );\r\n};\r\n\r\nconst NotificationManager = () => {\r\n const { notifications, removeNotification, clearAllNotifications } = useNotification();\r\n\r\n // Separate persistent and temporary notifications\r\n const persistentNotifications = notifications.filter(n => n.persistent) || [];\r\n const temporaryNotifications = notifications.filter(n => !n.persistent) || [];\r\n const latestTemporary = temporaryNotifications.length > 0 ? temporaryNotifications.slice(-1)[0] : null;\r\n\r\n if (notifications.length === 0) {\r\n return null;\r\n }\r\n\r\n return (\r\n <>\r\n {/* Persistent notifications container (top-right) */}\r\n {persistentNotifications.length > 0 && (\r\n <Box\r\n sx={{\r\n position: 'fixed',\r\n top: 80,\r\n right: 16,\r\n zIndex: 1400,\r\n maxWidth: 400,\r\n width: '100%',\r\n maxHeight: '70vh',\r\n overflow: 'auto'\r\n }}\r\n >\r\n <Stack spacing={1}>\r\n {/* Clear all button */}\r\n {persistentNotifications.length > 1 && (\r\n <Box display=\"flex\" justifyContent=\"flex-end\" mb={1}>\r\n <Button\r\n size=\"small\"\r\n variant=\"outlined\"\r\n onClick={clearAllNotifications}\r\n sx={{ fontSize: '0.7rem' }}\r\n >\r\n Clear All ({persistentNotifications.length})\r\n </Button>\r\n </Box>\r\n )}\r\n \r\n {persistentNotifications.map((notification) => {\r\n if (!notification || !notification.id) return null;\r\n \r\n return (\r\n <Fade key={`notification-${notification.id}`} in timeout={300}>\r\n <Box>\r\n <NotificationItem\r\n notification={notification}\r\n onClose={() => removeNotification(notification.id)}\r\n />\r\n </Box>\r\n </Fade>\r\n );\r\n })}\r\n </Stack>\r\n </Box>\r\n )}\r\n\r\n {/* Temporary notification (bottom snackbar) */}\r\n {latestTemporary && (\r\n <Snackbar\r\n key={`temp-notification-${latestTemporary.id}`}\r\n open={true}\r\n anchorOrigin={{ vertical: 'bottom', horizontal: 'center' }}\r\n TransitionComponent={Slide}\r\n TransitionProps={{ direction: 'up' }}\r\n sx={{ \r\n '& .MuiSnackbarContent-root': { \r\n p: 0,\r\n backgroundColor: 'transparent',\r\n boxShadow: 'none'\r\n }\r\n }}\r\n >\r\n <Box>\r\n <NotificationItem\r\n notification={latestTemporary}\r\n onClose={() => removeNotification(latestTemporary.id)}\r\n />\r\n </Box>\r\n </Snackbar>\r\n )}\r\n </>\r\n );\r\n};\r\n\r\nexport default NotificationManager;","import React, { useState, useEffect, useCallback } from 'react';\nimport {\n IconButton,\n Badge,\n Menu,\n MenuItem,\n Box,\n Typography,\n Divider,\n Avatar,\n ListItemText,\n ListItemAvatar,\n List,\n ListItem,\n Button,\n Chip,\n CircularProgress,\n Alert\n} from '@mui/material';\nimport {\n Notifications as NotificationsIcon,\n NotificationsNone,\n CheckCircle,\n Warning,\n Error as ErrorIcon,\n Info,\n Message,\n Assignment,\n Payment,\n Home,\n Build,\n Close,\n DoneAll,\n Settings as SettingsIcon\n} from '@mui/icons-material';\nimport { formatDistanceToNow } from 'date-fns';\n\nconst NotificationBell = ({ api, useSocket, useAuth }) => {\n const [anchorEl, setAnchorEl] = useState(null);\n const [notifications, setNotifications] = useState([]);\n const [unreadCount, setUnreadCount] = useState(0);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState(null);\n const [page, setPage] = useState(1);\n const [hasMore, setHasMore] = useState(true);\n\n const { socket, isConnected } = useSocket ? useSocket() : { socket: null, isConnected: false };\n const { user } = useAuth ? useAuth() : { user: null };\n\n const open = Boolean(anchorEl);\n\n // Fetch notifications from API\n const fetchNotifications = useCallback(async (pageNum = 1, append = false) => {\n if (!api) return;\n\n setLoading(true);\n setError(null);\n\n try {\n const response = await api.get('/notifications', {\n params: {\n page: pageNum,\n limit: 20,\n sort: '-createdAt'\n }\n });\n\n const newNotifications = response.data.notifications || [];\n\n if (append) {\n setNotifications(prev => [...prev, ...newNotifications]);\n } else {\n setNotifications(newNotifications);\n }\n\n setHasMore(newNotifications.length === 20);\n setUnreadCount(response.data.unreadCount || 0);\n } catch (err) {\n console.error('Failed to fetch notifications:', err);\n setError('Failed to load notifications');\n } finally {\n setLoading(false);\n }\n }, [api]);\n\n // Fetch unread count\n const fetchUnreadCount = useCallback(async () => {\n if (!api) return;\n\n try {\n const response = await api.get('/notifications/unread');\n setUnreadCount(response.data.count || 0);\n } catch (err) {\n console.error('Failed to fetch unread count:', err);\n }\n }, [api]);\n\n // Initial load\n useEffect(() => {\n fetchNotifications();\n fetchUnreadCount();\n }, [fetchNotifications, fetchUnreadCount]);\n\n // Socket.IO real-time notifications\n useEffect(() => {\n if (!socket || !isConnected) return;\n\n const handleNewNotification = (notification) => {\n setNotifications(prev => [notification, ...prev]);\n setUnreadCount(prev => prev + 1);\n };\n\n const handleNotificationRead = (notificationId) => {\n setNotifications(prev =>\n prev.map(n => n._id === notificationId ? { ...n, read: true } : n)\n );\n setUnreadCount(prev => Math.max(0, prev - 1));\n };\n\n socket.on('notification', handleNewNotification);\n socket.on('notification:read', handleNotificationRead);\n\n return () => {\n socket.off('notification', handleNewNotification);\n socket.off('notification:read', handleNotificationRead);\n };\n }, [socket, isConnected]);\n\n const handleClick = (event) => {\n setAnchorEl(event.currentTarget);\n if (notifications.length === 0) {\n fetchNotifications();\n }\n };\n\n const handleClose = () => {\n setAnchorEl(null);\n };\n\n const handleMarkAsRead = async (notificationId) => {\n if (!api) return;\n\n try {\n await api.put(`/notifications/${notificationId}/read`);\n\n setNotifications(prev =>\n prev.map(n => n._id === notificationId ? { ...n, read: true, readAt: new Date() } : n)\n );\n setUnreadCount(prev => Math.max(0, prev - 1));\n } catch (err) {\n console.error('Failed to mark notification as read:', err);\n }\n };\n\n const handleMarkAllAsRead = async () => {\n if (!api) return;\n\n try {\n await api.put('/notifications/mark-all-read');\n\n setNotifications(prev =>\n prev.map(n => ({ ...n, read: true, readAt: new Date() }))\n );\n setUnreadCount(0);\n } catch (err) {\n console.error('Failed to mark all as read:', err);\n }\n };\n\n const handleNotificationClick = async (notification) => {\n // Mark as read\n if (!notification.read) {\n await handleMarkAsRead(notification._id);\n }\n\n // Navigate to action URL if exists\n if (notification.actionUrl) {\n window.location.href = notification.actionUrl;\n }\n\n handleClose();\n };\n\n const handleLoadMore = () => {\n const nextPage = page + 1;\n setPage(nextPage);\n fetchNotifications(nextPage, true);\n };\n\n const getNotificationIcon = (type) => {\n const iconProps = { fontSize: 'small' };\n\n switch (type) {\n case 'TICKET_CREATED':\n case 'TICKET_UPDATED':\n case 'TICKET_ASSIGNED':\n case 'TICKET_RESOLVED':\n case 'TICKET_COMMENTED':\n case 'TICKET_STATUS_CHANGED':\n return <Assignment {...iconProps} />;\n case 'MESSAGE_RECEIVED':\n case 'MENTION_RECEIVED':\n return <Message {...iconProps} />;\n case 'PAYMENT_DUE':\n case 'PAYMENT_OVERDUE':\n return <Payment {...iconProps} />;\n case 'PROPERTY_UPDATED':\n case 'LEASE_EXPIRING':\n return <Home {...iconProps} />;\n case 'APPLIANCE_MAINTENANCE_DUE':\n case 'MAINTENANCE_SCHEDULED':\n return <Build {...iconProps} />;\n case 'SYSTEM_ALERT':\n return <Warning {...iconProps} />;\n case 'SUCCESS':\n return <CheckCircle {...iconProps} />;\n case 'ERROR':\n return <ErrorIcon {...iconProps} />;\n case 'WARNING':\n return <Warning {...iconProps} />;\n case 'INFO':\n default:\n return <Info {...iconProps} />;\n }\n };\n\n const getNotificationColor = (type) => {\n if (type?.includes('ERROR') || type?.includes('OVERDUE')) return 'error.main';\n if (type?.includes('WARNING') || type?.includes('DUE')) return 'warning.main';\n if (type?.includes('SUCCESS') || type?.includes('RESOLVED')) return 'success.main';\n return 'primary.main';\n };\n\n const getPriorityChip = (priority) => {\n if (!priority || priority === 'NORMAL' || priority === 'LOW') return null;\n\n const colors = {\n HIGH: 'warning',\n URGENT: 'error'\n };\n\n return (\n <Chip\n label={priority}\n size=\"small\"\n color={colors[priority] || 'default'}\n sx={{ ml: 1, height: 20, fontSize: '0.7rem' }}\n />\n );\n };\n\n return (\n <>\n <IconButton\n color=\"inherit\"\n onClick={handleClick}\n sx={{\n ml: 1,\n '&:hover': {\n bgcolor: 'action.hover'\n }\n }}\n >\n <Badge\n badgeContent={unreadCount}\n color=\"error\"\n max={99}\n >\n {unreadCount > 0 ? (\n <NotificationsIcon />\n ) : (\n <NotificationsNone />\n )}\n </Badge>\n </IconButton>\n\n <Menu\n anchorEl={anchorEl}\n open={open}\n onClose={handleClose}\n PaperProps={{\n sx: {\n width: 420,\n maxHeight: 600,\n overflow: 'hidden',\n display: 'flex',\n flexDirection: 'column'\n }\n }}\n transformOrigin={{ horizontal: 'right', vertical: 'top' }}\n anchorOrigin={{ horizontal: 'right', vertical: 'bottom' }}\n >\n {/* Header */}\n <Box\n sx={{\n p: 2,\n pb: 1.5,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n borderBottom: '1px solid',\n borderColor: 'divider'\n }}\n >\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>\n <NotificationsIcon color=\"primary\" />\n <Typography variant=\"h6\" sx={{ fontWeight: 600 }}>\n Notifications\n </Typography>\n {unreadCount > 0 && (\n <Chip\n label={unreadCount}\n size=\"small\"\n color=\"primary\"\n sx={{ height: 22, fontSize: '0.75rem' }}\n />\n )}\n </Box>\n <Box>\n {unreadCount > 0 && (\n <Button\n size=\"small\"\n startIcon={<DoneAll />}\n onClick={handleMarkAllAsRead}\n sx={{ textTransform: 'none', fontSize: '0.75rem' }}\n >\n Mark all read\n </Button>\n )}\n <IconButton size=\"small\" onClick={handleClose}>\n <Close fontSize=\"small\" />\n </IconButton>\n </Box>\n </Box>\n\n {/* Error State */}\n {error && (\n <Alert severity=\"error\" sx={{ m: 2 }}>\n {error}\n </Alert>\n )}\n\n {/* Notifications List */}\n <Box\n sx={{\n flex: 1,\n overflow: 'auto',\n maxHeight: 450\n }}\n >\n {loading && notifications.length === 0 ? (\n <Box sx={{ display: 'flex', justifyContent: 'center', p: 4 }}>\n <CircularProgress size={32} />\n </Box>\n ) : notifications.length === 0 ? (\n <Box\n sx={{\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n p: 4,\n textAlign: 'center'\n }}\n >\n <NotificationsNone sx={{ fontSize: 64, color: 'text.secondary', mb: 2 }} />\n <Typography variant=\"body1\" color=\"text.secondary\" sx={{ fontWeight: 500 }}>\n No notifications yet\n </Typography>\n <Typography variant=\"body2\" color=\"text.secondary\">\n You're all caught up!\n </Typography>\n </Box>\n ) : (\n <List sx={{ p: 0 }}>\n {notifications.map((notification, index) => (\n <React.Fragment key={notification._id}>\n <ListItem\n button\n onClick={() => handleNotificationClick(notification)}\n sx={{\n py: 1.5,\n px: 2,\n bgcolor: notification.read ? 'transparent' : 'action.hover',\n '&:hover': {\n bgcolor: notification.read ? 'action.hover' : 'action.selected'\n },\n borderLeft: notification.read ? 'none' : '3px solid',\n borderLeftColor: getNotificationColor(notification.type),\n transition: 'all 0.2s'\n }}\n >\n <ListItemAvatar>\n <Avatar\n sx={{\n bgcolor: notification.read ? 'grey.300' : getNotificationColor(notification.type),\n width: 40,\n height: 40\n }}\n >\n {getNotificationIcon(notification.type)}\n </Avatar>\n </ListItemAvatar>\n <ListItemText\n primary={\n <Box sx={{ display: 'flex', alignItems: 'center', mb: 0.5 }}>\n <Typography\n variant=\"body2\"\n sx={{\n fontWeight: notification.read ? 400 : 600,\n flex: 1\n }}\n >\n {notification.title}\n </Typography>\n {getPriorityChip(notification.priority)}\n </Box>\n }\n secondary={\n <>\n <Typography\n variant=\"body2\"\n color=\"text.secondary\"\n sx={{\n display: '-webkit-box',\n WebkitLineClamp: 2,\n WebkitBoxOrient: 'vertical',\n overflow: 'hidden',\n mb: 0.5\n }}\n >\n {notification.message}\n </Typography>\n <Typography variant=\"caption\" color=\"text.secondary\">\n {formatDistanceToNow(new Date(notification.createdAt), { addSuffix: true })}\n </Typography>\n </>\n }\n />\n </ListItem>\n {index < notifications.length - 1 && <Divider />}\n </React.Fragment>\n ))}\n </List>\n )}\n\n {/* Load More */}\n {hasMore && notifications.length > 0 && (\n <Box sx={{ p: 2, textAlign: 'center', borderTop: '1px solid', borderColor: 'divider' }}>\n <Button\n onClick={handleLoadMore}\n disabled={loading}\n size=\"small\"\n sx={{ textTransform: 'none' }}\n >\n {loading ? 'Loading...' : 'Load more'}\n </Button>\n </Box>\n )}\n </Box>\n\n {/* Footer */}\n <Box\n sx={{\n p: 1.5,\n borderTop: '1px solid',\n borderColor: 'divider',\n textAlign: 'center'\n }}\n >\n <Button\n size=\"small\"\n startIcon={<SettingsIcon />}\n onClick={() => {\n window.location.href = '/settings?tab=general';\n handleClose();\n }}\n sx={{ textTransform: 'none' }}\n >\n Notification Settings\n </Button>\n </Box>\n </Menu>\n </>\n );\n};\n\nexport default NotificationBell;\n","import React from 'react';\r\nimport {\r\n Box,\r\n Typography,\r\n Button,\r\n Card,\r\n CardContent,\r\n Alert,\r\n Stack\r\n} from '@mui/material';\r\nimport {\r\n Refresh,\r\n BugReport,\r\n Home\r\n} from '@mui/icons-material';\r\n\r\nclass ErrorBoundary extends React.Component {\r\n constructor(props) {\r\n super(props);\r\n this.state = { \r\n hasError: false, \r\n error: null,\r\n errorInfo: null,\r\n errorId: null\r\n };\r\n }\r\n\r\n static getDerivedStateFromError(error) {\r\n // Update state so the next render will show the fallback UI\r\n return { \r\n hasError: true,\r\n errorId: Date.now() // Simple error ID for tracking\r\n };\r\n }\r\n\r\n componentDidCatch(error, errorInfo) {\r\n // Log error details\r\n console.error('ErrorBoundary caught an error:', error);\r\n console.error('Error info:', errorInfo);\r\n \r\n this.setState({\r\n error: error,\r\n errorInfo: errorInfo\r\n });\r\n\r\n // You could send error reports to an error reporting service here\r\n // For example: logErrorToService(error, errorInfo);\r\n }\r\n\r\n handleRetry = () => {\r\n this.setState({ \r\n hasError: false, \r\n error: null, \r\n errorInfo: null,\r\n errorId: null\r\n });\r\n };\r\n\r\n handleReload = () => {\r\n window.location.reload();\r\n };\r\n\r\n render() {\r\n if (this.state.hasError) {\r\n const isNavigationError = this.state.error?.message?.includes('getBoundingClientRect');\r\n const isDOMError = this.state.error?.message?.includes('null') || \r\n this.state.error?.message?.includes('undefined');\r\n\r\n return (\r\n <Box\r\n sx={{\r\n display: 'flex',\r\n flexDirection: 'column',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n minHeight: '50vh',\r\n p: 3\r\n }}\r\n >\r\n <Card sx={{ maxWidth: 600, width: '100%' }}>\r\n <CardContent>\r\n <Stack spacing={3} alignItems=\"center\">\r\n <BugReport sx={{ fontSize: 64, color: 'error.main' }} />\r\n \r\n <Typography variant=\"h5\" component=\"h2\" textAlign=\"center\">\r\n Oops! Something went wrong\r\n </Typography>\r\n\r\n <Alert severity=\"error\" sx={{ width: '100%' }}>\r\n <Typography variant=\"body2\">\r\n {isNavigationError && (\r\n <>\r\n <strong>UI Component Error:</strong> A component tried to access an element before it was ready. \r\n This is usually temporary.\r\n </>\r\n )}\r\n {isDOMError && !isNavigationError && (\r\n <>\r\n <strong>DOM Error:</strong> A component couldn't find an expected element. \r\n This might be due to rapid state changes.\r\n </>\r\n )}\r\n {!isNavigationError && !isDOMError && (\r\n <>\r\n <strong>Application Error:</strong> An unexpected error occurred while rendering the component.\r\n </>\r\n )}\r\n </Typography>\r\n </Alert>\r\n\r\n {process.env.NODE_ENV === 'development' && this.state.error && (\r\n <Alert severity=\"warning\" sx={{ width: '100%' }}>\r\n <Typography variant=\"body2\" component=\"div\">\r\n <strong>Debug Info:</strong><br />\r\n <code style={{ fontSize: '0.75rem', wordBreak: 'break-word' }}>\r\n {this.state.error.toString()}\r\n </code>\r\n </Typography>\r\n </Alert>\r\n )}\r\n\r\n <Stack direction=\"row\" spacing={2}>\r\n <Button\r\n variant=\"contained\"\r\n startIcon={<Refresh />}\r\n onClick={this.handleRetry}\r\n color=\"primary\"\r\n >\r\n Try Again\r\n </Button>\r\n \r\n <Button\r\n variant=\"outlined\"\r\n startIcon={<Refresh />}\r\n onClick={this.handleReload}\r\n >\r\n Reload Page\r\n </Button>\r\n\r\n {this.props.onNavigateHome && (\r\n <Button\r\n variant=\"outlined\"\r\n startIcon={<Home />}\r\n onClick={this.props.onNavigateHome}\r\n >\r\n Go Home\r\n </Button>\r\n )}\r\n </Stack>\r\n\r\n <Typography variant=\"body2\" color=\"text.secondary\" textAlign=\"center\">\r\n If this problem persists, try refreshing the page or clearing your browser cache.\r\n The error has been logged for debugging.\r\n </Typography>\r\n </Stack>\r\n </CardContent>\r\n </Card>\r\n </Box>\r\n );\r\n }\r\n\r\n return this.props.children;\r\n }\r\n}\r\n\r\nexport default ErrorBoundary;","import React, { createContext, useContext, useEffect, useState } from 'react';\r\nimport { io } from 'socket.io-client';\r\nimport { useAuth } from './AuthContext';\r\n\r\nconst SocketContext = createContext();\r\n\r\nexport const useSocket = () => {\r\n const context = useContext(SocketContext);\r\n if (!context) {\r\n throw new Error('useSocket must be used within SocketProvider');\r\n }\r\n return context;\r\n};\r\n\r\nexport const SocketProvider = ({ children }) => {\r\n const [socket, setSocket] = useState(null);\r\n const [isConnected, setIsConnected] = useState(false);\r\n const [tenantToken, setTenantToken] = useState(null);\r\n const { user } = useAuth();\r\n\r\n // Check for tenant token from localStorage\r\n useEffect(() => {\r\n const token = localStorage.getItem('tenantToken');\r\n setTenantToken(token);\r\n }, []);\r\n\r\n useEffect(() => {\r\n // Create socket connection for either authenticated property managers or tenants\r\n if (user || tenantToken) {\r\n const userType = user ? 'property_manager' : 'tenant';\r\n const authToken = user ? localStorage.getItem('token') : tenantToken;\r\n\r\n\r\n // Remove '/api' from the URL for Socket.IO connection\r\n const socketUrl = process.env.REACT_APP_API_URL\r\n ? process.env.REACT_APP_API_URL.replace('/api', '')\r\n : 'http://localhost:5000';\r\n\r\n const newSocket = io(socketUrl, {\r\n auth: {\r\n token: authToken,\r\n userType: userType\r\n }\r\n });\r\n\r\n newSocket.on('connect', () => {\r\n setIsConnected(true);\r\n });\r\n\r\n newSocket.on('disconnect', () => {\r\n setIsConnected(false);\r\n });\r\n\r\n setSocket(newSocket);\r\n\r\n return () => {\r\n newSocket.close();\r\n };\r\n }\r\n }, [user, tenantToken]);\r\n\r\n const value = {\r\n socket,\r\n isConnected\r\n };\r\n\r\n return (\r\n <SocketContext.Provider value={value}>\r\n {children}\r\n </SocketContext.Provider>\r\n );\r\n};","import { useCallback } from 'react';\r\nimport { useNotification } from '../contexts/NotificationContext';\r\nimport { Refresh, CloudUpload, Download, ContentCopy } from '@mui/icons-material';\r\n\r\nexport const useNotifications = () => {\r\n const notification = useNotification();\r\n\r\n // API operation notifications\r\n const notifyApiSuccess = useCallback((operation, entityName) => {\r\n const messages = {\r\n create: `${entityName} created successfully`,\r\n update: `${entityName} updated successfully`,\r\n delete: `${entityName} deleted successfully`,\r\n save: `${entityName} saved successfully`,\r\n load: `${entityName} loaded successfully`,\r\n fetch: `${entityName} fetched successfully`\r\n };\r\n \r\n return notification.showSuccess(messages[operation] || `${operation} completed successfully`);\r\n }, [notification]);\r\n\r\n const notifyApiError = useCallback((operation, entityName, error) => {\r\n const baseMessages = {\r\n create: `Failed to create ${entityName}`,\r\n update: `Failed to update ${entityName}`,\r\n delete: `Failed to delete ${entityName}`,\r\n save: `Failed to save ${entityName}`,\r\n load: `Failed to load ${entityName}`,\r\n fetch: `Failed to fetch ${entityName}`\r\n };\r\n \r\n const baseMessage = baseMessages[operation] || `Failed to ${operation}`;\r\n const errorMessage = error?.response?.data?.message || error?.message;\r\n \r\n return notification.showError(\r\n errorMessage ? `${baseMessage}: ${errorMessage}` : baseMessage,\r\n { persistent: true }\r\n );\r\n }, [notification]);\r\n\r\n // File operation notifications\r\n const notifyFileUploadStart = useCallback((fileName) => {\r\n return notification.showProgress(`Uploading ${fileName}...`, 0, {\r\n title: 'File Upload',\r\n actions: [{\r\n label: 'Cancel',\r\n icon: <ContentCopy />,\r\n color: 'error'\r\n }]\r\n });\r\n }, [notification]);\r\n\r\n const notifyFileUploadProgress = useCallback((notificationId, progress, fileName) => {\r\n notification.updateProgress(notificationId, progress, `Uploading ${fileName}... ${Math.round(progress)}%`);\r\n }, [notification]);\r\n\r\n const notifyFileUploadComplete = useCallback((notificationId, fileName) => {\r\n notification.updateNotification(notificationId, {\r\n type: 'success',\r\n message: `${fileName} uploaded successfully`,\r\n progress: undefined,\r\n duration: 3000,\r\n persistent: false,\r\n actions: []\r\n });\r\n }, [notification]);\r\n\r\n const notifyFileUploadError = useCallback((notificationId, fileName, error) => {\r\n notification.updateNotification(notificationId, {\r\n type: 'error',\r\n message: `Failed to upload ${fileName}: ${error}`,\r\n progress: undefined,\r\n persistent: true,\r\n actions: [{\r\n label: 'Retry',\r\n icon: <Refresh />,\r\n color: 'error'\r\n }]\r\n });\r\n }, [notification]);\r\n\r\n // Form validation notifications\r\n const notifyValidationError = useCallback((errors) => {\r\n const errorCount = Array.isArray(errors) ? errors.length : Object.keys(errors).length;\r\n const message = errorCount === 1 \r\n ? 'Please fix the validation error'\r\n : `Please fix ${errorCount} validation errors`;\r\n \r\n return notification.showWarning(message, {\r\n title: 'Form Validation',\r\n duration: 6000\r\n });\r\n }, [notification]);\r\n\r\n // Confirmation notifications with actions\r\n const notifyConfirmAction = useCallback((message, onConfirm, onCancel = null) => {\r\n return notification.showAction(message, [\r\n {\r\n label: 'Confirm',\r\n color: 'primary',\r\n variant: 'contained',\r\n onClick: onConfirm\r\n },\r\n {\r\n label: 'Cancel',\r\n color: 'inherit',\r\n onClick: onCancel || (() => {})\r\n }\r\n ], {\r\n type: 'warning',\r\n title: 'Confirmation Required'\r\n });\r\n }, [notification]);\r\n\r\n // Loading states\r\n const notifyLoading = useCallback((message) => {\r\n return notification.showLoading(message);\r\n }, [notification]);\r\n\r\n const stopLoading = useCallback((notificationId) => {\r\n notification.removeNotification(notificationId);\r\n }, [notification]);\r\n\r\n // Network status notifications\r\n const notifyNetworkError = useCallback(() => {\r\n return notification.showError('Network connection lost. Please check your internet connection.', {\r\n title: 'Connection Error',\r\n persistent: true,\r\n actions: [{\r\n label: 'Retry',\r\n icon: <Refresh />,\r\n color: 'error',\r\n onClick: () => window.location.reload()\r\n }]\r\n });\r\n }, [notification]);\r\n\r\n const notifyNetworkReconnected = useCallback(() => {\r\n return notification.showSuccess('Connection restored');\r\n }, [notification]);\r\n\r\n // Maintenance notifications\r\n const notifyMaintenance = useCallback((message, scheduledTime) => {\r\n return notification.showWarning(message, {\r\n title: 'Scheduled Maintenance',\r\n persistent: true,\r\n actions: [{\r\n label: 'Learn More',\r\n onClick: () => {\r\n // Could open a maintenance details dialog\r\n }\r\n }]\r\n });\r\n }, [notification]);\r\n\r\n // Permission notifications\r\n const notifyPermissionDenied = useCallback((action = 'perform this action') => {\r\n return notification.showError(`You don't have permission to ${action}`, {\r\n title: 'Access Denied',\r\n duration: 6000\r\n });\r\n }, [notification]);\r\n\r\n // Data sync notifications\r\n const notifyDataOutOfSync = useCallback((onRefresh) => {\r\n return notification.showWarning('Data may be outdated', {\r\n title: 'Sync Warning',\r\n actions: [{\r\n label: 'Refresh',\r\n icon: <Refresh />,\r\n onClick: onRefresh\r\n }]\r\n });\r\n }, [notification]);\r\n\r\n return {\r\n // Core notification functions\r\n ...notification,\r\n \r\n // Convenience functions\r\n notifyApiSuccess,\r\n notifyApiError,\r\n notifyFileUploadStart,\r\n notifyFileUploadProgress,\r\n notifyFileUploadComplete,\r\n notifyFileUploadError,\r\n notifyValidationError,\r\n notifyConfirmAction,\r\n notifyLoading,\r\n stopLoading,\r\n notifyNetworkError,\r\n notifyNetworkReconnected,\r\n notifyMaintenance,\r\n notifyPermissionDenied,\r\n notifyDataOutOfSync\r\n };\r\n};\r\n\r\nexport default useNotifications;","/**\r\n * React hook for using the unified notification system\r\n */\r\n\r\nimport { useEffect, useContext, useCallback } from 'react';\r\nimport { useNotification } from '../contexts/NotificationContext';\r\nimport { useSocket } from '../contexts/SocketContext';\r\nimport unifiedNotificationManager, {\r\n notify,\r\n notifySuccess,\r\n notifyError,\r\n notifyTicketUpdate,\r\n notifyMessage,\r\n requestNotificationPermission,\r\n subscribeToPushNotifications,\r\n setToastContext,\r\n setSocketContext,\r\n NOTIFICATION_TYPES,\r\n NOTIFICATION_CHANNELS\r\n} from '../utils/unifiedNotifications';\r\n\r\nexport const useUnifiedNotifications = () => {\r\n const toastContext = useNotification();\r\n const socketContext = useSocket();\r\n\r\n // Set up contexts when hook is initialized\r\n useEffect(() => {\r\n if (toastContext) {\r\n setToastContext(toastContext);\r\n }\r\n }, [toastContext]);\r\n\r\n useEffect(() => {\r\n if (socketContext) {\r\n setSocketContext(socketContext);\r\n }\r\n }, [socketContext]);\r\n\r\n // Initialize push notifications on first use\r\n const initializePushNotifications = useCallback(async () => {\r\n try {\r\n await requestNotificationPermission();\r\n await subscribeToPushNotifications();\r\n return true;\r\n } catch (error) {\r\n console.error('Failed to initialize push notifications:', error);\r\n return false;\r\n }\r\n }, []);\r\n\r\n // Convenience methods with better error handling\r\n const showSuccess = useCallback((message, title, options = {}) => {\r\n return notifySuccess(message, title, {\r\n channels: [NOTIFICATION_CHANNELS.TOAST],\r\n sound: true,\r\n ...options\r\n });\r\n }, []);\r\n\r\n const showError = useCallback((message, title, options = {}) => {\r\n return notifyError(message, title, {\r\n channels: [NOTIFICATION_CHANNELS.TOAST, NOTIFICATION_CHANNELS.BROWSER],\r\n persistent: true,\r\n ...options\r\n });\r\n }, []);\r\n\r\n const showWarning = useCallback((message, title, options = {}) => {\r\n return notify({\r\n message,\r\n title,\r\n type: NOTIFICATION_TYPES.WARNING,\r\n channels: [NOTIFICATION_CHANNELS.TOAST],\r\n ...options\r\n });\r\n }, []);\r\n\r\n const showInfo = useCallback((message, title, options = {}) => {\r\n return notify({\r\n message,\r\n title,\r\n type: NOTIFICATION_TYPES.INFO,\r\n channels: [NOTIFICATION_CHANNELS.TOAST],\r\n ...options\r\n });\r\n }, []);\r\n\r\n // Specialized notification methods\r\n const notifyTicket = useCallback((ticket, changeType, options = {}) => {\r\n return notifyTicketUpdate(ticket, changeType, {\r\n channels: [\r\n NOTIFICATION_CHANNELS.TOAST,\r\n NOTIFICATION_CHANNELS.DATABASE,\r\n NOTIFICATION_CHANNELS.SOCKET\r\n ],\r\n ...options\r\n });\r\n }, []);\r\n\r\n const notifyNewMessage = useCallback((senderName, messageContent, propertyAddress, options = {}) => {\r\n return notifyMessage(senderName, messageContent, propertyAddress, {\r\n channels: [\r\n NOTIFICATION_CHANNELS.BROWSER,\r\n NOTIFICATION_CHANNELS.SOUND\r\n ],\r\n priority: 'high',\r\n ...options\r\n });\r\n }, []);\r\n\r\n // System notifications\r\n const notifySystemAlert = useCallback((message, title, options = {}) => {\r\n return notify({\r\n message,\r\n title,\r\n type: NOTIFICATION_TYPES.SYSTEM_ALERT,\r\n channels: [\r\n NOTIFICATION_CHANNELS.TOAST,\r\n NOTIFICATION_CHANNELS.BROWSER,\r\n NOTIFICATION_CHANNELS.DATABASE\r\n ],\r\n priority: 'urgent',\r\n persistent: true,\r\n ...options\r\n });\r\n }, []);\r\n\r\n // Loading notifications\r\n const showLoading = useCallback((message, options = {}) => {\r\n return notify({\r\n message,\r\n type: NOTIFICATION_TYPES.LOADING,\r\n channels: [NOTIFICATION_CHANNELS.TOAST],\r\n persistent: true,\r\n ...options\r\n });\r\n }, []);\r\n\r\n // Multi-channel notifications\r\n const notifyImportant = useCallback((message, title, options = {}) => {\r\n return notify({\r\n message,\r\n title,\r\n type: NOTIFICATION_TYPES.INFO,\r\n channels: [\r\n NOTIFICATION_CHANNELS.TOAST,\r\n NOTIFICATION_CHANNELS.BROWSER,\r\n NOTIFICATION_CHANNELS.PUSH,\r\n NOTIFICATION_CHANNELS.SOUND\r\n ],\r\n priority: 'high',\r\n ...options\r\n });\r\n }, []);\r\n\r\n // Batch notifications\r\n const notifyBatch = useCallback(async (notifications) => {\r\n const results = [];\r\n for (const notification of notifications) {\r\n try {\r\n const result = await notify(notification);\r\n results.push({ success: true, result });\r\n } catch (error) {\r\n results.push({ success: false, error: error.message });\r\n }\r\n }\r\n return results;\r\n }, []);\r\n\r\n return {\r\n // Core notification methods\r\n notify,\r\n showSuccess,\r\n showError,\r\n showWarning,\r\n showInfo,\r\n showLoading,\r\n \r\n // Specialized methods\r\n notifyTicket,\r\n notifyNewMessage,\r\n notifySystemAlert,\r\n notifyImportant,\r\n notifyBatch,\r\n \r\n // Setup methods\r\n initializePushNotifications,\r\n \r\n // Access to the manager instance\r\n manager: unifiedNotificationManager,\r\n \r\n // Constants\r\n TYPES: NOTIFICATION_TYPES,\r\n CHANNELS: NOTIFICATION_CHANNELS\r\n };\r\n};\r\n\r\nexport default useUnifiedNotifications;","/**\r\n * Unified Notification Manager\r\n * Combines push notifications, browser notifications, and toast notifications\r\n * into a single, easy-to-use interface\r\n */\r\n\r\nimport api from '../services/api';\r\n\r\n// Notification types enum\r\nexport const NOTIFICATION_TYPES = {\r\n // Toast notification types (UI feedback)\r\n SUCCESS: 'success',\r\n ERROR: 'error',\r\n WARNING: 'warning',\r\n INFO: 'info',\r\n LOADING: 'loading',\r\n \r\n // Ticket/issue notification types\r\n TICKET_CREATED: 'ticket_created',\r\n TICKET_UPDATED: 'ticket_updated',\r\n TICKET_ASSIGNED: 'ticket_assigned',\r\n TICKET_RESOLVED: 'ticket_resolved',\r\n TICKET_COMMENTED: 'ticket_commented',\r\n \r\n // Messaging notification types\r\n MESSAGE_RECEIVED: 'message_received',\r\n MENTION_RECEIVED: 'mention_received',\r\n \r\n // System notification types\r\n SYSTEM_ALERT: 'system_alert',\r\n MAINTENANCE_SCHEDULED: 'maintenance_scheduled'\r\n};\r\n\r\n// Notification channels enum\r\nexport const NOTIFICATION_CHANNELS = {\r\n TOAST: 'toast', // In-app toast notifications\r\n BROWSER: 'browser', // Browser notifications\r\n PUSH: 'push', // Push notifications (service worker)\r\n DATABASE: 'database', // Persistent database notifications\r\n SOCKET: 'socket', // Real-time socket notifications\r\n SOUND: 'sound' // Audio notifications\r\n};\r\n\r\nclass UnifiedNotificationManager {\r\n constructor() {\r\n this.permission = null;\r\n this.audioContext = null;\r\n this.pushSubscription = null;\r\n this.toastNotificationContext = null;\r\n this.socketContext = null;\r\n \r\n this.init();\r\n }\r\n\r\n async init() {\r\n // Initialize browser notifications\r\n if ('Notification' in window) {\r\n this.permission = Notification.permission;\r\n }\r\n\r\n // Initialize audio context\r\n try {\r\n this.audioContext = new (window.AudioContext || window.webkitAudioContext)();\r\n } catch (e) {\r\n console.warn('Web Audio API not supported');\r\n }\r\n\r\n // Check for existing push subscription\r\n await this.checkPushSubscription();\r\n }\r\n\r\n // Set contexts from React components\r\n setToastContext(context) {\r\n this.toastNotificationContext = context;\r\n }\r\n\r\n setSocketContext(context) {\r\n this.socketContext = context;\r\n }\r\n\r\n // Permission management\r\n async requestPermission() {\r\n if (!('Notification' in window)) {\r\n throw new Error('Browser notifications not supported');\r\n }\r\n\r\n if (this.permission === 'granted') {\r\n return 'granted';\r\n }\r\n\r\n this.permission = await Notification.requestPermission();\r\n return this.permission;\r\n }\r\n\r\n hasPermission() {\r\n return this.permission === 'granted';\r\n }\r\n\r\n isSupported() {\r\n return 'Notification' in window && 'serviceWorker' in navigator && 'PushManager' in window;\r\n }\r\n\r\n // Push notification management\r\n async subscribeToPush() {\r\n if (!this.isSupported()) {\r\n throw new Error('Push notifications not supported');\r\n }\r\n\r\n if (this.permission !== 'granted') {\r\n await this.requestPermission();\r\n }\r\n\r\n if (this.permission !== 'granted') {\r\n throw new Error('Notification permission denied');\r\n }\r\n\r\n try {\r\n // Register service worker\r\n const registration = await navigator.serviceWorker.register('/sw.js', {\r\n scope: '/',\r\n updateViaCache: 'none'\r\n });\r\n\r\n await navigator.serviceWorker.ready;\r\n\r\n // Get or create subscription\r\n let subscription = await registration.pushManager.getSubscription();\r\n \r\n if (!subscription) {\r\n const vapidPublicKey = process.env.REACT_APP_VAPID_PUBLIC_KEY || \r\n 'BJ2eTitSHPWl9WBAk0F1Drwmv6bQB48aDpM1ilutZcdygYfpbK7ODrlMSzvplaHWVwPtvQ1x-Y2SK2LadSQZ2mc';\r\n \r\n subscription = await registration.pushManager.subscribe({\r\n userVisibleOnly: true,\r\n applicationServerKey: this.urlBase64ToUint8Array(vapidPublicKey)\r\n });\r\n }\r\n\r\n // Send subscription to backend\r\n await api.post('/notifications/subscribe', {\r\n subscription: subscription.toJSON()\r\n });\r\n\r\n this.pushSubscription = subscription;\r\n return subscription;\r\n } catch (error) {\r\n console.error('Error subscribing to push notifications:', error);\r\n throw error;\r\n }\r\n }\r\n\r\n async unsubscribeFromPush() {\r\n if (!this.pushSubscription) return;\r\n\r\n try {\r\n await this.pushSubscription.unsubscribe();\r\n \r\n await api.post('/notifications/unsubscribe', {\r\n endpoint: this.pushSubscription.endpoint\r\n });\r\n\r\n this.pushSubscription = null;\r\n } catch (error) {\r\n console.error('Error unsubscribing from push:', error);\r\n throw error;\r\n }\r\n }\r\n\r\n async checkPushSubscription() {\r\n if (!this.isSupported()) return false;\r\n\r\n try {\r\n const registration = await navigator.serviceWorker.getRegistration();\r\n if (registration) {\r\n this.pushSubscription = await registration.pushManager.getSubscription();\r\n return !!this.pushSubscription;\r\n }\r\n } catch (error) {\r\n console.error('Error checking push subscription:', error);\r\n }\r\n return false;\r\n }\r\n\r\n // Audio notifications\r\n playNotificationSound(type = 'default') {\r\n if (!this.audioContext) return;\r\n\r\n try {\r\n const oscillator = this.audioContext.createOscillator();\r\n const gainNode = this.audioContext.createGain();\r\n\r\n oscillator.connect(gainNode);\r\n gainNode.connect(this.audioContext.destination);\r\n\r\n // Different sounds for different notification types\r\n const soundConfig = this.getSoundConfig(type);\r\n \r\n oscillator.frequency.setValueAtTime(soundConfig.freq1, this.audioContext.currentTime);\r\n oscillator.frequency.setValueAtTime(soundConfig.freq2, this.audioContext.currentTime + 0.1);\r\n \r\n gainNode.gain.setValueAtTime(0, this.audioContext.currentTime);\r\n gainNode.gain.linearRampToValueAtTime(soundConfig.volume, this.audioContext.currentTime + 0.01);\r\n gainNode.gain.linearRampToValueAtTime(0, this.audioContext.currentTime + soundConfig.duration);\r\n\r\n oscillator.start(this.audioContext.currentTime);\r\n oscillator.stop(this.audioContext.currentTime + soundConfig.duration);\r\n } catch (e) {\r\n console.warn('Could not play notification sound:', e);\r\n }\r\n }\r\n\r\n getSoundConfig(type) {\r\n const configs = {\r\n default: { freq1: 800, freq2: 600, volume: 0.3, duration: 0.3 },\r\n success: { freq1: 600, freq2: 800, volume: 0.2, duration: 0.2 },\r\n error: { freq1: 300, freq2: 200, volume: 0.4, duration: 0.5 },\r\n message: { freq1: 800, freq2: 600, volume: 0.3, duration: 0.3 },\r\n urgent: { freq1: 900, freq2: 400, volume: 0.5, duration: 0.4 }\r\n };\r\n return configs[type] || configs.default;\r\n }\r\n\r\n // Browser notification\r\n showBrowserNotification(title, options = {}) {\r\n if (!this.hasPermission()) return null;\r\n\r\n const notification = new Notification(title, {\r\n icon: '/favicon.ico',\r\n badge: '/favicon.ico',\r\n ...options\r\n });\r\n\r\n // Auto close after timeout\r\n if (options.autoClose !== false) {\r\n setTimeout(() => {\r\n notification.close();\r\n }, options.duration || 5000);\r\n }\r\n\r\n return notification;\r\n }\r\n\r\n // Toast notification (requires context to be set)\r\n showToast(message, type = NOTIFICATION_TYPES.INFO, options = {}) {\r\n if (!this.toastNotificationContext) {\r\n console.warn('Toast notification context not set');\r\n return;\r\n }\r\n\r\n switch (type) {\r\n case NOTIFICATION_TYPES.SUCCESS:\r\n return this.toastNotificationContext.showSuccess(message, options);\r\n case NOTIFICATION_TYPES.ERROR:\r\n return this.toastNotificationContext.showError(message, options);\r\n case NOTIFICATION_TYPES.WARNING:\r\n return this.toastNotificationContext.showWarning(message, options);\r\n case NOTIFICATION_TYPES.LOADING:\r\n return this.toastNotificationContext.showLoading(message, options);\r\n default:\r\n return this.toastNotificationContext.showInfo(message, options);\r\n }\r\n }\r\n\r\n // Unified notification method - the main interface\r\n async notify(config) {\r\n const {\r\n title,\r\n message,\r\n type = NOTIFICATION_TYPES.INFO,\r\n channels = [NOTIFICATION_CHANNELS.TOAST],\r\n priority = 'normal', // low, normal, high, urgent\r\n data = {},\r\n actions = [],\r\n persistent = false,\r\n sound = false\r\n } = config;\r\n\r\n const results = {};\r\n\r\n // Show toast notification\r\n if (channels.includes(NOTIFICATION_CHANNELS.TOAST)) {\r\n results.toast = this.showToast(message, type, {\r\n title,\r\n persistent,\r\n actions,\r\n ...data\r\n });\r\n }\r\n\r\n // Show browser notification\r\n if (channels.includes(NOTIFICATION_CHANNELS.BROWSER)) {\r\n if (await this.requestPermission() === 'granted') {\r\n results.browser = this.showBrowserNotification(title || message, {\r\n body: title ? message : undefined,\r\n tag: type,\r\n renotify: priority === 'urgent',\r\n requireInteraction: persistent,\r\n actions: actions.slice(0, 2), // Browser notifications support max 2 actions\r\n data\r\n });\r\n }\r\n }\r\n\r\n // Send push notification (handled by backend)\r\n if (channels.includes(NOTIFICATION_CHANNELS.PUSH)) {\r\n try {\r\n results.push = await api.post('/notifications/send-push', {\r\n title: title || message,\r\n body: title ? message : '',\r\n type,\r\n data,\r\n priority\r\n });\r\n } catch (error) {\r\n console.error('Failed to send push notification:', error);\r\n }\r\n }\r\n\r\n // Create database notification (handled by backend)\r\n if (channels.includes(NOTIFICATION_CHANNELS.DATABASE)) {\r\n try {\r\n results.database = await api.post('/notifications/create', {\r\n title: title || message,\r\n message: title ? message : title,\r\n type,\r\n data,\r\n priority,\r\n persistent\r\n });\r\n } catch (error) {\r\n console.error('Failed to create database notification:', error);\r\n }\r\n }\r\n\r\n // Send real-time notification via socket\r\n if (channels.includes(NOTIFICATION_CHANNELS.SOCKET) && this.socketContext) {\r\n results.socket = this.socketContext.emit('notification', {\r\n title: title || message,\r\n message: title ? message : title,\r\n type,\r\n data,\r\n timestamp: new Date()\r\n });\r\n }\r\n\r\n // Play sound\r\n if (sound || channels.includes(NOTIFICATION_CHANNELS.SOUND)) {\r\n this.playNotificationSound(this.getSoundTypeFromNotificationType(type));\r\n }\r\n\r\n return results;\r\n }\r\n\r\n // Convenience methods for common notification types\r\n async notifySuccess(message, title, options = {}) {\r\n return this.notify({\r\n title,\r\n message,\r\n type: NOTIFICATION_TYPES.SUCCESS,\r\n channels: [NOTIFICATION_CHANNELS.TOAST],\r\n sound: true,\r\n ...options\r\n });\r\n }\r\n\r\n async notifyError(message, title, options = {}) {\r\n return this.notify({\r\n title,\r\n message,\r\n type: NOTIFICATION_TYPES.ERROR,\r\n channels: [NOTIFICATION_CHANNELS.TOAST, NOTIFICATION_CHANNELS.BROWSER],\r\n priority: 'high',\r\n sound: true,\r\n ...options\r\n });\r\n }\r\n\r\n async notifyTicketUpdate(ticket, changeType, options = {}) {\r\n const title = `Ticket #${ticket.ticketNumber} Updated`;\r\n const message = `${changeType}: ${ticket.title || ticket.description?.substring(0, 100)}`;\r\n\r\n return this.notify({\r\n title,\r\n message,\r\n type: NOTIFICATION_TYPES.TICKET_UPDATED,\r\n channels: [NOTIFICATION_CHANNELS.DATABASE, NOTIFICATION_CHANNELS.SOCKET, NOTIFICATION_CHANNELS.TOAST],\r\n data: { ticketId: ticket._id, ticketNumber: ticket.ticketNumber },\r\n ...options\r\n });\r\n }\r\n\r\n async notifyMessage(senderName, messageContent, propertyAddress, options = {}) {\r\n const title = `New message from ${senderName}`;\r\n const body = propertyAddress \r\n ? `${propertyAddress}\\n${messageContent.substring(0, 100)}...`\r\n : messageContent.substring(0, 100) + '...';\r\n \r\n return this.notify({\r\n title,\r\n message: body,\r\n type: NOTIFICATION_TYPES.MESSAGE_RECEIVED,\r\n channels: [NOTIFICATION_CHANNELS.BROWSER, NOTIFICATION_CHANNELS.SOUND],\r\n priority: 'high',\r\n data: { senderName, propertyAddress },\r\n ...options\r\n });\r\n }\r\n\r\n // Helper methods\r\n getSoundTypeFromNotificationType(notificationType) {\r\n const soundMap = {\r\n [NOTIFICATION_TYPES.SUCCESS]: 'success',\r\n [NOTIFICATION_TYPES.ERROR]: 'error',\r\n [NOTIFICATION_TYPES.MESSAGE_RECEIVED]: 'message',\r\n [NOTIFICATION_TYPES.TICKET_CREATED]: 'default',\r\n [NOTIFICATION_TYPES.SYSTEM_ALERT]: 'urgent'\r\n };\r\n return soundMap[notificationType] || 'default';\r\n }\r\n\r\n urlBase64ToUint8Array(base64String) {\r\n const padding = '='.repeat((4 - base64String.length % 4) % 4);\r\n const base64 = (base64String + padding)\r\n .replace(/-/g, '+')\r\n .replace(/_/g, '/');\r\n\r\n const rawData = window.atob(base64);\r\n const outputArray = new Uint8Array(rawData.length);\r\n\r\n for (let i = 0; i < rawData.length; ++i) {\r\n outputArray[i] = rawData.charCodeAt(i);\r\n }\r\n return outputArray;\r\n }\r\n}\r\n\r\n// Create and export singleton instance\r\nconst unifiedNotificationManager = new UnifiedNotificationManager();\r\nexport default unifiedNotificationManager;\r\n\r\n// Export convenience functions\r\nexport const notify = (config) => unifiedNotificationManager.notify(config);\r\nexport const notifySuccess = (message, title, options) => unifiedNotificationManager.notifySuccess(message, title, options);\r\nexport const notifyError = (message, title, options) => unifiedNotificationManager.notifyError(message, title, options);\r\nexport const notifyTicketUpdate = (ticket, changeType, options) => unifiedNotificationManager.notifyTicketUpdate(ticket, changeType, options);\r\nexport const notifyMessage = (senderName, messageContent, propertyAddress, options) => unifiedNotificationManager.notifyMessage(senderName, messageContent, propertyAddress, options);\r\n\r\n// Permission and subscription methods\r\nexport const requestNotificationPermission = () => unifiedNotificationManager.requestPermission();\r\nexport const subscribeToPushNotifications = () => unifiedNotificationManager.subscribeToPush();\r\nexport const unsubscribeFromPushNotifications = () => unifiedNotificationManager.unsubscribeFromPush();\r\nexport const hasNotificationPermission = () => unifiedNotificationManager.hasPermission();\r\nexport const isNotificationSupported = () => unifiedNotificationManager.isSupported();\r\n\r\n// Context setters (to be called from React components)\r\nexport const setToastContext = (context) => unifiedNotificationManager.setToastContext(context);\r\nexport const setSocketContext = (context) => unifiedNotificationManager.setSocketContext(context);","import { useTheme } from '@mui/material/styles';\r\nimport {\r\n getAccessibleTextColor,\r\n getContrastRatio,\r\n meetsWCAGAA,\r\n lightenColor,\r\n darkenColor,\r\n rgbToHex\r\n} from '../utils/colorExtractor';\r\n\r\n/**\r\n * Custom hook for accessible color combinations based on current theme\r\n * Ensures all text meets WCAG AA standards (4.5:1 contrast ratio)\r\n */\r\nexport const useAccessibleColors = () => {\r\n const theme = useTheme();\r\n\r\n /**\r\n * Get safe text color for any background\r\n * @param {string} backgroundColor - Hex color code\r\n * @param {string} standard - 'AA' or 'AAA' accessibility standard\r\n * @returns {string} Accessible text color\r\n */\r\n const getSafeTextColor = (backgroundColor, standard = 'AA') => {\r\n return getAccessibleTextColor(backgroundColor, { standard });\r\n };\r\n\r\n /**\r\n * Get accessible background for text on theme colors\r\n * @param {string} textColor - Desired text color\r\n * @param {string} baseColor - Theme color to base background on\r\n * @returns {string} Accessible background color\r\n */\r\n const getSafeBackground = (textColor = '#ffffff', baseColor = theme.palette.primary.main) => {\r\n // Start with the base color\r\n let background = baseColor;\r\n let attempts = 0;\r\n const maxAttempts = 10;\r\n\r\n // If contrast is insufficient, adjust the background\r\n while (!meetsWCAGAA(background, textColor) && attempts < maxAttempts) {\r\n const currentRatio = getContrastRatio(background, textColor);\r\n\r\n if (currentRatio < 4.5) {\r\n // If text is light, darken background; if text is dark, lighten background\r\n if (textColor === '#ffffff' || textColor === '#fff') {\r\n background = darkenColor(background, 0.1);\r\n } else {\r\n background = lightenColor(background, 0.1);\r\n }\r\n } else {\r\n break;\r\n }\r\n attempts++;\r\n }\r\n\r\n return background;\r\n };\r\n\r\n /**\r\n * Get contrast-safe gradient that maintains readability\r\n * @param {string} startColor - Start color of gradient\r\n * @param {string} endColor - End color of gradient\r\n * @param {string} textColor - Text color that will be used on gradient\r\n * @returns {Object} Gradient and text color information\r\n */\r\n const getSafeGradient = (startColor, endColor, textColor = '#ffffff') => {\r\n const safeStart = getSafeBackground(textColor, startColor);\r\n const safeEnd = getSafeBackground(textColor, endColor);\r\n const finalTextColor = getSafeTextColor(safeStart);\r\n\r\n return {\r\n gradient: `linear-gradient(135deg, ${safeStart}, ${safeEnd})`,\r\n textColor: finalTextColor,\r\n startColor: safeStart,\r\n endColor: safeEnd\r\n };\r\n };\r\n\r\n /**\r\n * Get theme-aware colors with contrast guarantees\r\n */\r\n const getThemeColors = () => {\r\n const primary = theme.palette.primary.main;\r\n const secondary = theme.palette.secondary?.main || theme.palette.primary.dark;\r\n\r\n return {\r\n // Primary color combinations\r\n primary: {\r\n background: primary,\r\n text: getSafeTextColor(primary),\r\n lightBackground: getSafeBackground('#000000', primary),\r\n darkBackground: getSafeBackground('#ffffff', primary)\r\n },\r\n\r\n // Secondary color combinations\r\n secondary: {\r\n background: secondary,\r\n text: getSafeTextColor(secondary),\r\n lightBackground: getSafeBackground('#000000', secondary),\r\n darkBackground: getSafeBackground('#ffffff', secondary)\r\n },\r\n\r\n // Safe gradients\r\n gradients: {\r\n primary: getSafeGradient(primary, theme.palette.primary.dark),\r\n secondary: getSafeGradient(secondary, primary),\r\n subtle: getSafeGradient(\r\n `${primary}1A`, // 10% opacity\r\n `${primary}0D` // 5% opacity\r\n )\r\n }\r\n };\r\n };\r\n\r\n /**\r\n * Generate opacity variants that maintain contrast\r\n * @param {string} baseColor - Base color\r\n * @param {string} textColor - Text color to maintain contrast with\r\n * @returns {Object} Opacity variants\r\n */\r\n const getSafeOpacityVariants = (baseColor, textColor = '#ffffff') => {\r\n const variants = {};\r\n const opacities = [\r\n { name: 'subtle', value: 0.05, hex: '0D' },\r\n { name: 'light', value: 0.1, hex: '1A' },\r\n { name: 'medium', value: 0.2, hex: '33' },\r\n { name: 'strong', value: 0.3, hex: '4D' },\r\n { name: 'bold', value: 0.4, hex: '66' }\r\n ];\r\n\r\n opacities.forEach(({ name, hex }) => {\r\n const colorWithOpacity = `${baseColor}${hex}`;\r\n const safeBackground = getSafeBackground(textColor, colorWithOpacity);\r\n\r\n variants[name] = {\r\n background: safeBackground,\r\n text: getSafeTextColor(safeBackground),\r\n original: colorWithOpacity\r\n };\r\n });\r\n\r\n return variants;\r\n };\r\n\r\n return {\r\n getSafeTextColor,\r\n getSafeBackground,\r\n getSafeGradient,\r\n getThemeColors,\r\n getSafeOpacityVariants,\r\n\r\n // Utility functions\r\n checkContrast: (bg, text) => getContrastRatio(bg, text),\r\n meetsAccessibility: (bg, text, standard = 'AA') => {\r\n const ratio = getContrastRatio(bg, text);\r\n return standard === 'AAA' ? ratio >= 7 : ratio >= 4.5;\r\n }\r\n };\r\n};\r\n\r\nexport default useAccessibleColors;","import { useMemo } from 'react';\r\nimport { useTheme } from '@mui/material/styles';\r\nimport { getAccessibleTextColor, getContrastRatio } from '../utils/colorExtractor';\r\n\r\n/**\r\n * Custom hook for getting accessible text colors based on background colors\r\n * Ensures WCAG compliance and consistent contrast across the application\r\n */\r\nexport const useContrastText = () => {\r\n const theme = useTheme();\r\n \r\n const utils = useMemo(() => ({\r\n /**\r\n * Get accessible text color for any background color\r\n * @param {string} backgroundColor - Background color in hex format\r\n * @param {Object} options - Options for text color preferences\r\n * @returns {string} Accessible text color\r\n */\r\n getTextColor: (backgroundColor, options = {}) => {\r\n return getAccessibleTextColor(backgroundColor, {\r\n preferredLight: theme.palette.common.white,\r\n preferredDark: theme.palette.text.primary,\r\n fallbackLight: theme.palette.grey[50],\r\n fallbackDark: theme.palette.grey[900],\r\n standard: 'AA',\r\n ...options\r\n });\r\n },\r\n\r\n /**\r\n * Get text color for primary backgrounds\r\n * @param {string} variant - 'main', 'light', or 'dark'\r\n * @returns {string} Accessible text color\r\n */\r\n getPrimaryTextColor: (variant = 'main') => {\r\n const backgroundColor = theme.palette.primary[variant];\r\n return getAccessibleTextColor(backgroundColor, {\r\n preferredLight: '#ffffff',\r\n preferredDark: theme.palette.text.primary,\r\n standard: 'AA'\r\n });\r\n },\r\n\r\n /**\r\n * Get text color for secondary backgrounds\r\n * @param {string} variant - 'main', 'light', or 'dark'\r\n * @returns {string} Accessible text color\r\n */\r\n getSecondaryTextColor: (variant = 'main') => {\r\n const backgroundColor = theme.palette.secondary[variant];\r\n return getAccessibleTextColor(backgroundColor, {\r\n preferredLight: '#ffffff',\r\n preferredDark: theme.palette.text.primary,\r\n standard: 'AA'\r\n });\r\n },\r\n\r\n /**\r\n * Get text color for status colors (success, warning, error)\r\n * @param {string} status - 'success', 'warning', 'error'\r\n * @param {string} variant - 'main', 'light', or 'dark'\r\n * @returns {string} Accessible text color\r\n */\r\n getStatusTextColor: (status, variant = 'main') => {\r\n const backgroundColor = theme.palette[status][variant];\r\n return getAccessibleTextColor(backgroundColor, {\r\n preferredLight: '#ffffff',\r\n preferredDark: theme.palette.text.primary,\r\n standard: 'AA'\r\n });\r\n },\r\n\r\n /**\r\n * Get text color for gradient backgrounds\r\n * Uses the darker color in the gradient for contrast calculation\r\n * @param {string} color1 - First gradient color\r\n * @param {string} color2 - Second gradient color\r\n * @returns {string} Accessible text color\r\n */\r\n getGradientTextColor: (color1, color2) => {\r\n // Use the color that would result in better contrast\r\n const textForColor1 = getAccessibleTextColor(color1);\r\n const textForColor2 = getAccessibleTextColor(color2);\r\n \r\n const contrast1 = getContrastRatio(color1, textForColor1);\r\n const contrast2 = getContrastRatio(color2, textForColor2);\r\n \r\n return contrast1 > contrast2 ? textForColor1 : textForColor2;\r\n },\r\n\r\n /**\r\n * Check if current combination meets WCAG standards\r\n * @param {string} backgroundColor - Background color\r\n * @param {string} textColor - Text color\r\n * @returns {Object} Object with accessibility info\r\n */\r\n checkAccessibility: (backgroundColor, textColor) => {\r\n const contrast = getContrastRatio(backgroundColor, textColor);\r\n return {\r\n contrast,\r\n meetsAA: contrast >= 4.5,\r\n meetsAAA: contrast >= 7,\r\n isGood: contrast >= 4.5,\r\n isExcellent: contrast >= 7\r\n };\r\n },\r\n\r\n /**\r\n * Get MUI sx props for text on colored backgrounds\r\n * @param {string} backgroundColor - Background color\r\n * @param {Object} options - Additional options\r\n * @returns {Object} MUI sx object with color and optional background\r\n */\r\n getSxForBackground: (backgroundColor, options = {}) => {\r\n const { includeBackground = false, ...textOptions } = options;\r\n const textColor = getAccessibleTextColor(backgroundColor, textOptions);\r\n \r\n return {\r\n color: textColor,\r\n ...(includeBackground && { backgroundColor }),\r\n };\r\n },\r\n\r\n /**\r\n * Get enhanced contrast colors for dark mode\r\n * @param {string} backgroundColor - Background color\r\n * @returns {Object} Text colors optimized for dark themes\r\n */\r\n getDarkModeColors: (backgroundColor) => {\r\n return {\r\n primary: getAccessibleTextColor(backgroundColor, {\r\n preferredLight: '#f8fafc',\r\n preferredDark: '#1e293b',\r\n fallbackLight: '#e2e8f0',\r\n fallbackDark: '#334155'\r\n }),\r\n secondary: getAccessibleTextColor(backgroundColor, {\r\n preferredLight: '#cbd5e1',\r\n preferredDark: '#475569',\r\n fallbackLight: '#94a3b8',\r\n fallbackDark: '#64748b'\r\n }),\r\n disabled: getAccessibleTextColor(backgroundColor, {\r\n preferredLight: '#94a3b8',\r\n preferredDark: '#64748b',\r\n fallbackLight: '#64748b',\r\n fallbackDark: '#94a3b8'\r\n })\r\n };\r\n }\r\n }), [theme]);\r\n\r\n return utils;\r\n};\r\n\r\nexport default useContrastText;","/**\r\n * Notification Helper Utilities\r\n * Automated helpers to ensure notifications are included with every appropriate change\r\n */\r\n\r\nimport { \r\n notify, \r\n NOTIFICATION_TYPES, \r\n NOTIFICATION_CHANNELS \r\n} from './unifiedNotifications';\r\n// Import shared types using CommonJS (compatible with both Node.js and React build tools)\r\nconst {\r\n getDefaultChannels,\r\n getDefaultPriority,\r\n isHighPriorityType\r\n} = require('./notificationTypes');\r\n\r\n// Smart API wrapper that automatically adds notifications\r\nexport const withNotifications = (apiCall, notificationConfig) => {\r\n return async (...args) => {\r\n const startTime = Date.now();\r\n \r\n try {\r\n \r\n const result = await apiCall(...args);\r\n \r\n // Auto-success notification\r\n if (notificationConfig.onSuccess) {\r\n const successConfig = {\r\n ...notificationConfig.onSuccess,\r\n data: {\r\n ...notificationConfig.onSuccess.data,\r\n result,\r\n duration: Date.now() - startTime\r\n }\r\n };\r\n \r\n await notify(successConfig);\r\n }\r\n \r\n return result;\r\n } catch (error) {\r\n // Auto-error notification\r\n if (notificationConfig.onError) {\r\n const errorConfig = {\r\n ...notificationConfig.onError,\r\n message: notificationConfig.onError.message || error.message,\r\n data: {\r\n ...notificationConfig.onError.data,\r\n error: error.message,\r\n duration: Date.now() - startTime\r\n }\r\n };\r\n \r\n await notify(errorConfig);\r\n }\r\n \r\n throw error;\r\n }\r\n };\r\n};\r\n\r\n// Notification audit decorator for functions\r\nexport const auditNotifications = (functionName, expectedNotifications = []) => {\r\n return (target, propertyKey, descriptor) => {\r\n const originalMethod = descriptor.value;\r\n \r\n descriptor.value = async function(...args) {\r\n \r\n const result = await originalMethod.apply(this, args);\r\n \r\n // Log what notifications should have been sent\r\n if (expectedNotifications.length > 0) {\r\n }\r\n \r\n return result;\r\n };\r\n \r\n return descriptor;\r\n };\r\n};\r\n\r\n// Pre-configured notification patterns for common operations \r\nexport const NotificationPatterns = {\r\n // CRUD Operations\r\n CREATE: (entityType, entityName) => ({\r\n onSuccess: {\r\n type: NOTIFICATION_TYPES.SUCCESS,\r\n channels: [NOTIFICATION_CHANNELS.TOAST, NOTIFICATION_CHANNELS.DATABASE, NOTIFICATION_CHANNELS.SOCKET],\r\n title: `${entityType} Created`,\r\n message: `${entityName} has been created successfully`,\r\n data: { operation: 'create', entityType }\r\n },\r\n onError: {\r\n type: NOTIFICATION_TYPES.ERROR,\r\n channels: [NOTIFICATION_CHANNELS.TOAST, NOTIFICATION_CHANNELS.BROWSER],\r\n title: `Failed to Create ${entityType}`,\r\n message: `Unable to create ${entityName}. Please try again.`,\r\n persistent: true,\r\n data: { operation: 'create', entityType }\r\n }\r\n }),\r\n\r\n UPDATE: (entityType, entityName) => ({\r\n onSuccess: {\r\n type: NOTIFICATION_TYPES.SUCCESS,\r\n channels: [NOTIFICATION_CHANNELS.TOAST],\r\n message: `${entityName} updated successfully`,\r\n data: { operation: 'update', entityType }\r\n },\r\n onError: {\r\n type: NOTIFICATION_TYPES.ERROR,\r\n channels: [NOTIFICATION_CHANNELS.TOAST],\r\n title: `Update Failed`,\r\n message: `Unable to update ${entityName}`,\r\n data: { operation: 'update', entityType }\r\n }\r\n }),\r\n\r\n DELETE: (entityType, entityName) => ({\r\n onSuccess: {\r\n type: NOTIFICATION_TYPES.SUCCESS,\r\n channels: [NOTIFICATION_CHANNELS.TOAST, NOTIFICATION_CHANNELS.DATABASE],\r\n message: `${entityName} deleted successfully`,\r\n data: { operation: 'delete', entityType }\r\n },\r\n onError: {\r\n type: NOTIFICATION_TYPES.ERROR,\r\n channels: [NOTIFICATION_CHANNELS.TOAST, NOTIFICATION_CHANNELS.BROWSER],\r\n title: `Delete Failed`,\r\n message: `Unable to delete ${entityName}`,\r\n persistent: true,\r\n data: { operation: 'delete', entityType }\r\n }\r\n }),\r\n\r\n // Status Changes\r\n STATUS_CHANGE: (entityType, oldStatus, newStatus) => ({\r\n onSuccess: {\r\n type: NOTIFICATION_TYPES.TICKET_UPDATED,\r\n channels: [NOTIFICATION_CHANNELS.DATABASE, NOTIFICATION_CHANNELS.SOCKET, NOTIFICATION_CHANNELS.TOAST],\r\n title: `${entityType} Status Updated`,\r\n message: `Status changed from ${oldStatus} to ${newStatus}`,\r\n data: { \r\n operation: 'status_change', \r\n entityType, \r\n oldStatus, \r\n newStatus \r\n }\r\n },\r\n onError: {\r\n type: NOTIFICATION_TYPES.ERROR,\r\n channels: [NOTIFICATION_CHANNELS.TOAST],\r\n message: `Failed to update status`,\r\n data: { operation: 'status_change', entityType }\r\n }\r\n }),\r\n\r\n // Assignment Changes\r\n ASSIGNMENT: (entityType, assigneeName) => ({\r\n onSuccess: {\r\n type: NOTIFICATION_TYPES.TICKET_ASSIGNED,\r\n channels: [NOTIFICATION_CHANNELS.DATABASE, NOTIFICATION_CHANNELS.SOCKET, NOTIFICATION_CHANNELS.PUSH],\r\n title: `${entityType} Assigned`,\r\n message: `Assigned to ${assigneeName}`,\r\n data: { \r\n operation: 'assignment', \r\n entityType, \r\n assigneeName \r\n }\r\n },\r\n onError: {\r\n type: NOTIFICATION_TYPES.ERROR,\r\n channels: [NOTIFICATION_CHANNELS.TOAST],\r\n message: `Failed to assign ${entityType}`,\r\n data: { operation: 'assignment', entityType }\r\n }\r\n }),\r\n\r\n // File Operations\r\n FILE_UPLOAD: (fileName) => ({\r\n onSuccess: {\r\n type: NOTIFICATION_TYPES.SUCCESS,\r\n channels: [NOTIFICATION_CHANNELS.TOAST],\r\n message: `${fileName} uploaded successfully`,\r\n data: { operation: 'file_upload', fileName }\r\n },\r\n onError: {\r\n type: NOTIFICATION_TYPES.ERROR,\r\n channels: [NOTIFICATION_CHANNELS.TOAST, NOTIFICATION_CHANNELS.BROWSER],\r\n title: 'Upload Failed',\r\n message: `Failed to upload ${fileName}`,\r\n data: { operation: 'file_upload', fileName }\r\n }\r\n }),\r\n\r\n // Batch Operations\r\n BATCH_OPERATION: (operationType, itemCount) => ({\r\n onSuccess: {\r\n type: NOTIFICATION_TYPES.SUCCESS,\r\n channels: [NOTIFICATION_CHANNELS.TOAST, NOTIFICATION_CHANNELS.DATABASE],\r\n title: 'Batch Operation Complete',\r\n message: `${operationType} completed for ${itemCount} items`,\r\n data: { operation: 'batch', operationType, itemCount }\r\n },\r\n onError: {\r\n type: NOTIFICATION_TYPES.ERROR,\r\n channels: [NOTIFICATION_CHANNELS.TOAST, NOTIFICATION_CHANNELS.BROWSER],\r\n title: 'Batch Operation Failed',\r\n message: `${operationType} failed`,\r\n persistent: true,\r\n data: { operation: 'batch', operationType, itemCount }\r\n }\r\n })\r\n};\r\n\r\n// Smart notification decision maker\r\nexport const decideNotificationChannels = (operationType, priority, affectedUsers) => {\r\n const channels = [NOTIFICATION_CHANNELS.TOAST]; // Always include toast for immediate feedback\r\n \r\n // Add database for persistent operations\r\n if (['create', 'update', 'delete', 'status_change', 'assignment'].includes(operationType)) {\r\n channels.push(NOTIFICATION_CHANNELS.DATABASE);\r\n }\r\n \r\n // Add socket for real-time updates\r\n if (affectedUsers && affectedUsers.length > 1) {\r\n channels.push(NOTIFICATION_CHANNELS.SOCKET);\r\n }\r\n \r\n // Add push/browser for high priority\r\n if (priority === 'high' || priority === 'urgent') {\r\n channels.push(NOTIFICATION_CHANNELS.PUSH, NOTIFICATION_CHANNELS.BROWSER);\r\n }\r\n \r\n // Add sound for urgent notifications\r\n if (priority === 'urgent') {\r\n channels.push(NOTIFICATION_CHANNELS.SOUND);\r\n }\r\n \r\n return channels;\r\n};\r\n\r\n// Notification audit logger\r\nexport const logNotificationAudit = (operation, hasNotification, shouldHaveNotification) => {\r\n const status = hasNotification ? '✅' : (shouldHaveNotification ? '❌' : '⚪');\r\n const message = hasNotification \r\n ? 'Has notification' \r\n : (shouldHaveNotification ? 'MISSING notification' : 'No notification needed');\r\n \r\n \r\n if (!hasNotification && shouldHaveNotification) {\r\n console.warn(`⚠️ NOTIFICATION AUDIT FAIL: ${operation} should have notifications but doesn't!`);\r\n // In development, you could throw an error or show a warning\r\n if (process.env.NODE_ENV === 'development') {\r\n console.trace('Stack trace for missing notification');\r\n }\r\n }\r\n};\r\n\r\n// Helper to create notification-aware API functions\r\nexport const createNotificationAwareAPI = (baseAPI) => {\r\n return {\r\n // Tickets\r\n createTicket: withNotifications(\r\n baseAPI.createTicket,\r\n NotificationPatterns.CREATE('Ticket', 'New ticket')\r\n ),\r\n \r\n updateTicket: withNotifications(\r\n baseAPI.updateTicket,\r\n NotificationPatterns.UPDATE('Ticket', 'Ticket')\r\n ),\r\n \r\n deleteTicket: withNotifications(\r\n baseAPI.deleteTicket,\r\n NotificationPatterns.DELETE('Ticket', 'Ticket')\r\n ),\r\n \r\n updateTicketStatus: withNotifications(\r\n baseAPI.updateTicketStatus,\r\n {\r\n onSuccess: {\r\n type: NOTIFICATION_TYPES.TICKET_UPDATED,\r\n channels: [NOTIFICATION_CHANNELS.DATABASE, NOTIFICATION_CHANNELS.SOCKET, NOTIFICATION_CHANNELS.TOAST],\r\n title: 'Ticket Status Updated',\r\n message: 'Status has been changed successfully'\r\n },\r\n onError: NotificationPatterns.STATUS_CHANGE('Ticket', '', '').onError\r\n }\r\n ),\r\n \r\n assignTicket: withNotifications(\r\n baseAPI.assignTicket,\r\n {\r\n onSuccess: {\r\n type: NOTIFICATION_TYPES.TICKET_ASSIGNED,\r\n channels: [NOTIFICATION_CHANNELS.DATABASE, NOTIFICATION_CHANNELS.SOCKET, NOTIFICATION_CHANNELS.PUSH],\r\n title: 'Ticket Assigned',\r\n message: 'Ticket has been assigned successfully'\r\n },\r\n onError: NotificationPatterns.ASSIGNMENT('Ticket', '').onError\r\n }\r\n ),\r\n \r\n // Properties\r\n createProperty: withNotifications(\r\n baseAPI.createProperty,\r\n NotificationPatterns.CREATE('Property', 'New property')\r\n ),\r\n \r\n updateProperty: withNotifications(\r\n baseAPI.updateProperty,\r\n NotificationPatterns.UPDATE('Property', 'Property')\r\n ),\r\n \r\n // Tenants\r\n createTenant: withNotifications(\r\n baseAPI.createTenant,\r\n NotificationPatterns.CREATE('Tenant', 'New tenant')\r\n ),\r\n \r\n // Messages\r\n sendMessage: withNotifications(\r\n baseAPI.sendMessage,\r\n {\r\n onSuccess: {\r\n type: NOTIFICATION_TYPES.MESSAGE_RECEIVED,\r\n channels: [NOTIFICATION_CHANNELS.SOCKET, NOTIFICATION_CHANNELS.BROWSER, NOTIFICATION_CHANNELS.SOUND],\r\n title: 'Message Sent',\r\n message: 'Your message has been sent'\r\n },\r\n onError: {\r\n type: NOTIFICATION_TYPES.ERROR,\r\n channels: [NOTIFICATION_CHANNELS.TOAST],\r\n message: 'Failed to send message'\r\n }\r\n }\r\n ),\r\n \r\n // File Operations\r\n uploadFile: withNotifications(\r\n baseAPI.uploadFile,\r\n NotificationPatterns.FILE_UPLOAD('File')\r\n )\r\n };\r\n};\r\n\r\n// Notification testing helper\r\nexport const testNotificationCoverage = (operations) => {\r\n \r\n const results = operations.map(operation => {\r\n const hasNotification = operation.hasNotification || false;\r\n const shouldHave = operation.shouldHaveNotification !== false; // Default to true\r\n const passed = hasNotification === shouldHave;\r\n \r\n return {\r\n operation: operation.name,\r\n hasNotification,\r\n shouldHave,\r\n passed,\r\n status: passed ? '✅ PASS' : '❌ FAIL'\r\n };\r\n });\r\n \r\n const passCount = results.filter(r => r.passed).length;\r\n const totalCount = results.length;\r\n const coverage = Math.round((passCount / totalCount) * 100);\r\n \r\n console.table(results);\r\n \r\n return { results, coverage, passed: passCount, total: totalCount };\r\n};\r\n\r\nexport default {\r\n withNotifications,\r\n auditNotifications,\r\n NotificationPatterns,\r\n decideNotificationChannels,\r\n logNotificationAudit,\r\n createNotificationAwareAPI,\r\n testNotificationCoverage\r\n};","// Notification utilities for messaging system\r\n\r\nclass NotificationManager {\r\n constructor() {\r\n this.permission = null;\r\n this.audioContext = null;\r\n this.init();\r\n }\r\n\r\n async init() {\r\n // Request notification permission\r\n if ('Notification' in window) {\r\n this.permission = await Notification.requestPermission();\r\n }\r\n\r\n // Initialize audio context for sound notifications\r\n try {\r\n this.audioContext = new (window.AudioContext || window.webkitAudioContext)();\r\n } catch (e) {\r\n console.warn('Web Audio API not supported');\r\n }\r\n }\r\n\r\n // Show browser notification\r\n showBrowserNotification(title, options = {}) {\r\n if (this.permission === 'granted' && 'Notification' in window) {\r\n const notification = new Notification(title, {\r\n icon: '/favicon.ico',\r\n badge: '/favicon.ico',\r\n ...options\r\n });\r\n\r\n // Auto close after 5 seconds\r\n setTimeout(() => {\r\n notification.close();\r\n }, 5000);\r\n\r\n return notification;\r\n }\r\n return null;\r\n }\r\n\r\n // Play notification sound\r\n playNotificationSound() {\r\n if (!this.audioContext) return;\r\n\r\n try {\r\n const oscillator = this.audioContext.createOscillator();\r\n const gainNode = this.audioContext.createGain();\r\n\r\n oscillator.connect(gainNode);\r\n gainNode.connect(this.audioContext.destination);\r\n\r\n // Create a pleasant notification sound\r\n oscillator.frequency.setValueAtTime(800, this.audioContext.currentTime);\r\n oscillator.frequency.setValueAtTime(600, this.audioContext.currentTime + 0.1);\r\n \r\n gainNode.gain.setValueAtTime(0, this.audioContext.currentTime);\r\n gainNode.gain.linearRampToValueAtTime(0.3, this.audioContext.currentTime + 0.01);\r\n gainNode.gain.linearRampToValueAtTime(0, this.audioContext.currentTime + 0.3);\r\n\r\n oscillator.start(this.audioContext.currentTime);\r\n oscillator.stop(this.audioContext.currentTime + 0.3);\r\n } catch (e) {\r\n console.warn('Could not play notification sound:', e);\r\n }\r\n }\r\n\r\n // Show message notification\r\n showMessageNotification(senderName, messageContent, propertyAddress = '') {\r\n const title = `New message from ${senderName}`;\r\n const body = propertyAddress \r\n ? `${propertyAddress}\\n${messageContent.substring(0, 100)}${messageContent.length > 100 ? '...' : ''}`\r\n : messageContent.substring(0, 100) + (messageContent.length > 100 ? '...' : '');\r\n\r\n this.showBrowserNotification(title, {\r\n body,\r\n tag: 'message-notification',\r\n renotify: true\r\n });\r\n\r\n this.playNotificationSound();\r\n }\r\n\r\n // Check if notifications are supported\r\n static isSupported() {\r\n return 'Notification' in window;\r\n }\r\n\r\n // Check if permission is granted\r\n hasPermission() {\r\n return this.permission === 'granted';\r\n }\r\n\r\n // Request permission if not already granted\r\n async requestPermission() {\r\n if ('Notification' in window && this.permission !== 'granted') {\r\n this.permission = await Notification.requestPermission();\r\n }\r\n return this.permission;\r\n }\r\n}\r\n\r\n// Create and export singleton instance\r\nconst notificationManager = new NotificationManager();\r\nexport default notificationManager;\r\n\r\n// Export utility functions\r\nexport const showMessageNotification = (senderName, messageContent, propertyAddress) => {\r\n notificationManager.showMessageNotification(senderName, messageContent, propertyAddress);\r\n};\r\n\r\nexport const requestNotificationPermission = () => {\r\n return notificationManager.requestPermission();\r\n};\r\n\r\nexport const hasNotificationPermission = () => {\r\n return notificationManager.hasPermission();\r\n};\r\n\r\nexport const isNotificationSupported = () => {\r\n return NotificationManager.isSupported();\r\n};","// Push notification utility functions\r\nimport api from '../services/api';\r\n\r\n// Check if push notifications are supported\r\nexport const isPushNotificationSupported = () => {\r\n return 'serviceWorker' in navigator && 'PushManager' in window;\r\n};\r\n\r\n// Check current permission status\r\nexport const getNotificationPermission = () => {\r\n if (!isPushNotificationSupported()) {\r\n return 'unsupported';\r\n }\r\n return Notification.permission;\r\n};\r\n\r\n// Request notification permission\r\nexport const requestNotificationPermission = async () => {\r\n if (!isPushNotificationSupported()) {\r\n throw new Error('Push notifications are not supported in this browser');\r\n }\r\n\r\n const permission = await Notification.requestPermission();\r\n return permission;\r\n};\r\n\r\n// Convert URL-safe base64 to Uint8Array (for VAPID key)\r\nconst urlBase64ToUint8Array = (base64String) => {\r\n const padding = '='.repeat((4 - base64String.length % 4) % 4);\r\n const base64 = (base64String + padding)\r\n .replace(/-/g, '+')\r\n .replace(/_/g, '/');\r\n\r\n const rawData = window.atob(base64);\r\n const outputArray = new Uint8Array(rawData.length);\r\n\r\n for (let i = 0; i < rawData.length; ++i) {\r\n outputArray[i] = rawData.charCodeAt(i);\r\n }\r\n return outputArray;\r\n};\r\n\r\n// Get or create push subscription\r\nexport const subscribeToPushNotifications = async () => {\r\n if (!isPushNotificationSupported()) {\r\n throw new Error('Push notifications are not supported');\r\n }\r\n\r\n if (Notification.permission !== 'granted') {\r\n throw new Error('Notification permission not granted');\r\n }\r\n\r\n try {\r\n // Unregister any existing service workers to ensure we get a fresh start\r\n const existingRegistrations = await navigator.serviceWorker.getRegistrations();\r\n for (let registration of existingRegistrations) {\r\n await registration.unregister();\r\n }\r\n\r\n // Register service worker\r\n const registration = await navigator.serviceWorker.register('/sw.js', {\r\n scope: '/',\r\n updateViaCache: 'none' // Don't cache the service worker\r\n });\r\n\r\n // Wait for service worker to be ready\r\n await navigator.serviceWorker.ready;\r\n\r\n // Get existing subscription\r\n let subscription = await registration.pushManager.getSubscription();\r\n \r\n if (!subscription) {\r\n // Create new subscription\r\n const vapidPublicKey = process.env.REACT_APP_VAPID_PUBLIC_KEY || \r\n 'BJ2eTitSHPWl9WBAk0F1Drwmv6bQB48aDpM1ilutZcdygYfpbK7ODrlMSzvplaHWVwPtvQ1x-Y2SK2LadSQZ2mc';\r\n \r\n \r\n const subscriptionOptions = {\r\n userVisibleOnly: true,\r\n applicationServerKey: urlBase64ToUint8Array(vapidPublicKey)\r\n };\r\n \r\n \r\n subscription = await registration.pushManager.subscribe(subscriptionOptions);\r\n }\r\n\r\n // Send subscription to backend\r\n await api.post('/notifications/subscribe', {\r\n subscription: subscription.toJSON()\r\n });\r\n\r\n return subscription;\r\n } catch (error) {\r\n console.error('Error subscribing to push notifications:', error);\r\n console.error('Error name:', error.name);\r\n console.error('Error message:', error.message);\r\n console.error('Error stack:', error.stack);\r\n \r\n // Provide more specific error messages\r\n if (error.name === 'AbortError') {\r\n throw new Error('Push subscription was aborted. This might be due to invalid VAPID keys or browser restrictions.');\r\n } else if (error.name === 'NotAllowedError') {\r\n throw new Error('Push notifications permission was denied by the user.');\r\n } else if (error.name === 'NotSupportedError') {\r\n throw new Error('Push notifications are not supported in this browser.');\r\n }\r\n \r\n throw error;\r\n }\r\n};\r\n\r\n// Unsubscribe from push notifications\r\nexport const unsubscribeFromPushNotifications = async () => {\r\n if (!isPushNotificationSupported()) {\r\n return;\r\n }\r\n\r\n try {\r\n const registration = await navigator.serviceWorker.getRegistration();\r\n if (!registration) {\r\n return;\r\n }\r\n\r\n const subscription = await registration.pushManager.getSubscription();\r\n if (!subscription) {\r\n return;\r\n }\r\n\r\n // Unsubscribe from browser\r\n await subscription.unsubscribe();\r\n\r\n // Remove subscription from backend\r\n await api.post('/notifications/unsubscribe', {\r\n endpoint: subscription.endpoint\r\n });\r\n\r\n } catch (error) {\r\n console.error('Error unsubscribing from push notifications:', error);\r\n throw error;\r\n }\r\n};\r\n\r\n// Check if currently subscribed\r\nexport const isPushSubscribed = async () => {\r\n if (!isPushNotificationSupported()) {\r\n return false;\r\n }\r\n\r\n try {\r\n const registration = await navigator.serviceWorker.getRegistration();\r\n if (!registration) {\r\n return false;\r\n }\r\n\r\n const subscription = await registration.pushManager.getSubscription();\r\n return !!subscription;\r\n } catch (error) {\r\n console.error('Error checking push subscription:', error);\r\n return false;\r\n }\r\n};\r\n\r\n// Send a test notification\r\nexport const sendTestNotification = async () => {\r\n if (!isPushNotificationSupported()) {\r\n throw new Error('Push notifications are not supported');\r\n }\r\n\r\n try {\r\n await api.post('/notifications/test');\r\n } catch (error) {\r\n console.error('Error sending test notification:', error);\r\n throw error;\r\n }\r\n};\r\n\r\n// Show local notification (fallback)\r\nexport const showLocalNotification = (title, options = {}) => {\r\n if (!isPushNotificationSupported()) {\r\n return;\r\n }\r\n\r\n if (Notification.permission === 'granted') {\r\n const notification = new Notification(title, {\r\n icon: '/favicon.ico',\r\n badge: '/favicon.ico',\r\n ...options\r\n });\r\n\r\n // Auto close after 5 seconds\r\n setTimeout(() => {\r\n notification.close();\r\n }, 5000);\r\n\r\n return notification;\r\n }\r\n};","import api from '../services/api';\r\n\r\n/**\r\n * Centralized tenant logout function to ensure consistent cleanup\r\n * @param {Function} navigate - React Router navigate function\r\n */\r\nexport const logoutTenant = (navigate) => {\r\n // Remove tenant authentication data\r\n localStorage.removeItem('tenantToken');\r\n localStorage.removeItem('tenantData');\r\n \r\n // Clear API authorization header\r\n delete api.defaults.headers.common['Authorization'];\r\n \r\n // Dispatch custom event to immediately notify theme context\r\n window.dispatchEvent(new CustomEvent('tenantLogout'));\r\n \r\n // Navigate to main login page (tenant tab will be available there)\r\n navigate('/login');\r\n};\r\n\r\n/**\r\n * Check if tenant is authenticated\r\n * @returns {boolean} - True if tenant has valid authentication\r\n */\r\nexport const isTenantAuthenticated = () => {\r\n const tenantToken = localStorage.getItem('tenantToken');\r\n const tenantData = localStorage.getItem('tenantData');\r\n return !!(tenantToken && tenantData);\r\n};"],"mappings":"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","names":["exports","module","NOTIFICATION_TYPES","NOTIFICATION_CHANNELS","getDefaultChannels","getDefaultPriority","isHighPriorityType","requestNotificationPermission","subscribeToPushNotifications","import_react","axios","user","React","import_react","React","import_react","React","CssBaseline","notifications","MdSupport","MdReportProblem","MdWork","MdSchedule","MdConstruction","MdPsychology","MdBusiness","MdHome","MdPeople","MdEngineering","MdInventory","MdDashboard","lightenColor","darkenColor","React","MdMenu","MdKeyboardArrowDown","MdMessage","MdNotifications","MdAccountCircle","import_react","import_material","React","import_react","import_material","import_react_router_dom","React","import_react","import_material","React","import_react","import_material","import_react","import_styles","lightenColor","darkenColor","React","React","import_react","import_material","React","import_react","import_material","React","import_react","import_material","import_icons_material","React","import_react","import_material","import_icons_material","import_date_fns","api","useSocket","useAuth","React","ErrorIcon","NotificationsIcon","SettingsIcon","import_react","import_material","import_icons_material","React","import_react","React","import_react","import_icons_material","import_react","import_styles","import_react","import_styles","NotificationManager","requestNotificationPermission","NotificationManager","subscribeToPushNotifications","registration"]}
1
+ {"version":3,"sources":["../src/utils/notificationTypes.js","../src/index.js","../src/components/Navigation/Navbar.js","../src/contexts/AuthContext.js","../src/services/api.js","../src/contexts/NotificationContext.js","../src/contexts/ThemeContext.js","../src/utils/colorExtractor.js","../src/utils/themeContrast.js","../src/components/Layout/PageLayout.js","../src/components/Layout/PageHeader.js","../src/components/Layout/AuthLayout.js","../src/components/Layout/TenantLayout.js","../src/contexts/TenantThemeContext.js","../src/components/UI/LoadingSpinner.js","../src/components/UI/ModernCard.js","../src/components/Notifications/NotificationManager.js","../src/components/Notifications/NotificationBell.js","../src/components/ErrorBoundary/ErrorBoundary.js","../src/contexts/SocketContext.js","../src/hooks/useNotifications.js","../src/hooks/useUnifiedNotifications.js","../src/utils/unifiedNotifications.js","../src/hooks/useAccessibleColors.js","../src/hooks/useContrastText.js","../src/utils/notificationHelpers.js","../src/utils/notifications.js","../src/utils/pushNotifications.js","../src/utils/tenantAuth.js"],"sourcesContent":["/**\r\n * Shared notification types and constants\r\n * This file is used by both frontend and backend to ensure consistency\r\n */\r\n\r\n// Notification types enum\r\nconst NOTIFICATION_TYPES = {\r\n // Toast notification types (UI feedback)\r\n SUCCESS: 'success',\r\n ERROR: 'error',\r\n WARNING: 'warning',\r\n INFO: 'info',\r\n LOADING: 'loading',\r\n \r\n // Ticket/issue notification types\r\n TICKET_CREATED: 'ticket_created',\r\n TICKET_UPDATED: 'ticket_updated',\r\n TICKET_ASSIGNED: 'ticket_assigned',\r\n TICKET_RESOLVED: 'ticket_resolved',\r\n TICKET_COMMENTED: 'ticket_commented',\r\n TICKET_STATUS_CHANGED: 'ticket_status_changed',\r\n \r\n // Messaging notification types\r\n MESSAGE_RECEIVED: 'message_received',\r\n MENTION_RECEIVED: 'mention_received',\r\n \r\n // System notification types\r\n SYSTEM_ALERT: 'system_alert',\r\n MAINTENANCE_SCHEDULED: 'maintenance_scheduled',\r\n \r\n // Tenant-specific types\r\n LEASE_EXPIRING: 'lease_expiring',\r\n PAYMENT_DUE: 'payment_due',\r\n PAYMENT_OVERDUE: 'payment_overdue',\r\n \r\n // Property-specific types\r\n PROPERTY_UPDATED: 'property_updated',\r\n APPLIANCE_MAINTENANCE_DUE: 'appliance_maintenance_due'\r\n};\r\n\r\n// Notification channels enum\r\nconst NOTIFICATION_CHANNELS = {\r\n TOAST: 'toast', // In-app toast notifications\r\n BROWSER: 'browser', // Browser notifications\r\n PUSH: 'push', // Push notifications (service worker)\r\n DATABASE: 'database', // Persistent database notifications\r\n SOCKET: 'socket', // Real-time socket notifications\r\n EMAIL: 'email', // Email notifications\r\n SMS: 'sms', // SMS notifications\r\n SOUND: 'sound' // Audio notifications\r\n};\r\n\r\n// Priority levels\r\nconst PRIORITY_LEVELS = {\r\n LOW: 'low',\r\n NORMAL: 'normal',\r\n HIGH: 'high',\r\n URGENT: 'urgent'\r\n};\r\n\r\n// Notification status\r\nconst NOTIFICATION_STATUS = {\r\n UNREAD: 'unread',\r\n READ: 'read',\r\n DISMISSED: 'dismissed',\r\n ARCHIVED: 'archived'\r\n};\r\n\r\n// Default channel configurations for different notification types\r\nconst DEFAULT_CHANNEL_CONFIGS = {\r\n [NOTIFICATION_TYPES.SUCCESS]: [NOTIFICATION_CHANNELS.TOAST],\r\n [NOTIFICATION_TYPES.ERROR]: [NOTIFICATION_CHANNELS.TOAST, NOTIFICATION_CHANNELS.BROWSER],\r\n [NOTIFICATION_TYPES.WARNING]: [NOTIFICATION_CHANNELS.TOAST],\r\n [NOTIFICATION_TYPES.INFO]: [NOTIFICATION_CHANNELS.TOAST],\r\n \r\n [NOTIFICATION_TYPES.TICKET_CREATED]: [\r\n NOTIFICATION_CHANNELS.DATABASE,\r\n NOTIFICATION_CHANNELS.SOCKET,\r\n NOTIFICATION_CHANNELS.PUSH\r\n ],\r\n [NOTIFICATION_TYPES.TICKET_UPDATED]: [\r\n NOTIFICATION_CHANNELS.DATABASE,\r\n NOTIFICATION_CHANNELS.SOCKET,\r\n NOTIFICATION_CHANNELS.TOAST\r\n ],\r\n [NOTIFICATION_TYPES.TICKET_ASSIGNED]: [\r\n NOTIFICATION_CHANNELS.DATABASE,\r\n NOTIFICATION_CHANNELS.SOCKET,\r\n NOTIFICATION_CHANNELS.PUSH\r\n ],\r\n [NOTIFICATION_TYPES.TICKET_RESOLVED]: [\r\n NOTIFICATION_CHANNELS.DATABASE,\r\n NOTIFICATION_CHANNELS.SOCKET,\r\n NOTIFICATION_CHANNELS.PUSH\r\n ],\r\n [NOTIFICATION_TYPES.TICKET_COMMENTED]: [\r\n NOTIFICATION_CHANNELS.DATABASE,\r\n NOTIFICATION_CHANNELS.SOCKET\r\n ],\r\n \r\n [NOTIFICATION_TYPES.MESSAGE_RECEIVED]: [\r\n NOTIFICATION_CHANNELS.BROWSER,\r\n NOTIFICATION_CHANNELS.SOUND,\r\n NOTIFICATION_CHANNELS.SOCKET\r\n ],\r\n \r\n [NOTIFICATION_TYPES.SYSTEM_ALERT]: [\r\n NOTIFICATION_CHANNELS.DATABASE,\r\n NOTIFICATION_CHANNELS.PUSH,\r\n NOTIFICATION_CHANNELS.BROWSER\r\n ],\r\n \r\n [NOTIFICATION_TYPES.PAYMENT_OVERDUE]: [\r\n NOTIFICATION_CHANNELS.DATABASE,\r\n NOTIFICATION_CHANNELS.PUSH,\r\n NOTIFICATION_CHANNELS.EMAIL\r\n ]\r\n};\r\n\r\n// Default priority mapping\r\nconst DEFAULT_PRIORITY_MAPPING = {\r\n [NOTIFICATION_TYPES.SUCCESS]: PRIORITY_LEVELS.LOW,\r\n [NOTIFICATION_TYPES.ERROR]: PRIORITY_LEVELS.HIGH,\r\n [NOTIFICATION_TYPES.WARNING]: PRIORITY_LEVELS.NORMAL,\r\n [NOTIFICATION_TYPES.INFO]: PRIORITY_LEVELS.LOW,\r\n \r\n [NOTIFICATION_TYPES.TICKET_CREATED]: PRIORITY_LEVELS.NORMAL,\r\n [NOTIFICATION_TYPES.TICKET_UPDATED]: PRIORITY_LEVELS.LOW,\r\n [NOTIFICATION_TYPES.TICKET_ASSIGNED]: PRIORITY_LEVELS.NORMAL,\r\n [NOTIFICATION_TYPES.TICKET_RESOLVED]: PRIORITY_LEVELS.NORMAL,\r\n [NOTIFICATION_TYPES.TICKET_COMMENTED]: PRIORITY_LEVELS.LOW,\r\n \r\n [NOTIFICATION_TYPES.MESSAGE_RECEIVED]: PRIORITY_LEVELS.NORMAL,\r\n [NOTIFICATION_TYPES.SYSTEM_ALERT]: PRIORITY_LEVELS.HIGH,\r\n [NOTIFICATION_TYPES.PAYMENT_OVERDUE]: PRIORITY_LEVELS.URGENT,\r\n [NOTIFICATION_TYPES.LEASE_EXPIRING]: PRIORITY_LEVELS.HIGH\r\n};\r\n\r\n// Notification icons mapping\r\nconst NOTIFICATION_ICONS = {\r\n [NOTIFICATION_TYPES.SUCCESS]: '✅',\r\n [NOTIFICATION_TYPES.ERROR]: '❌',\r\n [NOTIFICATION_TYPES.WARNING]: '⚠️',\r\n [NOTIFICATION_TYPES.INFO]: 'ℹ️',\r\n \r\n [NOTIFICATION_TYPES.TICKET_CREATED]: '📋',\r\n [NOTIFICATION_TYPES.TICKET_UPDATED]: '🔄',\r\n [NOTIFICATION_TYPES.TICKET_ASSIGNED]: '👤',\r\n [NOTIFICATION_TYPES.TICKET_RESOLVED]: '✅',\r\n [NOTIFICATION_TYPES.TICKET_COMMENTED]: '💬',\r\n \r\n [NOTIFICATION_TYPES.MESSAGE_RECEIVED]: '💬',\r\n [NOTIFICATION_TYPES.SYSTEM_ALERT]: '🚨',\r\n [NOTIFICATION_TYPES.PAYMENT_OVERDUE]: '💰',\r\n [NOTIFICATION_TYPES.LEASE_EXPIRING]: '📅'\r\n};\r\n\r\n// Helper functions\r\nfunction getDefaultChannels(notificationType) {\r\n return DEFAULT_CHANNEL_CONFIGS[notificationType] || [NOTIFICATION_CHANNELS.TOAST];\r\n}\r\n\r\nfunction getDefaultPriority(notificationType) {\r\n return DEFAULT_PRIORITY_MAPPING[notificationType] || PRIORITY_LEVELS.NORMAL;\r\n}\r\n\r\nconst getNotificationIcon = (notificationType) => {\r\n return NOTIFICATION_ICONS[notificationType] || 'ℹ️';\r\n};\r\n\r\nconst isHighPriorityType = (notificationType) => {\r\n const priority = getDefaultPriority(notificationType);\r\n return [PRIORITY_LEVELS.HIGH, PRIORITY_LEVELS.URGENT].includes(priority);\r\n};\r\n\r\nconst shouldPlaySound = (notificationType) => {\r\n const channels = getDefaultChannels(notificationType);\r\n return channels.includes(NOTIFICATION_CHANNELS.SOUND) || \r\n [NOTIFICATION_TYPES.MESSAGE_RECEIVED, NOTIFICATION_TYPES.SYSTEM_ALERT].includes(notificationType);\r\n};\r\n\r\n// CommonJS export (works for both Node.js backend and React frontend with build tools)\r\nmodule.exports = {\r\n NOTIFICATION_TYPES,\r\n NOTIFICATION_CHANNELS,\r\n PRIORITY_LEVELS,\r\n NOTIFICATION_STATUS,\r\n DEFAULT_CHANNEL_CONFIGS,\r\n DEFAULT_PRIORITY_MAPPING,\r\n NOTIFICATION_ICONS,\r\n getDefaultChannels,\r\n getDefaultPriority,\r\n getNotificationIcon,\r\n isHighPriorityType,\r\n shouldPlaySound\r\n};","export * from './components/Navigation';\r\nexport * from './components/Layout';\r\nexport * from './components/UI';\r\nexport * from './components/Notifications';\r\nexport * from './components/ErrorBoundary';\r\n\r\nexport * from './contexts/AuthContext';\r\nexport * from './contexts/NotificationContext';\r\nexport * from './contexts/SocketContext';\r\nexport * from './contexts/ThemeContext';\r\nexport * from './contexts/TenantThemeContext';\r\n\r\n// useAuth is exported from AuthContext\r\n// useSocket is exported from SocketContext\r\nexport { useAuth } from './contexts/AuthContext';\r\nexport { useSocket } from './contexts/SocketContext';\r\nexport * from './hooks/useNotifications';\r\nexport * from './hooks/useUnifiedNotifications';\r\nexport * from './hooks/useAccessibleColors';\r\nexport * from './hooks/useContrastText';\r\n\r\nexport * from './services/api';\r\n// export * from './services/auth'; // TODO: services/auth does not exist yet\r\n// export * from './services/socket'; // TODO: services/socket does not exist yet\r\n\r\nexport * from './utils/colorExtractor';\r\nexport * from './utils/notificationHelpers';\r\nexport * from './utils/notifications';\r\nexport {\r\n showMessageNotification,\r\n requestNotificationPermission,\r\n hasNotificationPermission,\r\n isNotificationSupported\r\n} from './utils/notifications';\r\nexport * from './utils/pushNotifications';\r\nexport {\r\n subscribeToPushNotifications,\r\n unsubscribeFromPushNotifications,\r\n isPushNotificationSupported,\r\n isPushSubscribed,\r\n sendTestNotification,\r\n showLocalNotification\r\n} from './utils/pushNotifications';\r\nexport * from './utils/tenantAuth';\r\nexport * from './utils/themeContrast';\r\nexport * from './utils/unifiedNotifications';\r\n","import React, { useState, useEffect } from 'react';\r\nimport {\r\n AppBar,\r\n Toolbar,\r\n Button,\r\n IconButton,\r\n Typography,\r\n Badge,\r\n Box,\r\n Drawer,\r\n List,\r\n ListItem,\r\n ListItemText,\r\n ListItemIcon,\r\n Menu,\r\n MenuItem,\r\n useMediaQuery,\r\n useTheme,\r\n Stack,\r\n Divider,\r\n Avatar\r\n} from '@mui/material';\r\nimport {\r\n Dashboard as MdDashboard,\r\n ReportProblem as MdReportProblem,\r\n Work as MdWork,\r\n Engineering as MdEngineering,\r\n Home as MdHome,\r\n People as MdPeople,\r\n AccountCircle as MdAccountCircle,\r\n Menu as MdMenu,\r\n Notifications as MdNotifications,\r\n Settings as MdSettings,\r\n Message as MdMessage,\r\n Psychology as MdPsychology,\r\n Business as MdBusiness,\r\n Support as MdSupport,\r\n KeyboardArrowDown as MdKeyboardArrowDown,\r\n Inventory as MdInventory,\r\n Schedule as MdSchedule,\r\n Construction as MdConstruction,\r\n} from '@mui/icons-material';\r\nimport { useNavigate, useLocation } from 'react-router-dom';\r\nimport { useAuth } from '../../contexts/AuthContext';\r\nimport { useNotification } from '../../contexts/NotificationContext';\r\nimport { useCustomTheme } from '../../contexts/ThemeContext';\r\nimport api from '../../services/api';\r\nimport { extractColorsFromImage, isColorDark, getAccessibleTextColor, getContrastRatio } from '../../utils/colorExtractor';\r\n\r\n// Enhanced Navbar with Dynamic Tenant Banner Color Theming\r\n// This component now uses the property manager's chosen tenant banner color \r\n// (from preferredBrandingColor) to create sophisticated gradients and hover effects\r\n\r\nconst Navbar = () => {\r\n const [mobileOpen, setMobileOpen] = useState(false);\r\n const [userMenuAnchor, setUserMenuAnchor] = useState(null);\r\n const [notificationMenuAnchor, setNotificationMenuAnchor] = useState(null);\r\n const [recentTickets, setRecentTickets] = useState([]);\r\n const [logoColors, setLogoColors] = useState(null);\r\n const [operationsMenuAnchor, setOperationsMenuAnchor] = useState(null);\r\n const [managementMenuAnchor, setManagementMenuAnchor] = useState(null);\r\n const navigate = useNavigate();\r\n const location = useLocation();\r\n const { user, companyBranding, logout } = useAuth();\r\n const { isDarkMode } = useCustomTheme();\r\n const { notifications, removeNotification, clearAllNotifications } = useNotification();\r\n const theme = useTheme();\r\n const isMobile = useMediaQuery(theme.breakpoints.down('md'));\r\n const isTablet = useMediaQuery(theme.breakpoints.down('lg'));\r\n const isSmallScreen = useMediaQuery(theme.breakpoints.down('sm'));\r\n\r\n // Helper function to get effective branding (company branding for employees)\r\n const getEffectiveBranding = () => {\r\n if ((user?.role === 'maintenance' || user?.role === 'property_manager') && companyBranding) {\r\n return companyBranding;\r\n }\r\n return {\r\n companyName: user?.companyName || '',\r\n companyLogo: user?.companyLogo || null,\r\n preferredBrandingColor: user?.preferredBrandingColor || 0\r\n };\r\n };\r\n\r\n // Fetch recent notifications\r\n useEffect(() => {\r\n const fetchNotifications = async () => {\r\n try {\r\n // Check if we're in the tenant portal based on the current path\r\n const isTenantPortal = location.pathname.startsWith('/tenant');\r\n const endpoint = isTenantPortal ? '/tenant-portal/notifications/unread' : '/notifications/unread';\r\n \r\n const response = await api.get(endpoint);\r\n const notifications = response.data.notifications || [];\r\n \r\n if (notifications.length > 0) {\r\n const formattedNotifications = notifications.map(notif => ({\r\n id: notif._id,\r\n notificationId: notif._id, // Add this for marking as read\r\n title: notif.title,\r\n message: notif.message,\r\n time: new Date(notif.createdAt).toLocaleString(),\r\n type: notif.type,\r\n ticketId: notif.ticketId,\r\n ticketNumber: notif.ticketNumber,\r\n actionUrl: notif.actionUrl,\r\n priority: notif.priority,\r\n read: notif.read\r\n }));\r\n setRecentTickets(formattedNotifications);\r\n }\r\n } catch (error) {\r\n console.error('Error fetching notifications:', error);\r\n }\r\n };\r\n\r\n if (user) {\r\n fetchNotifications();\r\n const interval = setInterval(fetchNotifications, 30000);\r\n return () => clearInterval(interval);\r\n }\r\n }, [user]);\r\n\r\n // Extract colors from logo when user logo changes\r\n useEffect(() => {\r\n const extractLogoColors = async () => {\r\n const effectiveBranding = getEffectiveBranding();\r\n if (effectiveBranding.companyLogo) {\r\n try {\r\n const baseURL = api.defaults.baseURL.replace('/api', '');\r\n const logoUrl = `${baseURL}/uploads/logos/${effectiveBranding.companyLogo}`;\r\n const colors = await extractColorsFromImage(logoUrl);\r\n setLogoColors(colors);\r\n } catch (error) {\r\n console.error('Error extracting logo colors:', error);\r\n setLogoColors(null);\r\n }\r\n } else {\r\n setLogoColors(null);\r\n }\r\n };\r\n\r\n extractLogoColors();\r\n }, [user?.companyLogo, companyBranding]);\r\n\r\n const handleDrawerToggle = () => {\r\n setMobileOpen(!mobileOpen);\r\n };\r\n\r\n const handleNavigate = (path) => {\r\n navigate(path);\r\n setMobileOpen(false);\r\n };\r\n\r\n const handleUserMenuClick = (event) => {\r\n setUserMenuAnchor(event.currentTarget);\r\n };\r\n\r\n const handleUserMenuClose = () => {\r\n setUserMenuAnchor(null);\r\n };\r\n\r\n const handleNotificationMenuClick = (event) => {\r\n setNotificationMenuAnchor(event.currentTarget);\r\n };\r\n\r\n const handleNotificationMenuClose = () => {\r\n setNotificationMenuAnchor(null);\r\n };\r\n\r\n const handleOperationsMenuClick = (event) => {\r\n setOperationsMenuAnchor(event.currentTarget);\r\n };\r\n\r\n const handleOperationsMenuClose = () => {\r\n setOperationsMenuAnchor(null);\r\n };\r\n\r\n const handleManagementMenuClick = (event) => {\r\n setManagementMenuAnchor(event.currentTarget);\r\n };\r\n\r\n const handleManagementMenuClose = () => {\r\n setManagementMenuAnchor(null);\r\n };\r\n\r\n const markNotificationAsRead = async (notificationId) => {\r\n try {\r\n // Check if we're in the tenant portal based on the current path\r\n const isTenantPortal = location.pathname.startsWith('/tenant');\r\n \r\n if (isTenantPortal) {\r\n // Use tenant portal endpoint\r\n await api.put(`/tenant-portal/notifications/${notificationId}/read`);\r\n } else {\r\n // Use property manager endpoint\r\n await api.put(`/notifications/${notificationId}/read`);\r\n }\r\n } catch (error) {\r\n console.error('Error marking notification as read:', error);\r\n // Fallback: try the other endpoint if the first one fails\r\n try {\r\n const isTenantPortal = location.pathname.startsWith('/tenant');\r\n if (isTenantPortal) {\r\n await api.put(`/notifications/${notificationId}/read`);\r\n } else {\r\n await api.put(`/tenant-portal/notifications/${notificationId}/read`);\r\n }\r\n } catch (fallbackError) {\r\n console.error('Fallback also failed:', fallbackError);\r\n }\r\n }\r\n };\r\n\r\n const handleLogout = () => {\r\n logout();\r\n handleUserMenuClose();\r\n };\r\n\r\n // Categorized navigation structure\r\n const navigationCategories = {\r\n operations: {\r\n label: 'Operations',\r\n icon: MdSupport,\r\n items: [\r\n { path: '/tickets', label: 'Tickets', icon: MdReportProblem },\r\n { path: '/work-orders', label: 'Work Orders', icon: MdWork, featureRequired: 'maintenanceModule' },\r\n { path: '/maintenance-schedules', label: 'Maintenance Schedules', icon: MdSchedule, roles: ['property_manager', 'owner', 'admin'], featureRequired: 'maintenanceModule' },\r\n { path: '/renovations', label: 'Renovations', icon: MdConstruction, roles: ['property_manager', 'owner', 'admin'], featureRequired: 'renovationsModule' },\r\n { path: '/ai-training', label: 'AI Training', icon: MdPsychology, roles: ['owner', 'property_manager', 'admin'], featureRequired: 'aiAssistant' },\r\n ]\r\n },\r\n management: {\r\n label: 'Management',\r\n icon: MdBusiness,\r\n items: [\r\n { path: '/properties', label: 'Properties', icon: MdHome, roles: ['property_manager', 'owner', 'admin'] },\r\n { path: '/tenants', label: 'Tenants', icon: MdPeople, roles: ['property_manager', 'owner', 'admin'] },\r\n { path: '/workers', label: 'Workers', icon: MdEngineering, roles: ['property_manager', 'owner', 'admin'], featureRequired: 'workersModule' },\r\n { path: '/property-managers', label: 'Property Managers', icon: MdBusiness, roles: ['owner', 'admin'] },\r\n { path: '/inventory', label: 'Inventory', icon: MdInventory, roles: ['property_manager', 'owner', 'admin'], featureRequired: 'inventoryModule' },\r\n ]\r\n }\r\n };\r\n\r\n // Standalone items that don't fit in categories\r\n const standaloneItems = [\r\n { path: '/dashboard', label: 'Dashboard', icon: MdDashboard },\r\n ];\r\n\r\n const notificationCount = recentTickets.length;\r\n\r\n // Generate lighter and darker color variations\r\n const lightenColor = (hex, amount) => {\r\n const num = parseInt(hex.replace(\"#\", \"\"), 16);\r\n const r = Math.min(255, (num >> 16) + Math.round(255 * amount));\r\n const g = Math.min(255, (num >> 8 & 0x00FF) + Math.round(255 * amount));\r\n const b = Math.min(255, (num & 0x0000FF) + Math.round(255 * amount));\r\n return `#${((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1)}`;\r\n };\r\n\r\n const darkenColor = (hex, amount) => {\r\n const num = parseInt(hex.replace(\"#\", \"\"), 16);\r\n const r = Math.max(0, (num >> 16) - Math.round(255 * amount));\r\n const g = Math.max(0, (num >> 8 & 0x00FF) - Math.round(255 * amount));\r\n const b = Math.max(0, (num & 0x0000FF) - Math.round(255 * amount));\r\n return `#${((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1)}`;\r\n };\r\n\r\n // Generate dynamic navbar styles based on property manager's chosen tenant banner color\r\n const getNavbarStyles = () => {\r\n if (!logoColors || !logoColors.topColors) {\r\n // Default Material-UI theme colors\r\n return {\r\n backgroundColor: theme.palette.primary.main,\r\n color: theme.palette.primary.contrastText\r\n };\r\n }\r\n\r\n // Get the property manager's chosen tenant banner color\r\n const effectiveBranding = getEffectiveBranding();\r\n const chosenColorIndex = effectiveBranding.preferredBrandingColor || 0;\r\n const chosenColor = logoColors.topColors?.[chosenColorIndex];\r\n const tenantBannerColor = chosenColor?.hex || logoColors.primaryHex || '#1976d2';\r\n \r\n // Create sophisticated gradient using the tenant banner color\r\n const lightVariant = lightenColor(tenantBannerColor, 0.3);\r\n const darkVariant = darkenColor(tenantBannerColor, 0.2);\r\n \r\n // Create gradient based on mode\r\n const gradientStart = isDarkMode ? darkVariant : lightVariant;\r\n const gradientEnd = tenantBannerColor;\r\n \r\n // Get accessible text color for the primary banner color\r\n const textColor = getAccessibleTextColor(tenantBannerColor, {\r\n preferredLight: '#ffffff',\r\n preferredDark: '#000000',\r\n fallbackLight: '#f8fafc',\r\n fallbackDark: '#1e293b'\r\n });\r\n \r\n return {\r\n background: `linear-gradient(135deg, ${gradientStart} 0%, ${gradientEnd} 70%, ${darkVariant} 100%)`,\r\n color: textColor,\r\n boxShadow: `0 4px 20px ${tenantBannerColor}40, 0 2px 10px ${tenantBannerColor}20`,\r\n borderBottom: `1px solid ${tenantBannerColor}30`\r\n };\r\n };\r\n\r\n // Generate button hover styles using tenant banner color\r\n const getButtonHoverStyles = () => {\r\n if (!logoColors || !logoColors.topColors) {\r\n return {\r\n backgroundColor: 'rgba(255, 255, 255, 0.2)'\r\n };\r\n }\r\n\r\n // Get the property manager's chosen tenant banner color\r\n const effectiveBranding = getEffectiveBranding();\r\n const chosenColorIndex = effectiveBranding.preferredBrandingColor || 0;\r\n const chosenColor = logoColors.topColors?.[chosenColorIndex];\r\n const tenantBannerColor = chosenColor?.hex || logoColors.primaryHex || '#1976d2';\r\n\r\n // Create sophisticated hover effect with the tenant banner color\r\n const hoverColor = isDarkMode ? lightenColor(tenantBannerColor, 0.1) : darkenColor(tenantBannerColor, 0.1);\r\n \r\n return {\r\n backgroundColor: `${hoverColor}60`,\r\n backdropFilter: 'blur(10px)',\r\n border: `1px solid ${tenantBannerColor}30`\r\n };\r\n };\r\n\r\n // Get the tenant banner color and appropriate text color for UI elements\r\n const getTenantBannerColorStyles = () => {\r\n if (!logoColors || !logoColors.topColors) {\r\n // Fallback to theme colors when no logo colors are available\r\n const fallbackColor = isDarkMode ? '#ffffff' : theme.palette.primary.main;\r\n return {\r\n color: getAccessibleTextColor(fallbackColor),\r\n tenantBannerColor: fallbackColor\r\n };\r\n }\r\n\r\n // Get the property manager's chosen tenant banner color\r\n const effectiveBranding = getEffectiveBranding();\r\n const chosenColorIndex = effectiveBranding.preferredBrandingColor || 0;\r\n const chosenColor = logoColors.topColors?.[chosenColorIndex];\r\n const tenantBannerColor = chosenColor?.hex || logoColors.primaryHex || '#1976d2';\r\n\r\n // Get accessible text color for the tenant banner color\r\n const textColor = getAccessibleTextColor(tenantBannerColor, {\r\n preferredLight: '#ffffff',\r\n preferredDark: '#000000',\r\n fallbackLight: '#f8fafc',\r\n fallbackDark: '#1e293b'\r\n });\r\n\r\n return {\r\n color: textColor,\r\n tenantBannerColor: tenantBannerColor\r\n };\r\n };\r\n\r\n // Enhanced notification icon styling consistent with navbar text elements\r\n const getNotificationIconStyles = () => {\r\n // Get the same text color used by other navbar elements\r\n const { color: navbarTextColor } = getNavbarStyles();\r\n const buttonHoverStyles = getButtonHoverStyles();\r\n \r\n return {\r\n color: navbarTextColor,\r\n backgroundColor: 'rgba(255, 255, 255, 0.08)',\r\n backdropFilter: 'blur(10px)',\r\n border: '1px solid rgba(255, 255, 255, 0.15)',\r\n boxShadow: '0 2px 8px rgba(0, 0, 0, 0.15), inset 0 1px 0 rgba(255, 255, 255, 0.1)',\r\n transition: 'all 0.2s cubic-bezier(0.4, 0, 0.2, 1)',\r\n '&:hover': {\r\n ...buttonHoverStyles,\r\n transform: 'translateY(-1px)',\r\n boxShadow: '0 4px 12px rgba(0, 0, 0, 0.2), inset 0 1px 0 rgba(255, 255, 255, 0.2)',\r\n },\r\n '& .MuiSvgIcon-root': {\r\n fontSize: '1.5rem',\r\n filter: 'drop-shadow(0 1px 2px rgba(0, 0, 0, 0.2))'\r\n }\r\n };\r\n };\r\n\r\n const drawer = (\r\n <Box onClick={handleDrawerToggle} sx={{ textAlign: 'center' }}>\r\n <Box sx={{ my: 2, display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 1 }}>\r\n <Box\r\n component=\"img\"\r\n src=\"/images/propman-logo-new.png\"\r\n alt=\"PropMan Logo\"\r\n sx={{\r\n height: 32,\r\n width: 'auto',\r\n maxWidth: '80px'\r\n }}\r\n />\r\n <Typography variant=\"h6\">\r\n {getEffectiveBranding().companyName ? `${getEffectiveBranding().companyName} Management` : 'Property AI'}\r\n </Typography>\r\n </Box>\r\n <Divider />\r\n <List>\r\n {/* Standalone items */}\r\n {standaloneItems.map((item) => {\r\n const IconComponent = item.icon;\r\n return (\r\n <ListItem\r\n key={item.path}\r\n disablePadding\r\n onClick={() => handleNavigate(item.path)}\r\n sx={{\r\n backgroundColor: location.pathname === item.path ?\r\n theme.palette.action.selected : 'transparent'\r\n }}\r\n >\r\n <ListItemIcon sx={{ justifyContent: 'center' }}>\r\n <IconComponent />\r\n </ListItemIcon>\r\n <ListItemText primary={item.label} />\r\n </ListItem>\r\n );\r\n })}\r\n\r\n {/* Operations category */}\r\n <ListItem sx={{ py: 1 }}>\r\n <ListItemIcon sx={{ justifyContent: 'center' }}>\r\n <MdSupport />\r\n </ListItemIcon>\r\n <ListItemText\r\n primary=\"Operations\"\r\n sx={{\r\n '& .MuiListItemText-primary': {\r\n fontWeight: 'bold',\r\n fontSize: '0.9rem',\r\n color: theme.palette.text.secondary\r\n }\r\n }}\r\n />\r\n </ListItem>\r\n {navigationCategories.operations.items\r\n .filter(item => {\r\n // Check role permission\r\n if (item.roles && !item.roles.includes(user?.role)) return false;\r\n // Check feature flag if required\r\n if (item.featureRequired && user?.enabledFeatures?.[item.featureRequired] === false) return false;\r\n return true;\r\n })\r\n .map((item) => {\r\n const IconComponent = item.icon;\r\n return (\r\n <ListItem\r\n key={item.path}\r\n disablePadding\r\n onClick={() => handleNavigate(item.path)}\r\n sx={{\r\n backgroundColor: location.pathname === item.path ?\r\n theme.palette.action.selected : 'transparent',\r\n pl: 4\r\n }}\r\n >\r\n <ListItemIcon sx={{ justifyContent: 'center', minWidth: 40 }}>\r\n <IconComponent fontSize=\"small\" />\r\n </ListItemIcon>\r\n <ListItemText primary={item.label} />\r\n </ListItem>\r\n );\r\n })}\r\n\r\n {/* Management category - only for property managers, companies and admins */}\r\n {(user?.role === 'property_manager' || user?.role === 'owner' || user?.role === 'admin') && (\r\n <>\r\n <ListItem sx={{ py: 1 }}>\r\n <ListItemIcon sx={{ justifyContent: 'center' }}>\r\n <MdBusiness />\r\n </ListItemIcon>\r\n <ListItemText\r\n primary=\"Management\"\r\n sx={{\r\n '& .MuiListItemText-primary': {\r\n fontWeight: 'bold',\r\n fontSize: '0.9rem',\r\n color: theme.palette.text.secondary\r\n }\r\n }}\r\n />\r\n </ListItem>\r\n {navigationCategories.management.items\r\n .filter(item => {\r\n // Check role permission\r\n if (item.roles && !item.roles.includes(user?.role)) return false;\r\n // Check feature flag if required\r\n if (item.featureRequired && user?.enabledFeatures?.[item.featureRequired] === false) return false;\r\n return true;\r\n })\r\n .map((item) => {\r\n const IconComponent = item.icon;\r\n return (\r\n <ListItem\r\n key={item.path}\r\n disablePadding\r\n onClick={() => handleNavigate(item.path)}\r\n sx={{\r\n backgroundColor: location.pathname === item.path ?\r\n theme.palette.action.selected : 'transparent',\r\n pl: 4\r\n }}\r\n >\r\n <ListItemIcon sx={{ justifyContent: 'center', minWidth: 40 }}>\r\n <IconComponent fontSize=\"small\" />\r\n </ListItemIcon>\r\n <ListItemText primary={item.label} />\r\n </ListItem>\r\n );\r\n })}\r\n </>\r\n )}\r\n </List>\r\n </Box>\r\n );\r\n\r\n return (\r\n <>\r\n <AppBar\r\n position=\"static\"\r\n data-testid=\"navbar\"\r\n sx={{\r\n borderRadius: '0 0 20px 20px',\r\n ...getNavbarStyles(),\r\n transition: 'all 0.3s cubic-bezier(0.4, 0, 0.2, 1)',\r\n backdrop: 'saturate(180%) blur(20px)',\r\n border: isDarkMode ? '1px solid rgba(255, 255, 255, 0.1)' : '1px solid rgba(0, 0, 0, 0.1)',\r\n borderTop: 'none'\r\n }}\r\n >\r\n <Toolbar>\r\n {isMobile && (\r\n <IconButton\r\n color=\"inherit\"\r\n aria-label=\"open drawer\"\r\n edge=\"start\"\r\n onClick={handleDrawerToggle}\r\n sx={{\r\n color: getNavbarStyles().color\r\n }}\r\n >\r\n <MdMenu />\r\n </IconButton>\r\n )}\r\n \r\n <Box \r\n sx={{ \r\n display: 'flex', \r\n alignItems: 'center', \r\n gap: 1,\r\n flexGrow: isMobile ? 1 : 0,\r\n mr: isMobile ? 0 : 4\r\n }}\r\n >\r\n <Box\r\n component=\"img\"\r\n src=\"/images/propman-logo-new.png\"\r\n alt=\"PropMan Logo\"\r\n sx={{\r\n height: 40,\r\n width: 'auto',\r\n maxWidth: '100px',\r\n cursor: 'pointer'\r\n }}\r\n onClick={() => navigate('/dashboard')}\r\n />\r\n <Typography\r\n variant=\"h6\"\r\n component=\"div\"\r\n sx={{\r\n cursor: 'pointer',\r\n color: getNavbarStyles().color,\r\n whiteSpace: 'nowrap',\r\n overflow: 'hidden',\r\n textOverflow: 'ellipsis',\r\n maxWidth: isTablet ? '200px' : 'none'\r\n }}\r\n onClick={() => navigate('/dashboard')}\r\n >\r\n {getEffectiveBranding().companyName ? (\r\n isSmallScreen\r\n ? getEffectiveBranding().companyName.length > 15\r\n ? `${getEffectiveBranding().companyName.substring(0, 15)}...`\r\n : getEffectiveBranding().companyName\r\n : isTablet\r\n ? `${getEffectiveBranding().companyName} Mgmt`\r\n : `${getEffectiveBranding().companyName} Management`\r\n ) : (\r\n isSmallScreen\r\n ? 'PropAI'\r\n : isTablet\r\n ? 'Property AI'\r\n : 'Property Management AI'\r\n )}\r\n </Typography>\r\n </Box>\r\n\r\n {!isMobile && (\r\n <Stack direction=\"row\" spacing={isTablet ? 0.5 : 1} sx={{ flexGrow: 1 }}>\r\n {/* Standalone items */}\r\n {standaloneItems.map((item) => {\r\n const IconComponent = item.icon;\r\n const isActive = location.pathname === item.path;\r\n\r\n if (isTablet) {\r\n return (\r\n <IconButton\r\n key={item.path}\r\n color=\"inherit\"\r\n onClick={() => navigate(item.path)}\r\n title={item.label}\r\n sx={{\r\n backgroundColor: isActive ? 'rgba(255, 255, 255, 0.15)' : 'transparent',\r\n borderRadius: '12px',\r\n padding: '8px',\r\n transition: 'all 0.2s cubic-bezier(0.4, 0, 0.2, 1)',\r\n '&:hover': {\r\n ...getButtonHoverStyles(),\r\n transform: 'translateY(-1px)',\r\n boxShadow: '0 4px 12px rgba(0, 0, 0, 0.15)'\r\n }\r\n }}\r\n >\r\n <IconComponent />\r\n </IconButton>\r\n );\r\n }\r\n\r\n return (\r\n <Button\r\n key={item.path}\r\n color=\"inherit\"\r\n onClick={() => navigate(item.path)}\r\n startIcon={<IconComponent />}\r\n sx={{\r\n backgroundColor: isActive ? 'rgba(255, 255, 255, 0.15)' : 'transparent',\r\n borderRadius: '16px',\r\n padding: '8px 16px',\r\n minHeight: '44px',\r\n transition: 'all 0.2s cubic-bezier(0.4, 0, 0.2, 1)',\r\n '&:hover': {\r\n ...getButtonHoverStyles(),\r\n transform: 'translateY(-1px)',\r\n boxShadow: '0 4px 12px rgba(0, 0, 0, 0.15)'\r\n }\r\n }}\r\n >\r\n {item.label}\r\n </Button>\r\n );\r\n })}\r\n\r\n {/* Operations dropdown */}\r\n <Box>\r\n <Button\r\n color=\"inherit\"\r\n onClick={handleOperationsMenuClick}\r\n endIcon={<MdKeyboardArrowDown />}\r\n startIcon={!isTablet ? <MdSupport /> : null}\r\n sx={{\r\n backgroundColor: navigationCategories.operations.items.some(item =>\r\n location.pathname === item.path && (!item.roles || item.roles.includes(user?.role))\r\n ) ? 'rgba(255, 255, 255, 0.15)' : 'transparent',\r\n borderRadius: isTablet ? '12px' : '16px',\r\n padding: isTablet ? '8px' : '8px 16px',\r\n minHeight: '44px',\r\n transition: 'all 0.2s cubic-bezier(0.4, 0, 0.2, 1)',\r\n '&:hover': {\r\n ...getButtonHoverStyles(),\r\n transform: 'translateY(-1px)',\r\n boxShadow: '0 4px 12px rgba(0, 0, 0, 0.15)'\r\n }\r\n }}\r\n >\r\n {isTablet ? <MdSupport /> : navigationCategories.operations.label}\r\n </Button>\r\n <Menu\r\n anchorEl={operationsMenuAnchor}\r\n open={Boolean(operationsMenuAnchor)}\r\n onClose={handleOperationsMenuClose}\r\n PaperProps={{\r\n sx: {\r\n borderRadius: '16px',\r\n minWidth: 180,\r\n mt: 1,\r\n boxShadow: '0 8px 32px rgba(0, 0, 0, 0.15)'\r\n }\r\n }}\r\n >\r\n {navigationCategories.operations.items\r\n .filter(item => {\r\n // Check role permission\r\n if (item.roles && !item.roles.includes(user?.role)) return false;\r\n // Check feature flag if required\r\n if (item.featureRequired && user?.enabledFeatures?.[item.featureRequired] === false) return false;\r\n return true;\r\n })\r\n .map((item) => {\r\n const IconComponent = item.icon;\r\n return (\r\n <MenuItem\r\n key={item.path}\r\n onClick={() => {\r\n navigate(item.path);\r\n handleOperationsMenuClose();\r\n }}\r\n sx={{\r\n borderRadius: '12px',\r\n margin: '4px 8px',\r\n backgroundColor: location.pathname === item.path ? 'rgba(0, 0, 0, 0.04)' : 'transparent'\r\n }}\r\n >\r\n <IconComponent sx={{ mr: 2, fontSize: '1.2rem' }} />\r\n {item.label}\r\n </MenuItem>\r\n );\r\n })}\r\n </Menu>\r\n </Box>\r\n\r\n {/* Management dropdown - only for property managers, companies and admins */}\r\n {(user?.role === 'property_manager' || user?.role === 'owner' || user?.role === 'admin') && (\r\n <Box>\r\n <Button\r\n color=\"inherit\"\r\n onClick={handleManagementMenuClick}\r\n endIcon={<MdKeyboardArrowDown />}\r\n startIcon={!isTablet ? <MdBusiness /> : null}\r\n sx={{\r\n backgroundColor: navigationCategories.management.items.some(item =>\r\n location.pathname === item.path && (!item.roles || item.roles.includes(user?.role))\r\n ) ? 'rgba(255, 255, 255, 0.15)' : 'transparent',\r\n borderRadius: isTablet ? '12px' : '16px',\r\n padding: isTablet ? '8px' : '8px 16px',\r\n minHeight: '44px',\r\n transition: 'all 0.2s cubic-bezier(0.4, 0, 0.2, 1)',\r\n '&:hover': {\r\n ...getButtonHoverStyles(),\r\n transform: 'translateY(-1px)',\r\n boxShadow: '0 4px 12px rgba(0, 0, 0, 0.15)'\r\n }\r\n }}\r\n >\r\n {isTablet ? <MdBusiness /> : navigationCategories.management.label}\r\n </Button>\r\n <Menu\r\n anchorEl={managementMenuAnchor}\r\n open={Boolean(managementMenuAnchor)}\r\n onClose={handleManagementMenuClose}\r\n PaperProps={{\r\n sx: {\r\n borderRadius: '16px',\r\n minWidth: 180,\r\n mt: 1,\r\n boxShadow: '0 8px 32px rgba(0, 0, 0, 0.15)'\r\n }\r\n }}\r\n >\r\n {navigationCategories.management.items\r\n .filter(item => {\r\n // Check role permission\r\n if (item.roles && !item.roles.includes(user?.role)) return false;\r\n // Check feature flag if required\r\n if (item.featureRequired && user?.enabledFeatures?.[item.featureRequired] === false) return false;\r\n return true;\r\n })\r\n .map((item) => {\r\n const IconComponent = item.icon;\r\n return (\r\n <MenuItem\r\n key={item.path}\r\n onClick={() => {\r\n navigate(item.path);\r\n handleManagementMenuClose();\r\n }}\r\n sx={{\r\n borderRadius: '12px',\r\n margin: '4px 8px',\r\n backgroundColor: location.pathname === item.path ? 'rgba(0, 0, 0, 0.04)' : 'transparent'\r\n }}\r\n >\r\n <IconComponent sx={{ mr: 2, fontSize: '1.2rem' }} />\r\n {item.label}\r\n </MenuItem>\r\n );\r\n })}\r\n </Menu>\r\n </Box>\r\n )}\r\n </Stack>\r\n )}\r\n\r\n <Stack direction=\"row\" spacing={isTablet ? 0.5 : 1} alignItems=\"center\">\r\n {/* Messages Button - for property managers, admins, owners, and workers */}\r\n {(user?.role === 'property_manager' || user?.role === 'admin' || user?.role === 'owner' || user?.role === 'maintenance') && (\r\n <IconButton\r\n onClick={() => navigate('/messages')}\r\n aria-label=\"Messages\"\r\n sx={{\r\n borderRadius: '16px',\r\n padding: '12px',\r\n ...getNotificationIconStyles()\r\n }}\r\n >\r\n <MdMessage />\r\n </IconButton>\r\n )}\r\n\r\n {/* Notifications */}\r\n <IconButton\r\n onClick={handleNotificationMenuClick}\r\n aria-label={`${notificationCount} new notifications`}\r\n aria-describedby=\"notification-menu\"\r\n sx={{\r\n borderRadius: '16px',\r\n padding: '12px',\r\n ...getNotificationIconStyles(),\r\n // Add subtle glow when there are notifications\r\n ...(notificationCount > 0 && {\r\n boxShadow: `${getNotificationIconStyles().boxShadow}, 0 0 20px rgba(255, 23, 68, 0.2)`\r\n }),\r\n '&:hover': {\r\n ...getNotificationIconStyles()['&:hover'],\r\n // Enhanced glow on hover when there are notifications\r\n ...(notificationCount > 0 && {\r\n boxShadow: `${getNotificationIconStyles()['&:hover'].boxShadow}, 0 0 30px rgba(255, 23, 68, 0.3)`\r\n })\r\n }\r\n }}\r\n >\r\n <Badge\r\n badgeContent={notificationCount}\r\n color=\"error\"\r\n sx={{\r\n '& .MuiBadge-badge': {\r\n backgroundColor: '#ff1744',\r\n color: '#ffffff',\r\n fontWeight: 'bold',\r\n fontSize: '0.75rem',\r\n minWidth: '20px',\r\n height: '20px',\r\n border: '2px solid #ffffff',\r\n boxShadow: '0 3px 8px rgba(255, 23, 68, 0.4), 0 1px 3px rgba(0, 0, 0, 0.3)',\r\n animation: notificationCount > 0 ? 'pulse 2s infinite' : 'none',\r\n '@keyframes pulse': {\r\n '0%': {\r\n transform: 'scale(1)',\r\n boxShadow: '0 3px 8px rgba(255, 23, 68, 0.4), 0 1px 3px rgba(0, 0, 0, 0.3)'\r\n },\r\n '50%': {\r\n transform: 'scale(1.1)',\r\n boxShadow: '0 4px 12px rgba(255, 23, 68, 0.6), 0 2px 6px rgba(0, 0, 0, 0.4)'\r\n },\r\n '100%': {\r\n transform: 'scale(1)',\r\n boxShadow: '0 3px 8px rgba(255, 23, 68, 0.4), 0 1px 3px rgba(0, 0, 0, 0.3)'\r\n }\r\n }\r\n }\r\n }}\r\n >\r\n <MdNotifications />\r\n </Badge>\r\n </IconButton>\r\n\r\n <Menu\r\n id=\"notification-menu\"\r\n anchorEl={notificationMenuAnchor}\r\n open={Boolean(notificationMenuAnchor)}\r\n onClose={handleNotificationMenuClose}\r\n PaperProps={{\r\n sx: {\r\n borderRadius: '16px',\r\n maxWidth: 400,\r\n minWidth: 300,\r\n mt: 1,\r\n maxHeight: 400,\r\n boxShadow: '0 8px 32px rgba(0, 0, 0, 0.15)'\r\n }\r\n }}\r\n >\r\n {recentTickets.length === 0 ? (\r\n <MenuItem sx={{ borderRadius: '12px', justifyContent: 'center' }}>\r\n <Typography variant=\"body2\" color=\"text.secondary\">\r\n No new notifications\r\n </Typography>\r\n </MenuItem>\r\n ) : (\r\n recentTickets.map((ticket) => (\r\n <MenuItem \r\n key={ticket.id}\r\n onClick={async () => {\r\n // Mark notification as read\r\n if (ticket.notificationId) {\r\n await markNotificationAsRead(ticket.notificationId);\r\n // Remove from local state\r\n setRecentTickets(prev => prev.filter(item => item.id !== ticket.id));\r\n }\r\n \r\n // Navigate to the ticket\r\n if (ticket.actionUrl) {\r\n navigate(ticket.actionUrl);\r\n } else if (ticket.ticketId) {\r\n navigate(`/tickets/${ticket.ticketId}`);\r\n }\r\n handleNotificationMenuClose();\r\n }}\r\n sx={{ \r\n borderRadius: '12px',\r\n flexDirection: 'column',\r\n alignItems: 'flex-start',\r\n whiteSpace: 'normal',\r\n py: 1.5\r\n }}\r\n >\r\n <Typography variant=\"body2\" fontWeight=\"medium\">\r\n {ticket.title}\r\n </Typography>\r\n <Typography variant=\"caption\" color=\"text.secondary\" sx={{ mt: 0.5 }}>\r\n {ticket.message}\r\n </Typography>\r\n <Typography variant=\"caption\" color=\"text.secondary\" sx={{ mt: 0.5 }}>\r\n {ticket.time}\r\n </Typography>\r\n </MenuItem>\r\n ))\r\n )}\r\n <Divider />\r\n <MenuItem \r\n onClick={() => {\r\n navigate('/notifications');\r\n handleNotificationMenuClose();\r\n }}\r\n sx={{ borderRadius: '12px', justifyContent: 'center' }}\r\n >\r\n <Typography variant=\"body2\" color=\"primary.main\">\r\n View All Notifications\r\n </Typography>\r\n </MenuItem>\r\n </Menu>\r\n\r\n {/* User Name - hide on tablet and smaller */}\r\n {!isMobile && !isTablet && (\r\n <Typography\r\n variant=\"body2\"\r\n sx={{\r\n color: getTenantBannerColorStyles().color,\r\n whiteSpace: 'nowrap'\r\n }}\r\n >\r\n {user?.firstName} {user?.lastName}\r\n </Typography>\r\n )}\r\n\r\n {/* User Menu */}\r\n <IconButton\r\n onClick={handleUserMenuClick}\r\n sx={{\r\n borderRadius: '16px',\r\n padding: '8px',\r\n // Use consistent navbar text color\r\n color: getNavbarStyles().color,\r\n backgroundColor: 'rgba(255, 255, 255, 0.08)',\r\n backdropFilter: 'blur(8px)',\r\n border: '1px solid rgba(255, 255, 255, 0.15)',\r\n transition: 'all 0.2s cubic-bezier(0.4, 0, 0.2, 1)',\r\n '&:hover': {\r\n ...getButtonHoverStyles(),\r\n transform: 'translateY(-1px)',\r\n boxShadow: '0 4px 12px rgba(0, 0, 0, 0.15)'\r\n },\r\n '& .MuiSvgIcon-root': {\r\n filter: 'drop-shadow(0 1px 2px rgba(0, 0, 0, 0.2))',\r\n fontSize: '1.8rem'\r\n }\r\n }}\r\n >\r\n {getEffectiveBranding().companyLogo ? (\r\n <Avatar\r\n src={`${api.defaults.baseURL.replace('/api', '')}/uploads/logos/${getEffectiveBranding().companyLogo}`}\r\n sx={{\r\n width: 32,\r\n height: 32,\r\n border: '2px solid rgba(255, 255, 255, 0.8)',\r\n boxShadow: '0 2px 8px rgba(0, 0, 0, 0.15)'\r\n }}\r\n />\r\n ) : (\r\n <MdAccountCircle />\r\n )}\r\n </IconButton>\r\n \r\n <Menu\r\n anchorEl={userMenuAnchor}\r\n open={Boolean(userMenuAnchor)}\r\n onClose={handleUserMenuClose}\r\n PaperProps={{\r\n sx: {\r\n borderRadius: '16px',\r\n minWidth: 150,\r\n mt: 1\r\n }\r\n }}\r\n >\r\n <MenuItem\r\n onClick={() => {\r\n navigate('/settings');\r\n handleUserMenuClose();\r\n }}\r\n sx={{ borderRadius: '12px' }}\r\n >\r\n Settings\r\n </MenuItem>\r\n <Divider />\r\n <MenuItem\r\n onClick={handleLogout}\r\n sx={{ borderRadius: '12px' }}\r\n data-testid=\"logout-button\"\r\n >\r\n Logout\r\n </MenuItem>\r\n </Menu>\r\n </Stack>\r\n </Toolbar>\r\n </AppBar>\r\n\r\n {/* Mobile Drawer */}\r\n <Drawer\r\n variant=\"temporary\"\r\n open={mobileOpen}\r\n onClose={handleDrawerToggle}\r\n ModalProps={{\r\n keepMounted: true, // Better open performance on mobile\r\n }}\r\n sx={{\r\n display: { xs: 'block', md: 'none' },\r\n '& .MuiDrawer-paper': { \r\n boxSizing: 'border-box', \r\n width: 300,\r\n borderRadius: '0 16px 16px 0'\r\n },\r\n }}\r\n >\r\n {drawer}\r\n </Drawer>\r\n </>\r\n );\r\n};\r\n\r\nexport default Navbar;","import React, { createContext, useContext, useState, useEffect } from 'react';\r\nimport api from '../services/api';\r\n\r\nconst AuthContext = createContext();\r\n\r\nexport const useAuth = () => {\r\n const context = useContext(AuthContext);\r\n if (!context) {\r\n throw new Error('useAuth must be used within AuthProvider');\r\n }\r\n return context;\r\n};\r\n\r\nexport const AuthProvider = ({ children }) => {\r\n const [user, setUser] = useState(null);\r\n const [companyBranding, setCompanyBranding] = useState(null);\r\n const [isLoading, setIsLoading] = useState(true);\r\n const [needsOnboarding, setNeedsOnboarding] = useState(false);\r\n\r\n useEffect(() => {\r\n const token = localStorage.getItem('token');\r\n \r\n // Comprehensive token validation\r\n const isValidToken = token && \r\n token !== 'null' && \r\n token !== 'undefined' && \r\n token !== '' &&\r\n token.length > 20 && \r\n token.split('.').length === 3; // JWT should have 3 parts\r\n \r\n if (isValidToken) {\r\n api.defaults.headers.common['Authorization'] = `Bearer ${token}`;\r\n fetchUser();\r\n } else {\r\n // Clear any invalid tokens\r\n localStorage.removeItem('token');\r\n delete api.defaults.headers.common['Authorization'];\r\n setUser(null);\r\n setNeedsOnboarding(false);\r\n setIsLoading(false);\r\n }\r\n }, []);\r\n\r\n const fetchUser = async () => {\r\n try {\r\n const response = await api.get('/auth/me');\r\n \r\n // Normalize user object to ensure consistent ID field\r\n const normalizedUser = {\r\n ...response.data.user,\r\n id: response.data.user._id || response.data.user.id,\r\n enabledFeatures: response.data.user.enabledFeatures || {\r\n workersModule: true,\r\n inventoryModule: true,\r\n advancedAnalytics: false,\r\n aiAssistant: true\r\n }\r\n };\r\n\r\n setUser(normalizedUser);\r\n\r\n // Check if owner needs to complete onboarding\r\n const isOwnerRole = ['owner', 'admin', 'super_admin'].includes(normalizedUser.role);\r\n const hasNoCompany = !normalizedUser.company;\r\n setNeedsOnboarding(isOwnerRole && hasNoCompany);\r\n\r\n // If user is a property manager or maintenance worker, fetch company branding\r\n if (normalizedUser.role === 'property_manager' || normalizedUser.role === 'maintenance') {\r\n try {\r\n const brandingResponse = await api.get('/auth/company-branding');\r\n setCompanyBranding(brandingResponse.data.branding);\r\n } catch (brandingError) {\r\n console.warn('Failed to fetch company branding:', brandingError);\r\n setCompanyBranding(null);\r\n }\r\n } else {\r\n setCompanyBranding(null);\r\n }\r\n } catch (error) {\r\n console.error('Failed to fetch user:', error);\r\n // Clear any invalid/malformed tokens\r\n localStorage.removeItem('token');\r\n delete api.defaults.headers.common['Authorization'];\r\n setUser(null);\r\n setNeedsOnboarding(false);\r\n } finally {\r\n setIsLoading(false);\r\n }\r\n };\r\n\r\n const login = async (email, password) => {\r\n try {\r\n const response = await api.post('/auth/login', { email, password });\r\n const { token, user } = response.data;\r\n\r\n localStorage.setItem('token', token);\r\n api.defaults.headers.common['Authorization'] = `Bearer ${token}`;\r\n setUser(user);\r\n\r\n return { success: true };\r\n } catch (error) {\r\n console.error('Login failed:', error);\r\n return {\r\n success: false,\r\n error: error.response?.data?.message || 'Login failed'\r\n };\r\n }\r\n };\r\n\r\n const logout = () => {\r\n localStorage.removeItem('token');\r\n delete api.defaults.headers.common['Authorization'];\r\n setUser(null);\r\n setCompanyBranding(null);\r\n setNeedsOnboarding(false);\r\n };\r\n\r\n const refreshUser = async () => {\r\n await fetchUser();\r\n };\r\n\r\n const updateUser = (updatedUser) => {\r\n setUser(updatedUser);\r\n };\r\n\r\n const completeOnboarding = async (companyData) => {\r\n try {\r\n const response = await api.post('/companies/onboard', companyData);\r\n\r\n if (response.data.success) {\r\n // Update user with new company association\r\n setUser(response.data.data.user);\r\n setNeedsOnboarding(false);\r\n return { success: true, data: response.data.data };\r\n }\r\n\r\n return { success: false, error: 'Onboarding failed' };\r\n } catch (error) {\r\n console.error('Onboarding failed:', error);\r\n return {\r\n success: false,\r\n error: error.response?.data?.error?.message || 'Onboarding failed'\r\n };\r\n }\r\n };\r\n\r\n const value = {\r\n user,\r\n isAuthenticated: !!user,\r\n companyBranding,\r\n managerBranding: companyBranding, // Keep old name for backward compatibility\r\n needsOnboarding,\r\n login,\r\n logout,\r\n refreshUser,\r\n updateUser,\r\n completeOnboarding,\r\n isLoading\r\n };\r\n\r\n return (\r\n <AuthContext.Provider value={value}>\r\n {children}\r\n </AuthContext.Provider>\r\n );\r\n};","import axios from 'axios';\r\n\r\n// Auto-detect the correct API URL based on current window location\r\nconst getApiUrl = () => {\r\n // If we have an environment variable, use it\r\n if (process.env.REACT_APP_API_URL) {\r\n return process.env.REACT_APP_API_URL;\r\n }\r\n\r\n // Otherwise, auto-detect based on current hostname\r\n const hostname = window.location.hostname;\r\n const port = hostname === 'localhost' ? '5000' : '5000'; // Always use 5000 for API\r\n return `http://${hostname}:${port}/api`;\r\n};\r\n\r\nconst apiUrl = getApiUrl();\r\n\r\nconst api = axios.create({\r\n baseURL: apiUrl,\r\n timeout: 10000,\r\n});\r\n\r\napi.interceptors.response.use(\r\n (response) => response,\r\n (error) => {\r\n if (error.response?.status === 401) {\r\n localStorage.removeItem('token');\r\n delete api.defaults.headers.common['Authorization'];\r\n window.location.href = '/login';\r\n }\r\n return Promise.reject(error);\r\n }\r\n);\r\n\r\nexport { api };\r\nexport default api;","import React, { createContext, useContext, useState, useCallback } from 'react';\r\n\r\nconst NotificationContext = createContext();\r\n\r\nexport const useNotification = () => {\r\n const context = useContext(NotificationContext);\r\n if (!context) {\r\n throw new Error('useNotification must be used within a NotificationProvider');\r\n }\r\n return context;\r\n};\r\n\r\nexport const NotificationProvider = ({ children }) => {\r\n const [notifications, setNotifications] = useState([]);\r\n const [nextId, setNextId] = useState(1);\r\n\r\n const addNotification = useCallback((notification) => {\r\n try {\r\n const id = nextId;\r\n setNextId(prev => prev + 1);\r\n\r\n const newNotification = {\r\n id,\r\n type: 'info', // 'success', 'error', 'warning', 'info'\r\n title: '',\r\n message: '',\r\n duration: 5000, // Auto-hide duration in ms (0 for persistent)\r\n actions: [], // Custom action buttons\r\n dismissible: true,\r\n persistent: false,\r\n timestamp: new Date(),\r\n ...notification\r\n };\r\n\r\n // Validate required fields\r\n if (!newNotification.message) {\r\n console.warn('Notification missing message:', notification);\r\n return null;\r\n }\r\n\r\n setNotifications(prev => Array.isArray(prev) ? [...prev, newNotification] : [newNotification]);\r\n\r\n // Auto-hide notification if duration is set\r\n if (newNotification.duration > 0) {\r\n setTimeout(() => {\r\n removeNotification(id);\r\n }, newNotification.duration);\r\n }\r\n\r\n return id;\r\n } catch (error) {\r\n console.error('Error adding notification:', error);\r\n return null;\r\n }\r\n }, [nextId]);\r\n\r\n const removeNotification = useCallback((id) => {\r\n try {\r\n setNotifications(prev => Array.isArray(prev) ? prev.filter(notification => notification && notification.id !== id) : []);\r\n } catch (error) {\r\n console.error('Error removing notification:', error);\r\n }\r\n }, []);\r\n\r\n const clearAllNotifications = useCallback(() => {\r\n setNotifications([]);\r\n }, []);\r\n\r\n const updateNotification = useCallback((id, updates) => {\r\n setNotifications(prev => \r\n prev.map(notification => \r\n notification.id === id \r\n ? { ...notification, ...updates }\r\n : notification\r\n )\r\n );\r\n }, []);\r\n\r\n // Convenience methods for common notification types\r\n const showSuccess = useCallback((message, options = {}) => {\r\n return addNotification({\r\n type: 'success',\r\n message,\r\n duration: 4000,\r\n ...options\r\n });\r\n }, [addNotification]);\r\n\r\n const showError = useCallback((message, options = {}) => {\r\n return addNotification({\r\n type: 'error',\r\n message,\r\n duration: 7000,\r\n ...options\r\n });\r\n }, [addNotification]);\r\n\r\n const showWarning = useCallback((message, options = {}) => {\r\n return addNotification({\r\n type: 'warning',\r\n message,\r\n duration: 5000,\r\n ...options\r\n });\r\n }, [addNotification]);\r\n\r\n const showInfo = useCallback((message, options = {}) => {\r\n return addNotification({\r\n type: 'info',\r\n message,\r\n duration: 5000,\r\n ...options\r\n });\r\n }, [addNotification]);\r\n\r\n const showLoading = useCallback((message, options = {}) => {\r\n return addNotification({\r\n type: 'info',\r\n message,\r\n persistent: true,\r\n dismissible: false,\r\n duration: 0,\r\n ...options\r\n });\r\n }, [addNotification]);\r\n\r\n // Progress notification for long operations\r\n const showProgress = useCallback((message, progress = 0, options = {}) => {\r\n return addNotification({\r\n type: 'info',\r\n message,\r\n progress,\r\n persistent: true,\r\n dismissible: false,\r\n duration: 0,\r\n ...options\r\n });\r\n }, [addNotification]);\r\n\r\n const updateProgress = useCallback((id, progress, message) => {\r\n updateNotification(id, { \r\n progress,\r\n ...(message && { message })\r\n });\r\n }, [updateNotification]);\r\n\r\n // Action notification with custom buttons\r\n const showAction = useCallback((message, actions, options = {}) => {\r\n return addNotification({\r\n type: 'info',\r\n message,\r\n actions,\r\n persistent: true,\r\n duration: 0,\r\n ...options\r\n });\r\n }, [addNotification]);\r\n\r\n const value = {\r\n notifications,\r\n addNotification,\r\n removeNotification,\r\n clearAllNotifications,\r\n updateNotification,\r\n showSuccess,\r\n showError,\r\n showWarning,\r\n showInfo,\r\n showLoading,\r\n showProgress,\r\n updateProgress,\r\n showAction\r\n };\r\n\r\n return (\r\n <NotificationContext.Provider value={value}>\r\n {children}\r\n </NotificationContext.Provider>\r\n );\r\n};\r\n\r\nexport default NotificationContext;","import React, { createContext, useContext, useState, useEffect } from 'react';\r\nimport { createTheme, ThemeProvider } from '@mui/material/styles';\r\nimport CssBaseline from '@mui/material/CssBaseline';\r\nimport api from '../services/api';\r\nimport { useAuth } from './AuthContext';\r\nimport { createContrastEnhancedComponents } from '../utils/themeContrast';\r\n\r\nconst ThemeContext = createContext();\r\n\r\nexport const useCustomTheme = () => {\r\n const context = useContext(ThemeContext);\r\n if (!context) {\r\n throw new Error('useCustomTheme must be used within a CustomThemeProvider');\r\n }\r\n return context;\r\n};\r\n\r\n// Light theme configuration with modern design\r\nconst baseLightTheme = {\r\n palette: {\r\n mode: 'light',\r\n primary: {\r\n main: '#2563eb', // Modern blue\r\n light: '#3b82f6',\r\n dark: '#1d4ed8',\r\n contrastText: '#ffffff',\r\n },\r\n secondary: {\r\n main: '#7c3aed', // Modern purple\r\n light: '#8b5cf6',\r\n dark: '#6d28d9',\r\n contrastText: '#ffffff',\r\n },\r\n success: {\r\n main: '#10b981', // Modern green\r\n light: '#34d399',\r\n dark: '#059669',\r\n },\r\n warning: {\r\n main: '#f59e0b', // Modern amber\r\n light: '#fbbf24',\r\n dark: '#d97706',\r\n },\r\n error: {\r\n main: '#ef4444', // Modern red\r\n light: '#f87171',\r\n dark: '#dc2626',\r\n },\r\n background: {\r\n default: '#f8fafc', // Subtle gray background\r\n paper: '#ffffff',\r\n },\r\n text: {\r\n primary: '#0f172a', // Rich dark blue-gray\r\n secondary: '#64748b', // Modern gray\r\n },\r\n divider: '#e2e8f0',\r\n grey: {\r\n 50: '#f8fafc',\r\n 100: '#f1f5f9',\r\n 200: '#e2e8f0',\r\n 300: '#cbd5e1',\r\n 400: '#94a3b8',\r\n 500: '#64748b',\r\n 600: '#475569',\r\n 700: '#334155',\r\n 800: '#1e293b',\r\n 900: '#0f172a',\r\n },\r\n },\r\n typography: {\r\n fontFamily: '\"Inter\", \"SF Pro Display\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", \"Roboto\", sans-serif',\r\n h1: {\r\n fontWeight: 800,\r\n letterSpacing: '-0.025em',\r\n fontSize: '2.25rem',\r\n lineHeight: 1.2,\r\n },\r\n h2: {\r\n fontWeight: 700,\r\n letterSpacing: '-0.025em',\r\n fontSize: '1.875rem',\r\n lineHeight: 1.25,\r\n },\r\n h3: {\r\n fontWeight: 600,\r\n letterSpacing: '-0.025em',\r\n fontSize: '1.5rem',\r\n lineHeight: 1.3,\r\n },\r\n h4: {\r\n fontWeight: 600,\r\n fontSize: '1.25rem',\r\n lineHeight: 1.4,\r\n '@media (max-width:600px)': {\r\n fontSize: '1.125rem',\r\n },\r\n },\r\n h5: {\r\n fontWeight: 600,\r\n fontSize: '1.125rem',\r\n lineHeight: 1.5,\r\n },\r\n h6: {\r\n fontWeight: 600,\r\n fontSize: '1rem',\r\n lineHeight: 1.5,\r\n '@media (max-width:600px)': {\r\n fontSize: '0.875rem',\r\n },\r\n },\r\n body1: {\r\n fontSize: '1rem',\r\n lineHeight: 1.6,\r\n color: '#334155',\r\n },\r\n body2: {\r\n fontSize: '0.875rem',\r\n lineHeight: 1.5,\r\n color: '#64748b',\r\n },\r\n button: {\r\n fontWeight: 500,\r\n letterSpacing: '0.025em',\r\n textTransform: 'none',\r\n },\r\n caption: {\r\n fontSize: '0.75rem',\r\n lineHeight: 1.4,\r\n color: '#94a3b8',\r\n },\r\n },\r\n shape: {\r\n borderRadius: 12, // More modern rounded corners\r\n },\r\n breakpoints: {\r\n values: {\r\n xs: 0,\r\n sm: 640,\r\n md: 768,\r\n lg: 1024,\r\n xl: 1280,\r\n },\r\n },\r\n components: {\r\n MuiCssBaseline: {\r\n styleOverrides: {\r\n '@global': {\r\n '@keyframes pulse': {\r\n '0%, 100%': {\r\n opacity: 1,\r\n },\r\n '50%': {\r\n opacity: 0.5,\r\n },\r\n },\r\n '@keyframes spin': {\r\n from: {\r\n transform: 'rotate(0deg)',\r\n },\r\n to: {\r\n transform: 'rotate(360deg)',\r\n },\r\n },\r\n '@keyframes fadeIn': {\r\n from: {\r\n opacity: 0,\r\n transform: 'translateY(10px)',\r\n },\r\n to: {\r\n opacity: 1,\r\n transform: 'translateY(0)',\r\n },\r\n },\r\n '@keyframes slideInRight': {\r\n from: {\r\n opacity: 0,\r\n transform: 'translateX(20px)',\r\n },\r\n to: {\r\n opacity: 1,\r\n transform: 'translateX(0)',\r\n },\r\n },\r\n '@keyframes bounce': {\r\n '0%, 20%, 53%, 80%, 100%': {\r\n transform: 'translate3d(0,0,0)',\r\n },\r\n '40%, 43%': {\r\n transform: 'translate3d(0, -8px, 0)',\r\n },\r\n '70%': {\r\n transform: 'translate3d(0, -4px, 0)',\r\n },\r\n '90%': {\r\n transform: 'translate3d(0, -2px, 0)',\r\n },\r\n },\r\n },\r\n },\r\n },\r\n MuiCard: {\r\n styleOverrides: {\r\n root: {\r\n borderRadius: 16,\r\n boxShadow: '0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)',\r\n transition: 'all 0.2s cubic-bezier(0.4, 0, 0.2, 1)',\r\n '&:hover': {\r\n boxShadow: '0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)',\r\n transform: 'translateY(-2px)',\r\n },\r\n },\r\n },\r\n },\r\n MuiButton: {\r\n styleOverrides: {\r\n root: {\r\n borderRadius: 12,\r\n textTransform: 'none',\r\n fontWeight: 500,\r\n padding: '10px 24px',\r\n boxShadow: 'none',\r\n '&:hover': {\r\n boxShadow: '0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)',\r\n },\r\n },\r\n contained: {\r\n '&:hover': {\r\n boxShadow: '0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)',\r\n },\r\n },\r\n outlined: {\r\n borderWidth: 2,\r\n '&:hover': {\r\n borderWidth: 2,\r\n },\r\n },\r\n },\r\n },\r\n MuiPaper: {\r\n styleOverrides: {\r\n root: {\r\n borderRadius: 16,\r\n boxShadow: '0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)',\r\n },\r\n elevation1: {\r\n boxShadow: '0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)',\r\n },\r\n elevation2: {\r\n boxShadow: '0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)',\r\n },\r\n elevation3: {\r\n boxShadow: '0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)',\r\n },\r\n },\r\n },\r\n MuiTextField: {\r\n styleOverrides: {\r\n root: {\r\n '& .MuiOutlinedInput-root': {\r\n borderRadius: 12,\r\n '& fieldset': {\r\n borderColor: '#e2e8f0',\r\n },\r\n '&:hover fieldset': {\r\n borderColor: '#cbd5e1',\r\n },\r\n '&.Mui-focused fieldset': {\r\n borderWidth: 2,\r\n borderColor: '#2563eb',\r\n },\r\n },\r\n },\r\n },\r\n },\r\n MuiChip: {\r\n styleOverrides: {\r\n root: {\r\n borderRadius: 8,\r\n fontWeight: 500,\r\n },\r\n },\r\n },\r\n MuiAppBar: {\r\n styleOverrides: {\r\n root: {\r\n borderRadius: '0 0 16px 16px',\r\n boxShadow: '0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)',\r\n },\r\n },\r\n },\r\n },\r\n};\r\n\r\n// Dark theme configuration with modern design\r\nconst baseDarkTheme = {\r\n palette: {\r\n mode: 'dark',\r\n primary: {\r\n main: '#3b82f6', // Modern blue for dark mode\r\n light: '#60a5fa',\r\n dark: '#2563eb',\r\n contrastText: '#ffffff',\r\n },\r\n secondary: {\r\n main: '#8b5cf6', // Modern purple for dark mode\r\n light: '#a78bfa',\r\n dark: '#7c3aed',\r\n contrastText: '#ffffff',\r\n },\r\n success: {\r\n main: '#34d399', // Modern green for dark mode\r\n light: '#6ee7b7',\r\n dark: '#10b981',\r\n },\r\n warning: {\r\n main: '#fbbf24', // Modern amber for dark mode\r\n light: '#fcd34d',\r\n dark: '#f59e0b',\r\n },\r\n error: {\r\n main: '#f87171', // Modern red for dark mode\r\n light: '#fca5a5',\r\n dark: '#ef4444',\r\n },\r\n background: {\r\n default: '#0f172a', // Rich dark blue-gray\r\n paper: '#1e293b',\r\n },\r\n text: {\r\n primary: '#f8fafc',\r\n secondary: '#cbd5e1',\r\n },\r\n divider: '#334155',\r\n grey: {\r\n 50: '#0f172a',\r\n 100: '#1e293b',\r\n 200: '#334155',\r\n 300: '#475569',\r\n 400: '#64748b',\r\n 500: '#94a3b8',\r\n 600: '#cbd5e1',\r\n 700: '#e2e8f0',\r\n 800: '#f1f5f9',\r\n 900: '#f8fafc',\r\n },\r\n },\r\n typography: {\r\n fontFamily: '\"Inter\", \"SF Pro Display\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", \"Roboto\", sans-serif',\r\n h1: {\r\n fontWeight: 800,\r\n letterSpacing: '-0.025em',\r\n fontSize: '2.25rem',\r\n lineHeight: 1.2,\r\n },\r\n h2: {\r\n fontWeight: 700,\r\n letterSpacing: '-0.025em',\r\n fontSize: '1.875rem',\r\n lineHeight: 1.25,\r\n },\r\n h3: {\r\n fontWeight: 600,\r\n letterSpacing: '-0.025em',\r\n fontSize: '1.5rem',\r\n lineHeight: 1.3,\r\n },\r\n h4: {\r\n fontWeight: 600,\r\n fontSize: '1.25rem',\r\n lineHeight: 1.4,\r\n '@media (max-width:600px)': {\r\n fontSize: '1.125rem',\r\n },\r\n },\r\n h5: {\r\n fontWeight: 600,\r\n fontSize: '1.125rem',\r\n lineHeight: 1.5,\r\n },\r\n h6: {\r\n fontWeight: 600,\r\n fontSize: '1rem',\r\n lineHeight: 1.5,\r\n '@media (max-width:600px)': {\r\n fontSize: '0.875rem',\r\n },\r\n },\r\n body1: {\r\n fontSize: '1rem',\r\n lineHeight: 1.6,\r\n color: '#e2e8f0', // Lighter text for better contrast on dark backgrounds\r\n },\r\n body2: {\r\n fontSize: '0.875rem',\r\n lineHeight: 1.5,\r\n color: '#cbd5e1', // Improved contrast from #94a3b8\r\n },\r\n button: {\r\n fontWeight: 500,\r\n letterSpacing: '0.025em',\r\n textTransform: 'none',\r\n },\r\n caption: {\r\n fontSize: '0.75rem',\r\n lineHeight: 1.4,\r\n color: '#94a3b8', // Improved contrast from #64748b\r\n },\r\n },\r\n shape: {\r\n borderRadius: 12,\r\n },\r\n breakpoints: {\r\n values: {\r\n xs: 0,\r\n sm: 640,\r\n md: 768,\r\n lg: 1024,\r\n xl: 1280,\r\n },\r\n },\r\n components: {\r\n MuiCssBaseline: {\r\n styleOverrides: {\r\n '@global': {\r\n '@keyframes pulse': {\r\n '0%, 100%': {\r\n opacity: 1,\r\n },\r\n '50%': {\r\n opacity: 0.5,\r\n },\r\n },\r\n '@keyframes spin': {\r\n from: {\r\n transform: 'rotate(0deg)',\r\n },\r\n to: {\r\n transform: 'rotate(360deg)',\r\n },\r\n },\r\n '@keyframes fadeIn': {\r\n from: {\r\n opacity: 0,\r\n transform: 'translateY(10px)',\r\n },\r\n to: {\r\n opacity: 1,\r\n transform: 'translateY(0)',\r\n },\r\n },\r\n '@keyframes slideInRight': {\r\n from: {\r\n opacity: 0,\r\n transform: 'translateX(20px)',\r\n },\r\n to: {\r\n opacity: 1,\r\n transform: 'translateX(0)',\r\n },\r\n },\r\n '@keyframes bounce': {\r\n '0%, 20%, 53%, 80%, 100%': {\r\n transform: 'translate3d(0,0,0)',\r\n },\r\n '40%, 43%': {\r\n transform: 'translate3d(0, -8px, 0)',\r\n },\r\n '70%': {\r\n transform: 'translate3d(0, -4px, 0)',\r\n },\r\n '90%': {\r\n transform: 'translate3d(0, -2px, 0)',\r\n },\r\n },\r\n },\r\n },\r\n },\r\n MuiCard: {\r\n styleOverrides: {\r\n root: {\r\n backgroundColor: '#1e293b',\r\n borderRadius: 16,\r\n border: '1px solid #334155',\r\n boxShadow: '0 4px 6px -1px rgb(0 0 0 / 0.3), 0 2px 4px -2px rgb(0 0 0 / 0.3)',\r\n transition: 'all 0.2s cubic-bezier(0.4, 0, 0.2, 1)',\r\n '&:hover': {\r\n boxShadow: '0 20px 25px -5px rgb(0 0 0 / 0.4), 0 8px 10px -6px rgb(0 0 0 / 0.4)',\r\n transform: 'translateY(-2px)',\r\n borderColor: '#475569',\r\n },\r\n },\r\n },\r\n },\r\n MuiButton: {\r\n styleOverrides: {\r\n root: {\r\n borderRadius: 12,\r\n textTransform: 'none',\r\n fontWeight: 500,\r\n padding: '10px 24px',\r\n boxShadow: 'none',\r\n '&:hover': {\r\n boxShadow: '0 4px 6px -1px rgb(0 0 0 / 0.3), 0 2px 4px -2px rgb(0 0 0 / 0.3)',\r\n },\r\n },\r\n contained: {\r\n '&:hover': {\r\n boxShadow: '0 10px 15px -3px rgb(0 0 0 / 0.3), 0 4px 6px -4px rgb(0 0 0 / 0.3)',\r\n },\r\n },\r\n outlined: {\r\n borderWidth: 2,\r\n '&:hover': {\r\n borderWidth: 2,\r\n },\r\n },\r\n },\r\n },\r\n MuiPaper: {\r\n styleOverrides: {\r\n root: {\r\n backgroundColor: '#1e293b',\r\n borderRadius: 16,\r\n border: '1px solid #334155',\r\n boxShadow: '0 4px 6px -1px rgb(0 0 0 / 0.3), 0 2px 4px -2px rgb(0 0 0 / 0.3)',\r\n },\r\n elevation1: {\r\n boxShadow: '0 1px 3px 0 rgb(0 0 0 / 0.3), 0 1px 2px -1px rgb(0 0 0 / 0.3)',\r\n },\r\n elevation2: {\r\n boxShadow: '0 4px 6px -1px rgb(0 0 0 / 0.3), 0 2px 4px -2px rgb(0 0 0 / 0.3)',\r\n },\r\n elevation3: {\r\n boxShadow: '0 10px 15px -3px rgb(0 0 0 / 0.3), 0 4px 6px -4px rgb(0 0 0 / 0.3)',\r\n },\r\n },\r\n },\r\n MuiTextField: {\r\n styleOverrides: {\r\n root: {\r\n '& .MuiOutlinedInput-root': {\r\n borderRadius: 12,\r\n '& fieldset': {\r\n borderColor: '#475569',\r\n },\r\n '&:hover fieldset': {\r\n borderColor: '#64748b',\r\n },\r\n '&.Mui-focused fieldset': {\r\n borderWidth: 2,\r\n borderColor: '#3b82f6',\r\n },\r\n },\r\n },\r\n },\r\n },\r\n MuiChip: {\r\n styleOverrides: {\r\n root: {\r\n borderRadius: 8,\r\n fontWeight: 500,\r\n backgroundColor: '#334155',\r\n color: '#f8fafc',\r\n },\r\n },\r\n },\r\n MuiAppBar: {\r\n styleOverrides: {\r\n root: {\r\n backgroundColor: '#1e293b',\r\n borderRadius: '0 0 16px 16px',\r\n border: '1px solid #334155',\r\n borderTop: 'none',\r\n boxShadow: '0 4px 6px -1px rgb(0 0 0 / 0.3), 0 2px 4px -2px rgb(0 0 0 / 0.3)',\r\n },\r\n },\r\n },\r\n },\r\n};\r\n\r\n// Create enhanced themes with better contrast\r\nconst createEnhancedTheme = (baseTheme) => {\r\n const theme = createTheme(baseTheme);\r\n const enhancedComponents = createContrastEnhancedComponents(theme);\r\n \r\n return createTheme({\r\n ...baseTheme,\r\n components: {\r\n ...baseTheme.components,\r\n ...enhancedComponents\r\n }\r\n });\r\n};\r\n\r\nconst lightTheme = createEnhancedTheme(baseLightTheme);\r\nconst darkTheme = createEnhancedTheme(baseDarkTheme);\r\n\r\nexport const CustomThemeProvider = ({ children }) => {\r\n const [currentTheme, setCurrentTheme] = useState('light');\r\n const [loading, setLoading] = useState(false);\r\n const { user, companyBranding } = useAuth();\r\n\r\n // Check if running in embedded mode\r\n const isEmbedded = new URLSearchParams(window.location.search).get('embedded') === 'true';\r\n\r\n // All authenticated users can modify their theme preference\r\n const canModifyTheme = Boolean(user && (user.role === 'admin' || user.role === 'owner' || user.role === 'property_manager' || user.role === 'maintenance'));\r\n\r\n // Listen for theme changes from parent in embedded mode\r\n useEffect(() => {\r\n if (!isEmbedded) return;\r\n\r\n const handleMessage = (event) => {\r\n // Only accept messages from localhost (development)\r\n if (!event.origin.startsWith('http://localhost:')) return;\r\n\r\n const { type, theme } = event.data;\r\n\r\n if (type === 'THEME_CHANGE' && theme && ['light', 'dark'].includes(theme)) {\r\n // In embedded mode, directly set theme without API call or permission check\r\n setCurrentTheme(theme);\r\n }\r\n };\r\n\r\n window.addEventListener('message', handleMessage);\r\n\r\n // Request current theme from parent\r\n if (window.parent !== window) {\r\n window.parent.postMessage({ type: 'REQUEST_THEME' }, '*');\r\n }\r\n\r\n return () => window.removeEventListener('message', handleMessage);\r\n }, [isEmbedded]);\r\n\r\n // Load theme preference when user changes\r\n useEffect(() => {\r\n // Skip auto-loading theme in embedded mode (wait for parent to send theme)\r\n if (isEmbedded) return;\r\n\r\n if (user && canModifyTheme) {\r\n // All authenticated users use their own theme preference\r\n const themeToUse = user.themePreference || 'light';\r\n setCurrentTheme(themeToUse);\r\n } else {\r\n // Not authenticated - use light theme\r\n setCurrentTheme('light');\r\n }\r\n }, [user, canModifyTheme, isEmbedded]);\r\n\r\n const toggleTheme = async () => {\r\n if (!canModifyTheme) return;\r\n\r\n const newTheme = currentTheme === 'light' ? 'dark' : 'light';\r\n setCurrentTheme(newTheme);\r\n\r\n try {\r\n await api.put('/users/me', { themePreference: newTheme });\r\n } catch (error) {\r\n console.error('Failed to save theme preference:', error);\r\n // Revert on error\r\n setCurrentTheme(currentTheme);\r\n }\r\n };\r\n\r\n const setTheme = async (themeKey) => {\r\n if (!canModifyTheme || !['light', 'dark'].includes(themeKey)) return;\r\n\r\n setCurrentTheme(themeKey);\r\n\r\n try {\r\n await api.put('/users/me', { themePreference: themeKey });\r\n } catch (error) {\r\n console.error('Failed to save theme preference:', error);\r\n // Revert on error\r\n setCurrentTheme(currentTheme);\r\n }\r\n };\r\n\r\n const resetTheme = async () => {\r\n if (!canModifyTheme) return;\r\n\r\n setCurrentTheme('light');\r\n\r\n try {\r\n await api.put('/users/me', { themePreference: 'light' });\r\n } catch (error) {\r\n console.error('Failed to save theme preference:', error);\r\n // Revert on error\r\n setCurrentTheme(currentTheme);\r\n }\r\n };\r\n\r\n // Helper function to get effective branding color\r\n const getEffectiveBrandingColor = () => {\r\n if ((user?.role === 'maintenance' || user?.role === 'property_manager') && companyBranding) {\r\n return companyBranding.preferredBrandingColor || 0;\r\n }\r\n return user?.preferredBrandingColor || 0;\r\n };\r\n\r\n // Use current theme for authenticated users, light theme for login pages\r\n const effectiveTheme = user ? currentTheme : 'light';\r\n const themeObject = effectiveTheme === 'dark' ? darkTheme : lightTheme;\r\n const isDarkMode = effectiveTheme === 'dark';\r\n const effectiveBrandingColor = getEffectiveBrandingColor();\r\n\r\n const value = {\r\n currentThemeKey: effectiveTheme,\r\n theme: themeObject,\r\n isDarkMode,\r\n setTheme,\r\n toggleTheme,\r\n resetTheme,\r\n canModifyTheme,\r\n loading,\r\n isTenantMode: false, // No tenant theming\r\n effectiveBrandingColor,\r\n };\r\n\r\n return (\r\n <ThemeContext.Provider value={value}>\r\n <ThemeProvider theme={themeObject}>\r\n <CssBaseline />\r\n {children}\r\n </ThemeProvider>\r\n </ThemeContext.Provider>\r\n );\r\n};","/**\r\n * Color extraction utility for analyzing logo images and generating color schemes\r\n */\r\n\r\n/**\r\n * Extract dominant colors from an image URL\r\n * @param {string} imageUrl - URL of the image to analyze\r\n * @returns {Promise<Object>} Object containing primary, secondary, and accent colors\r\n */\r\nexport const extractColorsFromImage = (imageUrl) => {\r\n return new Promise((resolve, reject) => {\r\n const img = new Image();\r\n img.crossOrigin = 'Anonymous';\r\n \r\n img.onload = () => {\r\n try {\r\n const canvas = document.createElement('canvas');\r\n const ctx = canvas.getContext('2d');\r\n \r\n // Set canvas size to match image\r\n canvas.width = img.width;\r\n canvas.height = img.height;\r\n \r\n // Draw image to canvas\r\n ctx.drawImage(img, 0, 0);\r\n \r\n // Get image data\r\n const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);\r\n const data = imageData.data;\r\n \r\n // Extract colors using color quantization\r\n const colors = extractDominantColors(data);\r\n \r\n // Generate color scheme\r\n const colorScheme = generateColorScheme(colors);\r\n \r\n resolve(colorScheme);\r\n } catch (error) {\r\n reject(error);\r\n }\r\n };\r\n \r\n img.onerror = () => {\r\n reject(new Error('Failed to load image'));\r\n };\r\n \r\n img.src = imageUrl;\r\n });\r\n};\r\n\r\n/**\r\n * Extract dominant colors from image data using simple color quantization\r\n * @param {Uint8ClampedArray} data - Image pixel data\r\n * @returns {Array} Array of dominant colors in RGB format\r\n */\r\nconst extractDominantColors = (data) => {\r\n const colorCounts = {};\r\n const step = 4; // Skip pixels for performance\r\n \r\n // Count color occurrences (simplified to reduce similar colors)\r\n for (let i = 0; i < data.length; i += 4 * step) {\r\n const r = Math.floor(data[i] / 32) * 32; // Quantize to reduce similar colors\r\n const g = Math.floor(data[i + 1] / 32) * 32;\r\n const b = Math.floor(data[i + 2] / 32) * 32;\r\n const a = data[i + 3];\r\n \r\n // Skip transparent or very light pixels\r\n if (a < 128 || (r > 200 && g > 200 && b > 200)) continue;\r\n \r\n const colorKey = `${r},${g},${b}`;\r\n colorCounts[colorKey] = (colorCounts[colorKey] || 0) + 1;\r\n }\r\n \r\n // Sort colors by frequency and return top colors\r\n const sortedColors = Object.entries(colorCounts)\r\n .sort(([,a], [,b]) => b - a)\r\n .slice(0, 5)\r\n .map(([color]) => {\r\n const [r, g, b] = color.split(',').map(Number);\r\n return { r, g, b };\r\n });\r\n \r\n return sortedColors;\r\n};\r\n\r\n/**\r\n * Generate a cohesive color scheme from dominant colors\r\n * @param {Array} dominantColors - Array of dominant colors\r\n * @returns {Object} Color scheme object\r\n */\r\nconst generateColorScheme = (dominantColors) => {\r\n if (dominantColors.length === 0) {\r\n // Fallback to default colors\r\n return {\r\n primary: '#1976d2',\r\n secondary: '#dc004e',\r\n accent: '#9c27b0',\r\n light: '#bbdefb',\r\n dark: '#0d47a1'\r\n };\r\n }\r\n \r\n const primary = dominantColors[0];\r\n const secondary = dominantColors[1] || primary;\r\n \r\n // Convert to hex and generate variations\r\n const primaryHex = rgbToHex(primary.r, primary.g, primary.b);\r\n const secondaryHex = rgbToHex(secondary.r, secondary.g, secondary.b);\r\n \r\n // Generate lighter and darker variations\r\n const lightVariation = lightenColor(primaryHex, 0.3);\r\n const darkVariation = darkenColor(primaryHex, 0.3);\r\n \r\n // Generate accent color (complementary or triadic)\r\n const accentHex = generateAccentColor(primary);\r\n \r\n // Get top 4 dominant colors for user selection\r\n const topColors = dominantColors.slice(0, 4).map((color, index) => ({\r\n id: index,\r\n rgb: color,\r\n hex: rgbToHex(color.r, color.g, color.b),\r\n name: `Color ${index + 1}`\r\n }));\r\n\r\n return {\r\n primary: primary,\r\n secondary: secondary,\r\n accent: hexToRgb(accentHex),\r\n light: hexToRgb(lightVariation),\r\n dark: hexToRgb(darkVariation),\r\n // Also include hex versions for CSS use\r\n primaryHex: primaryHex,\r\n secondaryHex: secondaryHex,\r\n accentHex: accentHex,\r\n // Top 4 prominent colors for selection\r\n topColors: topColors\r\n };\r\n};\r\n\r\n/**\r\n * Convert RGB to hex\r\n */\r\nexport const rgbToHex = (r, g, b) => {\r\n return \"#\" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);\r\n};\r\n\r\n/**\r\n * Convert hex to RGB object\r\n */\r\nconst hexToRgb = (hex) => {\r\n const num = parseInt(hex.replace(\"#\", \"\"), 16);\r\n return {\r\n r: num >> 16,\r\n g: (num >> 8 & 0x00FF),\r\n b: num & 0x0000FF\r\n };\r\n};\r\n\r\n/**\r\n * Lighten a hex color\r\n */\r\nexport const lightenColor = (hex, amount) => {\r\n const num = parseInt(hex.replace(\"#\", \"\"), 16);\r\n const r = Math.min(255, (num >> 16) + Math.round(255 * amount));\r\n const g = Math.min(255, (num >> 8 & 0x00FF) + Math.round(255 * amount));\r\n const b = Math.min(255, (num & 0x0000FF) + Math.round(255 * amount));\r\n return rgbToHex(r, g, b);\r\n};\r\n\r\n/**\r\n * Darken a hex color\r\n */\r\nexport const darkenColor = (hex, amount) => {\r\n const num = parseInt(hex.replace(\"#\", \"\"), 16);\r\n const r = Math.max(0, (num >> 16) - Math.round(255 * amount));\r\n const g = Math.max(0, (num >> 8 & 0x00FF) - Math.round(255 * amount));\r\n const b = Math.max(0, (num & 0x0000FF) - Math.round(255 * amount));\r\n return rgbToHex(r, g, b);\r\n};\r\n\r\n/**\r\n * Generate accent color (simple complementary color)\r\n */\r\nconst generateAccentColor = (rgb) => {\r\n // Simple complementary color calculation\r\n const complementaryR = 255 - rgb.r;\r\n const complementaryG = 255 - rgb.g;\r\n const complementaryB = 255 - rgb.b;\r\n \r\n return rgbToHex(complementaryR, complementaryG, complementaryB);\r\n};\r\n\r\n/**\r\n * Check if a color is dark or light (for text contrast)\r\n */\r\nexport const isColorDark = (hex) => {\r\n const num = parseInt(hex.replace(\"#\", \"\"), 16);\r\n const r = (num >> 16);\r\n const g = (num >> 8 & 0x00FF);\r\n const b = (num & 0x0000FF);\r\n \r\n // Calculate luminance\r\n const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255;\r\n return luminance < 0.5;\r\n};\r\n\r\n/**\r\n * Calculate relative luminance according to WCAG 2.1\r\n * @param {string} hex - Hex color code\r\n * @returns {number} Relative luminance (0-1)\r\n */\r\nexport const getRelativeLuminance = (hex) => {\r\n const num = parseInt(hex.replace(\"#\", \"\"), 16);\r\n const r = (num >> 16) / 255;\r\n const g = (num >> 8 & 0x00FF) / 255;\r\n const b = (num & 0x0000FF) / 255;\r\n\r\n // Apply gamma correction\r\n const toLinear = (c) => {\r\n return c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);\r\n };\r\n\r\n const rLinear = toLinear(r);\r\n const gLinear = toLinear(g);\r\n const bLinear = toLinear(b);\r\n\r\n return 0.2126 * rLinear + 0.7152 * gLinear + 0.0722 * bLinear;\r\n};\r\n\r\n/**\r\n * Calculate contrast ratio between two colors according to WCAG 2.1\r\n * @param {string} color1 - First hex color\r\n * @param {string} color2 - Second hex color\r\n * @returns {number} Contrast ratio (1-21)\r\n */\r\nexport const getContrastRatio = (color1, color2) => {\r\n const luminance1 = getRelativeLuminance(color1);\r\n const luminance2 = getRelativeLuminance(color2);\r\n \r\n const lighter = Math.max(luminance1, luminance2);\r\n const darker = Math.min(luminance1, luminance2);\r\n \r\n return (lighter + 0.05) / (darker + 0.05);\r\n};\r\n\r\n/**\r\n * Get the best contrast text color for a given background\r\n * @param {string} backgroundColor - Background color in hex\r\n * @param {string} lightColor - Light text color (default: white)\r\n * @param {string} darkColor - Dark text color (default: black)\r\n * @returns {string} Best contrasting text color\r\n */\r\nexport const getBestContrastText = (backgroundColor, lightColor = '#ffffff', darkColor = '#000000') => {\r\n const lightContrast = getContrastRatio(backgroundColor, lightColor);\r\n const darkContrast = getContrastRatio(backgroundColor, darkColor);\r\n \r\n return lightContrast > darkContrast ? lightColor : darkColor;\r\n};\r\n\r\n/**\r\n * Check if color combination meets WCAG AA standard (4.5:1)\r\n * @param {string} backgroundColor - Background color\r\n * @param {string} textColor - Text color\r\n * @returns {boolean} Whether combination meets WCAG AA\r\n */\r\nexport const meetsWCAGAA = (backgroundColor, textColor) => {\r\n return getContrastRatio(backgroundColor, textColor) >= 4.5;\r\n};\r\n\r\n/**\r\n * Check if color combination meets WCAG AAA standard (7:1)\r\n * @param {string} backgroundColor - Background color\r\n * @param {string} textColor - Text color\r\n * @returns {boolean} Whether combination meets WCAG AAA\r\n */\r\nexport const meetsWCAGAAA = (backgroundColor, textColor) => {\r\n return getContrastRatio(backgroundColor, textColor) >= 7;\r\n};\r\n\r\n/**\r\n * Get accessible text color with fallback options\r\n * @param {string} backgroundColor - Background color\r\n * @param {Object} options - Options for text colors and standards\r\n * @returns {string} Accessible text color\r\n */\r\nexport const getAccessibleTextColor = (backgroundColor, options = {}) => {\r\n const {\r\n preferredLight = '#ffffff',\r\n preferredDark = '#000000',\r\n fallbackLight = '#f8fafc',\r\n fallbackDark = '#1e293b',\r\n standard = 'AA' // 'AA' or 'AAA'\r\n } = options;\r\n\r\n const requiredRatio = standard === 'AAA' ? 7 : 4.5;\r\n \r\n // Try preferred colors first\r\n if (getContrastRatio(backgroundColor, preferredLight) >= requiredRatio) {\r\n return preferredLight;\r\n }\r\n \r\n if (getContrastRatio(backgroundColor, preferredDark) >= requiredRatio) {\r\n return preferredDark;\r\n }\r\n \r\n // Try fallback colors\r\n if (getContrastRatio(backgroundColor, fallbackLight) >= requiredRatio) {\r\n return fallbackLight;\r\n }\r\n \r\n if (getContrastRatio(backgroundColor, fallbackDark) >= requiredRatio) {\r\n return fallbackDark;\r\n }\r\n \r\n // Last resort: return the color with better contrast\r\n return getBestContrastText(backgroundColor, preferredLight, preferredDark);\r\n};","import { getAccessibleTextColor, getContrastRatio, meetsWCAGAA } from './colorExtractor';\r\n\r\n/**\r\n * Enhanced theme contrast utilities for Material-UI components\r\n * Ensures all components meet WCAG accessibility standards\r\n */\r\n\r\n/**\r\n * Get enhanced button colors with proper contrast\r\n * @param {string} backgroundColor - Background color of the button\r\n * @param {string} mode - Theme mode ('light' or 'dark')\r\n * @returns {Object} Button color configuration\r\n */\r\nexport const getButtonContrastColors = (backgroundColor, mode = 'light') => {\r\n const textColor = getAccessibleTextColor(backgroundColor);\r\n const contrast = getContrastRatio(backgroundColor, textColor);\r\n \r\n return {\r\n color: textColor,\r\n backgroundColor,\r\n contrastRatio: contrast,\r\n isAccessible: meetsWCAGAA(backgroundColor, textColor),\r\n // Hover state with adjusted opacity\r\n '&:hover': {\r\n backgroundColor: mode === 'dark' ? \r\n `${backgroundColor}dd` : // Slightly transparent in dark mode\r\n `${backgroundColor}e6`, // Slightly transparent in light mode\r\n color: textColor\r\n }\r\n };\r\n};\r\n\r\n/**\r\n * Get enhanced chip colors with proper contrast\r\n * @param {string} backgroundColor - Background color of the chip\r\n * @param {string} variant - Chip variant ('filled', 'outlined')\r\n * @returns {Object} Chip color configuration\r\n */\r\nexport const getChipContrastColors = (backgroundColor, variant = 'filled') => {\r\n if (variant === 'outlined') {\r\n return {\r\n borderColor: backgroundColor,\r\n color: backgroundColor,\r\n '&:hover': {\r\n backgroundColor: `${backgroundColor}20`,\r\n color: backgroundColor\r\n }\r\n };\r\n }\r\n \r\n const textColor = getAccessibleTextColor(backgroundColor);\r\n return {\r\n backgroundColor,\r\n color: textColor,\r\n '&:hover': {\r\n backgroundColor: `${backgroundColor}dd`,\r\n color: textColor\r\n }\r\n };\r\n};\r\n\r\n/**\r\n * Get enhanced card colors with proper contrast\r\n * @param {string} backgroundColor - Background color of the card\r\n * @param {boolean} isDarkMode - Whether dark mode is active\r\n * @returns {Object} Card styling with proper text contrast\r\n */\r\nexport const getCardContrastColors = (backgroundColor, isDarkMode = false) => {\r\n const textColor = getAccessibleTextColor(backgroundColor, {\r\n preferredLight: isDarkMode ? '#f8fafc' : '#ffffff',\r\n preferredDark: isDarkMode ? '#1e293b' : '#000000',\r\n fallbackLight: isDarkMode ? '#e2e8f0' : '#f8fafc',\r\n fallbackDark: isDarkMode ? '#334155' : '#1e293b'\r\n });\r\n \r\n return {\r\n backgroundColor,\r\n color: textColor,\r\n '& .MuiTypography-root': {\r\n color: textColor\r\n },\r\n '& .MuiTypography-body2': {\r\n color: `${textColor}cc` // Slightly transparent for secondary text\r\n },\r\n '& .MuiTypography-caption': {\r\n color: `${textColor}99` // More transparent for caption text\r\n }\r\n };\r\n};\r\n\r\n/**\r\n * Get enhanced gradient text color for complex backgrounds\r\n * @param {Array} gradientColors - Array of hex colors in the gradient\r\n * @param {Object} options - Text color options\r\n * @returns {string} Best contrast text color for gradient\r\n */\r\nexport const getGradientContrastColor = (gradientColors, options = {}) => {\r\n // Calculate contrast for each color and pick the best overall option\r\n const contrasts = gradientColors.map(color => {\r\n const lightContrast = getContrastRatio(color, '#ffffff');\r\n const darkContrast = getContrastRatio(color, '#000000');\r\n return { color, lightContrast, darkContrast };\r\n });\r\n \r\n // Use the color that provides the minimum acceptable contrast across all gradient colors\r\n const minLightContrast = Math.min(...contrasts.map(c => c.lightContrast));\r\n const minDarkContrast = Math.min(...contrasts.map(c => c.darkContrast));\r\n \r\n if (minLightContrast >= 4.5) {\r\n return options.preferredLight || '#ffffff';\r\n } else if (minDarkContrast >= 4.5) {\r\n return options.preferredDark || '#000000';\r\n } else {\r\n // If neither meets standards, use the better of the two\r\n return minLightContrast > minDarkContrast ? \r\n (options.preferredLight || '#ffffff') : \r\n (options.preferredDark || '#000000');\r\n }\r\n};\r\n\r\n/**\r\n * Get enhanced status colors with proper contrast\r\n * @param {string} status - Status type ('success', 'warning', 'error', 'info')\r\n * @param {string} variant - Color variant ('main', 'light', 'dark')\r\n * @param {Object} theme - MUI theme object\r\n * @returns {Object} Status styling with proper contrast\r\n */\r\nexport const getStatusContrastColors = (status, variant = 'main', theme) => {\r\n const backgroundColor = theme.palette[status][variant];\r\n const textColor = getAccessibleTextColor(backgroundColor);\r\n \r\n return {\r\n backgroundColor,\r\n color: textColor,\r\n borderColor: backgroundColor,\r\n '&:hover': {\r\n backgroundColor: theme.palette[status].dark,\r\n color: getAccessibleTextColor(theme.palette[status].dark)\r\n }\r\n };\r\n};\r\n\r\n/**\r\n * Create enhanced theme component overrides with better contrast\r\n * @param {Object} theme - Base MUI theme\r\n * @returns {Object} Component overrides with enhanced contrast\r\n */\r\nexport const createContrastEnhancedComponents = (theme) => {\r\n const isDark = theme.palette.mode === 'dark';\r\n \r\n return {\r\n // Enhanced Button components\r\n MuiButton: {\r\n styleOverrides: {\r\n containedPrimary: getButtonContrastColors(theme.palette.primary.main, theme.palette.mode),\r\n containedSecondary: getButtonContrastColors(theme.palette.secondary.main, theme.palette.mode),\r\n containedSuccess: getButtonContrastColors(theme.palette.success.main, theme.palette.mode),\r\n containedWarning: getButtonContrastColors(theme.palette.warning.main, theme.palette.mode),\r\n containedError: getButtonContrastColors(theme.palette.error.main, theme.palette.mode),\r\n }\r\n },\r\n \r\n // Enhanced Chip components\r\n MuiChip: {\r\n styleOverrides: {\r\n filledPrimary: getChipContrastColors(theme.palette.primary.main),\r\n filledSecondary: getChipContrastColors(theme.palette.secondary.main),\r\n filledSuccess: getChipContrastColors(theme.palette.success.main),\r\n filledWarning: getChipContrastColors(theme.palette.warning.main),\r\n filledError: getChipContrastColors(theme.palette.error.main),\r\n }\r\n },\r\n \r\n // Enhanced Alert components\r\n MuiAlert: {\r\n styleOverrides: {\r\n filledSuccess: getStatusContrastColors('success', 'main', theme),\r\n filledWarning: getStatusContrastColors('warning', 'main', theme),\r\n filledError: getStatusContrastColors('error', 'main', theme),\r\n filledInfo: getStatusContrastColors('info', 'main', theme),\r\n }\r\n },\r\n \r\n // Enhanced Badge components\r\n MuiBadge: {\r\n styleOverrides: {\r\n colorPrimary: {\r\n backgroundColor: theme.palette.primary.main,\r\n color: getAccessibleTextColor(theme.palette.primary.main)\r\n },\r\n colorSecondary: {\r\n backgroundColor: theme.palette.secondary.main,\r\n color: getAccessibleTextColor(theme.palette.secondary.main)\r\n },\r\n colorError: {\r\n backgroundColor: theme.palette.error.main,\r\n color: getAccessibleTextColor(theme.palette.error.main)\r\n }\r\n }\r\n },\r\n \r\n // Enhanced Avatar components\r\n MuiAvatar: {\r\n styleOverrides: {\r\n colorDefault: {\r\n backgroundColor: theme.palette.primary.main,\r\n color: getAccessibleTextColor(theme.palette.primary.main)\r\n }\r\n }\r\n },\r\n \r\n // Enhanced Fab components\r\n MuiFab: {\r\n styleOverrides: {\r\n primary: getButtonContrastColors(theme.palette.primary.main, theme.palette.mode),\r\n secondary: getButtonContrastColors(theme.palette.secondary.main, theme.palette.mode),\r\n }\r\n }\r\n };\r\n};\r\n\r\n/**\r\n * Validate theme colors for accessibility compliance\r\n * @param {Object} theme - MUI theme object\r\n * @returns {Object} Accessibility report\r\n */\r\nexport const validateThemeAccessibility = (theme) => {\r\n const report = {\r\n compliant: true,\r\n issues: [],\r\n recommendations: []\r\n };\r\n \r\n // Check primary colors\r\n const primaryContrast = getContrastRatio(theme.palette.primary.main, theme.palette.primary.contrastText);\r\n if (!meetsWCAGAA(theme.palette.primary.main, theme.palette.primary.contrastText)) {\r\n report.compliant = false;\r\n report.issues.push({\r\n component: 'Primary color',\r\n current: `${primaryContrast.toFixed(1)}:1`,\r\n required: '4.5:1',\r\n recommendation: `Use ${getAccessibleTextColor(theme.palette.primary.main)} as contrast text`\r\n });\r\n }\r\n \r\n // Check secondary colors\r\n const secondaryContrast = getContrastRatio(theme.palette.secondary.main, theme.palette.secondary.contrastText);\r\n if (!meetsWCAGAA(theme.palette.secondary.main, theme.palette.secondary.contrastText)) {\r\n report.compliant = false;\r\n report.issues.push({\r\n component: 'Secondary color',\r\n current: `${secondaryContrast.toFixed(1)}:1`,\r\n required: '4.5:1',\r\n recommendation: `Use ${getAccessibleTextColor(theme.palette.secondary.main)} as contrast text`\r\n });\r\n }\r\n \r\n return report;\r\n};","import React from 'react';\r\nimport { Box } from '@mui/material';\r\nimport { useCustomTheme } from '../../contexts/ThemeContext';\r\n\r\nconst PageLayout = ({ children, maxWidth = \"1400px\", padding = { xs: 2, sm: 3, md: 4 } }) => {\r\n const { isDarkMode } = useCustomTheme();\r\n\r\n return (\r\n <Box\r\n sx={{\r\n minHeight: 'calc(100vh - 64px)', // Account for navbar height\r\n background: isDarkMode \r\n ? 'linear-gradient(135deg, rgba(59, 130, 246, 0.03) 0%, rgba(139, 92, 246, 0.03) 100%)'\r\n : 'linear-gradient(135deg, rgba(37, 99, 235, 0.02) 0%, rgba(124, 58, 237, 0.02) 100%)',\r\n p: padding\r\n }}\r\n >\r\n <Box\r\n sx={{\r\n maxWidth: maxWidth,\r\n margin: '0 auto',\r\n width: '100%'\r\n }}\r\n >\r\n {children}\r\n </Box>\r\n </Box>\r\n );\r\n};\r\n\r\nexport default PageLayout;","import React from 'react';\r\nimport {\r\n Box,\r\n Typography,\r\n Stack,\r\n Breadcrumbs,\r\n Link,\r\n useMediaQuery,\r\n useTheme\r\n} from '@mui/material';\r\nimport { useNavigate, useLocation } from 'react-router-dom';\r\nimport { useCustomTheme } from '../../contexts/ThemeContext';\r\n\r\nconst PageHeader = ({\r\n title,\r\n subtitle,\r\n children, // Action buttons go here\r\n breadcrumbs = [],\r\n marginBottom = { xs: 3, sm: 4, md: 6 }\r\n}) => {\r\n const navigate = useNavigate();\r\n const location = useLocation();\r\n const theme = useTheme();\r\n const { isDarkMode } = useCustomTheme();\r\n const isMobile = useMediaQuery(theme.breakpoints.down('sm'));\r\n\r\n const handleBreadcrumbClick = (path) => {\r\n if (path) {\r\n navigate(path);\r\n }\r\n };\r\n\r\n return (\r\n <Box sx={{ mb: marginBottom }}>\r\n {/* Breadcrumbs */}\r\n {breadcrumbs.length > 0 && (\r\n <Breadcrumbs\r\n aria-label=\"breadcrumb\"\r\n sx={{ \r\n mb: 2,\r\n '& .MuiBreadcrumbs-separator': {\r\n color: 'text.secondary',\r\n opacity: 0.6\r\n }\r\n }}\r\n >\r\n {breadcrumbs.map((breadcrumb, index) => {\r\n const isLast = index === breadcrumbs.length - 1;\r\n return isLast ? (\r\n <Typography\r\n key={breadcrumb.label}\r\n component=\"span\"\r\n color=\"text.primary\"\r\n sx={{ \r\n fontWeight: 500,\r\n fontSize: '0.875rem'\r\n }}\r\n >\r\n {breadcrumb.label}\r\n </Typography>\r\n ) : (\r\n <Link\r\n key={breadcrumb.label}\r\n color=\"inherit\"\r\n href=\"#\"\r\n onClick={(e) => {\r\n e.preventDefault();\r\n handleBreadcrumbClick(breadcrumb.path);\r\n }}\r\n sx={{ \r\n textDecoration: 'none',\r\n fontSize: '0.875rem',\r\n fontWeight: 400,\r\n '&:hover': {\r\n textDecoration: 'underline',\r\n color: 'primary.main'\r\n }\r\n }}\r\n >\r\n {breadcrumb.label}\r\n </Link>\r\n );\r\n })}\r\n </Breadcrumbs>\r\n )}\r\n\r\n {/* Header Content */}\r\n <Box\r\n display=\"flex\"\r\n justifyContent=\"space-between\"\r\n alignItems={isMobile ? 'flex-start' : 'center'}\r\n flexDirection={isMobile ? 'column' : 'row'}\r\n gap={isMobile ? 2 : 0}\r\n >\r\n {/* Title and Subtitle */}\r\n <Box sx={{ flex: 1 }}>\r\n <Typography\r\n variant=\"h2\"\r\n component=\"h1\"\r\n data-testid=\"dashboard-title\"\r\n sx={{\r\n fontWeight: 800,\r\n background: isDarkMode\r\n ? 'linear-gradient(135deg, #60a5fa 0%, #a78bfa 100%)'\r\n : 'linear-gradient(135deg, #2563eb 0%, #7c3aed 100%)',\r\n WebkitBackgroundClip: 'text',\r\n WebkitTextFillColor: 'transparent',\r\n backgroundClip: 'text',\r\n fontSize: {\r\n xs: '1.75rem',\r\n sm: '2.25rem',\r\n md: '2.5rem'\r\n },\r\n lineHeight: 1.2,\r\n mb: subtitle ? 0.5 : 0\r\n }}\r\n >\r\n {title}\r\n </Typography>\r\n \r\n {subtitle && (\r\n <Typography\r\n variant=\"body1\"\r\n color=\"text.secondary\"\r\n sx={{\r\n fontSize: {\r\n xs: '0.875rem',\r\n sm: '1rem'\r\n },\r\n fontWeight: 400,\r\n maxWidth: '600px'\r\n }}\r\n >\r\n {subtitle}\r\n </Typography>\r\n )}\r\n </Box>\r\n\r\n {/* Action Buttons */}\r\n {children && (\r\n <Box\r\n sx={{\r\n flexShrink: 0,\r\n width: isMobile ? '100%' : 'auto'\r\n }}\r\n >\r\n <Stack\r\n direction={isMobile ? 'column' : 'row'}\r\n spacing={1.5}\r\n sx={{\r\n '& > *': {\r\n minWidth: isMobile ? '100%' : 'auto'\r\n }\r\n }}\r\n >\r\n {children}\r\n </Stack>\r\n </Box>\r\n )}\r\n </Box>\r\n </Box>\r\n );\r\n};\r\n\r\nexport default PageHeader;","import React from 'react';\r\nimport {\r\n Container,\r\n Box,\r\n Paper,\r\n Typography,\r\n Stack\r\n} from '@mui/material';\r\nimport { useCustomTheme } from '../../contexts/ThemeContext';\r\n\r\nconst AuthLayout = ({ \r\n children, \r\n title, \r\n subtitle,\r\n maxWidth = \"sm\",\r\n showLogo = true\r\n}) => {\r\n const { isDarkMode } = useCustomTheme();\r\n\r\n return (\r\n <Box\r\n sx={{\r\n minHeight: '100vh',\r\n display: 'flex',\r\n alignItems: 'center',\r\n background: isDarkMode\r\n ? 'linear-gradient(135deg, rgba(59, 130, 246, 0.08) 0%, rgba(139, 92, 246, 0.08) 100%)'\r\n : 'linear-gradient(135deg, rgba(37, 99, 235, 0.05) 0%, rgba(124, 58, 237, 0.05) 100%)',\r\n py: { xs: 2, sm: 4 }\r\n }}\r\n >\r\n <Container maxWidth={maxWidth}>\r\n <Box\r\n display=\"flex\"\r\n flexDirection=\"column\"\r\n alignItems=\"center\"\r\n px={{ xs: 1, sm: 0 }}\r\n >\r\n {/* Logo/Brand Section */}\r\n {showLogo && (\r\n <Box sx={{ mb: 4, textAlign: 'center' }}>\r\n <Typography\r\n variant=\"h4\"\r\n component=\"h1\"\r\n sx={{\r\n fontWeight: 800,\r\n background: isDarkMode\r\n ? 'linear-gradient(135deg, #60a5fa 0%, #a78bfa 100%)'\r\n : 'linear-gradient(135deg, #2563eb 0%, #7c3aed 100%)',\r\n WebkitBackgroundClip: 'text',\r\n WebkitTextFillColor: 'transparent',\r\n backgroundClip: 'text',\r\n mb: 1\r\n }}\r\n >\r\n PropertyManager AI\r\n </Typography>\r\n <Typography\r\n variant=\"body2\"\r\n color=\"text.secondary\"\r\n sx={{ fontWeight: 500 }}\r\n >\r\n Intelligent Property Management Solutions\r\n </Typography>\r\n </Box>\r\n )}\r\n\r\n <Paper\r\n elevation={6}\r\n sx={{\r\n p: { xs: 3, sm: 4, md: 5 },\r\n width: '100%',\r\n maxWidth: 480,\r\n borderRadius: 3,\r\n background: isDarkMode\r\n ? 'rgba(17, 25, 40, 0.95)'\r\n : 'rgba(255, 255, 255, 0.95)',\r\n backdropFilter: 'blur(10px)',\r\n border: isDarkMode\r\n ? '1px solid rgba(59, 130, 246, 0.1)'\r\n : '1px solid rgba(37, 99, 235, 0.1)',\r\n boxShadow: isDarkMode\r\n ? '0 20px 25px -5px rgba(0, 0, 0, 0.4), 0 10px 10px -5px rgba(0, 0, 0, 0.2)'\r\n : '0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)'\r\n }}\r\n >\r\n {/* Form Header */}\r\n {(title || subtitle) && (\r\n <Box sx={{ mb: 3, textAlign: 'center' }}>\r\n {title && (\r\n <Typography\r\n variant=\"h5\"\r\n component=\"h2\"\r\n sx={{\r\n fontWeight: 700,\r\n mb: subtitle ? 1 : 0,\r\n color: 'text.primary'\r\n }}\r\n >\r\n {title}\r\n </Typography>\r\n )}\r\n {subtitle && (\r\n <Typography\r\n variant=\"body2\"\r\n color=\"text.secondary\"\r\n sx={{ fontWeight: 400 }}\r\n >\r\n {subtitle}\r\n </Typography>\r\n )}\r\n </Box>\r\n )}\r\n\r\n {/* Form Content */}\r\n {children}\r\n </Paper>\r\n </Box>\r\n </Container>\r\n </Box>\r\n );\r\n};\r\n\r\nexport default AuthLayout;","import React from 'react';\r\nimport { Box, CircularProgress, Typography, Stack } from '@mui/material';\r\nimport { TenantThemeProvider, useTenantTheme } from '../../contexts/TenantThemeContext';\r\n\r\n// Loading component that uses the theme context\r\nconst TenantContent = ({ children }) => {\r\n const { isThemeLoading } = useTenantTheme();\r\n\r\n if (isThemeLoading) {\r\n return (\r\n <Box\r\n sx={{\r\n minHeight: '100vh',\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n backgroundColor: 'background.default'\r\n }}\r\n >\r\n <Stack \r\n spacing={3} \r\n alignItems=\"center\"\r\n sx={{\r\n textAlign: 'center'\r\n }}\r\n >\r\n <CircularProgress \r\n size={60}\r\n thickness={4}\r\n sx={{\r\n color: 'primary.main',\r\n '& .MuiCircularProgress-circle': {\r\n strokeLinecap: 'round',\r\n },\r\n }}\r\n />\r\n <Typography \r\n variant=\"h6\" \r\n color=\"text.secondary\"\r\n sx={{ \r\n fontWeight: 500,\r\n letterSpacing: 0.5\r\n }}\r\n >\r\n Loading your personalized experience...\r\n </Typography>\r\n </Stack>\r\n </Box>\r\n );\r\n }\r\n\r\n return (\r\n <Box\r\n sx={{\r\n minHeight: '100vh',\r\n backgroundColor: 'background.default',\r\n transition: 'all 0.3s ease-in-out'\r\n }}\r\n >\r\n {children}\r\n </Box>\r\n );\r\n};\r\n\r\nconst TenantLayout = ({ children }) => {\r\n return (\r\n <TenantThemeProvider>\r\n <TenantContent>\r\n {children}\r\n </TenantContent>\r\n </TenantThemeProvider>\r\n );\r\n};\r\n\r\nexport default TenantLayout;","import React, { createContext, useContext, useState, useEffect } from 'react';\r\nimport { createTheme, ThemeProvider } from '@mui/material/styles';\r\nimport { extractColorsFromImage, getAccessibleTextColor } from '../utils/colorExtractor';\r\nimport api from '../services/api';\r\n\r\nconst TenantThemeContext = createContext();\r\n\r\nexport const useTenantTheme = () => {\r\n const context = useContext(TenantThemeContext);\r\n if (!context) {\r\n throw new Error('useTenantTheme must be used within a TenantThemeProvider');\r\n }\r\n return context;\r\n};\r\n\r\nexport const TenantThemeProvider = ({ children }) => {\r\n const [brandingColors, setBrandingColors] = useState(null);\r\n const [theme, setTheme] = useState(createDefaultTheme());\r\n const [isThemeLoading, setIsThemeLoading] = useState(true);\r\n const [darkMode, setDarkMode] = useState(() => {\r\n // Load dark mode preference from localStorage\r\n const saved = localStorage.getItem('tenantDarkMode');\r\n return saved === 'true';\r\n });\r\n\r\n // Create default theme\r\n function createDefaultTheme(isDark = false) {\r\n return createTheme({\r\n palette: {\r\n mode: isDark ? 'dark' : 'light',\r\n primary: {\r\n main: '#1976d2',\r\n light: '#42a5f5',\r\n dark: '#1565c0',\r\n },\r\n secondary: {\r\n main: '#9c27b0',\r\n },\r\n },\r\n });\r\n }\r\n\r\n // Create theme with branding colors\r\n const createBrandedTheme = (colorScheme, selectedColorIndex = 0, isDark = false) => {\r\n if (!colorScheme?.topColors?.[selectedColorIndex]) {\r\n return createDefaultTheme(isDark);\r\n }\r\n\r\n const selectedColor = colorScheme.topColors[selectedColorIndex];\r\n const primaryHex = selectedColor.hex;\r\n\r\n // Generate lighter and darker variations\r\n const lightenColor = (hex, amount) => {\r\n const num = parseInt(hex.replace(\"#\", \"\"), 16);\r\n const r = Math.min(255, (num >> 16) + Math.round(255 * amount));\r\n const g = Math.min(255, (num >> 8 & 0x00FF) + Math.round(255 * amount));\r\n const b = Math.min(255, (num & 0x0000FF) + Math.round(255 * amount));\r\n return `#${((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1)}`;\r\n };\r\n\r\n const darkenColor = (hex, amount) => {\r\n const num = parseInt(hex.replace(\"#\", \"\"), 16);\r\n const r = Math.max(0, (num >> 16) - Math.round(255 * amount));\r\n const g = Math.max(0, (num >> 8 & 0x00FF) - Math.round(255 * amount));\r\n const b = Math.max(0, (num & 0x0000FF) - Math.round(255 * amount));\r\n return `#${((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1)}`;\r\n };\r\n\r\n const lightVariant = lightenColor(primaryHex, 0.2);\r\n const darkVariant = darkenColor(primaryHex, 0.2);\r\n\r\n // Get secondary color from available colors or generate one\r\n const secondaryColor = colorScheme.topColors[1]?.hex || colorScheme.accentHex || '#9c27b0';\r\n\r\n return createTheme({\r\n palette: {\r\n mode: isDark ? 'dark' : 'light',\r\n primary: {\r\n main: primaryHex,\r\n light: lightVariant,\r\n dark: darkVariant,\r\n contrastText: getAccessibleTextColor(primaryHex),\r\n },\r\n secondary: {\r\n main: secondaryColor,\r\n },\r\n },\r\n components: {\r\n // Customize button styles\r\n MuiButton: {\r\n styleOverrides: {\r\n root: {\r\n borderRadius: '8px',\r\n textTransform: 'none',\r\n fontWeight: 500,\r\n },\r\n contained: {\r\n boxShadow: `0 2px 8px ${primaryHex}40`,\r\n '&:hover': {\r\n boxShadow: `0 4px 12px ${primaryHex}60`,\r\n },\r\n },\r\n },\r\n },\r\n // Customize fab styles\r\n MuiFab: {\r\n styleOverrides: {\r\n root: {\r\n boxShadow: `0 4px 12px ${primaryHex}40`,\r\n '&:hover': {\r\n boxShadow: `0 6px 16px ${primaryHex}60`,\r\n },\r\n },\r\n },\r\n },\r\n // Customize chip styles\r\n MuiChip: {\r\n styleOverrides: {\r\n root: {\r\n borderRadius: '6px',\r\n },\r\n colorPrimary: {\r\n backgroundColor: primaryHex,\r\n color: getAccessibleTextColor(primaryHex),\r\n },\r\n },\r\n },\r\n // Customize icon button styles\r\n MuiIconButton: {\r\n styleOverrides: {\r\n colorPrimary: {\r\n color: primaryHex,\r\n '&:hover': {\r\n backgroundColor: `${primaryHex}20`,\r\n },\r\n },\r\n },\r\n },\r\n // Customize progress indicators\r\n MuiLinearProgress: {\r\n styleOverrides: {\r\n colorPrimary: {\r\n backgroundColor: `${primaryHex}30`,\r\n '& .MuiLinearProgress-bar': {\r\n backgroundColor: primaryHex,\r\n },\r\n },\r\n },\r\n },\r\n MuiCircularProgress: {\r\n styleOverrides: {\r\n colorPrimary: {\r\n color: primaryHex,\r\n },\r\n },\r\n },\r\n // Customize tabs\r\n MuiTab: {\r\n styleOverrides: {\r\n root: {\r\n textTransform: 'none',\r\n fontWeight: 500,\r\n '&.Mui-selected': {\r\n color: primaryHex,\r\n },\r\n },\r\n },\r\n },\r\n MuiTabs: {\r\n styleOverrides: {\r\n indicator: {\r\n backgroundColor: primaryHex,\r\n },\r\n },\r\n },\r\n },\r\n });\r\n };\r\n\r\n // Fetch company data and create branded theme\r\n const initializeBrandedTheme = async () => {\r\n try {\r\n // Get company data from tenant portal API\r\n const response = await api.get('/tenant-portal/company-info');\r\n const company = response.data;\r\n \r\n // Optimization: Check if custom branding is needed before processing\r\n if (!company.companyLogo && !company.preferredBrandingColor) {\r\n // No custom branding, use default theme\r\n setBrandingColors({\r\n colorScheme: null,\r\n selectedColor: null,\r\n hasCustomBranding: false\r\n });\r\n setIsThemeLoading(false);\r\n return;\r\n }\r\n\r\n if (company.companyLogo) {\r\n const logoUrl = `${api.defaults.baseURL.replace('/api', '')}/uploads/logos/${company.companyLogo}`;\r\n const colorScheme = await extractColorsFromImage(logoUrl);\r\n \r\n setBrandingColors({\r\n colorScheme,\r\n selectedIndex: company.preferredBrandingColor || 0,\r\n company\r\n });\r\n \r\n // Create and apply the branded theme\r\n const brandedTheme = createBrandedTheme(colorScheme, company.preferredBrandingColor || 0, darkMode);\r\n setTheme(brandedTheme);\r\n } else {\r\n // No custom branding, use default theme\r\n setTheme(createDefaultTheme(darkMode));\r\n }\r\n } catch (error) {\r\n console.warn('[TENANT THEME] Could not initialize branded theme:', error);\r\n // Keep default theme on error\r\n setTheme(createDefaultTheme(darkMode));\r\n } finally {\r\n // Theme initialization complete\r\n setIsThemeLoading(false);\r\n }\r\n };\r\n\r\n // Toggle dark mode\r\n const toggleDarkMode = () => {\r\n const newDarkMode = !darkMode;\r\n setDarkMode(newDarkMode);\r\n localStorage.setItem('tenantDarkMode', newDarkMode.toString());\r\n\r\n // Re-create theme with new mode\r\n if (brandingColors?.colorScheme) {\r\n const brandedTheme = createBrandedTheme(\r\n brandingColors.colorScheme,\r\n brandingColors.selectedIndex || 0,\r\n newDarkMode\r\n );\r\n setTheme(brandedTheme);\r\n } else {\r\n setTheme(createDefaultTheme(newDarkMode));\r\n }\r\n };\r\n\r\n // Initialize theme when component mounts\r\n useEffect(() => {\r\n const token = localStorage.getItem('tenantToken');\r\n const tenantData = localStorage.getItem('tenantData');\r\n \r\n // Only initialize theme if we have both token and tenant data\r\n if (token && tenantData) {\r\n try {\r\n api.defaults.headers.common['Authorization'] = `Bearer ${token}`;\r\n initializeBrandedTheme();\r\n } catch (error) {\r\n console.warn('[TENANT THEME] Could not initialize theme:', error);\r\n setIsThemeLoading(false);\r\n }\r\n } else {\r\n // No tenant authentication, stop loading immediately\r\n setIsThemeLoading(false);\r\n }\r\n }, []);\r\n\r\n // Re-apply theme when dark mode changes\r\n useEffect(() => {\r\n if (!isThemeLoading) {\r\n if (brandingColors?.colorScheme) {\r\n const brandedTheme = createBrandedTheme(\r\n brandingColors.colorScheme,\r\n brandingColors.selectedIndex || 0,\r\n darkMode\r\n );\r\n setTheme(brandedTheme);\r\n } else {\r\n setTheme(createDefaultTheme(darkMode));\r\n }\r\n }\r\n }, [darkMode]);\r\n\r\n const contextValue = {\r\n theme,\r\n brandingColors,\r\n initializeBrandedTheme,\r\n isThemeLoading,\r\n darkMode,\r\n toggleDarkMode,\r\n };\r\n\r\n return (\r\n <TenantThemeContext.Provider value={contextValue}>\r\n <ThemeProvider theme={theme}>\r\n {children}\r\n </ThemeProvider>\r\n </TenantThemeContext.Provider>\r\n );\r\n};\r\n\r\nexport default TenantThemeProvider;","import React from 'react';\r\nimport { Box, CircularProgress, Typography } from '@mui/material';\r\n\r\nconst LoadingSpinner = ({ message = 'Loading...' }) => {\r\n return (\r\n <Box\r\n display=\"flex\"\r\n flexDirection=\"column\"\r\n justifyContent=\"center\"\r\n alignItems=\"center\"\r\n minHeight=\"100vh\"\r\n gap={3}\r\n sx={{\r\n background: 'linear-gradient(135deg, rgba(37, 99, 235, 0.02) 0%, rgba(124, 58, 237, 0.02) 100%)'\r\n }}\r\n >\r\n <Box\r\n sx={{\r\n position: 'relative',\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center'\r\n }}\r\n >\r\n <CircularProgress \r\n size={60} \r\n thickness={3}\r\n sx={{\r\n color: 'primary.main'\r\n }}\r\n />\r\n </Box>\r\n <Typography \r\n variant=\"h6\" \r\n sx={{\r\n color: 'text.primary',\r\n fontWeight: 500,\r\n textAlign: 'center'\r\n }}\r\n >\r\n {message}\r\n </Typography>\r\n </Box>\r\n );\r\n};\r\n\r\nexport default LoadingSpinner;","import React from 'react';\r\nimport { Card, CardContent, Box, useTheme } from '@mui/material';\r\nimport { useCustomTheme } from '../../contexts/ThemeContext';\r\n\r\nconst ModernCard = ({ \r\n children, \r\n hover = true, \r\n gradient = false, \r\n sx = {},\r\n elevation = 1,\r\n ...props \r\n}) => {\r\n const theme = useTheme();\r\n const { isDarkMode } = useCustomTheme();\r\n\r\n const baseStyles = {\r\n borderRadius: '20px',\r\n border: isDarkMode ? '1px solid rgba(255, 255, 255, 0.1)' : '1px solid rgba(0, 0, 0, 0.08)',\r\n background: gradient \r\n ? isDarkMode\r\n ? 'linear-gradient(135deg, #1e293b 0%, #334155 100%)'\r\n : 'linear-gradient(135deg, #ffffff 0%, #f8fafc 100%)'\r\n : isDarkMode \r\n ? '#1e293b' \r\n : '#ffffff',\r\n boxShadow: isDarkMode\r\n ? '0 4px 6px -1px rgba(0, 0, 0, 0.3), 0 2px 4px -2px rgba(0, 0, 0, 0.3)'\r\n : '0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px -1px rgba(0, 0, 0, 0.1)',\r\n transition: 'all 0.2s cubic-bezier(0.4, 0, 0.2, 1)',\r\n ...(hover && {\r\n '&:hover': {\r\n transform: 'translateY(-4px)',\r\n boxShadow: isDarkMode\r\n ? '0 20px 25px -5px rgba(0, 0, 0, 0.4), 0 8px 10px -6px rgba(0, 0, 0, 0.4)'\r\n : '0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.1)',\r\n borderColor: isDarkMode ? 'rgba(255, 255, 255, 0.2)' : 'rgba(37, 99, 235, 0.2)'\r\n }\r\n }),\r\n ...sx\r\n };\r\n\r\n return (\r\n <Card \r\n elevation={0}\r\n sx={baseStyles}\r\n {...props}\r\n >\r\n {children}\r\n </Card>\r\n );\r\n};\r\n\r\nconst ModernCardContent = ({ children, sx = {}, ...props }) => {\r\n return (\r\n <CardContent \r\n sx={{\r\n padding: '24px',\r\n '&:last-child': {\r\n paddingBottom: '24px'\r\n },\r\n ...sx\r\n }}\r\n {...props}\r\n >\r\n {children}\r\n </CardContent>\r\n );\r\n};\r\n\r\nModernCard.Content = ModernCardContent;\r\n\r\nexport default ModernCard;","import React from 'react';\r\nimport {\r\n Box,\r\n Snackbar,\r\n Alert,\r\n AlertTitle,\r\n IconButton,\r\n Button,\r\n LinearProgress,\r\n Typography,\r\n Slide,\r\n Fade,\r\n Stack,\r\n Paper,\r\n Chip\r\n} from '@mui/material';\r\nimport {\r\n Close,\r\n CheckCircle,\r\n Error,\r\n Warning,\r\n Info,\r\n CloudUpload,\r\n Refresh\r\n} from '@mui/icons-material';\r\nimport { useNotification } from '../../contexts/NotificationContext';\r\nimport { format } from 'date-fns';\r\n\r\nconst NotificationItem = ({ notification, onClose, onAction }) => {\r\n if (!notification) {\r\n return null;\r\n }\r\n\r\n const getSeverityIcon = (type) => {\r\n const icons = {\r\n success: <CheckCircle />,\r\n error: <Error />,\r\n warning: <Warning />,\r\n info: <Info />\r\n };\r\n return icons[type] || <Info />;\r\n };\r\n\r\n const handleActionClick = (action) => {\r\n if (action && action.onClick) {\r\n action.onClick();\r\n }\r\n if (action && action.closeAfter !== false && onClose) {\r\n onClose();\r\n }\r\n };\r\n\r\n const safeOnClose = () => {\r\n if (onClose) {\r\n onClose();\r\n }\r\n };\r\n\r\n return (\r\n <Alert\r\n severity={notification.type}\r\n icon={getSeverityIcon(notification.type)}\r\n action={\r\n <Box display=\"flex\" alignItems=\"center\" gap={1}>\r\n {/* Custom action buttons */}\r\n {notification.actions?.map((action, index) => (\r\n <Button\r\n key={index}\r\n size=\"small\"\r\n variant={action.variant || 'text'}\r\n color={action.color || 'inherit'}\r\n startIcon={action.icon}\r\n onClick={() => handleActionClick(action)}\r\n sx={{ \r\n minWidth: 'auto',\r\n fontSize: '0.75rem',\r\n px: 1\r\n }}\r\n >\r\n {action.label}\r\n </Button>\r\n ))}\r\n \r\n {/* Progress indicator */}\r\n {typeof notification.progress === 'number' && (\r\n <Box sx={{ minWidth: 120 }}>\r\n <LinearProgress \r\n variant=\"determinate\" \r\n value={notification.progress}\r\n sx={{ height: 6, borderRadius: 3 }}\r\n />\r\n <Typography variant=\"caption\" sx={{ fontSize: '0.7rem' }}>\r\n {Math.round(notification.progress)}%\r\n </Typography>\r\n </Box>\r\n )}\r\n \r\n {/* Timestamp */}\r\n {notification.timestamp && (\r\n <Chip\r\n label={(() => {\r\n try {\r\n return format(new Date(notification.timestamp), 'HH:mm:ss');\r\n } catch (e) {\r\n return new Date().toLocaleTimeString();\r\n }\r\n })()}\r\n size=\"small\"\r\n variant=\"outlined\"\r\n sx={{ \r\n height: 20,\r\n fontSize: '0.65rem',\r\n opacity: 0.7\r\n }}\r\n />\r\n )}\r\n\r\n {/* Close button */}\r\n {notification.dismissible && (\r\n <IconButton\r\n size=\"small\"\r\n onClick={safeOnClose}\r\n sx={{ ml: 1 }}\r\n >\r\n <Close fontSize=\"small\" />\r\n </IconButton>\r\n )}\r\n </Box>\r\n }\r\n sx={{\r\n mb: 1,\r\n alignItems: 'flex-start',\r\n '& .MuiAlert-message': {\r\n width: '100%'\r\n }\r\n }}\r\n >\r\n {notification.title && (\r\n <AlertTitle sx={{ fontSize: '0.875rem', mb: 0.5 }}>\r\n {notification.title}\r\n </AlertTitle>\r\n )}\r\n <Typography variant=\"body2\" sx={{ fontSize: '0.8rem' }}>\r\n {notification.message}\r\n </Typography>\r\n </Alert>\r\n );\r\n};\r\n\r\nconst NotificationManager = () => {\r\n const { notifications, removeNotification, clearAllNotifications } = useNotification();\r\n\r\n // Separate persistent and temporary notifications\r\n const persistentNotifications = notifications.filter(n => n.persistent) || [];\r\n const temporaryNotifications = notifications.filter(n => !n.persistent) || [];\r\n const latestTemporary = temporaryNotifications.length > 0 ? temporaryNotifications.slice(-1)[0] : null;\r\n\r\n if (notifications.length === 0) {\r\n return null;\r\n }\r\n\r\n return (\r\n <>\r\n {/* Persistent notifications container (top-right) */}\r\n {persistentNotifications.length > 0 && (\r\n <Box\r\n sx={{\r\n position: 'fixed',\r\n top: 80,\r\n right: 16,\r\n zIndex: 1400,\r\n maxWidth: 400,\r\n width: '100%',\r\n maxHeight: '70vh',\r\n overflow: 'auto'\r\n }}\r\n >\r\n <Stack spacing={1}>\r\n {/* Clear all button */}\r\n {persistentNotifications.length > 1 && (\r\n <Box display=\"flex\" justifyContent=\"flex-end\" mb={1}>\r\n <Button\r\n size=\"small\"\r\n variant=\"outlined\"\r\n onClick={clearAllNotifications}\r\n sx={{ fontSize: '0.7rem' }}\r\n >\r\n Clear All ({persistentNotifications.length})\r\n </Button>\r\n </Box>\r\n )}\r\n \r\n {persistentNotifications.map((notification) => {\r\n if (!notification || !notification.id) return null;\r\n \r\n return (\r\n <Fade key={`notification-${notification.id}`} in timeout={300}>\r\n <Box>\r\n <NotificationItem\r\n notification={notification}\r\n onClose={() => removeNotification(notification.id)}\r\n />\r\n </Box>\r\n </Fade>\r\n );\r\n })}\r\n </Stack>\r\n </Box>\r\n )}\r\n\r\n {/* Temporary notification (bottom snackbar) */}\r\n {latestTemporary && (\r\n <Snackbar\r\n key={`temp-notification-${latestTemporary.id}`}\r\n open={true}\r\n anchorOrigin={{ vertical: 'bottom', horizontal: 'center' }}\r\n TransitionComponent={Slide}\r\n TransitionProps={{ direction: 'up' }}\r\n sx={{ \r\n '& .MuiSnackbarContent-root': { \r\n p: 0,\r\n backgroundColor: 'transparent',\r\n boxShadow: 'none'\r\n }\r\n }}\r\n >\r\n <Box>\r\n <NotificationItem\r\n notification={latestTemporary}\r\n onClose={() => removeNotification(latestTemporary.id)}\r\n />\r\n </Box>\r\n </Snackbar>\r\n )}\r\n </>\r\n );\r\n};\r\n\r\nexport default NotificationManager;","import React, { useState, useEffect, useCallback } from 'react';\nimport {\n IconButton,\n Badge,\n Menu,\n MenuItem,\n Box,\n Typography,\n Divider,\n Avatar,\n ListItemText,\n ListItemAvatar,\n List,\n ListItem,\n Button,\n Chip,\n CircularProgress,\n Alert\n} from '@mui/material';\nimport {\n Notifications as NotificationsIcon,\n NotificationsNone,\n CheckCircle,\n Warning,\n Error as ErrorIcon,\n Info,\n Message,\n Assignment,\n Payment,\n Home,\n Build,\n Close,\n DoneAll,\n Settings as SettingsIcon\n} from '@mui/icons-material';\nimport { formatDistanceToNow } from 'date-fns';\n\nconst NotificationBell = ({ api, useSocket, useAuth }) => {\n const [anchorEl, setAnchorEl] = useState(null);\n const [notifications, setNotifications] = useState([]);\n const [unreadCount, setUnreadCount] = useState(0);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState(null);\n const [page, setPage] = useState(1);\n const [hasMore, setHasMore] = useState(true);\n\n const { socket, isConnected } = useSocket ? useSocket() : { socket: null, isConnected: false };\n const { user } = useAuth ? useAuth() : { user: null };\n\n const open = Boolean(anchorEl);\n\n // Fetch notifications from API\n const fetchNotifications = useCallback(async (pageNum = 1, append = false) => {\n if (!api) return;\n\n setLoading(true);\n setError(null);\n\n try {\n const response = await api.get('/notifications', {\n params: {\n page: pageNum,\n limit: 20,\n sort: '-createdAt'\n }\n });\n\n const newNotifications = response.data.notifications || [];\n\n if (append) {\n setNotifications(prev => [...prev, ...newNotifications]);\n } else {\n setNotifications(newNotifications);\n }\n\n setHasMore(newNotifications.length === 20);\n setUnreadCount(response.data.unreadCount || 0);\n } catch (err) {\n console.error('Failed to fetch notifications:', err);\n setError('Failed to load notifications');\n } finally {\n setLoading(false);\n }\n }, [api]);\n\n // Fetch unread count\n const fetchUnreadCount = useCallback(async () => {\n if (!api) return;\n\n try {\n const response = await api.get('/notifications/unread');\n setUnreadCount(response.data.count || 0);\n } catch (err) {\n console.error('Failed to fetch unread count:', err);\n }\n }, [api]);\n\n // Initial load\n useEffect(() => {\n fetchNotifications();\n fetchUnreadCount();\n }, [fetchNotifications, fetchUnreadCount]);\n\n // Socket.IO real-time notifications\n useEffect(() => {\n if (!socket || !isConnected) return;\n\n const handleNewNotification = (notification) => {\n setNotifications(prev => [notification, ...prev]);\n setUnreadCount(prev => prev + 1);\n };\n\n const handleNotificationRead = (notificationId) => {\n setNotifications(prev =>\n prev.map(n => n._id === notificationId ? { ...n, read: true } : n)\n );\n setUnreadCount(prev => Math.max(0, prev - 1));\n };\n\n socket.on('notification', handleNewNotification);\n socket.on('notification:read', handleNotificationRead);\n\n return () => {\n socket.off('notification', handleNewNotification);\n socket.off('notification:read', handleNotificationRead);\n };\n }, [socket, isConnected]);\n\n const handleClick = (event) => {\n setAnchorEl(event.currentTarget);\n if (notifications.length === 0) {\n fetchNotifications();\n }\n };\n\n const handleClose = () => {\n setAnchorEl(null);\n };\n\n const handleMarkAsRead = async (notificationId) => {\n if (!api) return;\n\n try {\n await api.put(`/notifications/${notificationId}/read`);\n\n setNotifications(prev =>\n prev.map(n => n._id === notificationId ? { ...n, read: true, readAt: new Date() } : n)\n );\n setUnreadCount(prev => Math.max(0, prev - 1));\n } catch (err) {\n console.error('Failed to mark notification as read:', err);\n }\n };\n\n const handleMarkAllAsRead = async () => {\n if (!api) return;\n\n try {\n await api.put('/notifications/mark-all-read');\n\n setNotifications(prev =>\n prev.map(n => ({ ...n, read: true, readAt: new Date() }))\n );\n setUnreadCount(0);\n } catch (err) {\n console.error('Failed to mark all as read:', err);\n }\n };\n\n const handleNotificationClick = async (notification) => {\n // Mark as read\n if (!notification.read) {\n await handleMarkAsRead(notification._id);\n }\n\n // Navigate to action URL if exists\n if (notification.actionUrl) {\n window.location.href = notification.actionUrl;\n }\n\n handleClose();\n };\n\n const handleLoadMore = () => {\n const nextPage = page + 1;\n setPage(nextPage);\n fetchNotifications(nextPage, true);\n };\n\n const getNotificationIcon = (type) => {\n const iconProps = { fontSize: 'small' };\n\n switch (type) {\n case 'TICKET_CREATED':\n case 'TICKET_UPDATED':\n case 'TICKET_ASSIGNED':\n case 'TICKET_RESOLVED':\n case 'TICKET_COMMENTED':\n case 'TICKET_STATUS_CHANGED':\n return <Assignment {...iconProps} />;\n case 'MESSAGE_RECEIVED':\n case 'MENTION_RECEIVED':\n return <Message {...iconProps} />;\n case 'PAYMENT_DUE':\n case 'PAYMENT_OVERDUE':\n return <Payment {...iconProps} />;\n case 'PROPERTY_UPDATED':\n case 'LEASE_EXPIRING':\n return <Home {...iconProps} />;\n case 'APPLIANCE_MAINTENANCE_DUE':\n case 'MAINTENANCE_SCHEDULED':\n return <Build {...iconProps} />;\n case 'SYSTEM_ALERT':\n return <Warning {...iconProps} />;\n case 'SUCCESS':\n return <CheckCircle {...iconProps} />;\n case 'ERROR':\n return <ErrorIcon {...iconProps} />;\n case 'WARNING':\n return <Warning {...iconProps} />;\n case 'INFO':\n default:\n return <Info {...iconProps} />;\n }\n };\n\n const getNotificationColor = (type) => {\n if (type?.includes('ERROR') || type?.includes('OVERDUE')) return 'error.main';\n if (type?.includes('WARNING') || type?.includes('DUE')) return 'warning.main';\n if (type?.includes('SUCCESS') || type?.includes('RESOLVED')) return 'success.main';\n return 'primary.main';\n };\n\n const getPriorityChip = (priority) => {\n if (!priority || priority === 'NORMAL' || priority === 'LOW') return null;\n\n const colors = {\n HIGH: 'warning',\n URGENT: 'error'\n };\n\n return (\n <Chip\n label={priority}\n size=\"small\"\n color={colors[priority] || 'default'}\n sx={{ ml: 1, height: 20, fontSize: '0.7rem' }}\n />\n );\n };\n\n return (\n <>\n <IconButton\n color=\"inherit\"\n onClick={handleClick}\n sx={{\n ml: 1,\n '&:hover': {\n bgcolor: 'action.hover'\n }\n }}\n >\n <Badge\n badgeContent={unreadCount}\n color=\"error\"\n max={99}\n >\n {unreadCount > 0 ? (\n <NotificationsIcon />\n ) : (\n <NotificationsNone />\n )}\n </Badge>\n </IconButton>\n\n <Menu\n anchorEl={anchorEl}\n open={open}\n onClose={handleClose}\n PaperProps={{\n sx: {\n width: 420,\n maxHeight: 600,\n overflow: 'hidden',\n display: 'flex',\n flexDirection: 'column'\n }\n }}\n transformOrigin={{ horizontal: 'right', vertical: 'top' }}\n anchorOrigin={{ horizontal: 'right', vertical: 'bottom' }}\n >\n {/* Header */}\n <Box\n sx={{\n p: 2,\n pb: 1.5,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n borderBottom: '1px solid',\n borderColor: 'divider'\n }}\n >\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>\n <NotificationsIcon color=\"primary\" />\n <Typography variant=\"h6\" sx={{ fontWeight: 600 }}>\n Notifications\n </Typography>\n {unreadCount > 0 && (\n <Chip\n label={unreadCount}\n size=\"small\"\n color=\"primary\"\n sx={{ height: 22, fontSize: '0.75rem' }}\n />\n )}\n </Box>\n <Box>\n {unreadCount > 0 && (\n <Button\n size=\"small\"\n startIcon={<DoneAll />}\n onClick={handleMarkAllAsRead}\n sx={{ textTransform: 'none', fontSize: '0.75rem' }}\n >\n Mark all read\n </Button>\n )}\n <IconButton size=\"small\" onClick={handleClose}>\n <Close fontSize=\"small\" />\n </IconButton>\n </Box>\n </Box>\n\n {/* Error State */}\n {error && (\n <Alert severity=\"error\" sx={{ m: 2 }}>\n {error}\n </Alert>\n )}\n\n {/* Notifications List */}\n <Box\n sx={{\n flex: 1,\n overflow: 'auto',\n maxHeight: 450\n }}\n >\n {loading && notifications.length === 0 ? (\n <Box sx={{ display: 'flex', justifyContent: 'center', p: 4 }}>\n <CircularProgress size={32} />\n </Box>\n ) : notifications.length === 0 ? (\n <Box\n sx={{\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n p: 4,\n textAlign: 'center'\n }}\n >\n <NotificationsNone sx={{ fontSize: 64, color: 'text.secondary', mb: 2 }} />\n <Typography variant=\"body1\" color=\"text.secondary\" sx={{ fontWeight: 500 }}>\n No notifications yet\n </Typography>\n <Typography variant=\"body2\" color=\"text.secondary\">\n You're all caught up!\n </Typography>\n </Box>\n ) : (\n <List sx={{ p: 0 }}>\n {notifications.map((notification, index) => (\n <React.Fragment key={notification._id}>\n <ListItem\n button\n onClick={() => handleNotificationClick(notification)}\n sx={{\n py: 1.5,\n px: 2,\n bgcolor: notification.read ? 'transparent' : 'action.hover',\n '&:hover': {\n bgcolor: notification.read ? 'action.hover' : 'action.selected'\n },\n borderLeft: notification.read ? 'none' : '3px solid',\n borderLeftColor: getNotificationColor(notification.type),\n transition: 'all 0.2s'\n }}\n >\n <ListItemAvatar>\n <Avatar\n sx={{\n bgcolor: notification.read ? 'grey.300' : getNotificationColor(notification.type),\n width: 40,\n height: 40\n }}\n >\n {getNotificationIcon(notification.type)}\n </Avatar>\n </ListItemAvatar>\n <ListItemText\n primary={\n <Box sx={{ display: 'flex', alignItems: 'center', mb: 0.5 }}>\n <Typography\n variant=\"body2\"\n sx={{\n fontWeight: notification.read ? 400 : 600,\n flex: 1\n }}\n >\n {notification.title}\n </Typography>\n {getPriorityChip(notification.priority)}\n </Box>\n }\n secondary={\n <>\n <Typography\n variant=\"body2\"\n color=\"text.secondary\"\n sx={{\n display: '-webkit-box',\n WebkitLineClamp: 2,\n WebkitBoxOrient: 'vertical',\n overflow: 'hidden',\n mb: 0.5\n }}\n >\n {notification.message}\n </Typography>\n <Typography variant=\"caption\" color=\"text.secondary\">\n {formatDistanceToNow(new Date(notification.createdAt), { addSuffix: true })}\n </Typography>\n </>\n }\n />\n </ListItem>\n {index < notifications.length - 1 && <Divider />}\n </React.Fragment>\n ))}\n </List>\n )}\n\n {/* Load More */}\n {hasMore && notifications.length > 0 && (\n <Box sx={{ p: 2, textAlign: 'center', borderTop: '1px solid', borderColor: 'divider' }}>\n <Button\n onClick={handleLoadMore}\n disabled={loading}\n size=\"small\"\n sx={{ textTransform: 'none' }}\n >\n {loading ? 'Loading...' : 'Load more'}\n </Button>\n </Box>\n )}\n </Box>\n\n {/* Footer */}\n <Box\n sx={{\n p: 1.5,\n borderTop: '1px solid',\n borderColor: 'divider',\n textAlign: 'center'\n }}\n >\n <Button\n size=\"small\"\n startIcon={<SettingsIcon />}\n onClick={() => {\n window.location.href = '/settings?tab=general';\n handleClose();\n }}\n sx={{ textTransform: 'none' }}\n >\n Notification Settings\n </Button>\n </Box>\n </Menu>\n </>\n );\n};\n\nexport default NotificationBell;\n","import React from 'react';\r\nimport {\r\n Box,\r\n Typography,\r\n Button,\r\n Card,\r\n CardContent,\r\n Alert,\r\n Stack\r\n} from '@mui/material';\r\nimport {\r\n Refresh,\r\n BugReport,\r\n Home\r\n} from '@mui/icons-material';\r\n\r\nclass ErrorBoundary extends React.Component {\r\n constructor(props) {\r\n super(props);\r\n this.state = { \r\n hasError: false, \r\n error: null,\r\n errorInfo: null,\r\n errorId: null\r\n };\r\n }\r\n\r\n static getDerivedStateFromError(error) {\r\n // Update state so the next render will show the fallback UI\r\n return { \r\n hasError: true,\r\n errorId: Date.now() // Simple error ID for tracking\r\n };\r\n }\r\n\r\n componentDidCatch(error, errorInfo) {\r\n // Log error details\r\n console.error('ErrorBoundary caught an error:', error);\r\n console.error('Error info:', errorInfo);\r\n \r\n this.setState({\r\n error: error,\r\n errorInfo: errorInfo\r\n });\r\n\r\n // You could send error reports to an error reporting service here\r\n // For example: logErrorToService(error, errorInfo);\r\n }\r\n\r\n handleRetry = () => {\r\n this.setState({ \r\n hasError: false, \r\n error: null, \r\n errorInfo: null,\r\n errorId: null\r\n });\r\n };\r\n\r\n handleReload = () => {\r\n window.location.reload();\r\n };\r\n\r\n render() {\r\n if (this.state.hasError) {\r\n const isNavigationError = this.state.error?.message?.includes('getBoundingClientRect');\r\n const isDOMError = this.state.error?.message?.includes('null') || \r\n this.state.error?.message?.includes('undefined');\r\n\r\n return (\r\n <Box\r\n sx={{\r\n display: 'flex',\r\n flexDirection: 'column',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n minHeight: '50vh',\r\n p: 3\r\n }}\r\n >\r\n <Card sx={{ maxWidth: 600, width: '100%' }}>\r\n <CardContent>\r\n <Stack spacing={3} alignItems=\"center\">\r\n <BugReport sx={{ fontSize: 64, color: 'error.main' }} />\r\n \r\n <Typography variant=\"h5\" component=\"h2\" textAlign=\"center\">\r\n Oops! Something went wrong\r\n </Typography>\r\n\r\n <Alert severity=\"error\" sx={{ width: '100%' }}>\r\n <Typography variant=\"body2\">\r\n {isNavigationError && (\r\n <>\r\n <strong>UI Component Error:</strong> A component tried to access an element before it was ready. \r\n This is usually temporary.\r\n </>\r\n )}\r\n {isDOMError && !isNavigationError && (\r\n <>\r\n <strong>DOM Error:</strong> A component couldn't find an expected element. \r\n This might be due to rapid state changes.\r\n </>\r\n )}\r\n {!isNavigationError && !isDOMError && (\r\n <>\r\n <strong>Application Error:</strong> An unexpected error occurred while rendering the component.\r\n </>\r\n )}\r\n </Typography>\r\n </Alert>\r\n\r\n {process.env.NODE_ENV === 'development' && this.state.error && (\r\n <Alert severity=\"warning\" sx={{ width: '100%' }}>\r\n <Typography variant=\"body2\" component=\"div\">\r\n <strong>Debug Info:</strong><br />\r\n <code style={{ fontSize: '0.75rem', wordBreak: 'break-word' }}>\r\n {this.state.error.toString()}\r\n </code>\r\n </Typography>\r\n </Alert>\r\n )}\r\n\r\n <Stack direction=\"row\" spacing={2}>\r\n <Button\r\n variant=\"contained\"\r\n startIcon={<Refresh />}\r\n onClick={this.handleRetry}\r\n color=\"primary\"\r\n >\r\n Try Again\r\n </Button>\r\n \r\n <Button\r\n variant=\"outlined\"\r\n startIcon={<Refresh />}\r\n onClick={this.handleReload}\r\n >\r\n Reload Page\r\n </Button>\r\n\r\n {this.props.onNavigateHome && (\r\n <Button\r\n variant=\"outlined\"\r\n startIcon={<Home />}\r\n onClick={this.props.onNavigateHome}\r\n >\r\n Go Home\r\n </Button>\r\n )}\r\n </Stack>\r\n\r\n <Typography variant=\"body2\" color=\"text.secondary\" textAlign=\"center\">\r\n If this problem persists, try refreshing the page or clearing your browser cache.\r\n The error has been logged for debugging.\r\n </Typography>\r\n </Stack>\r\n </CardContent>\r\n </Card>\r\n </Box>\r\n );\r\n }\r\n\r\n return this.props.children;\r\n }\r\n}\r\n\r\nexport default ErrorBoundary;","import React, { createContext, useContext, useEffect, useState } from 'react';\r\nimport { io } from 'socket.io-client';\r\nimport { useAuth } from './AuthContext';\r\n\r\nconst SocketContext = createContext();\r\n\r\nexport const useSocket = () => {\r\n const context = useContext(SocketContext);\r\n if (!context) {\r\n throw new Error('useSocket must be used within SocketProvider');\r\n }\r\n return context;\r\n};\r\n\r\nexport const SocketProvider = ({ children }) => {\r\n const [socket, setSocket] = useState(null);\r\n const [isConnected, setIsConnected] = useState(false);\r\n const [tenantToken, setTenantToken] = useState(null);\r\n const { user } = useAuth();\r\n\r\n // Check for tenant token from localStorage\r\n useEffect(() => {\r\n const token = localStorage.getItem('tenantToken');\r\n setTenantToken(token);\r\n }, []);\r\n\r\n useEffect(() => {\r\n // Create socket connection for either authenticated property managers or tenants\r\n if (user || tenantToken) {\r\n const userType = user ? 'property_manager' : 'tenant';\r\n const authToken = user ? localStorage.getItem('token') : tenantToken;\r\n\r\n\r\n // Remove '/api' from the URL for Socket.IO connection\r\n const socketUrl = process.env.REACT_APP_API_URL\r\n ? process.env.REACT_APP_API_URL.replace('/api', '')\r\n : 'http://localhost:5000';\r\n\r\n const newSocket = io(socketUrl, {\r\n auth: {\r\n token: authToken,\r\n userType: userType\r\n }\r\n });\r\n\r\n newSocket.on('connect', () => {\r\n setIsConnected(true);\r\n });\r\n\r\n newSocket.on('disconnect', () => {\r\n setIsConnected(false);\r\n });\r\n\r\n setSocket(newSocket);\r\n\r\n return () => {\r\n newSocket.close();\r\n };\r\n }\r\n }, [user, tenantToken]);\r\n\r\n const value = {\r\n socket,\r\n isConnected\r\n };\r\n\r\n return (\r\n <SocketContext.Provider value={value}>\r\n {children}\r\n </SocketContext.Provider>\r\n );\r\n};","import { useCallback } from 'react';\r\nimport { useNotification } from '../contexts/NotificationContext';\r\nimport { Refresh, CloudUpload, Download, ContentCopy } from '@mui/icons-material';\r\n\r\nexport const useNotifications = () => {\r\n const notification = useNotification();\r\n\r\n // API operation notifications\r\n const notifyApiSuccess = useCallback((operation, entityName) => {\r\n const messages = {\r\n create: `${entityName} created successfully`,\r\n update: `${entityName} updated successfully`,\r\n delete: `${entityName} deleted successfully`,\r\n save: `${entityName} saved successfully`,\r\n load: `${entityName} loaded successfully`,\r\n fetch: `${entityName} fetched successfully`\r\n };\r\n \r\n return notification.showSuccess(messages[operation] || `${operation} completed successfully`);\r\n }, [notification]);\r\n\r\n const notifyApiError = useCallback((operation, entityName, error) => {\r\n const baseMessages = {\r\n create: `Failed to create ${entityName}`,\r\n update: `Failed to update ${entityName}`,\r\n delete: `Failed to delete ${entityName}`,\r\n save: `Failed to save ${entityName}`,\r\n load: `Failed to load ${entityName}`,\r\n fetch: `Failed to fetch ${entityName}`\r\n };\r\n \r\n const baseMessage = baseMessages[operation] || `Failed to ${operation}`;\r\n const errorMessage = error?.response?.data?.message || error?.message;\r\n \r\n return notification.showError(\r\n errorMessage ? `${baseMessage}: ${errorMessage}` : baseMessage,\r\n { persistent: true }\r\n );\r\n }, [notification]);\r\n\r\n // File operation notifications\r\n const notifyFileUploadStart = useCallback((fileName) => {\r\n return notification.showProgress(`Uploading ${fileName}...`, 0, {\r\n title: 'File Upload',\r\n actions: [{\r\n label: 'Cancel',\r\n icon: <ContentCopy />,\r\n color: 'error'\r\n }]\r\n });\r\n }, [notification]);\r\n\r\n const notifyFileUploadProgress = useCallback((notificationId, progress, fileName) => {\r\n notification.updateProgress(notificationId, progress, `Uploading ${fileName}... ${Math.round(progress)}%`);\r\n }, [notification]);\r\n\r\n const notifyFileUploadComplete = useCallback((notificationId, fileName) => {\r\n notification.updateNotification(notificationId, {\r\n type: 'success',\r\n message: `${fileName} uploaded successfully`,\r\n progress: undefined,\r\n duration: 3000,\r\n persistent: false,\r\n actions: []\r\n });\r\n }, [notification]);\r\n\r\n const notifyFileUploadError = useCallback((notificationId, fileName, error) => {\r\n notification.updateNotification(notificationId, {\r\n type: 'error',\r\n message: `Failed to upload ${fileName}: ${error}`,\r\n progress: undefined,\r\n persistent: true,\r\n actions: [{\r\n label: 'Retry',\r\n icon: <Refresh />,\r\n color: 'error'\r\n }]\r\n });\r\n }, [notification]);\r\n\r\n // Form validation notifications\r\n const notifyValidationError = useCallback((errors) => {\r\n const errorCount = Array.isArray(errors) ? errors.length : Object.keys(errors).length;\r\n const message = errorCount === 1 \r\n ? 'Please fix the validation error'\r\n : `Please fix ${errorCount} validation errors`;\r\n \r\n return notification.showWarning(message, {\r\n title: 'Form Validation',\r\n duration: 6000\r\n });\r\n }, [notification]);\r\n\r\n // Confirmation notifications with actions\r\n const notifyConfirmAction = useCallback((message, onConfirm, onCancel = null) => {\r\n return notification.showAction(message, [\r\n {\r\n label: 'Confirm',\r\n color: 'primary',\r\n variant: 'contained',\r\n onClick: onConfirm\r\n },\r\n {\r\n label: 'Cancel',\r\n color: 'inherit',\r\n onClick: onCancel || (() => {})\r\n }\r\n ], {\r\n type: 'warning',\r\n title: 'Confirmation Required'\r\n });\r\n }, [notification]);\r\n\r\n // Loading states\r\n const notifyLoading = useCallback((message) => {\r\n return notification.showLoading(message);\r\n }, [notification]);\r\n\r\n const stopLoading = useCallback((notificationId) => {\r\n notification.removeNotification(notificationId);\r\n }, [notification]);\r\n\r\n // Network status notifications\r\n const notifyNetworkError = useCallback(() => {\r\n return notification.showError('Network connection lost. Please check your internet connection.', {\r\n title: 'Connection Error',\r\n persistent: true,\r\n actions: [{\r\n label: 'Retry',\r\n icon: <Refresh />,\r\n color: 'error',\r\n onClick: () => window.location.reload()\r\n }]\r\n });\r\n }, [notification]);\r\n\r\n const notifyNetworkReconnected = useCallback(() => {\r\n return notification.showSuccess('Connection restored');\r\n }, [notification]);\r\n\r\n // Maintenance notifications\r\n const notifyMaintenance = useCallback((message, scheduledTime) => {\r\n return notification.showWarning(message, {\r\n title: 'Scheduled Maintenance',\r\n persistent: true,\r\n actions: [{\r\n label: 'Learn More',\r\n onClick: () => {\r\n // Could open a maintenance details dialog\r\n }\r\n }]\r\n });\r\n }, [notification]);\r\n\r\n // Permission notifications\r\n const notifyPermissionDenied = useCallback((action = 'perform this action') => {\r\n return notification.showError(`You don't have permission to ${action}`, {\r\n title: 'Access Denied',\r\n duration: 6000\r\n });\r\n }, [notification]);\r\n\r\n // Data sync notifications\r\n const notifyDataOutOfSync = useCallback((onRefresh) => {\r\n return notification.showWarning('Data may be outdated', {\r\n title: 'Sync Warning',\r\n actions: [{\r\n label: 'Refresh',\r\n icon: <Refresh />,\r\n onClick: onRefresh\r\n }]\r\n });\r\n }, [notification]);\r\n\r\n return {\r\n // Core notification functions\r\n ...notification,\r\n \r\n // Convenience functions\r\n notifyApiSuccess,\r\n notifyApiError,\r\n notifyFileUploadStart,\r\n notifyFileUploadProgress,\r\n notifyFileUploadComplete,\r\n notifyFileUploadError,\r\n notifyValidationError,\r\n notifyConfirmAction,\r\n notifyLoading,\r\n stopLoading,\r\n notifyNetworkError,\r\n notifyNetworkReconnected,\r\n notifyMaintenance,\r\n notifyPermissionDenied,\r\n notifyDataOutOfSync\r\n };\r\n};\r\n\r\nexport default useNotifications;","/**\r\n * React hook for using the unified notification system\r\n */\r\n\r\nimport { useEffect, useContext, useCallback } from 'react';\r\nimport { useNotification } from '../contexts/NotificationContext';\r\nimport { useSocket } from '../contexts/SocketContext';\r\nimport unifiedNotificationManager, {\r\n notify,\r\n notifySuccess,\r\n notifyError,\r\n notifyTicketUpdate,\r\n notifyMessage,\r\n requestNotificationPermission,\r\n subscribeToPushNotifications,\r\n setToastContext,\r\n setSocketContext,\r\n NOTIFICATION_TYPES,\r\n NOTIFICATION_CHANNELS\r\n} from '../utils/unifiedNotifications';\r\n\r\nexport const useUnifiedNotifications = () => {\r\n const toastContext = useNotification();\r\n const socketContext = useSocket();\r\n\r\n // Set up contexts when hook is initialized\r\n useEffect(() => {\r\n if (toastContext) {\r\n setToastContext(toastContext);\r\n }\r\n }, [toastContext]);\r\n\r\n useEffect(() => {\r\n if (socketContext) {\r\n setSocketContext(socketContext);\r\n }\r\n }, [socketContext]);\r\n\r\n // Initialize push notifications on first use\r\n const initializePushNotifications = useCallback(async () => {\r\n try {\r\n await requestNotificationPermission();\r\n await subscribeToPushNotifications();\r\n return true;\r\n } catch (error) {\r\n console.error('Failed to initialize push notifications:', error);\r\n return false;\r\n }\r\n }, []);\r\n\r\n // Convenience methods with better error handling\r\n const showSuccess = useCallback((message, title, options = {}) => {\r\n return notifySuccess(message, title, {\r\n channels: [NOTIFICATION_CHANNELS.TOAST],\r\n sound: true,\r\n ...options\r\n });\r\n }, []);\r\n\r\n const showError = useCallback((message, title, options = {}) => {\r\n return notifyError(message, title, {\r\n channels: [NOTIFICATION_CHANNELS.TOAST, NOTIFICATION_CHANNELS.BROWSER],\r\n persistent: true,\r\n ...options\r\n });\r\n }, []);\r\n\r\n const showWarning = useCallback((message, title, options = {}) => {\r\n return notify({\r\n message,\r\n title,\r\n type: NOTIFICATION_TYPES.WARNING,\r\n channels: [NOTIFICATION_CHANNELS.TOAST],\r\n ...options\r\n });\r\n }, []);\r\n\r\n const showInfo = useCallback((message, title, options = {}) => {\r\n return notify({\r\n message,\r\n title,\r\n type: NOTIFICATION_TYPES.INFO,\r\n channels: [NOTIFICATION_CHANNELS.TOAST],\r\n ...options\r\n });\r\n }, []);\r\n\r\n // Specialized notification methods\r\n const notifyTicket = useCallback((ticket, changeType, options = {}) => {\r\n return notifyTicketUpdate(ticket, changeType, {\r\n channels: [\r\n NOTIFICATION_CHANNELS.TOAST,\r\n NOTIFICATION_CHANNELS.DATABASE,\r\n NOTIFICATION_CHANNELS.SOCKET\r\n ],\r\n ...options\r\n });\r\n }, []);\r\n\r\n const notifyNewMessage = useCallback((senderName, messageContent, propertyAddress, options = {}) => {\r\n return notifyMessage(senderName, messageContent, propertyAddress, {\r\n channels: [\r\n NOTIFICATION_CHANNELS.BROWSER,\r\n NOTIFICATION_CHANNELS.SOUND\r\n ],\r\n priority: 'high',\r\n ...options\r\n });\r\n }, []);\r\n\r\n // System notifications\r\n const notifySystemAlert = useCallback((message, title, options = {}) => {\r\n return notify({\r\n message,\r\n title,\r\n type: NOTIFICATION_TYPES.SYSTEM_ALERT,\r\n channels: [\r\n NOTIFICATION_CHANNELS.TOAST,\r\n NOTIFICATION_CHANNELS.BROWSER,\r\n NOTIFICATION_CHANNELS.DATABASE\r\n ],\r\n priority: 'urgent',\r\n persistent: true,\r\n ...options\r\n });\r\n }, []);\r\n\r\n // Loading notifications\r\n const showLoading = useCallback((message, options = {}) => {\r\n return notify({\r\n message,\r\n type: NOTIFICATION_TYPES.LOADING,\r\n channels: [NOTIFICATION_CHANNELS.TOAST],\r\n persistent: true,\r\n ...options\r\n });\r\n }, []);\r\n\r\n // Multi-channel notifications\r\n const notifyImportant = useCallback((message, title, options = {}) => {\r\n return notify({\r\n message,\r\n title,\r\n type: NOTIFICATION_TYPES.INFO,\r\n channels: [\r\n NOTIFICATION_CHANNELS.TOAST,\r\n NOTIFICATION_CHANNELS.BROWSER,\r\n NOTIFICATION_CHANNELS.PUSH,\r\n NOTIFICATION_CHANNELS.SOUND\r\n ],\r\n priority: 'high',\r\n ...options\r\n });\r\n }, []);\r\n\r\n // Batch notifications\r\n const notifyBatch = useCallback(async (notifications) => {\r\n const results = [];\r\n for (const notification of notifications) {\r\n try {\r\n const result = await notify(notification);\r\n results.push({ success: true, result });\r\n } catch (error) {\r\n results.push({ success: false, error: error.message });\r\n }\r\n }\r\n return results;\r\n }, []);\r\n\r\n return {\r\n // Core notification methods\r\n notify,\r\n showSuccess,\r\n showError,\r\n showWarning,\r\n showInfo,\r\n showLoading,\r\n \r\n // Specialized methods\r\n notifyTicket,\r\n notifyNewMessage,\r\n notifySystemAlert,\r\n notifyImportant,\r\n notifyBatch,\r\n \r\n // Setup methods\r\n initializePushNotifications,\r\n \r\n // Access to the manager instance\r\n manager: unifiedNotificationManager,\r\n \r\n // Constants\r\n TYPES: NOTIFICATION_TYPES,\r\n CHANNELS: NOTIFICATION_CHANNELS\r\n };\r\n};\r\n\r\nexport default useUnifiedNotifications;","/**\r\n * Unified Notification Manager\r\n * Combines push notifications, browser notifications, and toast notifications\r\n * into a single, easy-to-use interface\r\n */\r\n\r\nimport api from '../services/api';\r\n\r\n// Notification types enum\r\nexport const NOTIFICATION_TYPES = {\r\n // Toast notification types (UI feedback)\r\n SUCCESS: 'success',\r\n ERROR: 'error',\r\n WARNING: 'warning',\r\n INFO: 'info',\r\n LOADING: 'loading',\r\n \r\n // Ticket/issue notification types\r\n TICKET_CREATED: 'ticket_created',\r\n TICKET_UPDATED: 'ticket_updated',\r\n TICKET_ASSIGNED: 'ticket_assigned',\r\n TICKET_RESOLVED: 'ticket_resolved',\r\n TICKET_COMMENTED: 'ticket_commented',\r\n \r\n // Messaging notification types\r\n MESSAGE_RECEIVED: 'message_received',\r\n MENTION_RECEIVED: 'mention_received',\r\n \r\n // System notification types\r\n SYSTEM_ALERT: 'system_alert',\r\n MAINTENANCE_SCHEDULED: 'maintenance_scheduled'\r\n};\r\n\r\n// Notification channels enum\r\nexport const NOTIFICATION_CHANNELS = {\r\n TOAST: 'toast', // In-app toast notifications\r\n BROWSER: 'browser', // Browser notifications\r\n PUSH: 'push', // Push notifications (service worker)\r\n DATABASE: 'database', // Persistent database notifications\r\n SOCKET: 'socket', // Real-time socket notifications\r\n SOUND: 'sound' // Audio notifications\r\n};\r\n\r\nclass UnifiedNotificationManager {\r\n constructor() {\r\n this.permission = null;\r\n this.audioContext = null;\r\n this.pushSubscription = null;\r\n this.toastNotificationContext = null;\r\n this.socketContext = null;\r\n \r\n this.init();\r\n }\r\n\r\n async init() {\r\n // Initialize browser notifications\r\n if ('Notification' in window) {\r\n this.permission = Notification.permission;\r\n }\r\n\r\n // Initialize audio context\r\n try {\r\n this.audioContext = new (window.AudioContext || window.webkitAudioContext)();\r\n } catch (e) {\r\n console.warn('Web Audio API not supported');\r\n }\r\n\r\n // Check for existing push subscription\r\n await this.checkPushSubscription();\r\n }\r\n\r\n // Set contexts from React components\r\n setToastContext(context) {\r\n this.toastNotificationContext = context;\r\n }\r\n\r\n setSocketContext(context) {\r\n this.socketContext = context;\r\n }\r\n\r\n // Permission management\r\n async requestPermission() {\r\n if (!('Notification' in window)) {\r\n throw new Error('Browser notifications not supported');\r\n }\r\n\r\n if (this.permission === 'granted') {\r\n return 'granted';\r\n }\r\n\r\n this.permission = await Notification.requestPermission();\r\n return this.permission;\r\n }\r\n\r\n hasPermission() {\r\n return this.permission === 'granted';\r\n }\r\n\r\n isSupported() {\r\n return 'Notification' in window && 'serviceWorker' in navigator && 'PushManager' in window;\r\n }\r\n\r\n // Push notification management\r\n async subscribeToPush() {\r\n if (!this.isSupported()) {\r\n throw new Error('Push notifications not supported');\r\n }\r\n\r\n if (this.permission !== 'granted') {\r\n await this.requestPermission();\r\n }\r\n\r\n if (this.permission !== 'granted') {\r\n throw new Error('Notification permission denied');\r\n }\r\n\r\n try {\r\n // Register service worker\r\n const registration = await navigator.serviceWorker.register('/sw.js', {\r\n scope: '/',\r\n updateViaCache: 'none'\r\n });\r\n\r\n await navigator.serviceWorker.ready;\r\n\r\n // Get or create subscription\r\n let subscription = await registration.pushManager.getSubscription();\r\n \r\n if (!subscription) {\r\n const vapidPublicKey = process.env.REACT_APP_VAPID_PUBLIC_KEY || \r\n 'BJ2eTitSHPWl9WBAk0F1Drwmv6bQB48aDpM1ilutZcdygYfpbK7ODrlMSzvplaHWVwPtvQ1x-Y2SK2LadSQZ2mc';\r\n \r\n subscription = await registration.pushManager.subscribe({\r\n userVisibleOnly: true,\r\n applicationServerKey: this.urlBase64ToUint8Array(vapidPublicKey)\r\n });\r\n }\r\n\r\n // Send subscription to backend\r\n await api.post('/notifications/subscribe', {\r\n subscription: subscription.toJSON()\r\n });\r\n\r\n this.pushSubscription = subscription;\r\n return subscription;\r\n } catch (error) {\r\n console.error('Error subscribing to push notifications:', error);\r\n throw error;\r\n }\r\n }\r\n\r\n async unsubscribeFromPush() {\r\n if (!this.pushSubscription) return;\r\n\r\n try {\r\n await this.pushSubscription.unsubscribe();\r\n \r\n await api.post('/notifications/unsubscribe', {\r\n endpoint: this.pushSubscription.endpoint\r\n });\r\n\r\n this.pushSubscription = null;\r\n } catch (error) {\r\n console.error('Error unsubscribing from push:', error);\r\n throw error;\r\n }\r\n }\r\n\r\n async checkPushSubscription() {\r\n if (!this.isSupported()) return false;\r\n\r\n try {\r\n const registration = await navigator.serviceWorker.getRegistration();\r\n if (registration) {\r\n this.pushSubscription = await registration.pushManager.getSubscription();\r\n return !!this.pushSubscription;\r\n }\r\n } catch (error) {\r\n console.error('Error checking push subscription:', error);\r\n }\r\n return false;\r\n }\r\n\r\n // Audio notifications\r\n playNotificationSound(type = 'default') {\r\n if (!this.audioContext) return;\r\n\r\n try {\r\n const oscillator = this.audioContext.createOscillator();\r\n const gainNode = this.audioContext.createGain();\r\n\r\n oscillator.connect(gainNode);\r\n gainNode.connect(this.audioContext.destination);\r\n\r\n // Different sounds for different notification types\r\n const soundConfig = this.getSoundConfig(type);\r\n \r\n oscillator.frequency.setValueAtTime(soundConfig.freq1, this.audioContext.currentTime);\r\n oscillator.frequency.setValueAtTime(soundConfig.freq2, this.audioContext.currentTime + 0.1);\r\n \r\n gainNode.gain.setValueAtTime(0, this.audioContext.currentTime);\r\n gainNode.gain.linearRampToValueAtTime(soundConfig.volume, this.audioContext.currentTime + 0.01);\r\n gainNode.gain.linearRampToValueAtTime(0, this.audioContext.currentTime + soundConfig.duration);\r\n\r\n oscillator.start(this.audioContext.currentTime);\r\n oscillator.stop(this.audioContext.currentTime + soundConfig.duration);\r\n } catch (e) {\r\n console.warn('Could not play notification sound:', e);\r\n }\r\n }\r\n\r\n getSoundConfig(type) {\r\n const configs = {\r\n default: { freq1: 800, freq2: 600, volume: 0.3, duration: 0.3 },\r\n success: { freq1: 600, freq2: 800, volume: 0.2, duration: 0.2 },\r\n error: { freq1: 300, freq2: 200, volume: 0.4, duration: 0.5 },\r\n message: { freq1: 800, freq2: 600, volume: 0.3, duration: 0.3 },\r\n urgent: { freq1: 900, freq2: 400, volume: 0.5, duration: 0.4 }\r\n };\r\n return configs[type] || configs.default;\r\n }\r\n\r\n // Browser notification\r\n showBrowserNotification(title, options = {}) {\r\n if (!this.hasPermission()) return null;\r\n\r\n const notification = new Notification(title, {\r\n icon: '/favicon.ico',\r\n badge: '/favicon.ico',\r\n ...options\r\n });\r\n\r\n // Auto close after timeout\r\n if (options.autoClose !== false) {\r\n setTimeout(() => {\r\n notification.close();\r\n }, options.duration || 5000);\r\n }\r\n\r\n return notification;\r\n }\r\n\r\n // Toast notification (requires context to be set)\r\n showToast(message, type = NOTIFICATION_TYPES.INFO, options = {}) {\r\n if (!this.toastNotificationContext) {\r\n console.warn('Toast notification context not set');\r\n return;\r\n }\r\n\r\n switch (type) {\r\n case NOTIFICATION_TYPES.SUCCESS:\r\n return this.toastNotificationContext.showSuccess(message, options);\r\n case NOTIFICATION_TYPES.ERROR:\r\n return this.toastNotificationContext.showError(message, options);\r\n case NOTIFICATION_TYPES.WARNING:\r\n return this.toastNotificationContext.showWarning(message, options);\r\n case NOTIFICATION_TYPES.LOADING:\r\n return this.toastNotificationContext.showLoading(message, options);\r\n default:\r\n return this.toastNotificationContext.showInfo(message, options);\r\n }\r\n }\r\n\r\n // Unified notification method - the main interface\r\n async notify(config) {\r\n const {\r\n title,\r\n message,\r\n type = NOTIFICATION_TYPES.INFO,\r\n channels = [NOTIFICATION_CHANNELS.TOAST],\r\n priority = 'normal', // low, normal, high, urgent\r\n data = {},\r\n actions = [],\r\n persistent = false,\r\n sound = false\r\n } = config;\r\n\r\n const results = {};\r\n\r\n // Show toast notification\r\n if (channels.includes(NOTIFICATION_CHANNELS.TOAST)) {\r\n results.toast = this.showToast(message, type, {\r\n title,\r\n persistent,\r\n actions,\r\n ...data\r\n });\r\n }\r\n\r\n // Show browser notification\r\n if (channels.includes(NOTIFICATION_CHANNELS.BROWSER)) {\r\n if (await this.requestPermission() === 'granted') {\r\n results.browser = this.showBrowserNotification(title || message, {\r\n body: title ? message : undefined,\r\n tag: type,\r\n renotify: priority === 'urgent',\r\n requireInteraction: persistent,\r\n actions: actions.slice(0, 2), // Browser notifications support max 2 actions\r\n data\r\n });\r\n }\r\n }\r\n\r\n // Send push notification (handled by backend)\r\n if (channels.includes(NOTIFICATION_CHANNELS.PUSH)) {\r\n try {\r\n results.push = await api.post('/notifications/send-push', {\r\n title: title || message,\r\n body: title ? message : '',\r\n type,\r\n data,\r\n priority\r\n });\r\n } catch (error) {\r\n console.error('Failed to send push notification:', error);\r\n }\r\n }\r\n\r\n // Create database notification (handled by backend)\r\n if (channels.includes(NOTIFICATION_CHANNELS.DATABASE)) {\r\n try {\r\n results.database = await api.post('/notifications/create', {\r\n title: title || message,\r\n message: title ? message : title,\r\n type,\r\n data,\r\n priority,\r\n persistent\r\n });\r\n } catch (error) {\r\n console.error('Failed to create database notification:', error);\r\n }\r\n }\r\n\r\n // Send real-time notification via socket\r\n if (channels.includes(NOTIFICATION_CHANNELS.SOCKET) && this.socketContext) {\r\n results.socket = this.socketContext.emit('notification', {\r\n title: title || message,\r\n message: title ? message : title,\r\n type,\r\n data,\r\n timestamp: new Date()\r\n });\r\n }\r\n\r\n // Play sound\r\n if (sound || channels.includes(NOTIFICATION_CHANNELS.SOUND)) {\r\n this.playNotificationSound(this.getSoundTypeFromNotificationType(type));\r\n }\r\n\r\n return results;\r\n }\r\n\r\n // Convenience methods for common notification types\r\n async notifySuccess(message, title, options = {}) {\r\n return this.notify({\r\n title,\r\n message,\r\n type: NOTIFICATION_TYPES.SUCCESS,\r\n channels: [NOTIFICATION_CHANNELS.TOAST],\r\n sound: true,\r\n ...options\r\n });\r\n }\r\n\r\n async notifyError(message, title, options = {}) {\r\n return this.notify({\r\n title,\r\n message,\r\n type: NOTIFICATION_TYPES.ERROR,\r\n channels: [NOTIFICATION_CHANNELS.TOAST, NOTIFICATION_CHANNELS.BROWSER],\r\n priority: 'high',\r\n sound: true,\r\n ...options\r\n });\r\n }\r\n\r\n async notifyTicketUpdate(ticket, changeType, options = {}) {\r\n const title = `Ticket #${ticket.ticketNumber} Updated`;\r\n const message = `${changeType}: ${ticket.title || ticket.description?.substring(0, 100)}`;\r\n\r\n return this.notify({\r\n title,\r\n message,\r\n type: NOTIFICATION_TYPES.TICKET_UPDATED,\r\n channels: [NOTIFICATION_CHANNELS.DATABASE, NOTIFICATION_CHANNELS.SOCKET, NOTIFICATION_CHANNELS.TOAST],\r\n data: { ticketId: ticket._id, ticketNumber: ticket.ticketNumber },\r\n ...options\r\n });\r\n }\r\n\r\n async notifyMessage(senderName, messageContent, propertyAddress, options = {}) {\r\n const title = `New message from ${senderName}`;\r\n const body = propertyAddress \r\n ? `${propertyAddress}\\n${messageContent.substring(0, 100)}...`\r\n : messageContent.substring(0, 100) + '...';\r\n \r\n return this.notify({\r\n title,\r\n message: body,\r\n type: NOTIFICATION_TYPES.MESSAGE_RECEIVED,\r\n channels: [NOTIFICATION_CHANNELS.BROWSER, NOTIFICATION_CHANNELS.SOUND],\r\n priority: 'high',\r\n data: { senderName, propertyAddress },\r\n ...options\r\n });\r\n }\r\n\r\n // Helper methods\r\n getSoundTypeFromNotificationType(notificationType) {\r\n const soundMap = {\r\n [NOTIFICATION_TYPES.SUCCESS]: 'success',\r\n [NOTIFICATION_TYPES.ERROR]: 'error',\r\n [NOTIFICATION_TYPES.MESSAGE_RECEIVED]: 'message',\r\n [NOTIFICATION_TYPES.TICKET_CREATED]: 'default',\r\n [NOTIFICATION_TYPES.SYSTEM_ALERT]: 'urgent'\r\n };\r\n return soundMap[notificationType] || 'default';\r\n }\r\n\r\n urlBase64ToUint8Array(base64String) {\r\n const padding = '='.repeat((4 - base64String.length % 4) % 4);\r\n const base64 = (base64String + padding)\r\n .replace(/-/g, '+')\r\n .replace(/_/g, '/');\r\n\r\n const rawData = window.atob(base64);\r\n const outputArray = new Uint8Array(rawData.length);\r\n\r\n for (let i = 0; i < rawData.length; ++i) {\r\n outputArray[i] = rawData.charCodeAt(i);\r\n }\r\n return outputArray;\r\n }\r\n}\r\n\r\n// Create and export singleton instance\r\nconst unifiedNotificationManager = new UnifiedNotificationManager();\r\nexport default unifiedNotificationManager;\r\n\r\n// Export convenience functions\r\nexport const notify = (config) => unifiedNotificationManager.notify(config);\r\nexport const notifySuccess = (message, title, options) => unifiedNotificationManager.notifySuccess(message, title, options);\r\nexport const notifyError = (message, title, options) => unifiedNotificationManager.notifyError(message, title, options);\r\nexport const notifyTicketUpdate = (ticket, changeType, options) => unifiedNotificationManager.notifyTicketUpdate(ticket, changeType, options);\r\nexport const notifyMessage = (senderName, messageContent, propertyAddress, options) => unifiedNotificationManager.notifyMessage(senderName, messageContent, propertyAddress, options);\r\n\r\n// Permission and subscription methods\r\nexport const requestNotificationPermission = () => unifiedNotificationManager.requestPermission();\r\nexport const subscribeToPushNotifications = () => unifiedNotificationManager.subscribeToPush();\r\nexport const unsubscribeFromPushNotifications = () => unifiedNotificationManager.unsubscribeFromPush();\r\nexport const hasNotificationPermission = () => unifiedNotificationManager.hasPermission();\r\nexport const isNotificationSupported = () => unifiedNotificationManager.isSupported();\r\n\r\n// Context setters (to be called from React components)\r\nexport const setToastContext = (context) => unifiedNotificationManager.setToastContext(context);\r\nexport const setSocketContext = (context) => unifiedNotificationManager.setSocketContext(context);","import { useTheme } from '@mui/material/styles';\r\nimport {\r\n getAccessibleTextColor,\r\n getContrastRatio,\r\n meetsWCAGAA,\r\n lightenColor,\r\n darkenColor,\r\n rgbToHex\r\n} from '../utils/colorExtractor';\r\n\r\n/**\r\n * Custom hook for accessible color combinations based on current theme\r\n * Ensures all text meets WCAG AA standards (4.5:1 contrast ratio)\r\n */\r\nexport const useAccessibleColors = () => {\r\n const theme = useTheme();\r\n\r\n /**\r\n * Get safe text color for any background\r\n * @param {string} backgroundColor - Hex color code\r\n * @param {string} standard - 'AA' or 'AAA' accessibility standard\r\n * @returns {string} Accessible text color\r\n */\r\n const getSafeTextColor = (backgroundColor, standard = 'AA') => {\r\n return getAccessibleTextColor(backgroundColor, { standard });\r\n };\r\n\r\n /**\r\n * Get accessible background for text on theme colors\r\n * @param {string} textColor - Desired text color\r\n * @param {string} baseColor - Theme color to base background on\r\n * @returns {string} Accessible background color\r\n */\r\n const getSafeBackground = (textColor = '#ffffff', baseColor = theme.palette.primary.main) => {\r\n // Start with the base color\r\n let background = baseColor;\r\n let attempts = 0;\r\n const maxAttempts = 10;\r\n\r\n // If contrast is insufficient, adjust the background\r\n while (!meetsWCAGAA(background, textColor) && attempts < maxAttempts) {\r\n const currentRatio = getContrastRatio(background, textColor);\r\n\r\n if (currentRatio < 4.5) {\r\n // If text is light, darken background; if text is dark, lighten background\r\n if (textColor === '#ffffff' || textColor === '#fff') {\r\n background = darkenColor(background, 0.1);\r\n } else {\r\n background = lightenColor(background, 0.1);\r\n }\r\n } else {\r\n break;\r\n }\r\n attempts++;\r\n }\r\n\r\n return background;\r\n };\r\n\r\n /**\r\n * Get contrast-safe gradient that maintains readability\r\n * @param {string} startColor - Start color of gradient\r\n * @param {string} endColor - End color of gradient\r\n * @param {string} textColor - Text color that will be used on gradient\r\n * @returns {Object} Gradient and text color information\r\n */\r\n const getSafeGradient = (startColor, endColor, textColor = '#ffffff') => {\r\n const safeStart = getSafeBackground(textColor, startColor);\r\n const safeEnd = getSafeBackground(textColor, endColor);\r\n const finalTextColor = getSafeTextColor(safeStart);\r\n\r\n return {\r\n gradient: `linear-gradient(135deg, ${safeStart}, ${safeEnd})`,\r\n textColor: finalTextColor,\r\n startColor: safeStart,\r\n endColor: safeEnd\r\n };\r\n };\r\n\r\n /**\r\n * Get theme-aware colors with contrast guarantees\r\n */\r\n const getThemeColors = () => {\r\n const primary = theme.palette.primary.main;\r\n const secondary = theme.palette.secondary?.main || theme.palette.primary.dark;\r\n\r\n return {\r\n // Primary color combinations\r\n primary: {\r\n background: primary,\r\n text: getSafeTextColor(primary),\r\n lightBackground: getSafeBackground('#000000', primary),\r\n darkBackground: getSafeBackground('#ffffff', primary)\r\n },\r\n\r\n // Secondary color combinations\r\n secondary: {\r\n background: secondary,\r\n text: getSafeTextColor(secondary),\r\n lightBackground: getSafeBackground('#000000', secondary),\r\n darkBackground: getSafeBackground('#ffffff', secondary)\r\n },\r\n\r\n // Safe gradients\r\n gradients: {\r\n primary: getSafeGradient(primary, theme.palette.primary.dark),\r\n secondary: getSafeGradient(secondary, primary),\r\n subtle: getSafeGradient(\r\n `${primary}1A`, // 10% opacity\r\n `${primary}0D` // 5% opacity\r\n )\r\n }\r\n };\r\n };\r\n\r\n /**\r\n * Generate opacity variants that maintain contrast\r\n * @param {string} baseColor - Base color\r\n * @param {string} textColor - Text color to maintain contrast with\r\n * @returns {Object} Opacity variants\r\n */\r\n const getSafeOpacityVariants = (baseColor, textColor = '#ffffff') => {\r\n const variants = {};\r\n const opacities = [\r\n { name: 'subtle', value: 0.05, hex: '0D' },\r\n { name: 'light', value: 0.1, hex: '1A' },\r\n { name: 'medium', value: 0.2, hex: '33' },\r\n { name: 'strong', value: 0.3, hex: '4D' },\r\n { name: 'bold', value: 0.4, hex: '66' }\r\n ];\r\n\r\n opacities.forEach(({ name, hex }) => {\r\n const colorWithOpacity = `${baseColor}${hex}`;\r\n const safeBackground = getSafeBackground(textColor, colorWithOpacity);\r\n\r\n variants[name] = {\r\n background: safeBackground,\r\n text: getSafeTextColor(safeBackground),\r\n original: colorWithOpacity\r\n };\r\n });\r\n\r\n return variants;\r\n };\r\n\r\n return {\r\n getSafeTextColor,\r\n getSafeBackground,\r\n getSafeGradient,\r\n getThemeColors,\r\n getSafeOpacityVariants,\r\n\r\n // Utility functions\r\n checkContrast: (bg, text) => getContrastRatio(bg, text),\r\n meetsAccessibility: (bg, text, standard = 'AA') => {\r\n const ratio = getContrastRatio(bg, text);\r\n return standard === 'AAA' ? ratio >= 7 : ratio >= 4.5;\r\n }\r\n };\r\n};\r\n\r\nexport default useAccessibleColors;","import { useMemo } from 'react';\r\nimport { useTheme } from '@mui/material/styles';\r\nimport { getAccessibleTextColor, getContrastRatio } from '../utils/colorExtractor';\r\n\r\n/**\r\n * Custom hook for getting accessible text colors based on background colors\r\n * Ensures WCAG compliance and consistent contrast across the application\r\n */\r\nexport const useContrastText = () => {\r\n const theme = useTheme();\r\n \r\n const utils = useMemo(() => ({\r\n /**\r\n * Get accessible text color for any background color\r\n * @param {string} backgroundColor - Background color in hex format\r\n * @param {Object} options - Options for text color preferences\r\n * @returns {string} Accessible text color\r\n */\r\n getTextColor: (backgroundColor, options = {}) => {\r\n return getAccessibleTextColor(backgroundColor, {\r\n preferredLight: theme.palette.common.white,\r\n preferredDark: theme.palette.text.primary,\r\n fallbackLight: theme.palette.grey[50],\r\n fallbackDark: theme.palette.grey[900],\r\n standard: 'AA',\r\n ...options\r\n });\r\n },\r\n\r\n /**\r\n * Get text color for primary backgrounds\r\n * @param {string} variant - 'main', 'light', or 'dark'\r\n * @returns {string} Accessible text color\r\n */\r\n getPrimaryTextColor: (variant = 'main') => {\r\n const backgroundColor = theme.palette.primary[variant];\r\n return getAccessibleTextColor(backgroundColor, {\r\n preferredLight: '#ffffff',\r\n preferredDark: theme.palette.text.primary,\r\n standard: 'AA'\r\n });\r\n },\r\n\r\n /**\r\n * Get text color for secondary backgrounds\r\n * @param {string} variant - 'main', 'light', or 'dark'\r\n * @returns {string} Accessible text color\r\n */\r\n getSecondaryTextColor: (variant = 'main') => {\r\n const backgroundColor = theme.palette.secondary[variant];\r\n return getAccessibleTextColor(backgroundColor, {\r\n preferredLight: '#ffffff',\r\n preferredDark: theme.palette.text.primary,\r\n standard: 'AA'\r\n });\r\n },\r\n\r\n /**\r\n * Get text color for status colors (success, warning, error)\r\n * @param {string} status - 'success', 'warning', 'error'\r\n * @param {string} variant - 'main', 'light', or 'dark'\r\n * @returns {string} Accessible text color\r\n */\r\n getStatusTextColor: (status, variant = 'main') => {\r\n const backgroundColor = theme.palette[status][variant];\r\n return getAccessibleTextColor(backgroundColor, {\r\n preferredLight: '#ffffff',\r\n preferredDark: theme.palette.text.primary,\r\n standard: 'AA'\r\n });\r\n },\r\n\r\n /**\r\n * Get text color for gradient backgrounds\r\n * Uses the darker color in the gradient for contrast calculation\r\n * @param {string} color1 - First gradient color\r\n * @param {string} color2 - Second gradient color\r\n * @returns {string} Accessible text color\r\n */\r\n getGradientTextColor: (color1, color2) => {\r\n // Use the color that would result in better contrast\r\n const textForColor1 = getAccessibleTextColor(color1);\r\n const textForColor2 = getAccessibleTextColor(color2);\r\n \r\n const contrast1 = getContrastRatio(color1, textForColor1);\r\n const contrast2 = getContrastRatio(color2, textForColor2);\r\n \r\n return contrast1 > contrast2 ? textForColor1 : textForColor2;\r\n },\r\n\r\n /**\r\n * Check if current combination meets WCAG standards\r\n * @param {string} backgroundColor - Background color\r\n * @param {string} textColor - Text color\r\n * @returns {Object} Object with accessibility info\r\n */\r\n checkAccessibility: (backgroundColor, textColor) => {\r\n const contrast = getContrastRatio(backgroundColor, textColor);\r\n return {\r\n contrast,\r\n meetsAA: contrast >= 4.5,\r\n meetsAAA: contrast >= 7,\r\n isGood: contrast >= 4.5,\r\n isExcellent: contrast >= 7\r\n };\r\n },\r\n\r\n /**\r\n * Get MUI sx props for text on colored backgrounds\r\n * @param {string} backgroundColor - Background color\r\n * @param {Object} options - Additional options\r\n * @returns {Object} MUI sx object with color and optional background\r\n */\r\n getSxForBackground: (backgroundColor, options = {}) => {\r\n const { includeBackground = false, ...textOptions } = options;\r\n const textColor = getAccessibleTextColor(backgroundColor, textOptions);\r\n \r\n return {\r\n color: textColor,\r\n ...(includeBackground && { backgroundColor }),\r\n };\r\n },\r\n\r\n /**\r\n * Get enhanced contrast colors for dark mode\r\n * @param {string} backgroundColor - Background color\r\n * @returns {Object} Text colors optimized for dark themes\r\n */\r\n getDarkModeColors: (backgroundColor) => {\r\n return {\r\n primary: getAccessibleTextColor(backgroundColor, {\r\n preferredLight: '#f8fafc',\r\n preferredDark: '#1e293b',\r\n fallbackLight: '#e2e8f0',\r\n fallbackDark: '#334155'\r\n }),\r\n secondary: getAccessibleTextColor(backgroundColor, {\r\n preferredLight: '#cbd5e1',\r\n preferredDark: '#475569',\r\n fallbackLight: '#94a3b8',\r\n fallbackDark: '#64748b'\r\n }),\r\n disabled: getAccessibleTextColor(backgroundColor, {\r\n preferredLight: '#94a3b8',\r\n preferredDark: '#64748b',\r\n fallbackLight: '#64748b',\r\n fallbackDark: '#94a3b8'\r\n })\r\n };\r\n }\r\n }), [theme]);\r\n\r\n return utils;\r\n};\r\n\r\nexport default useContrastText;","/**\r\n * Notification Helper Utilities\r\n * Automated helpers to ensure notifications are included with every appropriate change\r\n */\r\n\r\nimport { \r\n notify, \r\n NOTIFICATION_TYPES, \r\n NOTIFICATION_CHANNELS \r\n} from './unifiedNotifications';\r\n// Import shared types using CommonJS (compatible with both Node.js and React build tools)\r\nconst {\r\n getDefaultChannels,\r\n getDefaultPriority,\r\n isHighPriorityType\r\n} = require('./notificationTypes');\r\n\r\n// Smart API wrapper that automatically adds notifications\r\nexport const withNotifications = (apiCall, notificationConfig) => {\r\n return async (...args) => {\r\n const startTime = Date.now();\r\n \r\n try {\r\n \r\n const result = await apiCall(...args);\r\n \r\n // Auto-success notification\r\n if (notificationConfig.onSuccess) {\r\n const successConfig = {\r\n ...notificationConfig.onSuccess,\r\n data: {\r\n ...notificationConfig.onSuccess.data,\r\n result,\r\n duration: Date.now() - startTime\r\n }\r\n };\r\n \r\n await notify(successConfig);\r\n }\r\n \r\n return result;\r\n } catch (error) {\r\n // Auto-error notification\r\n if (notificationConfig.onError) {\r\n const errorConfig = {\r\n ...notificationConfig.onError,\r\n message: notificationConfig.onError.message || error.message,\r\n data: {\r\n ...notificationConfig.onError.data,\r\n error: error.message,\r\n duration: Date.now() - startTime\r\n }\r\n };\r\n \r\n await notify(errorConfig);\r\n }\r\n \r\n throw error;\r\n }\r\n };\r\n};\r\n\r\n// Notification audit decorator for functions\r\nexport const auditNotifications = (functionName, expectedNotifications = []) => {\r\n return (target, propertyKey, descriptor) => {\r\n const originalMethod = descriptor.value;\r\n \r\n descriptor.value = async function(...args) {\r\n \r\n const result = await originalMethod.apply(this, args);\r\n \r\n // Log what notifications should have been sent\r\n if (expectedNotifications.length > 0) {\r\n }\r\n \r\n return result;\r\n };\r\n \r\n return descriptor;\r\n };\r\n};\r\n\r\n// Pre-configured notification patterns for common operations \r\nexport const NotificationPatterns = {\r\n // CRUD Operations\r\n CREATE: (entityType, entityName) => ({\r\n onSuccess: {\r\n type: NOTIFICATION_TYPES.SUCCESS,\r\n channels: [NOTIFICATION_CHANNELS.TOAST, NOTIFICATION_CHANNELS.DATABASE, NOTIFICATION_CHANNELS.SOCKET],\r\n title: `${entityType} Created`,\r\n message: `${entityName} has been created successfully`,\r\n data: { operation: 'create', entityType }\r\n },\r\n onError: {\r\n type: NOTIFICATION_TYPES.ERROR,\r\n channels: [NOTIFICATION_CHANNELS.TOAST, NOTIFICATION_CHANNELS.BROWSER],\r\n title: `Failed to Create ${entityType}`,\r\n message: `Unable to create ${entityName}. Please try again.`,\r\n persistent: true,\r\n data: { operation: 'create', entityType }\r\n }\r\n }),\r\n\r\n UPDATE: (entityType, entityName) => ({\r\n onSuccess: {\r\n type: NOTIFICATION_TYPES.SUCCESS,\r\n channels: [NOTIFICATION_CHANNELS.TOAST],\r\n message: `${entityName} updated successfully`,\r\n data: { operation: 'update', entityType }\r\n },\r\n onError: {\r\n type: NOTIFICATION_TYPES.ERROR,\r\n channels: [NOTIFICATION_CHANNELS.TOAST],\r\n title: `Update Failed`,\r\n message: `Unable to update ${entityName}`,\r\n data: { operation: 'update', entityType }\r\n }\r\n }),\r\n\r\n DELETE: (entityType, entityName) => ({\r\n onSuccess: {\r\n type: NOTIFICATION_TYPES.SUCCESS,\r\n channels: [NOTIFICATION_CHANNELS.TOAST, NOTIFICATION_CHANNELS.DATABASE],\r\n message: `${entityName} deleted successfully`,\r\n data: { operation: 'delete', entityType }\r\n },\r\n onError: {\r\n type: NOTIFICATION_TYPES.ERROR,\r\n channels: [NOTIFICATION_CHANNELS.TOAST, NOTIFICATION_CHANNELS.BROWSER],\r\n title: `Delete Failed`,\r\n message: `Unable to delete ${entityName}`,\r\n persistent: true,\r\n data: { operation: 'delete', entityType }\r\n }\r\n }),\r\n\r\n // Status Changes\r\n STATUS_CHANGE: (entityType, oldStatus, newStatus) => ({\r\n onSuccess: {\r\n type: NOTIFICATION_TYPES.TICKET_UPDATED,\r\n channels: [NOTIFICATION_CHANNELS.DATABASE, NOTIFICATION_CHANNELS.SOCKET, NOTIFICATION_CHANNELS.TOAST],\r\n title: `${entityType} Status Updated`,\r\n message: `Status changed from ${oldStatus} to ${newStatus}`,\r\n data: { \r\n operation: 'status_change', \r\n entityType, \r\n oldStatus, \r\n newStatus \r\n }\r\n },\r\n onError: {\r\n type: NOTIFICATION_TYPES.ERROR,\r\n channels: [NOTIFICATION_CHANNELS.TOAST],\r\n message: `Failed to update status`,\r\n data: { operation: 'status_change', entityType }\r\n }\r\n }),\r\n\r\n // Assignment Changes\r\n ASSIGNMENT: (entityType, assigneeName) => ({\r\n onSuccess: {\r\n type: NOTIFICATION_TYPES.TICKET_ASSIGNED,\r\n channels: [NOTIFICATION_CHANNELS.DATABASE, NOTIFICATION_CHANNELS.SOCKET, NOTIFICATION_CHANNELS.PUSH],\r\n title: `${entityType} Assigned`,\r\n message: `Assigned to ${assigneeName}`,\r\n data: { \r\n operation: 'assignment', \r\n entityType, \r\n assigneeName \r\n }\r\n },\r\n onError: {\r\n type: NOTIFICATION_TYPES.ERROR,\r\n channels: [NOTIFICATION_CHANNELS.TOAST],\r\n message: `Failed to assign ${entityType}`,\r\n data: { operation: 'assignment', entityType }\r\n }\r\n }),\r\n\r\n // File Operations\r\n FILE_UPLOAD: (fileName) => ({\r\n onSuccess: {\r\n type: NOTIFICATION_TYPES.SUCCESS,\r\n channels: [NOTIFICATION_CHANNELS.TOAST],\r\n message: `${fileName} uploaded successfully`,\r\n data: { operation: 'file_upload', fileName }\r\n },\r\n onError: {\r\n type: NOTIFICATION_TYPES.ERROR,\r\n channels: [NOTIFICATION_CHANNELS.TOAST, NOTIFICATION_CHANNELS.BROWSER],\r\n title: 'Upload Failed',\r\n message: `Failed to upload ${fileName}`,\r\n data: { operation: 'file_upload', fileName }\r\n }\r\n }),\r\n\r\n // Batch Operations\r\n BATCH_OPERATION: (operationType, itemCount) => ({\r\n onSuccess: {\r\n type: NOTIFICATION_TYPES.SUCCESS,\r\n channels: [NOTIFICATION_CHANNELS.TOAST, NOTIFICATION_CHANNELS.DATABASE],\r\n title: 'Batch Operation Complete',\r\n message: `${operationType} completed for ${itemCount} items`,\r\n data: { operation: 'batch', operationType, itemCount }\r\n },\r\n onError: {\r\n type: NOTIFICATION_TYPES.ERROR,\r\n channels: [NOTIFICATION_CHANNELS.TOAST, NOTIFICATION_CHANNELS.BROWSER],\r\n title: 'Batch Operation Failed',\r\n message: `${operationType} failed`,\r\n persistent: true,\r\n data: { operation: 'batch', operationType, itemCount }\r\n }\r\n })\r\n};\r\n\r\n// Smart notification decision maker\r\nexport const decideNotificationChannels = (operationType, priority, affectedUsers) => {\r\n const channels = [NOTIFICATION_CHANNELS.TOAST]; // Always include toast for immediate feedback\r\n \r\n // Add database for persistent operations\r\n if (['create', 'update', 'delete', 'status_change', 'assignment'].includes(operationType)) {\r\n channels.push(NOTIFICATION_CHANNELS.DATABASE);\r\n }\r\n \r\n // Add socket for real-time updates\r\n if (affectedUsers && affectedUsers.length > 1) {\r\n channels.push(NOTIFICATION_CHANNELS.SOCKET);\r\n }\r\n \r\n // Add push/browser for high priority\r\n if (priority === 'high' || priority === 'urgent') {\r\n channels.push(NOTIFICATION_CHANNELS.PUSH, NOTIFICATION_CHANNELS.BROWSER);\r\n }\r\n \r\n // Add sound for urgent notifications\r\n if (priority === 'urgent') {\r\n channels.push(NOTIFICATION_CHANNELS.SOUND);\r\n }\r\n \r\n return channels;\r\n};\r\n\r\n// Notification audit logger\r\nexport const logNotificationAudit = (operation, hasNotification, shouldHaveNotification) => {\r\n const status = hasNotification ? '✅' : (shouldHaveNotification ? '❌' : '⚪');\r\n const message = hasNotification \r\n ? 'Has notification' \r\n : (shouldHaveNotification ? 'MISSING notification' : 'No notification needed');\r\n \r\n \r\n if (!hasNotification && shouldHaveNotification) {\r\n console.warn(`⚠️ NOTIFICATION AUDIT FAIL: ${operation} should have notifications but doesn't!`);\r\n // In development, you could throw an error or show a warning\r\n if (process.env.NODE_ENV === 'development') {\r\n console.trace('Stack trace for missing notification');\r\n }\r\n }\r\n};\r\n\r\n// Helper to create notification-aware API functions\r\nexport const createNotificationAwareAPI = (baseAPI) => {\r\n return {\r\n // Tickets\r\n createTicket: withNotifications(\r\n baseAPI.createTicket,\r\n NotificationPatterns.CREATE('Ticket', 'New ticket')\r\n ),\r\n \r\n updateTicket: withNotifications(\r\n baseAPI.updateTicket,\r\n NotificationPatterns.UPDATE('Ticket', 'Ticket')\r\n ),\r\n \r\n deleteTicket: withNotifications(\r\n baseAPI.deleteTicket,\r\n NotificationPatterns.DELETE('Ticket', 'Ticket')\r\n ),\r\n \r\n updateTicketStatus: withNotifications(\r\n baseAPI.updateTicketStatus,\r\n {\r\n onSuccess: {\r\n type: NOTIFICATION_TYPES.TICKET_UPDATED,\r\n channels: [NOTIFICATION_CHANNELS.DATABASE, NOTIFICATION_CHANNELS.SOCKET, NOTIFICATION_CHANNELS.TOAST],\r\n title: 'Ticket Status Updated',\r\n message: 'Status has been changed successfully'\r\n },\r\n onError: NotificationPatterns.STATUS_CHANGE('Ticket', '', '').onError\r\n }\r\n ),\r\n \r\n assignTicket: withNotifications(\r\n baseAPI.assignTicket,\r\n {\r\n onSuccess: {\r\n type: NOTIFICATION_TYPES.TICKET_ASSIGNED,\r\n channels: [NOTIFICATION_CHANNELS.DATABASE, NOTIFICATION_CHANNELS.SOCKET, NOTIFICATION_CHANNELS.PUSH],\r\n title: 'Ticket Assigned',\r\n message: 'Ticket has been assigned successfully'\r\n },\r\n onError: NotificationPatterns.ASSIGNMENT('Ticket', '').onError\r\n }\r\n ),\r\n \r\n // Properties\r\n createProperty: withNotifications(\r\n baseAPI.createProperty,\r\n NotificationPatterns.CREATE('Property', 'New property')\r\n ),\r\n \r\n updateProperty: withNotifications(\r\n baseAPI.updateProperty,\r\n NotificationPatterns.UPDATE('Property', 'Property')\r\n ),\r\n \r\n // Tenants\r\n createTenant: withNotifications(\r\n baseAPI.createTenant,\r\n NotificationPatterns.CREATE('Tenant', 'New tenant')\r\n ),\r\n \r\n // Messages\r\n sendMessage: withNotifications(\r\n baseAPI.sendMessage,\r\n {\r\n onSuccess: {\r\n type: NOTIFICATION_TYPES.MESSAGE_RECEIVED,\r\n channels: [NOTIFICATION_CHANNELS.SOCKET, NOTIFICATION_CHANNELS.BROWSER, NOTIFICATION_CHANNELS.SOUND],\r\n title: 'Message Sent',\r\n message: 'Your message has been sent'\r\n },\r\n onError: {\r\n type: NOTIFICATION_TYPES.ERROR,\r\n channels: [NOTIFICATION_CHANNELS.TOAST],\r\n message: 'Failed to send message'\r\n }\r\n }\r\n ),\r\n \r\n // File Operations\r\n uploadFile: withNotifications(\r\n baseAPI.uploadFile,\r\n NotificationPatterns.FILE_UPLOAD('File')\r\n )\r\n };\r\n};\r\n\r\n// Notification testing helper\r\nexport const testNotificationCoverage = (operations) => {\r\n \r\n const results = operations.map(operation => {\r\n const hasNotification = operation.hasNotification || false;\r\n const shouldHave = operation.shouldHaveNotification !== false; // Default to true\r\n const passed = hasNotification === shouldHave;\r\n \r\n return {\r\n operation: operation.name,\r\n hasNotification,\r\n shouldHave,\r\n passed,\r\n status: passed ? '✅ PASS' : '❌ FAIL'\r\n };\r\n });\r\n \r\n const passCount = results.filter(r => r.passed).length;\r\n const totalCount = results.length;\r\n const coverage = Math.round((passCount / totalCount) * 100);\r\n \r\n console.table(results);\r\n \r\n return { results, coverage, passed: passCount, total: totalCount };\r\n};\r\n\r\nexport default {\r\n withNotifications,\r\n auditNotifications,\r\n NotificationPatterns,\r\n decideNotificationChannels,\r\n logNotificationAudit,\r\n createNotificationAwareAPI,\r\n testNotificationCoverage\r\n};","// Notification utilities for messaging system\r\n\r\nclass NotificationManager {\r\n constructor() {\r\n this.permission = null;\r\n this.audioContext = null;\r\n this.init();\r\n }\r\n\r\n async init() {\r\n // Request notification permission\r\n if ('Notification' in window) {\r\n this.permission = await Notification.requestPermission();\r\n }\r\n\r\n // Initialize audio context for sound notifications\r\n try {\r\n this.audioContext = new (window.AudioContext || window.webkitAudioContext)();\r\n } catch (e) {\r\n console.warn('Web Audio API not supported');\r\n }\r\n }\r\n\r\n // Show browser notification\r\n showBrowserNotification(title, options = {}) {\r\n if (this.permission === 'granted' && 'Notification' in window) {\r\n const notification = new Notification(title, {\r\n icon: '/favicon.ico',\r\n badge: '/favicon.ico',\r\n ...options\r\n });\r\n\r\n // Auto close after 5 seconds\r\n setTimeout(() => {\r\n notification.close();\r\n }, 5000);\r\n\r\n return notification;\r\n }\r\n return null;\r\n }\r\n\r\n // Play notification sound\r\n playNotificationSound() {\r\n if (!this.audioContext) return;\r\n\r\n try {\r\n const oscillator = this.audioContext.createOscillator();\r\n const gainNode = this.audioContext.createGain();\r\n\r\n oscillator.connect(gainNode);\r\n gainNode.connect(this.audioContext.destination);\r\n\r\n // Create a pleasant notification sound\r\n oscillator.frequency.setValueAtTime(800, this.audioContext.currentTime);\r\n oscillator.frequency.setValueAtTime(600, this.audioContext.currentTime + 0.1);\r\n \r\n gainNode.gain.setValueAtTime(0, this.audioContext.currentTime);\r\n gainNode.gain.linearRampToValueAtTime(0.3, this.audioContext.currentTime + 0.01);\r\n gainNode.gain.linearRampToValueAtTime(0, this.audioContext.currentTime + 0.3);\r\n\r\n oscillator.start(this.audioContext.currentTime);\r\n oscillator.stop(this.audioContext.currentTime + 0.3);\r\n } catch (e) {\r\n console.warn('Could not play notification sound:', e);\r\n }\r\n }\r\n\r\n // Show message notification\r\n showMessageNotification(senderName, messageContent, propertyAddress = '') {\r\n const title = `New message from ${senderName}`;\r\n const body = propertyAddress \r\n ? `${propertyAddress}\\n${messageContent.substring(0, 100)}${messageContent.length > 100 ? '...' : ''}`\r\n : messageContent.substring(0, 100) + (messageContent.length > 100 ? '...' : '');\r\n\r\n this.showBrowserNotification(title, {\r\n body,\r\n tag: 'message-notification',\r\n renotify: true\r\n });\r\n\r\n this.playNotificationSound();\r\n }\r\n\r\n // Check if notifications are supported\r\n static isSupported() {\r\n return 'Notification' in window;\r\n }\r\n\r\n // Check if permission is granted\r\n hasPermission() {\r\n return this.permission === 'granted';\r\n }\r\n\r\n // Request permission if not already granted\r\n async requestPermission() {\r\n if ('Notification' in window && this.permission !== 'granted') {\r\n this.permission = await Notification.requestPermission();\r\n }\r\n return this.permission;\r\n }\r\n}\r\n\r\n// Create and export singleton instance\r\nconst notificationManager = new NotificationManager();\r\nexport default notificationManager;\r\n\r\n// Export utility functions\r\nexport const showMessageNotification = (senderName, messageContent, propertyAddress) => {\r\n notificationManager.showMessageNotification(senderName, messageContent, propertyAddress);\r\n};\r\n\r\nexport const requestNotificationPermission = () => {\r\n return notificationManager.requestPermission();\r\n};\r\n\r\nexport const hasNotificationPermission = () => {\r\n return notificationManager.hasPermission();\r\n};\r\n\r\nexport const isNotificationSupported = () => {\r\n return NotificationManager.isSupported();\r\n};","// Push notification utility functions\r\nimport api from '../services/api';\r\n\r\n// Check if push notifications are supported\r\nexport const isPushNotificationSupported = () => {\r\n return 'serviceWorker' in navigator && 'PushManager' in window;\r\n};\r\n\r\n// Check current permission status\r\nexport const getNotificationPermission = () => {\r\n if (!isPushNotificationSupported()) {\r\n return 'unsupported';\r\n }\r\n return Notification.permission;\r\n};\r\n\r\n// Request notification permission\r\nexport const requestNotificationPermission = async () => {\r\n if (!isPushNotificationSupported()) {\r\n throw new Error('Push notifications are not supported in this browser');\r\n }\r\n\r\n const permission = await Notification.requestPermission();\r\n return permission;\r\n};\r\n\r\n// Convert URL-safe base64 to Uint8Array (for VAPID key)\r\nconst urlBase64ToUint8Array = (base64String) => {\r\n const padding = '='.repeat((4 - base64String.length % 4) % 4);\r\n const base64 = (base64String + padding)\r\n .replace(/-/g, '+')\r\n .replace(/_/g, '/');\r\n\r\n const rawData = window.atob(base64);\r\n const outputArray = new Uint8Array(rawData.length);\r\n\r\n for (let i = 0; i < rawData.length; ++i) {\r\n outputArray[i] = rawData.charCodeAt(i);\r\n }\r\n return outputArray;\r\n};\r\n\r\n// Get or create push subscription\r\nexport const subscribeToPushNotifications = async () => {\r\n if (!isPushNotificationSupported()) {\r\n throw new Error('Push notifications are not supported');\r\n }\r\n\r\n if (Notification.permission !== 'granted') {\r\n throw new Error('Notification permission not granted');\r\n }\r\n\r\n try {\r\n // Unregister any existing service workers to ensure we get a fresh start\r\n const existingRegistrations = await navigator.serviceWorker.getRegistrations();\r\n for (let registration of existingRegistrations) {\r\n await registration.unregister();\r\n }\r\n\r\n // Register service worker\r\n const registration = await navigator.serviceWorker.register('/sw.js', {\r\n scope: '/',\r\n updateViaCache: 'none' // Don't cache the service worker\r\n });\r\n\r\n // Wait for service worker to be ready\r\n await navigator.serviceWorker.ready;\r\n\r\n // Get existing subscription\r\n let subscription = await registration.pushManager.getSubscription();\r\n \r\n if (!subscription) {\r\n // Create new subscription\r\n const vapidPublicKey = process.env.REACT_APP_VAPID_PUBLIC_KEY || \r\n 'BJ2eTitSHPWl9WBAk0F1Drwmv6bQB48aDpM1ilutZcdygYfpbK7ODrlMSzvplaHWVwPtvQ1x-Y2SK2LadSQZ2mc';\r\n \r\n \r\n const subscriptionOptions = {\r\n userVisibleOnly: true,\r\n applicationServerKey: urlBase64ToUint8Array(vapidPublicKey)\r\n };\r\n \r\n \r\n subscription = await registration.pushManager.subscribe(subscriptionOptions);\r\n }\r\n\r\n // Send subscription to backend\r\n await api.post('/notifications/subscribe', {\r\n subscription: subscription.toJSON()\r\n });\r\n\r\n return subscription;\r\n } catch (error) {\r\n console.error('Error subscribing to push notifications:', error);\r\n console.error('Error name:', error.name);\r\n console.error('Error message:', error.message);\r\n console.error('Error stack:', error.stack);\r\n \r\n // Provide more specific error messages\r\n if (error.name === 'AbortError') {\r\n throw new Error('Push subscription was aborted. This might be due to invalid VAPID keys or browser restrictions.');\r\n } else if (error.name === 'NotAllowedError') {\r\n throw new Error('Push notifications permission was denied by the user.');\r\n } else if (error.name === 'NotSupportedError') {\r\n throw new Error('Push notifications are not supported in this browser.');\r\n }\r\n \r\n throw error;\r\n }\r\n};\r\n\r\n// Unsubscribe from push notifications\r\nexport const unsubscribeFromPushNotifications = async () => {\r\n if (!isPushNotificationSupported()) {\r\n return;\r\n }\r\n\r\n try {\r\n const registration = await navigator.serviceWorker.getRegistration();\r\n if (!registration) {\r\n return;\r\n }\r\n\r\n const subscription = await registration.pushManager.getSubscription();\r\n if (!subscription) {\r\n return;\r\n }\r\n\r\n // Unsubscribe from browser\r\n await subscription.unsubscribe();\r\n\r\n // Remove subscription from backend\r\n await api.post('/notifications/unsubscribe', {\r\n endpoint: subscription.endpoint\r\n });\r\n\r\n } catch (error) {\r\n console.error('Error unsubscribing from push notifications:', error);\r\n throw error;\r\n }\r\n};\r\n\r\n// Check if currently subscribed\r\nexport const isPushSubscribed = async () => {\r\n if (!isPushNotificationSupported()) {\r\n return false;\r\n }\r\n\r\n try {\r\n const registration = await navigator.serviceWorker.getRegistration();\r\n if (!registration) {\r\n return false;\r\n }\r\n\r\n const subscription = await registration.pushManager.getSubscription();\r\n return !!subscription;\r\n } catch (error) {\r\n console.error('Error checking push subscription:', error);\r\n return false;\r\n }\r\n};\r\n\r\n// Send a test notification\r\nexport const sendTestNotification = async () => {\r\n if (!isPushNotificationSupported()) {\r\n throw new Error('Push notifications are not supported');\r\n }\r\n\r\n try {\r\n await api.post('/notifications/test');\r\n } catch (error) {\r\n console.error('Error sending test notification:', error);\r\n throw error;\r\n }\r\n};\r\n\r\n// Show local notification (fallback)\r\nexport const showLocalNotification = (title, options = {}) => {\r\n if (!isPushNotificationSupported()) {\r\n return;\r\n }\r\n\r\n if (Notification.permission === 'granted') {\r\n const notification = new Notification(title, {\r\n icon: '/favicon.ico',\r\n badge: '/favicon.ico',\r\n ...options\r\n });\r\n\r\n // Auto close after 5 seconds\r\n setTimeout(() => {\r\n notification.close();\r\n }, 5000);\r\n\r\n return notification;\r\n }\r\n};","import api from '../services/api';\r\n\r\n/**\r\n * Centralized tenant logout function to ensure consistent cleanup\r\n * @param {Function} navigate - React Router navigate function\r\n */\r\nexport const logoutTenant = (navigate) => {\r\n // Remove tenant authentication data\r\n localStorage.removeItem('tenantToken');\r\n localStorage.removeItem('tenantData');\r\n \r\n // Clear API authorization header\r\n delete api.defaults.headers.common['Authorization'];\r\n \r\n // Dispatch custom event to immediately notify theme context\r\n window.dispatchEvent(new CustomEvent('tenantLogout'));\r\n \r\n // Navigate to main login page (tenant tab will be available there)\r\n navigate('/login');\r\n};\r\n\r\n/**\r\n * Check if tenant is authenticated\r\n * @returns {boolean} - True if tenant has valid authentication\r\n */\r\nexport const isTenantAuthenticated = () => {\r\n const tenantToken = localStorage.getItem('tenantToken');\r\n const tenantData = localStorage.getItem('tenantData');\r\n return !!(tenantToken && tenantData);\r\n};"],"mappings":"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","names":["exports","module","NOTIFICATION_TYPES","NOTIFICATION_CHANNELS","getDefaultChannels","getDefaultPriority","isHighPriorityType","requestNotificationPermission","subscribeToPushNotifications","import_react","axios","user","React","import_react","React","import_react","React","CssBaseline","notifications","MdSupport","MdReportProblem","MdWork","MdSchedule","MdConstruction","MdPsychology","MdBusiness","MdHome","MdPeople","MdEngineering","MdInventory","MdDashboard","lightenColor","darkenColor","React","MdMenu","MdKeyboardArrowDown","MdMessage","MdNotifications","MdAccountCircle","import_react","import_material","React","import_react","import_material","import_react_router_dom","React","import_react","import_material","React","import_react","import_material","import_react","import_styles","lightenColor","darkenColor","React","React","import_react","import_material","React","import_react","import_material","React","import_react","import_material","import_icons_material","React","import_react","import_material","import_icons_material","import_date_fns","api","useSocket","useAuth","React","ErrorIcon","NotificationsIcon","SettingsIcon","import_react","import_material","import_icons_material","React","import_react","React","import_react","import_icons_material","import_react","import_styles","import_react","import_styles","NotificationManager","requestNotificationPermission","NotificationManager","subscribeToPushNotifications","registration"]}