@edusight/notification-widget 1.0.28 → 1.0.30

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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.esm.js","sources":["../src/components/ErrorBoundary.tsx","../src/hooks/usePreferencesSync.ts","../src/components/NotificationWidget.tsx","../src/index.ts"],"sourcesContent":["import React, { Component, ErrorInfo, ReactNode } from 'react';\r\nimport { MdError, MdRefresh } from 'react-icons/md';\r\nimport { ErrorBoundaryState } from '../types/core';\r\n\r\ninterface ErrorBoundaryProps {\r\n children: ReactNode;\r\n onError?: (error: Error, errorInfo: ErrorInfo) => void;\r\n}\r\n\r\nconst ErrorFallback: React.FC<{\r\n error: Error | null;\r\n onRetry: () => void;\r\n}> = ({ error, onRetry }) => (\r\n <div\r\n className=\"p-4 bg-[var(--widget-error)]/10 border border-[var(--widget-error)]/20 rounded-lg\"\r\n role=\"alert\"\r\n data-testid=\"error-boundary-fallback\"\r\n >\r\n <div className=\"flex items-center mb-2\">\r\n <MdError\r\n className=\"w-6 h-6 text-[var(--widget-error)] mr-2\"\r\n aria-hidden=\"true\"\r\n />\r\n <h3\r\n className=\"text-sm font-medium text-[var(--widget-error)]\"\r\n >\r\n Something went wrong\r\n </h3>\r\n </div>\r\n\r\n <p\r\n className=\"text-sm mb-3 text-[var(--widget-error)]/80\"\r\n >\r\n The notification widget encountered an error and couldn't load properly.\r\n </p>\r\n\r\n {process.env.NODE_ENV === 'development' && error && (\r\n <details className=\"mb-3\">\r\n <summary\r\n className=\"text-xs cursor-pointer text-[var(--widget-error)] hover:text-[var(--widget-error)]/80 transition-colors\"\r\n >\r\n Error details (development only)\r\n </summary>\r\n <pre\r\n className=\"mt-2 text-xs bg-[var(--widget-error)]/5 p-2 rounded overflow-auto max-h-32 text-[var(--widget-error)]\"\r\n >\r\n {error.message}\r\n {error.stack && `\\n\\n${error.stack}`}\r\n </pre>\r\n </details>\r\n )}\r\n\r\n <button\r\n type=\"button\"\r\n className=\"inline-flex items-center px-3 py-2 border border-transparent text-sm leading-4 font-medium rounded-md text-[var(--widget-error)] bg-[var(--widget-error)]/10 hover:bg-[var(--widget-error)]/20 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-[var(--widget-error)] transition-colors\"\r\n onClick={onRetry}\r\n data-testid=\"error-retry-button\"\r\n >\r\n <MdRefresh\r\n className=\"mr-1 w-4 h-4\"\r\n aria-hidden=\"true\"\r\n />\r\n Try again\r\n </button>\r\n </div>\r\n);\r\n\r\nexport class NotificationWidgetErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {\r\n constructor(props: ErrorBoundaryProps) {\r\n super(props);\r\n this.state = {\r\n hasError: false,\r\n error: null,\r\n errorInfo: null,\r\n };\r\n }\r\n\r\n static getDerivedStateFromError(error: Error): Partial<ErrorBoundaryState> {\r\n return {\r\n hasError: true,\r\n error,\r\n };\r\n }\r\n\r\n componentDidCatch(error: Error, errorInfo: ErrorInfo) {\r\n this.setState({\r\n errorInfo,\r\n });\r\n\r\n console.error('NotificationWidget Error Boundary caught an error:', {\r\n message: error.message,\r\n stack: error.stack,\r\n componentStack: errorInfo.componentStack,\r\n timestamp: new Date().toISOString(),\r\n });\r\n\r\n if (this.props.onError) {\r\n this.props.onError(error, errorInfo);\r\n }\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 });\r\n };\r\n\r\n render() {\r\n if (this.state.hasError) {\r\n return (\r\n <ErrorFallback\r\n error={this.state.error}\r\n onRetry={this.handleRetry}\r\n />\r\n );\r\n }\r\n\r\n return this.props.children;\r\n }\r\n}\r\n\r\nexport const useErrorHandler = () => {\r\n return (error: Error, errorInfo?: ErrorInfo) => {\r\n console.error('Widget error:', {\r\n message: error.message,\r\n stack: error.stack,\r\n errorInfo,\r\n timestamp: new Date().toISOString(),\r\n });\r\n };\r\n};","import { useEffect, useState, useCallback } from 'react';\r\nimport { NotificationPreferences } from '../types/core';\r\n\r\nconst useNotificationsClient = () => {\r\n return (window as any).__notificationSDK?.client;\r\n};\r\n\r\nexport interface UsePreferencesSyncProps {\r\n onPreferencesLoaded: (preferences: NotificationPreferences) => void;\r\n onError?: (error: Error) => void;\r\n}\r\n\r\nexport interface UsePreferencesSyncResult {\r\n isLoading: boolean;\r\n error: Error | null;\r\n preferences: NotificationPreferences | null;\r\n}\r\n\r\nexport const usePreferencesSync = ({\r\n onPreferencesLoaded,\r\n onError,\r\n}: UsePreferencesSyncProps): UsePreferencesSyncResult => {\r\n const notificationClient = useNotificationsClient();\r\n const [isLoading, setIsLoading] = useState(true);\r\n const [error, setError] = useState<Error | null>(null);\r\n const [preferences, setPreferences] = useState<NotificationPreferences | null>(null);\r\n\r\n const loadPreferences = useCallback(async () => {\r\n try {\r\n setIsLoading(true);\r\n setError(null);\r\n\r\n if (!notificationClient) {\r\n throw new Error('Notification client not available');\r\n }\r\n\r\n const config = (window as any).__notificationSDK?.config;\r\n\r\n if (!config) {\r\n throw new Error('SDK configuration not available');\r\n }\r\n\r\n const { subscriberId, tenantId, environmentId } = config;\r\n\r\n if (!subscriberId || !tenantId || !environmentId) {\r\n throw new Error('SubscriberId, TenantId or EnvironmentId not available in config');\r\n }\r\n\r\n const servicePreferences = await notificationClient.preferences.get(\r\n tenantId,\r\n subscriberId,\r\n environmentId,\r\n );\r\n\r\n const mappedPreferences: NotificationPreferences = {\r\n channels: {\r\n email: servicePreferences.emailEnabled ?? true,\r\n push: servicePreferences.pushEnabled ?? true,\r\n sms: servicePreferences.smsEnabled ?? false,\r\n inApp: servicePreferences.inAppEnabled ?? true,\r\n },\r\n subscriptions: [],\r\n deliverySchedule: {\r\n timezone: 'UTC',\r\n quietHours: {\r\n start: servicePreferences.quietHoursStart ?? '22:00',\r\n end: servicePreferences.quietHoursEnd ?? '08:00',\r\n },\r\n weekdays: [true, true, true, true, true, false, false],\r\n },\r\n };\r\n\r\n if (servicePreferences.categories) {\r\n Object.entries(servicePreferences.categories).forEach(([workflowId, categoryPrefs]) => {\r\n mappedPreferences.subscriptions.push({\r\n workflowId,\r\n name: workflowId,\r\n enabled: true,\r\n channels: {\r\n email: (categoryPrefs as any).emailEnabled ?? true,\r\n push: (categoryPrefs as any).pushEnabled ?? true,\r\n sms: (categoryPrefs as any).smsEnabled ?? false,\r\n inApp: (categoryPrefs as any).inAppEnabled ?? true,\r\n },\r\n });\r\n });\r\n }\r\n\r\n setPreferences(mappedPreferences);\r\n onPreferencesLoaded(mappedPreferences);\r\n } catch (err: any) {\r\n const error = err instanceof Error ? err : new Error('Failed to load preferences');\r\n\r\n // If 404, it means preferences don't exist yet for this user. \r\n // We'll use defaults and suppress the error callback.\r\n const isNotFound = (err as any)?.response?.status === 404 || (err as any)?.status === 404;\r\n\r\n if (!isNotFound) {\r\n setError(error);\r\n onError?.(error);\r\n } else {\r\n console.warn('Preferences not found for user (404), using defaults.');\r\n }\r\n\r\n const defaultPreferences: NotificationPreferences = {\r\n channels: {\r\n email: true,\r\n push: true,\r\n sms: false,\r\n inApp: true,\r\n },\r\n subscriptions: [],\r\n deliverySchedule: {\r\n timezone: 'UTC',\r\n quietHours: {\r\n start: '22:00',\r\n end: '08:00',\r\n },\r\n weekdays: [true, true, true, true, true, false, false],\r\n },\r\n };\r\n setPreferences(defaultPreferences);\r\n onPreferencesLoaded(defaultPreferences);\r\n } finally {\r\n setIsLoading(false);\r\n }\r\n }, [notificationClient, onPreferencesLoaded, onError]);\r\n\r\n useEffect(() => {\r\n if (notificationClient) {\r\n loadPreferences();\r\n }\r\n }, [notificationClient, loadPreferences]);\r\n\r\n return {\r\n isLoading,\r\n error,\r\n preferences,\r\n };\r\n};\r\n","\r\nimport React, { useReducer, useEffect, useCallback, createContext, useContext, useRef } from 'react';\r\nimport { io as ioClient } from 'socket.io-client';\r\nimport { NotificationClient } from '@edusight/notification-sdk';\r\nimport { NotificationWidgetProps, WidgetState, WidgetAction, SDKConfiguration } from '../types/core';\r\nimport { BellComponent } from './BellComponent';\r\nimport { InboxPopover } from './InboxPopover';\r\nimport { NotificationWidgetErrorBoundary } from './ErrorBoundary';\r\nimport { ComponentErrorBoundary } from './ComponentErrorBoundary';\r\nimport { SDKConnectionFallback, LoadingFallback } from './FallbackComponents';\r\nimport { useLivePreferences } from '../hooks/useLivePreferences';\r\nimport { usePreferencesSync } from '../hooks/usePreferencesSync';\r\nimport { createNotificationMapper } from '../utils/notification-mapper';\r\n\r\ninterface SDKContextType {\r\n client: any;\r\n isInitialized: boolean;\r\n error: Error | null;\r\n}\r\n\r\nconst SDKContext = createContext<SDKContextType | null>(null);\r\n\r\nexport const useSDK = () => {\r\n const context = useContext(SDKContext);\r\n if (!context) {\r\n throw new Error('useSDK must be used within a NotificationWidget');\r\n }\r\n return context;\r\n};\r\n\r\nconst initialState: WidgetState = {\r\n notifications: [],\r\n unreadCount: 0,\r\n preferences: {\r\n channels: {\r\n email: true,\r\n push: true,\r\n sms: false,\r\n inApp: true,\r\n },\r\n subscriptions: [],\r\n deliverySchedule: {\r\n timezone: 'UTC',\r\n quietHours: {\r\n start: '22:00',\r\n end: '08:00',\r\n },\r\n weekdays: [true, true, true, true, true, false, false],\r\n },\r\n },\r\n ui: {\r\n isOpen: false,\r\n currentView: 'notifications',\r\n selectedNotifications: [],\r\n isLoading: false,\r\n error: null,\r\n },\r\n websocket: {\r\n connected: false,\r\n reconnecting: false,\r\n },\r\n};\r\n\r\nconst SDKProvider: React.FC<{ config: SDKConfiguration; children: React.ReactNode }> = ({\r\n config,\r\n children,\r\n}) => {\r\n const [sdkState, setSdkState] = React.useState<SDKContextType>({\r\n client: null,\r\n isInitialized: false,\r\n error: null,\r\n });\r\n\r\n useEffect(() => {\r\n let isMounted = true;\r\n\r\n const initializeSDK = async () => {\r\n try {\r\n const existingSDK = (window as any).__notificationSDK;\r\n\r\n // Check if we can reuse the existing SDK instance\r\n if (existingSDK?.client) {\r\n // Compare new config with existing config to determine if we need to re-initialize\r\n // We use simple JSON stringify as configs are simple objects with strings/numbers\r\n const isConfigMatch = JSON.stringify(existingSDK.config) === JSON.stringify(config);\r\n\r\n if (isConfigMatch) {\r\n if (isMounted) {\r\n setSdkState({\r\n client: existingSDK.client,\r\n isInitialized: true,\r\n error: null,\r\n });\r\n }\r\n return;\r\n } else {\r\n console.log('[NotificationWidget] Config changed, re-initializing SDK', { old: existingSDK.config, new: config });\r\n }\r\n }\r\n\r\n const client = new NotificationClient({\r\n apiUrl: config.baseUrl,\r\n apiKey: config.apiKey,\r\n tenantId: config.tenantId,\r\n environmentId: config.environmentId,\r\n });\r\n\r\n (window as any).__notificationSDK = { client, config };\r\n\r\n if (isMounted) {\r\n setSdkState({\r\n client,\r\n isInitialized: true,\r\n error: null,\r\n });\r\n }\r\n } catch (error) {\r\n console.error('Failed to initialize SDK:', error);\r\n if (isMounted) {\r\n setSdkState({\r\n client: null,\r\n isInitialized: false,\r\n error: error as Error,\r\n });\r\n }\r\n }\r\n };\r\n\r\n initializeSDK();\r\n\r\n return () => {\r\n isMounted = false;\r\n };\r\n }, [config]);\r\n\r\n return (\r\n <SDKContext.Provider value={sdkState}>\r\n {children}\r\n </SDKContext.Provider>\r\n );\r\n};\r\n\r\nconst widgetReducer = (state: WidgetState, action: WidgetAction): WidgetState => {\r\n switch (action.type) {\r\n case 'SET_NOTIFICATIONS':\r\n return {\r\n ...state,\r\n notifications: action.payload,\r\n unreadCount: action.payload.filter(n => !n.isRead).length,\r\n };\r\n\r\n case 'ADD_NOTIFICATION':\r\n const newNotifications = [action.payload, ...state.notifications];\r\n return {\r\n ...state,\r\n notifications: newNotifications,\r\n unreadCount: newNotifications.filter(n => !n.isRead).length,\r\n };\r\n\r\n case 'UPDATE_NOTIFICATION':\r\n const updatedNotifications = state.notifications.map(n =>\r\n n.id === action.payload.id ? { ...n, ...action.payload.updates } : n\r\n );\r\n return {\r\n ...state,\r\n notifications: updatedNotifications,\r\n unreadCount: updatedNotifications.filter(n => !n.isRead).length,\r\n };\r\n\r\n case 'DELETE_NOTIFICATION':\r\n const filteredNotifications = state.notifications.filter(n => n.id !== action.payload);\r\n return {\r\n ...state,\r\n notifications: filteredNotifications,\r\n unreadCount: filteredNotifications.filter(n => !n.isRead).length,\r\n };\r\n\r\n case 'SET_PREFERENCES':\r\n return {\r\n ...state,\r\n preferences: action.payload,\r\n };\r\n\r\n case 'SET_UI_STATE':\r\n return {\r\n ...state,\r\n ui: { ...state.ui, ...action.payload },\r\n };\r\n\r\n case 'SET_WEBSOCKET_STATE':\r\n return {\r\n ...state,\r\n websocket: { ...state.websocket, ...action.payload },\r\n };\r\n\r\n default:\r\n return state;\r\n }\r\n};\r\n\r\nconst NotificationWidgetInternal: React.FC<Omit<NotificationWidgetProps, 'sdkConfig'>> = ({\r\n position = 'right',\r\n size = 'medium',\r\n theme = 'light',\r\n className = '',\r\n onError,\r\n}) => {\r\n const [state, dispatch] = useReducer(widgetReducer, initialState);\r\n const { client, isInitialized, error: sdkError } = useSDK();\r\n const websocketRef = useRef<any>(null);\r\n\r\n const handlePreferencesChange = useCallback((preferences: any) => {\r\n dispatch({\r\n type: 'SET_PREFERENCES',\r\n payload: preferences,\r\n });\r\n }, []);\r\n\r\n const handleWidgetError = useCallback((error: Error) => {\r\n console.error('Widget error:', error);\r\n if (onError) {\r\n onError(error);\r\n }\r\n }, [onError]);\r\n\r\n const { isLoading: isPreferencesLoading, error: preferencesLoadError } = usePreferencesSync({\r\n onPreferencesLoaded: handlePreferencesChange,\r\n onError: handleWidgetError,\r\n });\r\n\r\n const { updatePreference, isSaving, error: preferencesError } = useLivePreferences({\r\n preferences: state.preferences,\r\n onPreferencesChange: handlePreferencesChange,\r\n onError: handleWidgetError,\r\n });\r\n\r\n const handleWebSocketEvent = useCallback((event: any) => {\r\n try {\r\n const notificationMapper = createNotificationMapper();\r\n\r\n switch (event.type) {\r\n case 'notification_received': {\r\n const wsPayload = event.data;\r\n\r\n if (!notificationMapper.validateWebSocketPayload(wsPayload)) {\r\n console.error('Invalid WebSocket notification payload, skipping', wsPayload);\r\n break;\r\n }\r\n\r\n const mappedNotification = notificationMapper.toWidgetNotificationFromWebSocket(wsPayload);\r\n dispatch({\r\n type: 'ADD_NOTIFICATION',\r\n payload: mappedNotification,\r\n });\r\n break;\r\n }\r\n\r\n case 'notification_updated':\r\n dispatch({\r\n type: 'UPDATE_NOTIFICATION',\r\n payload: {\r\n id: event.data.id || event.data.notificationId,\r\n updates: event.data,\r\n },\r\n });\r\n break;\r\n\r\n case 'notification_deleted':\r\n dispatch({\r\n type: 'DELETE_NOTIFICATION',\r\n payload: event.data.id || event.data.notificationId,\r\n });\r\n break;\r\n\r\n case 'preferences_updated':\r\n dispatch({\r\n type: 'SET_PREFERENCES',\r\n payload: event.data,\r\n });\r\n break;\r\n\r\n default:\r\n console.log('Unknown WebSocket event type:', event.type);\r\n }\r\n } catch (error) {\r\n console.error('Error handling WebSocket event:', error);\r\n }\r\n }, []);\r\n\r\n const connectWebSocket = useCallback(async () => {\r\n if (!client || !isInitialized || websocketRef.current) return;\r\n\r\n try {\r\n dispatch({\r\n type: 'SET_WEBSOCKET_STATE',\r\n payload: { reconnecting: true },\r\n });\r\n\r\n const sdkConfig = (window as any).__notificationSDK?.config;\r\n if (!sdkConfig) {\r\n throw new Error('SDK configuration not available for WebSocket connection');\r\n }\r\n\r\n const baseUrl = client.getApiHost();\r\n const namespace = '/v1/notifications';\r\n const fullUrl = `${baseUrl}${namespace}`;\r\n\r\n console.log('Connecting to Socket.IO at:', fullUrl);\r\n\r\n const socket = ioClient(fullUrl, {\r\n query: {\r\n tenantId: sdkConfig.tenantId,\r\n subscriberId: sdkConfig.subscriberId,\r\n environmentId: sdkConfig.environmentId,\r\n },\r\n transports: ['websocket'],\r\n autoConnect: false,\r\n reconnection: true,\r\n reconnectionAttempts: 10,\r\n reconnectionDelay: 1000,\r\n reconnectionDelayMax: 5000,\r\n });\r\n\r\n websocketRef.current = socket;\r\n\r\n socket.on('notification', (payload: any) => {\r\n console.log('Received notification:', payload);\r\n handleWebSocketEvent({\r\n type: 'notification_received',\r\n data: payload,\r\n });\r\n });\r\n\r\n socket.on('connect', () => {\r\n console.log('Socket.IO connected successfully');\r\n dispatch({\r\n type: 'SET_WEBSOCKET_STATE',\r\n payload: { connected: true, reconnecting: false },\r\n });\r\n });\r\n\r\n socket.on('disconnect', (reason: any) => {\r\n console.log('Socket.IO disconnected:', reason);\r\n dispatch({\r\n type: 'SET_WEBSOCKET_STATE',\r\n payload: { connected: false, reconnecting: false },\r\n });\r\n });\r\n\r\n socket.on('reconnect_attempt', (attempt: any) => {\r\n console.log('Socket.IO reconnection attempt:', attempt);\r\n dispatch({\r\n type: 'SET_WEBSOCKET_STATE',\r\n payload: { connected: false, reconnecting: true },\r\n });\r\n });\r\n\r\n socket.on('connect_error', (error: any) => {\r\n console.error('Socket.IO connection error:', error);\r\n dispatch({\r\n type: 'SET_WEBSOCKET_STATE',\r\n payload: { connected: false, reconnecting: false },\r\n });\r\n if (onError) {\r\n onError(error);\r\n }\r\n });\r\n\r\n socket.connect();\r\n\r\n } catch (error) {\r\n console.error('Failed to connect WebSocket:', error);\r\n dispatch({\r\n type: 'SET_WEBSOCKET_STATE',\r\n payload: { connected: false, reconnecting: false },\r\n });\r\n if (onError) {\r\n onError(error as Error);\r\n }\r\n }\r\n }, [client, isInitialized, handleWebSocketEvent, onError]);\r\n\r\n const disconnectWebSocket = useCallback(() => {\r\n if (websocketRef.current) {\r\n try {\r\n if (websocketRef.current.disconnect) {\r\n websocketRef.current.disconnect();\r\n }\r\n websocketRef.current = null;\r\n dispatch({\r\n type: 'SET_WEBSOCKET_STATE',\r\n payload: { connected: false, reconnecting: false },\r\n });\r\n } catch (error) {\r\n console.error('Error disconnecting WebSocket:', error);\r\n }\r\n }\r\n }, []);\r\n\r\n const handleBellClick = useCallback(() => {\r\n dispatch({\r\n type: 'SET_UI_STATE',\r\n payload: { isOpen: !state.ui.isOpen },\r\n });\r\n }, [state.ui.isOpen]);\r\n\r\n const handlePopoverClose = useCallback(() => {\r\n dispatch({\r\n type: 'SET_UI_STATE',\r\n payload: { isOpen: false },\r\n });\r\n }, []);\r\n\r\n const handleViewChange = useCallback((view: 'notifications' | 'preferences') => {\r\n dispatch({\r\n type: 'SET_UI_STATE',\r\n payload: { currentView: view },\r\n });\r\n }, []);\r\n\r\n const handleNotificationAction = useCallback(async (id: string, action: any) => {\r\n if (!client || !isInitialized) {\r\n console.error('SDK not initialized');\r\n return;\r\n }\r\n\r\n const sdkConfig = (window as any).__notificationSDK?.config;\r\n if (!sdkConfig) {\r\n console.error('SDK configuration not available');\r\n return;\r\n }\r\n\r\n try {\r\n switch (action.type) {\r\n case 'mark_read':\r\n await client.inbox.markAsRead(id, sdkConfig.tenantId, sdkConfig.environmentId, sdkConfig.subscriberId);\r\n break;\r\n case 'mark_unread':\r\n await client.inbox.markAsUnread(id, sdkConfig.tenantId, sdkConfig.environmentId, sdkConfig.subscriberId);\r\n break;\r\n case 'archive':\r\n await client.inbox.archive(id, sdkConfig.tenantId, sdkConfig.environmentId, sdkConfig.subscriberId);\r\n break;\r\n case 'delete':\r\n await client.inbox.delete(id, sdkConfig.tenantId, sdkConfig.environmentId, sdkConfig.subscriberId);\r\n break;\r\n default:\r\n if (action.handler) {\r\n await action.handler(id);\r\n }\r\n break;\r\n }\r\n\r\n switch (action.type) {\r\n case 'mark_read':\r\n dispatch({\r\n type: 'UPDATE_NOTIFICATION',\r\n payload: { id, updates: { isRead: true } },\r\n });\r\n break;\r\n case 'mark_unread':\r\n dispatch({\r\n type: 'UPDATE_NOTIFICATION',\r\n payload: { id, updates: { isRead: false } },\r\n });\r\n break;\r\n case 'archive':\r\n dispatch({\r\n type: 'UPDATE_NOTIFICATION',\r\n payload: { id, updates: { isArchived: true } },\r\n });\r\n break;\r\n case 'delete':\r\n dispatch({\r\n type: 'DELETE_NOTIFICATION',\r\n payload: id,\r\n });\r\n break;\r\n }\r\n } catch (error) {\r\n console.error('Error performing notification action:', error);\r\n if (onError) {\r\n onError(error as Error);\r\n }\r\n }\r\n }, [client]);\r\n\r\n useEffect(() => {\r\n if (!client || !isInitialized) return;\r\n\r\n const loadNotifications = async () => {\r\n try {\r\n dispatch({\r\n type: 'SET_UI_STATE',\r\n payload: { isLoading: true },\r\n });\r\n\r\n const sdkConfig = (window as any).__notificationSDK?.config;\r\n if (!sdkConfig) {\r\n throw new Error('SDK configuration not available');\r\n }\r\n\r\n const notificationMapper = createNotificationMapper();\r\n const response = await client.inbox.getRenderedNotifications(\r\n {\r\n channel: 'in_app',\r\n limit: 50,\r\n offset: 0,\r\n },\r\n sdkConfig.tenantId,\r\n sdkConfig.environmentId,\r\n sdkConfig.subscriberId,\r\n );\r\n\r\n const coreNotifications = (response?.items || []).map((item: any) =>\r\n notificationMapper.toWidgetNotification(item)\r\n );\r\n\r\n dispatch({\r\n type: 'SET_NOTIFICATIONS',\r\n payload: coreNotifications,\r\n });\r\n\r\n dispatch({\r\n type: 'SET_UI_STATE',\r\n payload: { isLoading: false, error: null },\r\n });\r\n } catch (error) {\r\n console.error('Failed to load notifications:', error);\r\n dispatch({\r\n type: 'SET_UI_STATE',\r\n payload: {\r\n isLoading: false,\r\n error: (error as Error)\r\n },\r\n });\r\n if (onError) {\r\n onError(error as Error);\r\n }\r\n }\r\n };\r\n\r\n loadNotifications();\r\n }, [client, isInitialized, onError]);\r\n\r\n useEffect(() => {\r\n if (client && isInitialized) {\r\n connectWebSocket();\r\n }\r\n\r\n return () => {\r\n disconnectWebSocket();\r\n };\r\n }, [client]);\r\n\r\n useEffect(() => {\r\n if (!client || !isInitialized) return;\r\n\r\n if (state.websocket.connected) return;\r\n\r\n const pollInterval = setInterval(async () => {\r\n try {\r\n const sdkConfig = (window as any).__notificationSDK?.config;\r\n if (!sdkConfig) {\r\n return;\r\n }\r\n\r\n const notificationMapper = createNotificationMapper();\r\n const response = await client.inbox.getRenderedNotifications(\r\n {\r\n channel: 'in_app',\r\n limit: 50,\r\n offset: 0,\r\n },\r\n sdkConfig.tenantId,\r\n sdkConfig.environmentId,\r\n sdkConfig.subscriberId,\r\n );\r\n\r\n const coreNotifications = (response?.items || []).map((item: any) =>\r\n notificationMapper.toWidgetNotification(item)\r\n );\r\n\r\n dispatch({\r\n type: 'SET_NOTIFICATIONS',\r\n payload: coreNotifications,\r\n });\r\n } catch (error) {\r\n console.error('Polling failed:', error);\r\n }\r\n }, 30000);\r\n\r\n return () => clearInterval(pollInterval);\r\n }, [client, state.websocket.connected]);\r\n\r\n useEffect(() => {\r\n const handleStorageChange = (event: StorageEvent) => {\r\n if (event.key === 'notification_widget_sync' && event.newValue) {\r\n try {\r\n const syncData = JSON.parse(event.newValue);\r\n handleWebSocketEvent(syncData);\r\n } catch (error) {\r\n console.error('Error parsing sync data:', error);\r\n }\r\n }\r\n };\r\n\r\n window.addEventListener('storage', handleStorageChange);\r\n return () => window.removeEventListener('storage', handleStorageChange);\r\n }, [handleWebSocketEvent]);\r\n\r\n useEffect(() => {\r\n dispatch({\r\n type: 'SET_UI_STATE',\r\n payload: { isLoading: isSaving },\r\n });\r\n }, [isSaving]);\r\n\r\n useEffect(() => {\r\n const error = sdkError || preferencesError || preferencesLoadError;\r\n if (error) {\r\n dispatch({\r\n type: 'SET_UI_STATE',\r\n payload: { error: error },\r\n });\r\n }\r\n }, [sdkError, preferencesError, preferencesLoadError]);\r\n\r\n if (!isInitialized && !sdkError) {\r\n return (\r\n <div\r\n className={`relative inline-block ${className}`}\r\n data-widget-size={size || 'small'}\r\n data-theme={theme}\r\n data-testid=\"notification-widget\"\r\n >\r\n <ComponentErrorBoundary componentName=\"BellComponent\">\r\n <BellComponent\r\n unreadCount={0}\r\n onClick={() => { }}\r\n size={size}\r\n disabled={true}\r\n />\r\n </ComponentErrorBoundary>\r\n </div>\r\n );\r\n }\r\n\r\n if (sdkError) {\r\n return (\r\n <div\r\n className={`relative inline-block ${className}`}\r\n data-widget-size={size || 'small'}\r\n data-theme={theme}\r\n data-testid=\"notification-widget\"\r\n >\r\n <ComponentErrorBoundary\r\n componentName=\"BellComponent\"\r\n fallback={\r\n <SDKConnectionFallback\r\n error={sdkError.message}\r\n onRetry={() => window.location.reload()}\r\n />\r\n }\r\n >\r\n <BellComponent\r\n unreadCount={0}\r\n onClick={() => { }}\r\n size={size}\r\n disabled={true}\r\n />\r\n </ComponentErrorBoundary>\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div\r\n className={`relative inline-block ${className}`}\r\n data-widget-size={size || 'small'}\r\n data-theme={theme}\r\n data-testid=\"notification-widget\"\r\n >\r\n <ComponentErrorBoundary componentName=\"BellComponent\">\r\n <BellComponent\r\n unreadCount={state.unreadCount}\r\n onClick={handleBellClick}\r\n size={size}\r\n disabled={state.ui.isLoading}\r\n />\r\n </ComponentErrorBoundary>\r\n\r\n <ComponentErrorBoundary\r\n componentName=\"InboxPopover\"\r\n fallback={<LoadingFallback message=\"Unable to load notifications\" />}\r\n >\r\n <InboxPopover\r\n isOpen={state.ui.isOpen}\r\n onClose={handlePopoverClose}\r\n position={position}\r\n currentView={state.ui.currentView}\r\n onViewChange={handleViewChange}\r\n notifications={state.notifications}\r\n onNotificationAction={handleNotificationAction}\r\n preferences={state.preferences}\r\n onPreferenceChange={updatePreference}\r\n isPreferencesLoading={isSaving}\r\n />\r\n </ComponentErrorBoundary>\r\n </div>\r\n );\r\n};\r\n\r\nexport const NotificationWidget: React.FC<NotificationWidgetProps> = ({\r\n sdkConfig,\r\n ...props\r\n}) => {\r\n return (\r\n <NotificationWidgetErrorBoundary onError={props.onError}>\r\n <SDKProvider config={sdkConfig}>\r\n <NotificationWidgetInternal {...props} />\r\n </SDKProvider>\r\n </NotificationWidgetErrorBoundary>\r\n );\r\n};","export { NotificationWidget } from './components/NotificationWidget';\r\n\r\nexport { BellComponent } from './components/BellComponent';\r\nexport { InboxPopover } from './components/InboxPopover';\r\nexport { NotificationItem } from './components/NotificationItem';\r\nexport { PreferencesView } from './components/PreferencesView';\r\n\r\nexport { NotificationWidgetErrorBoundary } from './components/ErrorBoundary';\r\n\r\nexport type * from './types/core';\r\n\r\nexport type { Notification as SDKNotification, NotificationFilters } from '@edusight/notification-sdk';\r\n\r\nimport './styles/index.css';\r\n\r\nexport const VERSION = '3.0.0';\r\nexport const WIDGET_NAME = '@edusight/notification-widget';"],"names":["ErrorFallback","error","onRetry","jsxs","jsx","MdError","MdRefresh","NotificationWidgetErrorBoundary","Component","props","errorInfo","useNotificationsClient","usePreferencesSync","onPreferencesLoaded","onError","notificationClient","isLoading","setIsLoading","useState","setError","preferences","setPreferences","loadPreferences","useCallback","config","subscriberId","tenantId","environmentId","servicePreferences","mappedPreferences","workflowId","categoryPrefs","err","defaultPreferences","useEffect","SDKContext","createContext","useSDK","context","useContext","initialState","SDKProvider","children","sdkState","setSdkState","React","isMounted","existingSDK","client","NotificationClient","widgetReducer","state","action","n","newNotifications","updatedNotifications","filteredNotifications","NotificationWidgetInternal","position","size","theme","className","dispatch","useReducer","isInitialized","sdkError","websocketRef","useRef","handlePreferencesChange","handleWidgetError","preferencesLoadError","updatePreference","isSaving","preferencesError","useLivePreferences","handleWebSocketEvent","event","notificationMapper","createNotificationMapper","wsPayload","mappedNotification","connectWebSocket","sdkConfig","fullUrl","socket","ioClient","payload","reason","attempt","disconnectWebSocket","handleBellClick","handlePopoverClose","handleViewChange","view","handleNotificationAction","id","coreNotifications","item","pollInterval","handleStorageChange","syncData","ComponentErrorBoundary","BellComponent","SDKConnectionFallback","LoadingFallback","InboxPopover","NotificationWidget","VERSION","WIDGET_NAME"],"mappings":"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"}
1
+ {"version":3,"file":"index.esm.js","sources":["../src/components/ErrorBoundary.tsx","../src/hooks/usePreferencesSync.ts","../src/hooks/useWorkflows.ts","../src/components/NotificationWidget.tsx","../src/index.ts"],"sourcesContent":["import React, { Component, ErrorInfo, ReactNode } from 'react';\r\nimport { MdError, MdRefresh } from 'react-icons/md';\r\nimport { ErrorBoundaryState } from '../types/core';\r\n\r\ninterface ErrorBoundaryProps {\r\n children: ReactNode;\r\n onError?: (error: Error, errorInfo: ErrorInfo) => void;\r\n}\r\n\r\nconst ErrorFallback: React.FC<{\r\n error: Error | null;\r\n onRetry: () => void;\r\n}> = ({ error, onRetry }) => (\r\n <div\r\n className=\"p-4 bg-[var(--widget-error)]/10 border border-[var(--widget-error)]/20 rounded-lg\"\r\n role=\"alert\"\r\n data-testid=\"error-boundary-fallback\"\r\n >\r\n <div className=\"flex items-center mb-2\">\r\n <MdError\r\n className=\"w-6 h-6 text-[var(--widget-error)] mr-2\"\r\n aria-hidden=\"true\"\r\n />\r\n <h3\r\n className=\"text-sm font-medium text-[var(--widget-error)]\"\r\n >\r\n Something went wrong\r\n </h3>\r\n </div>\r\n\r\n <p\r\n className=\"text-sm mb-3 text-[var(--widget-error)]/80\"\r\n >\r\n The notification widget encountered an error and couldn't load properly.\r\n </p>\r\n\r\n {process.env.NODE_ENV === 'development' && error && (\r\n <details className=\"mb-3\">\r\n <summary\r\n className=\"text-xs cursor-pointer text-[var(--widget-error)] hover:text-[var(--widget-error)]/80 transition-colors\"\r\n >\r\n Error details (development only)\r\n </summary>\r\n <pre\r\n className=\"mt-2 text-xs bg-[var(--widget-error)]/5 p-2 rounded overflow-auto max-h-32 text-[var(--widget-error)]\"\r\n >\r\n {error.message}\r\n {error.stack && `\\n\\n${error.stack}`}\r\n </pre>\r\n </details>\r\n )}\r\n\r\n <button\r\n type=\"button\"\r\n className=\"inline-flex items-center px-3 py-2 border border-transparent text-sm leading-4 font-medium rounded-md text-[var(--widget-error)] bg-[var(--widget-error)]/10 hover:bg-[var(--widget-error)]/20 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-[var(--widget-error)] transition-colors\"\r\n onClick={onRetry}\r\n data-testid=\"error-retry-button\"\r\n >\r\n <MdRefresh\r\n className=\"mr-1 w-4 h-4\"\r\n aria-hidden=\"true\"\r\n />\r\n Try again\r\n </button>\r\n </div>\r\n);\r\n\r\nexport class NotificationWidgetErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {\r\n constructor(props: ErrorBoundaryProps) {\r\n super(props);\r\n this.state = {\r\n hasError: false,\r\n error: null,\r\n errorInfo: null,\r\n };\r\n }\r\n\r\n static getDerivedStateFromError(error: Error): Partial<ErrorBoundaryState> {\r\n return {\r\n hasError: true,\r\n error,\r\n };\r\n }\r\n\r\n componentDidCatch(error: Error, errorInfo: ErrorInfo) {\r\n this.setState({\r\n errorInfo,\r\n });\r\n\r\n console.error('NotificationWidget Error Boundary caught an error:', {\r\n message: error.message,\r\n stack: error.stack,\r\n componentStack: errorInfo.componentStack,\r\n timestamp: new Date().toISOString(),\r\n });\r\n\r\n if (this.props.onError) {\r\n this.props.onError(error, errorInfo);\r\n }\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 });\r\n };\r\n\r\n render() {\r\n if (this.state.hasError) {\r\n return (\r\n <ErrorFallback\r\n error={this.state.error}\r\n onRetry={this.handleRetry}\r\n />\r\n );\r\n }\r\n\r\n return this.props.children;\r\n }\r\n}\r\n\r\nexport const useErrorHandler = () => {\r\n return (error: Error, errorInfo?: ErrorInfo) => {\r\n console.error('Widget error:', {\r\n message: error.message,\r\n stack: error.stack,\r\n errorInfo,\r\n timestamp: new Date().toISOString(),\r\n });\r\n };\r\n};","import { useEffect, useState, useCallback } from 'react';\r\nimport { NotificationPreferences } from '../types/core';\r\n\r\nconst useNotificationsClient = () => {\r\n return (window as any).__notificationSDK?.client;\r\n};\r\n\r\nexport interface UsePreferencesSyncProps {\r\n onPreferencesLoaded: (preferences: NotificationPreferences) => void;\r\n onError?: (error: Error) => void;\r\n}\r\n\r\nexport interface UsePreferencesSyncResult {\r\n isLoading: boolean;\r\n error: Error | null;\r\n preferences: NotificationPreferences | null;\r\n}\r\n\r\nexport const usePreferencesSync = ({\r\n onPreferencesLoaded,\r\n onError,\r\n}: UsePreferencesSyncProps): UsePreferencesSyncResult => {\r\n const notificationClient = useNotificationsClient();\r\n const [isLoading, setIsLoading] = useState(true);\r\n const [error, setError] = useState<Error | null>(null);\r\n const [preferences, setPreferences] = useState<NotificationPreferences | null>(null);\r\n\r\n const loadPreferences = useCallback(async () => {\r\n try {\r\n setIsLoading(true);\r\n setError(null);\r\n\r\n if (!notificationClient) {\r\n throw new Error('Notification client not available');\r\n }\r\n\r\n const config = (window as any).__notificationSDK?.config;\r\n\r\n if (!config) {\r\n throw new Error('SDK configuration not available');\r\n }\r\n\r\n const { subscriberId, tenantId, environmentId } = config;\r\n\r\n if (!subscriberId || !tenantId || !environmentId) {\r\n throw new Error('SubscriberId, TenantId or EnvironmentId not available in config');\r\n }\r\n\r\n const servicePreferences = await notificationClient.preferences.get(\r\n tenantId,\r\n subscriberId,\r\n environmentId,\r\n );\r\n\r\n const mappedPreferences: NotificationPreferences = {\r\n channels: {\r\n email: servicePreferences.emailEnabled ?? true,\r\n push: servicePreferences.pushEnabled ?? true,\r\n sms: servicePreferences.smsEnabled ?? false,\r\n inApp: servicePreferences.inAppEnabled ?? true,\r\n },\r\n subscriptions: [],\r\n deliverySchedule: {\r\n timezone: 'UTC',\r\n quietHours: {\r\n start: servicePreferences.quietHoursStart ?? '22:00',\r\n end: servicePreferences.quietHoursEnd ?? '08:00',\r\n },\r\n weekdays: [true, true, true, true, true, false, false],\r\n },\r\n };\r\n\r\n if (servicePreferences.categories) {\r\n Object.entries(servicePreferences.categories).forEach(([workflowId, categoryPrefs]) => {\r\n mappedPreferences.subscriptions.push({\r\n workflowId,\r\n name: workflowId,\r\n enabled: true,\r\n channels: {\r\n email: (categoryPrefs as any).emailEnabled ?? true,\r\n push: (categoryPrefs as any).pushEnabled ?? true,\r\n sms: (categoryPrefs as any).smsEnabled ?? false,\r\n inApp: (categoryPrefs as any).inAppEnabled ?? true,\r\n },\r\n });\r\n });\r\n }\r\n\r\n setPreferences(mappedPreferences);\r\n onPreferencesLoaded(mappedPreferences);\r\n } catch (err: any) {\r\n const error = err instanceof Error ? err : new Error('Failed to load preferences');\r\n\r\n // If 404, it means preferences don't exist yet for this user. \r\n // We'll use defaults and suppress the error callback.\r\n const isNotFound = (err as any)?.response?.status === 404 || (err as any)?.status === 404;\r\n\r\n if (!isNotFound) {\r\n setError(error);\r\n onError?.(error);\r\n } else {\r\n console.warn('Preferences not found for user (404), using defaults.');\r\n }\r\n\r\n const defaultPreferences: NotificationPreferences = {\r\n channels: {\r\n email: true,\r\n push: true,\r\n sms: false,\r\n inApp: true,\r\n },\r\n subscriptions: [],\r\n deliverySchedule: {\r\n timezone: 'UTC',\r\n quietHours: {\r\n start: '22:00',\r\n end: '08:00',\r\n },\r\n weekdays: [true, true, true, true, true, false, false],\r\n },\r\n };\r\n setPreferences(defaultPreferences);\r\n onPreferencesLoaded(defaultPreferences);\r\n } finally {\r\n setIsLoading(false);\r\n }\r\n }, [notificationClient, onPreferencesLoaded, onError]);\r\n\r\n useEffect(() => {\r\n if (notificationClient) {\r\n loadPreferences();\r\n }\r\n }, [notificationClient, loadPreferences]);\r\n\r\n return {\r\n isLoading,\r\n error,\r\n preferences,\r\n };\r\n};\r\n","import { useEffect, useState, useCallback } from 'react';\r\n\r\nconst useNotificationsClient = () => {\r\n return (window as any).__notificationSDK?.client;\r\n};\r\n\r\nexport interface Workflow {\r\n workflowId: string;\r\n name: string;\r\n description?: string;\r\n}\r\n\r\nexport interface UseWorkflowsResult {\r\n workflows: Workflow[];\r\n isLoading: boolean;\r\n error: Error | null;\r\n refetch: () => void;\r\n}\r\n\r\nexport const useWorkflows = (): UseWorkflowsResult => {\r\n const notificationClient = useNotificationsClient();\r\n const [workflows, setWorkflows] = useState<Workflow[]>([]);\r\n const [isLoading, setIsLoading] = useState(true);\r\n const [error, setError] = useState<Error | null>(null);\r\n\r\n const loadWorkflows = useCallback(async () => {\r\n try {\r\n setIsLoading(true);\r\n setError(null);\r\n\r\n if (!notificationClient) {\r\n throw new Error('Notification client not available');\r\n }\r\n\r\n const config = (window as any).__notificationSDK?.config;\r\n\r\n if (!config) {\r\n throw new Error('SDK configuration not available');\r\n }\r\n\r\n const { tenantId, environmentId } = config;\r\n\r\n if (!tenantId || !environmentId) {\r\n throw new Error('TenantId or EnvironmentId not available in config');\r\n }\r\n\r\n // List all active workflows for this tenant/environment\r\n const response = await notificationClient.workflows.list(\r\n { status: 'active' }, // Only load active workflows\r\n tenantId,\r\n environmentId\r\n );\r\n\r\n const mappedWorkflows: Workflow[] = (response?.workflows || []).map((wf: any) => ({\r\n workflowId: wf.workflowId,\r\n name: wf.name || wf.workflowId,\r\n description: wf.description,\r\n }));\r\n\r\n setWorkflows(mappedWorkflows);\r\n } catch (err: any) {\r\n const error = err instanceof Error ? err : new Error('Failed to load workflows');\r\n\r\n // Silently handle 404 or other errors - workflows are optional\r\n console.warn('Failed to load workflows:', error);\r\n setError(error);\r\n setWorkflows([]);\r\n } finally {\r\n setIsLoading(false);\r\n }\r\n }, [notificationClient]);\r\n\r\n useEffect(() => {\r\n if (notificationClient) {\r\n loadWorkflows();\r\n }\r\n }, [notificationClient, loadWorkflows]);\r\n\r\n return {\r\n workflows,\r\n isLoading,\r\n error,\r\n refetch: loadWorkflows,\r\n };\r\n};\r\n","\r\nimport React, { useReducer, useEffect, useCallback, createContext, useContext, useRef } from 'react';\r\nimport { io as ioClient } from 'socket.io-client';\r\nimport { NotificationClient } from '@edusight/notification-sdk';\r\nimport { NotificationWidgetProps, WidgetState, WidgetAction, SDKConfiguration } from '../types/core';\r\nimport { BellComponent } from './BellComponent';\r\nimport { InboxPopover } from './InboxPopover';\r\nimport { NotificationWidgetErrorBoundary } from './ErrorBoundary';\r\nimport { ComponentErrorBoundary } from './ComponentErrorBoundary';\r\nimport { SDKConnectionFallback, LoadingFallback } from './FallbackComponents';\r\nimport { useLivePreferences } from '../hooks/useLivePreferences';\r\nimport { usePreferencesSync } from '../hooks/usePreferencesSync';\r\nimport { useWorkflows } from '../hooks/useWorkflows';\r\nimport { createNotificationMapper } from '../utils/notification-mapper';\r\n\r\ninterface SDKContextType {\r\n client: any;\r\n isInitialized: boolean;\r\n error: Error | null;\r\n}\r\n\r\nconst SDKContext = createContext<SDKContextType | null>(null);\r\n\r\nexport const useSDK = () => {\r\n const context = useContext(SDKContext);\r\n if (!context) {\r\n throw new Error('useSDK must be used within a NotificationWidget');\r\n }\r\n return context;\r\n};\r\n\r\nconst initialState: WidgetState = {\r\n notifications: [],\r\n unreadCount: 0,\r\n preferences: {\r\n channels: {\r\n email: true,\r\n push: true,\r\n sms: false,\r\n inApp: true,\r\n },\r\n subscriptions: [],\r\n deliverySchedule: {\r\n timezone: 'UTC',\r\n quietHours: {\r\n start: '22:00',\r\n end: '08:00',\r\n },\r\n weekdays: [true, true, true, true, true, false, false],\r\n },\r\n },\r\n ui: {\r\n isOpen: false,\r\n currentView: 'notifications',\r\n selectedNotifications: [],\r\n isLoading: false,\r\n error: null,\r\n },\r\n websocket: {\r\n connected: false,\r\n reconnecting: false,\r\n },\r\n};\r\n\r\nconst SDKProvider: React.FC<{ config: SDKConfiguration; children: React.ReactNode }> = ({\r\n config,\r\n children,\r\n}) => {\r\n const [sdkState, setSdkState] = React.useState<SDKContextType>({\r\n client: null,\r\n isInitialized: false,\r\n error: null,\r\n });\r\n\r\n useEffect(() => {\r\n let isMounted = true;\r\n\r\n const initializeSDK = async () => {\r\n try {\r\n const existingSDK = (window as any).__notificationSDK;\r\n\r\n // Check if we can reuse the existing SDK instance\r\n if (existingSDK?.client) {\r\n // Compare new config with existing config to determine if we need to re-initialize\r\n // We use simple JSON stringify as configs are simple objects with strings/numbers\r\n const isConfigMatch = JSON.stringify(existingSDK.config) === JSON.stringify(config);\r\n\r\n if (isConfigMatch) {\r\n if (isMounted) {\r\n setSdkState({\r\n client: existingSDK.client,\r\n isInitialized: true,\r\n error: null,\r\n });\r\n }\r\n return;\r\n } else {\r\n console.log('[NotificationWidget] Config changed, re-initializing SDK', { old: existingSDK.config, new: config });\r\n }\r\n }\r\n\r\n const client = new NotificationClient({\r\n apiUrl: config.baseUrl,\r\n apiKey: config.apiKey,\r\n tenantId: config.tenantId,\r\n environmentId: config.environmentId,\r\n });\r\n\r\n (window as any).__notificationSDK = { client, config };\r\n\r\n if (isMounted) {\r\n setSdkState({\r\n client,\r\n isInitialized: true,\r\n error: null,\r\n });\r\n }\r\n } catch (error) {\r\n console.error('Failed to initialize SDK:', error);\r\n if (isMounted) {\r\n setSdkState({\r\n client: null,\r\n isInitialized: false,\r\n error: error as Error,\r\n });\r\n }\r\n }\r\n };\r\n\r\n initializeSDK();\r\n\r\n return () => {\r\n isMounted = false;\r\n };\r\n }, [config]);\r\n\r\n return (\r\n <SDKContext.Provider value={sdkState}>\r\n {children}\r\n </SDKContext.Provider>\r\n );\r\n};\r\n\r\nconst widgetReducer = (state: WidgetState, action: WidgetAction): WidgetState => {\r\n switch (action.type) {\r\n case 'SET_NOTIFICATIONS':\r\n return {\r\n ...state,\r\n notifications: action.payload,\r\n unreadCount: action.payload.filter(n => !n.isRead).length,\r\n };\r\n\r\n case 'ADD_NOTIFICATION':\r\n const newNotifications = [action.payload, ...state.notifications];\r\n return {\r\n ...state,\r\n notifications: newNotifications,\r\n unreadCount: newNotifications.filter(n => !n.isRead).length,\r\n };\r\n\r\n case 'UPDATE_NOTIFICATION':\r\n const updatedNotifications = state.notifications.map(n =>\r\n n.id === action.payload.id ? { ...n, ...action.payload.updates } : n\r\n );\r\n return {\r\n ...state,\r\n notifications: updatedNotifications,\r\n unreadCount: updatedNotifications.filter(n => !n.isRead).length,\r\n };\r\n\r\n case 'DELETE_NOTIFICATION':\r\n const filteredNotifications = state.notifications.filter(n => n.id !== action.payload);\r\n return {\r\n ...state,\r\n notifications: filteredNotifications,\r\n unreadCount: filteredNotifications.filter(n => !n.isRead).length,\r\n };\r\n\r\n case 'SET_PREFERENCES':\r\n return {\r\n ...state,\r\n preferences: action.payload,\r\n };\r\n\r\n case 'SET_UI_STATE':\r\n return {\r\n ...state,\r\n ui: { ...state.ui, ...action.payload },\r\n };\r\n\r\n case 'SET_WEBSOCKET_STATE':\r\n return {\r\n ...state,\r\n websocket: { ...state.websocket, ...action.payload },\r\n };\r\n\r\n default:\r\n return state;\r\n }\r\n};\r\n\r\nconst NotificationWidgetInternal: React.FC<Omit<NotificationWidgetProps, 'sdkConfig'>> = ({\r\n position = 'right',\r\n size = 'medium',\r\n theme = 'light',\r\n className = '',\r\n onError,\r\n}) => {\r\n const [state, dispatch] = useReducer(widgetReducer, initialState);\r\n const { client, isInitialized, error: sdkError } = useSDK();\r\n const websocketRef = useRef<any>(null);\r\n\r\n const handlePreferencesChange = useCallback((preferences: any) => {\r\n dispatch({\r\n type: 'SET_PREFERENCES',\r\n payload: preferences,\r\n });\r\n }, []);\r\n\r\n const handleWidgetError = useCallback((error: Error) => {\r\n console.error('Widget error:', error);\r\n if (onError) {\r\n onError(error);\r\n }\r\n }, [onError]);\r\n\r\n const { isLoading: isPreferencesLoading, error: preferencesLoadError } = usePreferencesSync({\r\n onPreferencesLoaded: handlePreferencesChange,\r\n onError: handleWidgetError,\r\n });\r\n\r\n // Load available workflows to populate subscription preferences\r\n const { workflows, isLoading: isWorkflowsLoading } = useWorkflows();\r\n\r\n const { updatePreference, isSaving, error: preferencesError } = useLivePreferences({\r\n preferences: state.preferences,\r\n onPreferencesChange: handlePreferencesChange,\r\n onError: handleWidgetError,\r\n });\r\n\r\n // Merge workflows into preferences subscriptions when they load\r\n useEffect(() => {\r\n if (!isWorkflowsLoading && workflows.length > 0) {\r\n const updatedSubscriptions = workflows.map(wf => {\r\n // Find existing preference for this workflow\r\n const existing = state.preferences.subscriptions.find(s => s.workflowId === wf.workflowId);\r\n\r\n return existing || {\r\n workflowId: wf.workflowId,\r\n name: wf.name,\r\n enabled: true, // Default to enabled\r\n channels: {\r\n email: true,\r\n push: true,\r\n sms: false,\r\n inApp: true,\r\n },\r\n };\r\n });\r\n\r\n // Only update if different to avoid infinite loops\r\n if (JSON.stringify(updatedSubscriptions) !== JSON.stringify(state.preferences.subscriptions)) {\r\n dispatch({\r\n type: 'SET_PREFERENCES',\r\n payload: {\r\n ...state.preferences,\r\n subscriptions: updatedSubscriptions,\r\n },\r\n });\r\n }\r\n }\r\n }, [workflows, isWorkflowsLoading, state.preferences]);\r\n\r\n const handleWebSocketEvent = useCallback((event: any) => {\r\n try {\r\n const notificationMapper = createNotificationMapper();\r\n\r\n switch (event.type) {\r\n case 'notification_received': {\r\n const wsPayload = event.data;\r\n\r\n if (!notificationMapper.validateWebSocketPayload(wsPayload)) {\r\n console.error('Invalid WebSocket notification payload, skipping', wsPayload);\r\n break;\r\n }\r\n\r\n const mappedNotification = notificationMapper.toWidgetNotificationFromWebSocket(wsPayload);\r\n dispatch({\r\n type: 'ADD_NOTIFICATION',\r\n payload: mappedNotification,\r\n });\r\n break;\r\n }\r\n\r\n case 'notification_updated':\r\n dispatch({\r\n type: 'UPDATE_NOTIFICATION',\r\n payload: {\r\n id: event.data.id || event.data.notificationId,\r\n updates: event.data,\r\n },\r\n });\r\n break;\r\n\r\n case 'notification_deleted':\r\n dispatch({\r\n type: 'DELETE_NOTIFICATION',\r\n payload: event.data.id || event.data.notificationId,\r\n });\r\n break;\r\n\r\n case 'preferences_updated':\r\n dispatch({\r\n type: 'SET_PREFERENCES',\r\n payload: event.data,\r\n });\r\n break;\r\n\r\n default:\r\n console.log('Unknown WebSocket event type:', event.type);\r\n }\r\n } catch (error) {\r\n console.error('Error handling WebSocket event:', error);\r\n }\r\n }, []);\r\n\r\n const connectWebSocket = useCallback(async () => {\r\n if (!client || !isInitialized || websocketRef.current) return;\r\n\r\n try {\r\n dispatch({\r\n type: 'SET_WEBSOCKET_STATE',\r\n payload: { reconnecting: true },\r\n });\r\n\r\n const sdkConfig = (window as any).__notificationSDK?.config;\r\n if (!sdkConfig) {\r\n throw new Error('SDK configuration not available for WebSocket connection');\r\n }\r\n\r\n const baseUrl = client.getApiHost();\r\n const namespace = '/v1/notifications';\r\n const fullUrl = `${baseUrl}${namespace}`;\r\n\r\n console.log('Connecting to Socket.IO at:', fullUrl);\r\n\r\n const socket = ioClient(fullUrl, {\r\n query: {\r\n tenantId: sdkConfig.tenantId,\r\n subscriberId: sdkConfig.subscriberId,\r\n environmentId: sdkConfig.environmentId,\r\n },\r\n transports: ['websocket'],\r\n autoConnect: false,\r\n reconnection: true,\r\n reconnectionAttempts: 10,\r\n reconnectionDelay: 1000,\r\n reconnectionDelayMax: 5000,\r\n });\r\n\r\n websocketRef.current = socket;\r\n\r\n socket.on('notification', (payload: any) => {\r\n console.log('Received notification:', payload);\r\n handleWebSocketEvent({\r\n type: 'notification_received',\r\n data: payload,\r\n });\r\n });\r\n\r\n socket.on('connect', () => {\r\n console.log('Socket.IO connected successfully');\r\n dispatch({\r\n type: 'SET_WEBSOCKET_STATE',\r\n payload: { connected: true, reconnecting: false },\r\n });\r\n });\r\n\r\n socket.on('disconnect', (reason: any) => {\r\n console.log('Socket.IO disconnected:', reason);\r\n dispatch({\r\n type: 'SET_WEBSOCKET_STATE',\r\n payload: { connected: false, reconnecting: false },\r\n });\r\n });\r\n\r\n socket.on('reconnect_attempt', (attempt: any) => {\r\n console.log('Socket.IO reconnection attempt:', attempt);\r\n dispatch({\r\n type: 'SET_WEBSOCKET_STATE',\r\n payload: { connected: false, reconnecting: true },\r\n });\r\n });\r\n\r\n socket.on('connect_error', (error: any) => {\r\n console.error('Socket.IO connection error:', error);\r\n dispatch({\r\n type: 'SET_WEBSOCKET_STATE',\r\n payload: { connected: false, reconnecting: false },\r\n });\r\n if (onError) {\r\n onError(error);\r\n }\r\n });\r\n\r\n socket.connect();\r\n\r\n } catch (error) {\r\n console.error('Failed to connect WebSocket:', error);\r\n dispatch({\r\n type: 'SET_WEBSOCKET_STATE',\r\n payload: { connected: false, reconnecting: false },\r\n });\r\n if (onError) {\r\n onError(error as Error);\r\n }\r\n }\r\n }, [client, isInitialized, handleWebSocketEvent, onError]);\r\n\r\n const disconnectWebSocket = useCallback(() => {\r\n if (websocketRef.current) {\r\n try {\r\n if (websocketRef.current.disconnect) {\r\n websocketRef.current.disconnect();\r\n }\r\n websocketRef.current = null;\r\n dispatch({\r\n type: 'SET_WEBSOCKET_STATE',\r\n payload: { connected: false, reconnecting: false },\r\n });\r\n } catch (error) {\r\n console.error('Error disconnecting WebSocket:', error);\r\n }\r\n }\r\n }, []);\r\n\r\n const handleBellClick = useCallback(() => {\r\n dispatch({\r\n type: 'SET_UI_STATE',\r\n payload: { isOpen: !state.ui.isOpen },\r\n });\r\n }, [state.ui.isOpen]);\r\n\r\n const handlePopoverClose = useCallback(() => {\r\n dispatch({\r\n type: 'SET_UI_STATE',\r\n payload: { isOpen: false },\r\n });\r\n }, []);\r\n\r\n const handleViewChange = useCallback((view: 'notifications' | 'preferences') => {\r\n dispatch({\r\n type: 'SET_UI_STATE',\r\n payload: { currentView: view },\r\n });\r\n }, []);\r\n\r\n const handleNotificationAction = useCallback(async (id: string, action: any) => {\r\n if (!client || !isInitialized) {\r\n console.error('SDK not initialized');\r\n return;\r\n }\r\n\r\n const sdkConfig = (window as any).__notificationSDK?.config;\r\n if (!sdkConfig) {\r\n console.error('SDK configuration not available');\r\n return;\r\n }\r\n\r\n if (!id) {\r\n console.error('notificationId is required');\r\n throw new Error('notificationId is required');\r\n }\r\n\r\n try {\r\n switch (action.type) {\r\n case 'mark_read':\r\n await client.inbox.markAsRead(id, sdkConfig.tenantId, sdkConfig.environmentId, sdkConfig.subscriberId);\r\n break;\r\n case 'mark_unread':\r\n await client.inbox.markAsUnread(id, sdkConfig.tenantId, sdkConfig.environmentId, sdkConfig.subscriberId);\r\n break;\r\n case 'archive':\r\n await client.inbox.archive(id, sdkConfig.tenantId, sdkConfig.environmentId, sdkConfig.subscriberId);\r\n break;\r\n case 'delete':\r\n await client.inbox.delete(id, sdkConfig.tenantId, sdkConfig.environmentId, sdkConfig.subscriberId);\r\n break;\r\n default:\r\n if (action.handler) {\r\n await action.handler(id);\r\n }\r\n break;\r\n }\r\n\r\n switch (action.type) {\r\n case 'mark_read':\r\n dispatch({\r\n type: 'UPDATE_NOTIFICATION',\r\n payload: { id, updates: { isRead: true } },\r\n });\r\n break;\r\n case 'mark_unread':\r\n dispatch({\r\n type: 'UPDATE_NOTIFICATION',\r\n payload: { id, updates: { isRead: false } },\r\n });\r\n break;\r\n case 'archive':\r\n dispatch({\r\n type: 'UPDATE_NOTIFICATION',\r\n payload: { id, updates: { isArchived: true } },\r\n });\r\n break;\r\n case 'delete':\r\n dispatch({\r\n type: 'DELETE_NOTIFICATION',\r\n payload: id,\r\n });\r\n break;\r\n }\r\n } catch (error) {\r\n console.error('Error performing notification action:', error);\r\n if (onError) {\r\n onError(error as Error);\r\n }\r\n }\r\n }, [client]);\r\n\r\n useEffect(() => {\r\n if (!client || !isInitialized) return;\r\n\r\n const loadNotifications = async () => {\r\n try {\r\n dispatch({\r\n type: 'SET_UI_STATE',\r\n payload: { isLoading: true },\r\n });\r\n\r\n const sdkConfig = (window as any).__notificationSDK?.config;\r\n if (!sdkConfig) {\r\n throw new Error('SDK configuration not available');\r\n }\r\n\r\n const notificationMapper = createNotificationMapper();\r\n const response = await client.inbox.getRenderedNotifications(\r\n {\r\n channel: 'in_app',\r\n limit: 50,\r\n offset: 0,\r\n },\r\n sdkConfig.tenantId,\r\n sdkConfig.environmentId,\r\n sdkConfig.subscriberId,\r\n );\r\n\r\n const coreNotifications = (response?.items || []).map((item: any) =>\r\n notificationMapper.toWidgetNotification(item)\r\n );\r\n\r\n dispatch({\r\n type: 'SET_NOTIFICATIONS',\r\n payload: coreNotifications,\r\n });\r\n\r\n dispatch({\r\n type: 'SET_UI_STATE',\r\n payload: { isLoading: false, error: null },\r\n });\r\n } catch (error) {\r\n console.error('Failed to load notifications:', error);\r\n dispatch({\r\n type: 'SET_UI_STATE',\r\n payload: {\r\n isLoading: false,\r\n error: (error as Error)\r\n },\r\n });\r\n if (onError) {\r\n onError(error as Error);\r\n }\r\n }\r\n };\r\n\r\n loadNotifications();\r\n }, [client, isInitialized, onError]);\r\n\r\n useEffect(() => {\r\n if (client && isInitialized) {\r\n connectWebSocket();\r\n }\r\n\r\n return () => {\r\n disconnectWebSocket();\r\n };\r\n }, [client]);\r\n\r\n useEffect(() => {\r\n if (!client || !isInitialized) return;\r\n\r\n if (state.websocket.connected) return;\r\n\r\n const pollInterval = setInterval(async () => {\r\n try {\r\n const sdkConfig = (window as any).__notificationSDK?.config;\r\n if (!sdkConfig) {\r\n return;\r\n }\r\n\r\n const notificationMapper = createNotificationMapper();\r\n const response = await client.inbox.getRenderedNotifications(\r\n {\r\n channel: 'in_app',\r\n limit: 50,\r\n offset: 0,\r\n },\r\n sdkConfig.tenantId,\r\n sdkConfig.environmentId,\r\n sdkConfig.subscriberId,\r\n );\r\n\r\n const coreNotifications = (response?.items || []).map((item: any) =>\r\n notificationMapper.toWidgetNotification(item)\r\n );\r\n\r\n dispatch({\r\n type: 'SET_NOTIFICATIONS',\r\n payload: coreNotifications,\r\n });\r\n } catch (error) {\r\n console.error('Polling failed:', error);\r\n }\r\n }, 30000);\r\n\r\n return () => clearInterval(pollInterval);\r\n }, [client, state.websocket.connected]);\r\n\r\n useEffect(() => {\r\n const handleStorageChange = (event: StorageEvent) => {\r\n if (event.key === 'notification_widget_sync' && event.newValue) {\r\n try {\r\n const syncData = JSON.parse(event.newValue);\r\n handleWebSocketEvent(syncData);\r\n } catch (error) {\r\n console.error('Error parsing sync data:', error);\r\n }\r\n }\r\n };\r\n\r\n window.addEventListener('storage', handleStorageChange);\r\n return () => window.removeEventListener('storage', handleStorageChange);\r\n }, [handleWebSocketEvent]);\r\n\r\n useEffect(() => {\r\n dispatch({\r\n type: 'SET_UI_STATE',\r\n payload: { isLoading: isSaving },\r\n });\r\n }, [isSaving]);\r\n\r\n useEffect(() => {\r\n const error = sdkError || preferencesError || preferencesLoadError;\r\n if (error) {\r\n dispatch({\r\n type: 'SET_UI_STATE',\r\n payload: { error: error },\r\n });\r\n }\r\n }, [sdkError, preferencesError, preferencesLoadError]);\r\n\r\n if (!isInitialized && !sdkError) {\r\n return (\r\n <div\r\n className={`relative inline-block ${className}`}\r\n data-widget-size={size || 'small'}\r\n data-theme={theme}\r\n data-testid=\"notification-widget\"\r\n >\r\n <ComponentErrorBoundary componentName=\"BellComponent\">\r\n <BellComponent\r\n unreadCount={0}\r\n onClick={() => { }}\r\n size={size}\r\n disabled={true}\r\n />\r\n </ComponentErrorBoundary>\r\n </div>\r\n );\r\n }\r\n\r\n if (sdkError) {\r\n return (\r\n <div\r\n className={`relative inline-block ${className}`}\r\n data-widget-size={size || 'small'}\r\n data-theme={theme}\r\n data-testid=\"notification-widget\"\r\n >\r\n <ComponentErrorBoundary\r\n componentName=\"BellComponent\"\r\n fallback={\r\n <SDKConnectionFallback\r\n error={sdkError.message}\r\n onRetry={() => window.location.reload()}\r\n />\r\n }\r\n >\r\n <BellComponent\r\n unreadCount={0}\r\n onClick={() => { }}\r\n size={size}\r\n disabled={true}\r\n />\r\n </ComponentErrorBoundary>\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div\r\n className={`relative inline-block ${className}`}\r\n data-widget-size={size || 'small'}\r\n data-theme={theme}\r\n data-testid=\"notification-widget\"\r\n >\r\n <ComponentErrorBoundary componentName=\"BellComponent\">\r\n <BellComponent\r\n unreadCount={state.unreadCount}\r\n onClick={handleBellClick}\r\n size={size}\r\n disabled={state.ui.isLoading}\r\n />\r\n </ComponentErrorBoundary>\r\n\r\n <ComponentErrorBoundary\r\n componentName=\"InboxPopover\"\r\n fallback={<LoadingFallback message=\"Unable to load notifications\" />}\r\n >\r\n <InboxPopover\r\n isOpen={state.ui.isOpen}\r\n onClose={handlePopoverClose}\r\n position={position}\r\n currentView={state.ui.currentView}\r\n onViewChange={handleViewChange}\r\n notifications={state.notifications}\r\n onNotificationAction={handleNotificationAction}\r\n preferences={state.preferences}\r\n onPreferenceChange={updatePreference}\r\n isPreferencesLoading={isSaving}\r\n />\r\n </ComponentErrorBoundary>\r\n </div>\r\n );\r\n};\r\n\r\nexport const NotificationWidget: React.FC<NotificationWidgetProps> = ({\r\n sdkConfig,\r\n ...props\r\n}) => {\r\n return (\r\n <NotificationWidgetErrorBoundary onError={props.onError}>\r\n <SDKProvider config={sdkConfig}>\r\n <NotificationWidgetInternal {...props} />\r\n </SDKProvider>\r\n </NotificationWidgetErrorBoundary>\r\n );\r\n};","export { NotificationWidget } from './components/NotificationWidget';\r\n\r\nexport { BellComponent } from './components/BellComponent';\r\nexport { InboxPopover } from './components/InboxPopover';\r\nexport { NotificationItem } from './components/NotificationItem';\r\nexport { PreferencesView } from './components/PreferencesView';\r\n\r\nexport { NotificationWidgetErrorBoundary } from './components/ErrorBoundary';\r\n\r\nexport type * from './types/core';\r\n\r\nexport type { Notification as SDKNotification, NotificationFilters } from '@edusight/notification-sdk';\r\n\r\nimport './styles/index.css';\r\n\r\nexport const VERSION = '3.0.0';\r\nexport const WIDGET_NAME = '@edusight/notification-widget';"],"names":["ErrorFallback","error","onRetry","jsxs","jsx","MdError","MdRefresh","NotificationWidgetErrorBoundary","Component","props","errorInfo","useNotificationsClient","usePreferencesSync","onPreferencesLoaded","onError","notificationClient","isLoading","setIsLoading","useState","setError","preferences","setPreferences","loadPreferences","useCallback","config","subscriberId","tenantId","environmentId","servicePreferences","mappedPreferences","workflowId","categoryPrefs","err","defaultPreferences","useEffect","useWorkflows","workflows","setWorkflows","loadWorkflows","mappedWorkflows","wf","SDKContext","createContext","useSDK","context","useContext","initialState","SDKProvider","children","sdkState","setSdkState","React","isMounted","existingSDK","client","NotificationClient","widgetReducer","state","action","n","newNotifications","updatedNotifications","filteredNotifications","NotificationWidgetInternal","position","size","theme","className","dispatch","useReducer","isInitialized","sdkError","websocketRef","useRef","handlePreferencesChange","handleWidgetError","preferencesLoadError","isWorkflowsLoading","updatePreference","isSaving","preferencesError","useLivePreferences","updatedSubscriptions","s","handleWebSocketEvent","event","notificationMapper","createNotificationMapper","wsPayload","mappedNotification","connectWebSocket","sdkConfig","fullUrl","socket","ioClient","payload","reason","attempt","disconnectWebSocket","handleBellClick","handlePopoverClose","handleViewChange","view","handleNotificationAction","id","coreNotifications","item","pollInterval","handleStorageChange","syncData","ComponentErrorBoundary","BellComponent","SDKConnectionFallback","LoadingFallback","InboxPopover","NotificationWidget","VERSION","WIDGET_NAME"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@edusight/notification-widget",
3
- "version": "1.0.28",
3
+ "version": "1.0.30",
4
4
  "type": "module",
5
5
  "description": "React notification center widget for EduSight Notification Service, aligned with Novu's React UI and functionalities",
6
6
  "main": "./dist/index.cjs.js",
@@ -13,8 +13,8 @@
13
13
  "import": "./dist/index.esm.js",
14
14
  "require": "./dist/index.cjs.js"
15
15
  },
16
- "./styles": "./dist/style.css",
17
- "./styles.css": "./dist/style.css"
16
+ "./styles": "./dist/index.css",
17
+ "./styles.css": "./dist/index.css"
18
18
  },
19
19
  "files": [
20
20
  "dist",
@@ -1,72 +0,0 @@
1
- "use strict";const h=require("react"),e=require("react/jsx-runtime");var q={color:void 0,size:void 0,className:void 0,style:void 0,attr:void 0},D=h.createContext&&h.createContext(q),ae=["attr","size","title"];function ne(t,r){if(t==null)return{};var s=ie(t,r),a,n;if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(t);for(n=0;n<l.length;n++)a=l[n],!(r.indexOf(a)>=0)&&Object.prototype.propertyIsEnumerable.call(t,a)&&(s[a]=t[a])}return s}function ie(t,r){if(t==null)return{};var s={};for(var a in t)if(Object.prototype.hasOwnProperty.call(t,a)){if(r.indexOf(a)>=0)continue;s[a]=t[a]}return s}function M(){return M=Object.assign?Object.assign.bind():function(t){for(var r=1;r<arguments.length;r++){var s=arguments[r];for(var a in s)Object.prototype.hasOwnProperty.call(s,a)&&(t[a]=s[a])}return t},M.apply(this,arguments)}function V(t,r){var s=Object.keys(t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(t);r&&(a=a.filter(function(n){return Object.getOwnPropertyDescriptor(t,n).enumerable})),s.push.apply(s,a)}return s}function z(t){for(var r=1;r<arguments.length;r++){var s=arguments[r]!=null?arguments[r]:{};r%2?V(Object(s),!0).forEach(function(a){le(t,a,s[a])}):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(s)):V(Object(s)).forEach(function(a){Object.defineProperty(t,a,Object.getOwnPropertyDescriptor(s,a))})}return t}function le(t,r,s){return r=oe(r),r in t?Object.defineProperty(t,r,{value:s,enumerable:!0,configurable:!0,writable:!0}):t[r]=s,t}function oe(t){var r=de(t,"string");return typeof r=="symbol"?r:r+""}function de(t,r){if(typeof t!="object"||!t)return t;var s=t[Symbol.toPrimitive];if(s!==void 0){var a=s.call(t,r);if(typeof a!="object")return a;throw new TypeError("@@toPrimitive must return a primitive value.")}return(r==="string"?String:Number)(t)}function G(t){return t&&t.map((r,s)=>h.createElement(r.tag,z({key:s},r.attr),G(r.child)))}function w(t){return r=>h.createElement(ce,M({attr:z({},t.attr)},r),G(t.child))}function ce(t){var r=s=>{var{attr:a,size:n,title:l}=t,m=ne(t,ae),f=n||s.size||"1em",x;return s.className&&(x=s.className),t.className&&(x=(x?x+" ":"")+t.className),h.createElement("svg",M({stroke:"currentColor",fill:"currentColor",strokeWidth:"0"},s.attr,a,m,{className:x,style:z(z({color:t.color||s.color},s.style),t.style),height:f,width:f,xmlns:"http://www.w3.org/2000/svg"}),l&&h.createElement("title",null,l),t.children)};return D!==void 0?h.createElement(D.Consumer,null,s=>r(s)):r(q)}function ue(t){return w({attr:{viewBox:"0 0 512 512"},child:[{tag:"path",attr:{d:"M257 120.471c7.083 0 23.911 4.479 23.911 4.479 45.589 10.447 77.678 52.439 77.678 99.85V352.412l9.321 9.364 7.788 7.823H136.302l7.788-7.823 9.321-9.364V224.8c0-47.41 32.089-89.403 77.678-99.85 0 0 18.043-4.479 23.911-4.479M256 48c-17.602 0-31.059 13.518-31.059 31.2v14.559c-59.015 13.523-103.53 67.601-103.53 131.041v114.4L80 380.8v20.8h352v-20.8l-41.411-41.6V224.8c0-63.44-44.516-117.518-103.53-131.041V79.2c0-17.682-13.457-31.2-31.059-31.2zm41.411 374.4h-82.823c0 22.881 18.633 41.6 41.412 41.6s41.411-18.719 41.411-41.6z"},child:[]}]})(t)}const he=({unreadCount:t,onClick:r,size:s,className:a="",disabled:n=!1})=>{const l=o=>o===0?"":o>99?"99+":o.toString(),m=o=>{n||(o.key==="Enter"||o.key===" ")&&(o.preventDefault(),r())},f=l(t),x=t>0;return e.jsxs("button",{type:"button",className:`
2
- relative inline-flex items-center justify-center
3
- rounded-full
4
- text-[var(--widget-text-secondary)] hover:text-[var(--widget-text)]
5
- bg-transparent hover:bg-[var(--widget-bg-hover)]
6
- border-0 cursor-pointer
7
- transition-colors duration-300
8
- focus:outline-none focus:ring-1 focus:ring-[var(--widget-primary)] focus:ring-offset-1
9
- disabled:opacity-70 disabled:cursor-not-allowed
10
- w-10 h-10
11
- ${a}
12
- `,onClick:r,onKeyDown:m,disabled:n,"aria-label":x?`Notifications (${t} unread)`:"Notifications","aria-expanded":!1,"aria-haspopup":"dialog","data-testid":"bell-component",children:[e.jsx(ue,{className:"w-6 h-6"}),x&&e.jsx("span",{className:`
13
- absolute top-1 right-1
14
- inline-flex items-center justify-center
15
- min-w-[17px] h-[17px]
16
- px-1
17
- text-[8px] font-bold leading-none
18
- text-white bg-[var(--widget-primary)]
19
- rounded-full
20
- animate-in zoom-in-50 duration-300
21
- `,"aria-hidden":"true","data-testid":"unread-badge",children:f}),e.jsx("span",{className:"sr-only",children:x?`${t} unread notifications`:"No unread notifications"})]})};function O(t){return w({attr:{viewBox:"0 0 24 24"},child:[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"},child:[]},{tag:"path",attr:{d:"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"},child:[]}]})(t)}function me(t){return w({attr:{viewBox:"0 0 24 24"},child:[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"},child:[]},{tag:"path",attr:{d:"M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"},child:[]}]})(t)}function xe(t){return w({attr:{viewBox:"0 0 24 24"},child:[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"},child:[]},{tag:"path",attr:{d:"M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z"},child:[]},{tag:"path",attr:{d:"M12.5 7H11v6l5.25 3.15.75-1.23-4.5-2.67z"},child:[]}]})(t)}function fe(t){return w({attr:{viewBox:"0 0 24 24"},child:[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"},child:[]},{tag:"path",attr:{d:"M15.5 14h-.79l-.28-.27A6.471 6.471 0 0 0 16 9.5 6.5 6.5 0 1 0 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"},child:[]}]})(t)}function Y(t){return w({attr:{viewBox:"0 0 24 24"},child:[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0V0z"},child:[]},{tag:"path",attr:{d:"M19.14 12.94c.04-.3.06-.61.06-.94 0-.32-.02-.64-.07-.94l2.03-1.58a.49.49 0 0 0 .12-.61l-1.92-3.32a.488.488 0 0 0-.59-.22l-2.39.96c-.5-.38-1.03-.7-1.62-.94l-.36-2.54a.484.484 0 0 0-.48-.41h-3.84c-.24 0-.43.17-.47.41l-.36 2.54c-.59.24-1.13.57-1.62.94l-2.39-.96c-.22-.08-.47 0-.59.22L2.74 8.87c-.12.21-.08.47.12.61l2.03 1.58c-.05.3-.09.63-.09.94s.02.64.07.94l-2.03 1.58a.49.49 0 0 0-.12.61l1.92 3.32c.12.22.37.29.59.22l2.39-.96c.5.38 1.03.7 1.62.94l.36 2.54c.05.24.24.41.48.41h3.84c.24 0 .44-.17.47-.41l.36-2.54c.59-.24 1.13-.56 1.62-.94l2.39.96c.22.08.47 0 .59-.22l1.92-3.32c.12-.22.07-.47-.12-.61l-2.01-1.58zM12 15.6c-1.98 0-3.6-1.62-3.6-3.6s1.62-3.6 3.6-3.6 3.6 1.62 3.6 3.6-1.62 3.6-3.6 3.6z"},child:[]}]})(t)}function ge(t){return w({attr:{viewBox:"0 0 24 24"},child:[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"},child:[]},{tag:"path",attr:{d:"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z"},child:[]}]})(t)}function pe(t){return w({attr:{viewBox:"0 0 24 24"},child:[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"},child:[]},{tag:"path",attr:{d:"M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z"},child:[]}]})(t)}function ve(t){return w({attr:{viewBox:"0 0 24 24"},child:[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"},child:[]},{tag:"path",attr:{d:"M20 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 4-8 5-8-5V6l8 5 8-5v2z"},child:[]}]})(t)}function J(t){return w({attr:{viewBox:"0 0 24 24"},child:[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"},child:[]},{tag:"path",attr:{d:"m20.54 5.23-1.39-1.68C18.88 3.21 18.47 3 18 3H6c-.47 0-.88.21-1.16.55L3.46 5.23C3.17 5.57 3 6.02 3 6.5V19c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V6.5c0-.48-.17-.93-.46-1.27zM12 17.5 6.5 12H10v-2h4v2h3.5L12 17.5zM5.12 5l.81-1h12l.94 1H5.12z"},child:[]}]})(t)}function be(t){return w({attr:{viewBox:"0 0 24 24"},child:[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"},child:[]},{tag:"path",attr:{d:"M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z"},child:[]},{tag:"path",attr:{d:"M12.5 7H11v6l5.25 3.15.75-1.23-4.5-2.67z"},child:[]}]})(t)}function we(t){return w({attr:{viewBox:"0 0 24 24"},child:[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"},child:[]},{tag:"path",attr:{d:"M17 1.01 7 1c-1.1 0-2 .9-2 2v18c0 1.1.9 2 2 2h10c1.1 0 2-.9 2-2V3c0-1.1-.9-1.99-2-1.99zM17 19H7V5h10v14z"},child:[]}]})(t)}function ye(t){return w({attr:{viewBox:"0 0 24 24"},child:[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"},child:[]},{tag:"path",attr:{d:"m21.41 11.58-9-9C12.05 2.22 11.55 2 11 2H4c-1.1 0-2 .9-2 2v7c0 .55.22 1.05.59 1.42l9 9c.36.36.86.58 1.41.58.55 0 1.05-.22 1.41-.59l7-7c.37-.36.59-.86.59-1.41 0-.55-.23-1.06-.59-1.42zM5.5 7C4.67 7 4 6.33 4 5.5S4.67 4 5.5 4 7 4.67 7 5.5 6.33 7 5.5 7z"},child:[]}]})(t)}function je(t){return w({attr:{viewBox:"0 0 24 24"},child:[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"},child:[]},{tag:"path",attr:{d:"M20 11H7.83l5.59-5.59L12 4l-8 8 8 8 1.41-1.41L7.83 13H20v-2z"},child:[]}]})(t)}function Q(t){return w({attr:{viewBox:"0 0 24 24"},child:[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"},child:[]},{tag:"path",attr:{d:"M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"},child:[]}]})(t)}function _(t){return w({attr:{viewBox:"0 0 24 24"},child:[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"},child:[]},{tag:"path",attr:{d:"m12 8-6 6 1.41 1.41L12 10.83l4.59 4.58L18 14z"},child:[]}]})(t)}function I(t){return w({attr:{viewBox:"0 0 24 24"},child:[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"},child:[]},{tag:"path",attr:{d:"M16.59 8.59 12 13.17 7.41 8.59 6 10l6 6 6-6z"},child:[]}]})(t)}function Ne(t){return w({attr:{viewBox:"0 0 24 24"},child:[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"},child:[]},{tag:"path",attr:{d:"M17.65 6.35A7.958 7.958 0 0 0 12 4c-4.42 0-7.99 3.58-7.99 8s3.57 8 7.99 8c3.73 0 6.84-2.55 7.73-6h-2.08A5.99 5.99 0 0 1 12 18c-3.31 0-6-2.69-6-6s2.69-6 6-6c1.66 0 3.14.69 4.22 1.78L13 11h7V4l-2.35 2.35z"},child:[]}]})(t)}function ke(t){return w({attr:{viewBox:"0 0 24 24"},child:[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"},child:[]},{tag:"path",attr:{d:"M20 2H4c-1.1 0-1.99.9-1.99 2L2 22l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zM9 11H7V9h2v2zm4 0h-2V9h2v2zm4 0h-2V9h2v2z"},child:[]}]})(t)}function F(t){return w({attr:{viewBox:"0 0 24 24"},child:[{tag:"path",attr:{d:"M12 22c1.1 0 2-.9 2-2h-4a2 2 0 0 0 2 2zm6-6v-5c0-3.07-1.64-5.64-4.5-6.32V4c0-.83-.67-1.5-1.5-1.5s-1.5.67-1.5 1.5v.68C7.63 5.36 6 7.92 6 11v5l-2 2v1h16v-1l-2-2z"},child:[]}]})(t)}function Ce(t){return w({attr:{viewBox:"0 0 24 24"},child:[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"},child:[]},{tag:"path",attr:{d:"M19 5v14H5V5h14m0-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2z"},child:[]},{tag:"path",attr:{d:"M14 17H7v-2h7v2zm3-4H7v-2h10v2zm0-4H7V7h10v2z"},child:[]}]})(t)}function X(t){return w({attr:{viewBox:"0 0 24 24"},child:[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0V0z"},child:[]},{tag:"path",attr:{d:"M20 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 14H4V8l8 5 8-5v10zm-8-7L4 6h16l-8 5z"},child:[]}]})(t)}const T=({content:t,children:r,position:s="top",delay:a=200})=>{const[n,l]=h.useState(!1),[m,f]=h.useState({x:0,y:0}),x=h.useRef(null),o=h.useRef(null),y=()=>{x.current&&clearTimeout(x.current),x.current=setTimeout(()=>{if(o.current){const g=o.current.getBoundingClientRect();let i=0,c=0;switch(s){case"top":i=g.left+g.width/2,c=g.top-8;break;case"bottom":i=g.left+g.width/2,c=g.bottom+8;break;case"left":i=g.left-8,c=g.top+g.height/2;break;case"right":i=g.right+8,c=g.top+g.height/2;break}f({x:i,y:c}),l(!0)}},a)},d=()=>{x.current&&clearTimeout(x.current),l(!1)};h.useEffect(()=>()=>{x.current&&clearTimeout(x.current)},[]);const v={top:"-translate-x-1/2 -translate-y-full",bottom:"-translate-x-1/2 translate-y-0",left:"-translate-x-full -translate-y-1/2",right:"translate-x-0 -translate-y-1/2"};return e.jsxs(e.Fragment,{children:[e.jsx("div",{ref:o,onMouseEnter:y,onMouseLeave:d,className:"inline-flex",children:r}),n&&e.jsx("div",{className:`
22
- fixed z-50 px-2 py-1 text-xs font-medium text-white rounded-md pointer-events-none
23
- bg-[var(--widget-text)] shadow-lg
24
- ${v[s]}
25
- animate-in fade-in-0 zoom-in-95 duration-200
26
- `,style:{left:`${m.x}px`,top:`${m.y}px`},children:t})]})},Me=t=>{if(Number.isNaN(t.getTime()))return"Long ago";const a=new Date().getTime()-t.getTime(),n=Math.floor(a/6e4),l=Math.floor(a/36e5),m=Math.floor(a/864e5);return n<1?"Just now":n<60?`${n}m ago`:l<24?`${l}h ago`:m<7?`${m}d ago`:t.toLocaleDateString()},A=({type:t,className:r})=>{const s=r||"w-4 h-4";switch(t){case"mark_read":return e.jsx(O,{className:s});case"snooze":return e.jsx(be,{className:s});case"archive":return e.jsx(J,{className:s});default:return null}},Z=({notification:t,onActionClick:r,onSelectionChange:s,isSelected:a=!1})=>{const[n,l]=h.useState(!1),m=Number.isNaN(t.timestamp.getTime()),f=m?void 0:t.timestamp.toISOString(),x=Me(t.timestamp),o=d=>{r&&r(d),l(!1)},y=()=>{s&&s(!a)};return e.jsxs("div",{className:`
27
- relative group flex items-start gap-3 px-4 py-3 border-b border-border-light
28
- transition-all duration-200
29
- bg-widget-background hover:bg-widget-hover
30
- ${a?"bg-widget-primary-light":""}
31
- `,onMouseEnter:()=>l(!0),onMouseLeave:()=>l(!1),"data-testid":"notification-item","data-notification-id":t.id,children:[s&&e.jsx("div",{className:"flex-shrink-0 pt-0.5",children:e.jsx("input",{type:"checkbox",checked:a,onChange:y,className:"w-4 h-4 text-[var(--widget-primary)] border-[var(--widget-border)] rounded cursor-pointer focus:ring-2 focus:ring-[var(--widget-primary)] focus:ring-offset-0","aria-label":`Select notification: ${t.subject}`})}),e.jsx("div",{className:"flex-shrink-0",children:t.avatar?e.jsx("img",{src:t.avatar,alt:"",className:"w-10 h-10 rounded-full object-cover border border-border","aria-hidden":"true",loading:"lazy"}):e.jsx("div",{className:"w-10 h-10 rounded-full bg-gradient-to-br from-widget-primary to-widget-primary-hover flex items-center justify-center shadow-sm",children:e.jsx("span",{className:"text-white font-semibold text-base",children:t.subject.charAt(0).toUpperCase()})})}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsxs("div",{className:"flex items-start justify-between gap-2 mb-0.5",children:[e.jsx("h3",{className:`text-sm leading-5 text-[var(--widget-text)] ${t.isRead?"font-medium":"font-semibold"}`,children:t.subject}),!t.isRead&&e.jsx("div",{className:"flex-shrink-0 mt-1.5 ml-1",children:e.jsx("div",{className:"w-2 h-2 rounded-full bg-unread-indicator shadow-sm","aria-label":"Unread",role:"img"})})]}),e.jsx("p",{className:"text-sm text-[var(--widget-text-secondary)] line-clamp-2 leading-relaxed mb-2",children:t.body}),t.actions&&t.actions.length>0&&e.jsx("div",{className:"flex items-center gap-2 mb-2",children:t.actions.map((d,v)=>e.jsx("button",{onClick:g=>{g.stopPropagation(),o(d)},className:`
32
- px-3 py-1.5 rounded-md text-sm font-medium transition-colors
33
- ${v===0?"bg-[var(--widget-primary)] text-white hover:bg-[var(--widget-primary-hover)] shadow-sm":"bg-transparent text-[var(--widget-text-secondary)] hover:bg-[var(--widget-bg-hover)] border border-[var(--widget-border)]"}
34
- `,children:d.label},v))}),e.jsxs("div",{className:"flex items-center justify-between min-h-[20px]",children:[e.jsx("div",{className:"flex items-center gap-2",children:e.jsx("time",{className:"text-xs text-[var(--widget-text-tertiary)]",dateTime:f,children:x})}),e.jsxs("div",{className:`flex items-center gap-1 transition-opacity duration-200 ${n?"opacity-100":"opacity-0"}`,onClick:d=>d.stopPropagation(),children:[e.jsx(T,{content:"Mark as read",position:"top",children:e.jsx("button",{className:"inline-flex items-center justify-center w-7 h-7 rounded-md text-[var(--widget-text-secondary)] hover:text-[var(--widget-text)] hover:bg-[var(--widget-bg-hover)] transition-colors",onClick:()=>o({type:"mark_read",label:"Mark as read",handler:async()=>{}}),"aria-label":"Mark as read",children:e.jsx(A,{type:"mark_read"})})}),e.jsx(T,{content:"Snooze",position:"top",children:e.jsx("button",{className:"inline-flex items-center justify-center w-7 h-7 rounded-md text-[var(--widget-text-secondary)] hover:text-[var(--widget-text)] hover:bg-[var(--widget-bg-hover)] transition-colors",onClick:()=>o({type:"custom",label:"Snooze",handler:async()=>{}}),"aria-label":"Snooze",children:e.jsx(A,{type:"snooze"})})}),e.jsx(T,{content:"Archive",position:"top",children:e.jsx("button",{className:"inline-flex items-center justify-center w-7 h-7 rounded-md text-[var(--widget-text-secondary)] hover:text-[var(--widget-text)] hover:bg-[var(--widget-bg-hover)] transition-colors",onClick:()=>o({type:"archive",label:"Archive",handler:async()=>{}}),"aria-label":"Archive",children:e.jsx(A,{type:"archive"})})})]})]})]}),e.jsxs("div",{className:"sr-only",children:["Notification from ",m?"Unknown time":t.timestamp.toLocaleString(),".",t.isRead?"Read":"Unread",".",t.isArchived?"Archived":"Active","."]})]})},W=({count:t=3})=>e.jsx(e.Fragment,{children:Array.from({length:t}).map((r,s)=>e.jsxs("div",{className:"flex items-start gap-3 px-4 py-3 border-b border-border-light animate-pulse",children:[e.jsx("div",{className:"flex-shrink-0",children:e.jsx("div",{className:"w-10 h-10 rounded-full bg-widget-hover"})}),e.jsxs("div",{className:"flex-1 space-y-2",children:[e.jsx("div",{className:"h-4 w-3/4 rounded bg-widget-hover"}),e.jsxs("div",{className:"space-y-1",children:[e.jsx("div",{className:"h-3 w-full rounded bg-widget-hover"}),e.jsx("div",{className:"h-3 w-5/6 rounded bg-widget-hover"})]}),e.jsx("div",{className:"h-3 w-16 rounded bg-widget-hover"})]}),e.jsx("div",{className:"flex-shrink-0",children:e.jsx("div",{className:"w-2 h-2 rounded-full bg-widget-hover"})})]},s))}),K=({title:t="No Items",description:r="There are no items to display",icon:s})=>e.jsxs("div",{className:"flex flex-col items-center justify-center py-8 px-4",children:[s&&e.jsx("div",{className:"mb-4",children:s}),e.jsx("h3",{className:"text-lg font-semibold text-text-primary mb-2",children:t}),e.jsx("p",{className:"text-sm text-text-secondary text-center",children:r})]}),ze=({selectedNotifications:t,onMarkAllAsRead:r,onMarkAllAsUnread:s,onArchiveAll:a,onDeleteAll:n,onClearSelection:l,className:m=""})=>{const[f,x]=h.useState(!1),[o,y]=h.useState(null),d=t.length,v=async(g,i)=>{if(d!==0){x(!0),y(null);try{const c=await g(t);y(c),c.success&&l()}catch(c){y({success:!1,processedCount:0,failedCount:d,errors:[{notificationId:"",error:c}]})}finally{x(!1)}}};return d===0?null:e.jsxs("div",{className:`border-t border-border bg-widget-primary-light p-2 ${m}`,children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs("span",{className:"text-sm font-medium text-widget-primary",children:[d," notification",d!==1?"s":""," selected"]}),o&&!o.success&&e.jsxs("span",{className:"text-xs text-[var(--widget-error)]",children:[o.failedCount," failed"]})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs("button",{type:"button",onClick:()=>v(r),disabled:f,className:"inline-flex items-center px-2 py-1 text-xs font-medium text-blue-700 bg-white border border-blue-300 rounded hover:bg-blue-50 focus:outline-none focus:ring-2 focus:ring-blue-500 disabled:opacity-50 disabled:cursor-not-allowed transition-colors","data-testid":"bulk-mark-read",children:[e.jsx(O,{className:"mr-1 w-4 h-4"}),"Mark Read"]}),e.jsxs("button",{type:"button",onClick:()=>v(s),disabled:f,className:"inline-flex items-center px-2 py-1 text-xs font-medium text-blue-700 bg-white border border-blue-300 rounded hover:bg-blue-50 focus:outline-none focus:ring-2 focus:ring-blue-500 disabled:opacity-50 disabled:cursor-not-allowed transition-colors","data-testid":"bulk-mark-unread",children:[e.jsx(X,{className:"mr-1 w-4 h-4"}),"Mark Unread"]}),e.jsxs("button",{type:"button",onClick:()=>v(a),disabled:f,className:"inline-flex items-center px-2 py-1 text-xs font-medium text-text-secondary bg-white border border-border rounded hover:bg-widget-hover focus:outline-none focus:ring-2 focus:ring-text-secondary disabled:opacity-50 disabled:cursor-not-allowed transition-colors","data-testid":"bulk-archive",children:[e.jsx(J,{className:"mr-1 w-4 h-4"}),"Archive"]}),e.jsxs("button",{type:"button",onClick:()=>{window.confirm(`Are you sure you want to delete ${d} notification${d!==1?"s":""}? This action cannot be undone.`)&&v(n)},disabled:f,className:"inline-flex items-center px-2 py-1 text-xs font-medium text-[var(--widget-error)] bg-white border border-[var(--widget-error)]/30 rounded hover:bg-[var(--widget-error)]/10 focus:outline-none focus:ring-2 focus:ring-[var(--widget-error)] disabled:opacity-50 disabled:cursor-not-allowed transition-colors","data-testid":"bulk-delete",children:[e.jsx(me,{className:"mr-1 w-4 h-4"}),"Delete"]}),e.jsx("button",{type:"button",onClick:l,disabled:f,className:"inline-flex items-center px-1 py-1 text-xs font-medium text-text-secondary hover:text-text-primary focus:outline-none focus:ring-2 focus:ring-text-secondary disabled:opacity-50 disabled:cursor-not-allowed transition-colors","data-testid":"clear-selection","aria-label":"Clear selection",children:e.jsx(Q,{className:"w-5 h-5"})})]})]}),f&&e.jsxs("div",{className:"mt-2 flex items-center gap-2",children:[e.jsx("div",{className:"animate-spin rounded-full h-4 w-4 border-b-2 border-[var(--widget-primary)]"}),e.jsx("span",{className:"text-xs text-[var(--widget-primary)]",children:"Processing..."})]}),o&&e.jsx("div",{className:"mt-2",children:o.success?e.jsxs("div",{className:"text-xs text-[var(--widget-success)]",children:["Successfully processed ",o.processedCount," notification",o.processedCount!==1?"s":""]}):e.jsxs("div",{className:"text-xs text-[var(--widget-error)]",children:[o.processedCount>0&&e.jsxs("span",{children:["Processed ",o.processedCount,", "]}),"Failed to process ",o.failedCount," notification",o.failedCount!==1?"s":""]})})]})},Se=({notifications:t,isLoading:r=!1,error:s,onNotificationAction:a,selectedNotifications:n=[],onSelectionChange:l,onSelectAll:m,onLoadMore:f,hasMore:x=!1,className:o=""})=>{const y=h.useRef(null),d=h.useRef(null),[v,g]=h.useState(!1);h.useEffect(()=>{if(!(!f||!x||v))return y.current=new IntersectionObserver(u=>{u[0].isIntersecting&&x&&!v&&(g(!0),f(),setTimeout(()=>g(!1),500))},{root:null,rootMargin:"100px",threshold:.1}),d.current&&y.current.observe(d.current),()=>{y.current&&y.current.disconnect()}},[f,x,v]);const i=h.useCallback(async u=>{try{u.handler&&await u.handler(""),a&&u.type&&a("",u)}catch{}},[a]),c=h.useCallback((u,p)=>{l&&l(u,p)},[l]);return r&&t.length===0?e.jsx("div",{className:`flex flex-col h-full bg-widget-background ${o}`,children:e.jsx(W,{count:5})}):s?e.jsx("div",{className:`flex flex-col h-full bg-widget-background ${o}`,children:e.jsx("div",{className:"flex items-center justify-center flex-1 py-12",children:e.jsx(K,{title:"Error Loading Notifications",description:"Failed to load notifications. Please try again.",icon:e.jsx("svg",{className:"w-12 h-12 text-[var(--widget-error)]",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M12 8v4m0 4v.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"})})})})}):t.length===0?e.jsx("div",{className:`flex flex-col h-full bg-widget-background ${o}`,children:e.jsx("div",{className:"flex items-center justify-center flex-1 py-12",children:e.jsx(K,{title:"No Notifications",description:"You're all caught up! No notifications to display.",icon:e.jsx("svg",{className:"w-12 h-12 text-[var(--widget-text-tertiary)]",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M20 13V6a2 2 0 00-2-2H6a2 2 0 00-2 2v7m16 0v5a2 2 0 01-2 2H6a2 2 0 01-2-2v-5m16 0h-2.586a1 1 0 00-.707.293l-2.414 2.414a1 1 0 01-.707.293h-3.172a1 1 0 01-.707-.293l-2.414-2.414A1 1 0 006.586 13H4"})})})})}):e.jsxs("div",{className:`flex flex-col h-full ${o}`,children:[m&&a&&e.jsx(ze,{selectedNotifications:n,onMarkAllAsRead:async u=>{try{for(const p of u)a(p,{type:"mark_read",label:"Mark as read",handler:async()=>{}});return{success:!0,processedCount:u.length,failedCount:0,errors:[]}}catch(p){return{success:!1,processedCount:0,failedCount:u.length,errors:[{notificationId:"",error:p}]}}},onMarkAllAsUnread:async u=>{try{for(const p of u)a(p,{type:"mark_unread",label:"Mark as unread",handler:async()=>{}});return{success:!0,processedCount:u.length,failedCount:0,errors:[]}}catch(p){return{success:!1,processedCount:0,failedCount:u.length,errors:[{notificationId:"",error:p}]}}},onArchiveAll:async u=>{try{for(const p of u)a(p,{type:"archive",label:"Archive",handler:async()=>{}});return{success:!0,processedCount:u.length,failedCount:0,errors:[]}}catch(p){return{success:!1,processedCount:0,failedCount:u.length,errors:[{notificationId:"",error:p}]}}},onDeleteAll:async u=>{try{for(const p of u)a(p,{type:"delete",label:"Delete",handler:async()=>{}});return{success:!0,processedCount:u.length,failedCount:0,errors:[]}}catch(p){return{success:!1,processedCount:0,failedCount:u.length,errors:[{notificationId:"",error:p}]}}},onClearSelection:()=>m(!1)}),e.jsx("div",{className:"flex-1 overflow-y-auto widget-scrollbar bg-widget-background",children:e.jsxs("div",{children:[t.map(u=>e.jsx(Z,{notification:u,onActionClick:i,isSelected:n.includes(u.id),onSelectionChange:l?p=>c(u.id,p):void 0},u.id)),x&&e.jsx("div",{ref:d,className:"py-2",children:v&&e.jsx(W,{count:3})})]})})]})},Ee=({notifications:t,activeTab:r,onTabChange:s,size:a="medium",className:n=""})=>{const l=h.useMemo(()=>{const m=t.length,f=t.filter(d=>!d.isRead).length,x=new Map;t.forEach(d=>{d.tags.forEach(v=>{x.set(v,(x.get(v)||0)+1)})});const o=[{id:"all",label:"All",count:m,icon:e.jsx(Ce,{className:"w-4 h-4"})},{id:"unread",label:"Unread",count:f,icon:e.jsx(X,{className:"w-4 h-4"})}],y=Array.from(x.entries()).sort(([,d],[,v])=>v-d).slice(0,5).map(([d,v])=>({id:`tag:${d}`,label:d,count:v,icon:e.jsx(ye,{className:"w-4 h-4"})}));return[...o,...y]},[t]);return e.jsx("div",{className:`
35
- flex items-center gap-1 overflow-x-auto widget-scrollbar border-b border-[var(--widget-border)] bg-[var(--widget-bg)] px-2 py-1.5
36
- ${n}
37
- `,role:"tablist",children:l.map(m=>{const f=r===m.id;return e.jsxs("button",{onClick:()=>s(m.id),className:`
38
- flex items-center gap-2 px-3 py-1.5 rounded-full text-sm font-medium transition-all whitespace-nowrap outline-none focus:ring-2 focus:ring-widget-primary focus:ring-offset-1
39
- ${f?"bg-widget-primary text-white shadow-sm":"text-text-secondary hover:bg-widget-hover hover:text-text-primary"}
40
- `,role:"tab","aria-selected":f,"data-testid":`tab-${m.id}`,children:[m.icon&&e.jsx("span",{className:`${f?"text-white":"text-[var(--widget-text-tertiary)]"}`,children:m.icon}),e.jsx("span",{children:m.label}),m.count!==void 0&&m.count>0&&e.jsx("span",{className:`
41
- ml-0.5 px-1.5 py-0.5 rounded-full text-[10px] font-bold leading-none
42
- ${f?"bg-white/20 text-white":"bg-[var(--widget-bg-secondary)] text-[var(--widget-text-tertiary)]"}
43
- `,children:m.count>99?"99+":m.count})]},m.id)})})},k=({id:t,label:r,checked:s,onChange:a,disabled:n=!1,icon:l})=>e.jsxs("div",{className:"flex items-center justify-between py-2.5",children:[r&&e.jsxs("label",{htmlFor:t,className:"flex items-center gap-2 text-sm font-medium text-text-primary cursor-pointer",children:[l&&e.jsx("span",{className:"text-widget-primary",children:l}),e.jsx("span",{children:r})]}),e.jsx("button",{type:"button",id:t,role:"switch","aria-checked":s,disabled:n,className:`
44
- relative inline-flex h-3 w-6 flex-shrink-0 rounded-full border-2 border-transparent
45
- transition-colors duration-200 ease-in-out
46
- focus:outline-none focus:ring-2 focus:ring-widget-primary focus:ring-offset-2
47
- ${s?"bg-widget-primary":"bg-border"}
48
- ${n?"opacity-50 cursor-not-allowed":"cursor-pointer"}
49
- `,onClick:()=>!n&&a(!s),children:e.jsx("span",{className:`
50
- pointer-events-none inline-block h-2 w-2 transform rounded-full bg-white shadow-sm ring-0
51
- transition duration-200 ease-in-out
52
- ${s?"translate-x-3":"translate-x-0"}
53
- `})})]}),He=["Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"],ee=({preferences:t,onPreferenceChange:r,isLoading:s})=>{const[a,n]=h.useState({global:!0,schedule:!1}),[l,m]=h.useState({}),f=i=>{n(c=>({...c,[i]:!c[i]}))},x=i=>{m(c=>({...c,[i]:!c[i]}))},o=(i,c)=>{r(`channels.${i}`,c)},y=(i,c)=>{r(`subscriptions.${i}.enabled`,c)},d=(i,c,u)=>{r(`subscriptions.${i}.channels.${c}`,u)},v=i=>{const c=[...t.deliverySchedule.weekdays];c[i]=!c[i],r("deliverySchedule.weekdays",c)},g=i=>{switch(i){case"email":return e.jsx(ve,{className:"w-4 h-4"});case"push":return e.jsx(F,{className:"w-4 h-4"});case"sms":return e.jsx(ke,{className:"w-4 h-4"});case"inApp":return e.jsx(we,{className:"w-4 h-4"});default:return null}};return e.jsxs("div",{className:"h-full overflow-y-auto widget-scrollbar p-2","data-testid":"preferences-view",children:[s&&e.jsx("div",{className:"absolute inset-0 bg-[var(--widget-bg)]/75 backdrop-blur-sm flex items-center justify-center z-10",children:e.jsx("div",{className:"w-8 h-8 border-2 border-[var(--widget-primary)] border-t-transparent rounded-full animate-spin"})}),e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"border border-[var(--widget-border)] rounded-lg overflow-hidden",children:[e.jsxs("button",{type:"button",onClick:()=>f("global"),className:"w-full flex items-center justify-between px-2 py-1.5 bg-[var(--widget-bg-secondary)] hover:bg-[var(--widget-bg-hover)] transition-colors",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(F,{className:"w-5 h-5 text-widget-primary"}),e.jsx("span",{className:"font-semibold text-sm text-text-primary",children:"Global Preferences"})]}),a.global?e.jsx(_,{className:"w-5 h-5 text-text-secondary"}):e.jsx(I,{className:"w-5 h-5 text-text-secondary"})]}),a.global&&e.jsxs("div",{className:"px-2 pb-1.5 bg-widget-background divide-y divide-border-light",children:[e.jsx(k,{id:"channel-email",label:"Email",icon:g("email"),checked:t.channels.email,onChange:i=>o("email",i),disabled:s}),e.jsx(k,{id:"channel-inapp",label:"In-App",icon:g("inApp"),checked:t.channels.inApp,onChange:i=>o("inApp",i),disabled:s}),e.jsx(k,{id:"channel-push",label:"Push",icon:g("push"),checked:t.channels.push,onChange:i=>o("push",i),disabled:s})]})]}),e.jsxs("div",{className:"border border-[var(--widget-border)] rounded-lg overflow-hidden bg-[var(--widget-bg)]",children:[e.jsxs("button",{type:"button",onClick:()=>f("schedule"),className:"w-full flex items-center justify-between px-2 py-1.5 bg-[var(--widget-bg-secondary)] hover:bg-[var(--widget-bg-hover)] transition-colors",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(xe,{className:"w-5 h-5 text-widget-primary"}),e.jsx("span",{className:"font-semibold text-sm text-text-primary",children:"Schedule"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(k,{id:"schedule-enabled",checked:a.schedule,onChange:()=>{},disabled:s}),e.jsx("div",{className:`transition-transform duration-200 ${a.schedule?"rotate-180":""}`,"aria-hidden":"true",children:e.jsx(I,{className:"w-5 h-5 text-text-secondary"})})]})]}),a.schedule&&e.jsxs("div",{className:"px-2 py-1.5 space-y-2 animate-in slide-in-from-top-2 duration-200",children:[e.jsx("div",{className:"text-sm text-[var(--widget-text-secondary)]",children:"Allow notifications between:"}),e.jsxs("div",{className:"grid grid-cols-[auto_1fr_auto_auto] gap-x-4 gap-y-3 items-center",children:[e.jsx("div",{className:"col-span-2 text-xs font-semibold text-[var(--widget-text-tertiary)] pl-1",children:"Days"}),e.jsx("div",{className:"text-xs font-semibold text-[var(--widget-text-tertiary)] w-[88px]",children:"From"}),e.jsx("div",{className:"text-xs font-semibold text-[var(--widget-text-tertiary)] w-[88px]",children:"To"}),He.map((i,c)=>{const u=t.deliverySchedule.weekdays[c];return e.jsxs(h.Fragment,{children:[e.jsx("div",{className:"flex items-center h-8",children:e.jsx(k,{id:`day-${c}`,checked:u,onChange:()=>v(c),disabled:s})}),e.jsx("div",{className:`text-sm ${u?"text-text-primary":"text-text-tertiary"}`,children:i}),e.jsx("div",{className:"w-[88px]",children:e.jsx("input",{type:"time",className:"w-full px-2 py-1 bg-widget-background border border-border rounded text-sm text-text-primary focus:outline-none focus:ring-1 focus:ring-widget-primary disabled:opacity-50 disabled:bg-widget-hover",value:t.deliverySchedule.quietHours.start,onChange:p=>r("deliverySchedule.quietHours.start",p.target.value),disabled:s||!u})}),e.jsx("div",{className:"w-[88px]",children:e.jsx("input",{type:"time",className:"w-full px-2 py-1 bg-widget-background border border-border rounded text-sm text-text-primary focus:outline-none focus:ring-1 focus:ring-widget-primary disabled:opacity-50 disabled:bg-widget-hover",value:t.deliverySchedule.quietHours.end,onChange:p=>r("deliverySchedule.quietHours.end",p.target.value),disabled:s||!u})})]},i)})]})]})]}),t.subscriptions.length>0&&t.subscriptions.map(i=>e.jsxs("div",{className:"border border-[var(--widget-border)] rounded-lg overflow-hidden",children:[e.jsxs("button",{type:"button",onClick:()=>x(i.workflowId),className:"w-full flex items-center justify-between px-2 py-1.5 bg-[var(--widget-bg-secondary)] hover:bg-[var(--widget-bg-hover)] transition-colors",children:[e.jsx("div",{className:"flex items-center gap-2",children:e.jsx("span",{className:"text-sm font-medium text-text-primary",children:i.name})}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(k,{id:`workflow-${i.workflowId}`,checked:i.enabled,onChange:c=>y(i.workflowId,c),disabled:s}),l[i.workflowId]?e.jsx(_,{className:"w-5 h-5 text-text-secondary"}):e.jsx(I,{className:"w-5 h-5 text-text-secondary"})]})]}),l[i.workflowId]&&i.enabled&&e.jsxs("div",{className:"px-2 pb-1.5 bg-widget-background divide-y divide-border-light",children:[e.jsx(k,{id:`sub-${i.workflowId}-inapp`,label:"In-App",icon:g("inApp"),checked:i.channels.inApp,onChange:c=>d(i.workflowId,"inApp",c),disabled:s}),e.jsx(k,{id:`sub-${i.workflowId}-push`,label:"Push",icon:g("push"),checked:i.channels.push,onChange:c=>d(i.workflowId,"push",c),disabled:s})]})]},i.workflowId))]})]})};class $ extends h.Component{constructor(r){super(r),this.state={hasError:!1,error:null}}static getDerivedStateFromError(r){return{hasError:!0,error:r}}componentDidCatch(r,s){const{componentName:a="Unknown Component",onError:n}=this.props;n&&n(r,s)}render(){return this.state.hasError?this.props.fallback?this.props.fallback:e.jsx("div",{className:"p-2 text-sm text-gray-500 bg-gray-50 border border-gray-200 rounded","data-testid":"component-error-fallback",children:e.jsxs("span",{children:["Unable to load ",this.props.componentName||"component"]})}):this.props.children}}const Ie=({onRetry:t,error:r})=>e.jsxs("div",{className:"p-3 text-center","data-testid":"notifications-fallback",children:[e.jsx("div",{className:"text-[var(--widget-text-tertiary)] mb-2",children:e.jsx(O,{className:"w-12 h-12 mx-auto"})}),e.jsx("p",{className:"text-sm text-[var(--widget-text-secondary)] mb-3",children:r?"Failed to load notifications":"No notifications available"}),t&&e.jsx("button",{type:"button",className:"text-sm text-[var(--widget-primary)] hover:text-[var(--widget-primary-hover)] font-medium transition-colors",onClick:t,children:"Try again"})]}),U=({onRetry:t,onBack:r})=>e.jsxs("div",{className:"p-3 text-center","data-testid":"preferences-fallback",children:[e.jsx("div",{className:"text-[var(--widget-text-tertiary)] mb-2",children:e.jsx(Y,{className:"w-12 h-12 mx-auto"})}),e.jsx("p",{className:"text-sm text-[var(--widget-text-secondary)] mb-3",children:"Unable to load preferences"}),e.jsxs("div",{className:"space-x-2",children:[t&&e.jsx("button",{type:"button",className:"text-sm text-[var(--widget-primary)] hover:text-[var(--widget-primary-hover)] font-medium transition-colors",onClick:t,children:"Try again"}),r&&e.jsx("button",{type:"button",className:"text-sm text-[var(--widget-text-secondary)] hover:text-[var(--widget-text)] font-medium transition-colors",onClick:r,children:"Back"})]})]}),Te=({onRetry:t,error:r})=>e.jsxs("div",{className:"p-3 text-center bg-[var(--widget-warning)]/10 border border-[var(--widget-warning)]/20 rounded-lg","data-testid":"sdk-connection-fallback",children:[e.jsx("div",{className:"text-[var(--widget-warning)] mb-2",children:e.jsx(pe,{className:"w-12 h-12 mx-auto"})}),e.jsx("p",{className:"text-sm text-[var(--widget-warning)] mb-3 font-medium",children:"Connection to notification service failed"}),r&&process.env.NODE_ENV==="development"&&e.jsx("p",{className:"text-xs text-[var(--widget-warning)] mb-3 font-mono opacity-80",children:r}),t&&e.jsx("button",{type:"button",className:"text-sm font-medium bg-[var(--widget-warning)]/20 text-[var(--widget-warning)] hover:bg-[var(--widget-warning)]/30 px-3 py-1 rounded transition-colors",onClick:t,children:"Retry connection"})]}),Ae=({message:t="Loading..."})=>e.jsxs("div",{className:"p-3 text-center","data-testid":"loading-fallback",children:[e.jsx("div",{className:"w-6 h-6 border-2 border-[var(--widget-primary)] border-t-transparent rounded-full animate-spin mx-auto mb-2"}),e.jsx("p",{className:"text-sm text-[var(--widget-text-secondary)]",children:t})]}),$e=(t,r)=>{switch(r){case"all":return t;case"unread":return t.filter(s=>!s.isRead);default:if(r.startsWith("tag:")){const s=r.substring(4);return t.filter(a=>a.tags.includes(s))}return t}},Oe=(t,r)=>{if(!r.trim())return t;const s=r.toLowerCase().trim();return t.filter(a=>{const n=a.subject.toLowerCase(),l=a.body.toLowerCase(),m=a.tags.join(" ").toLowerCase();return n.includes(s)||l.includes(s)||m.includes(s)})},Le=(t,r)=>{const s=[...t];switch(r){case"newest":return s.sort((a,n)=>n.timestamp.getTime()-a.timestamp.getTime());case"oldest":return s.sort((a,n)=>a.timestamp.getTime()-n.timestamp.getTime());case"unread-first":return s.sort((a,n)=>a.isRead===n.isRead?n.timestamp.getTime()-a.timestamp.getTime():a.isRead?1:-1);case"read-first":return s.sort((a,n)=>a.isRead===n.isRead?n.timestamp.getTime()-a.timestamp.getTime():a.isRead?-1:1);default:return s}},Be=(t,r,s,a="newest")=>{let n=t;return n=$e(n,r),s&&(n=Oe(n,s)),n=Le(n,a),n},Re=({isOpen:t,onClose:r,position:s,currentView:a,onViewChange:n,notifications:l,onNotificationAction:m,preferences:f,onPreferenceChange:x,isPreferencesLoading:o=!1,size:y="medium"})=>{const d=h.useRef(null),v=h.useRef(null),[g,i]=h.useState("all"),[c,u]=h.useState([]),[p,L]=h.useState(""),B=h.useCallback(()=>{const b=window.__notificationSDK?.config,j=window.__notificationSDK?.client;if(!b||!j)return null;const{tenantId:N,environmentId:C,subscriberId:P}=b;return!N||!C||!P?null:{client:j,tenantId:N,environmentId:C,subscriberId:P}},[]),te=h.useCallback(async b=>{const j=B();if(!j)return{success:!1,processedCount:0,failedCount:b.length,errors:[]};try{for(const N of b)await j.client.inbox.markAsRead(N,j.tenantId,j.environmentId,j.subscriberId);return{success:!0,processedCount:b.length,failedCount:0,errors:[]}}catch(N){return{success:!1,processedCount:0,failedCount:b.length,errors:[{notificationId:"",error:N}]}}},[B]),re=h.useMemo(()=>Be(l,g,p),[l,g,p]),S=h.useCallback(b=>{d.current&&!d.current.contains(b.target)&&r()},[r]),E=h.useCallback(b=>{b.key==="Escape"&&r()},[r]),H=h.useCallback(b=>{if(!(!t||!d.current)&&b.key==="Tab"){const j=d.current.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])');if(j.length===0)return;const N=j[0],C=j[j.length-1];b.shiftKey?document.activeElement===N&&(C.focus(),b.preventDefault()):document.activeElement===C&&(N.focus(),b.preventDefault())}},[t]);if(h.useEffect(()=>(t?(v.current=document.activeElement,document.addEventListener("mousedown",S),document.addEventListener("keydown",E),document.addEventListener("keydown",H),setTimeout(()=>{d.current?.querySelector('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])')?.focus()},0)):(v.current&&v.current.focus(),i("all"),u([]),L("")),()=>{document.removeEventListener("mousedown",S),document.removeEventListener("keydown",E),document.removeEventListener("keydown",H)}),[t,S,E,H]),!t)return null;const se={left:"left-0 origin-top-left",right:"right-0 origin-top-right"},R=l.filter(b=>!b.isRead).length;return e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"fixed inset-0 bg-black/20 backdrop-blur-sm z-40 md:hidden transition-opacity duration-200","aria-hidden":"true",onClick:r}),e.jsxs("div",{ref:d,className:`
54
- absolute top-full mt-2 ${se[s]}
55
- w-[var(--widget-popover-width,400px)] max-h-[var(--widget-popover-max-height,580px)]
56
- bg-widget-background border border-border rounded-2xl
57
- shadow-[var(--widget-shadow-xl)]
58
- z-50 flex flex-col
59
- animate-in fade-in-0 zoom-in-95 duration-200
60
- max-sm:fixed max-sm:inset-x-4 max-sm:top-16 max-sm:bottom-4
61
- max-sm:w-auto max-sm:max-w-none max-sm:max-h-[calc(100vh-120px)]
62
- `,role:"dialog","aria-modal":"true","aria-label":"Notifications","data-testid":"inbox-popover",children:[e.jsxs("div",{className:"flex-shrink-0 flex items-center justify-between px-3 py-2 border-b border-border bg-widget-background",children:[e.jsx("div",{className:"flex items-center gap-2",children:e.jsx("h2",{className:"text-sm font-semibold text-[var(--widget-text)]",children:a==="notifications"?"Notifications":"Preferences"})}),e.jsxs("div",{className:"flex items-center gap-1",children:[a==="notifications"&&e.jsx("button",{type:"button",className:"inline-flex items-center justify-center w-6 h-6 rounded-lg text-[var(--widget-text-secondary)] hover:text-[var(--widget-text)] hover:bg-[var(--widget-bg-hover)] transition-colors",onClick:()=>n("preferences"),"aria-label":"Open preferences","data-testid":"preferences-button",children:e.jsx(Y,{className:"w-4 h-4"})}),a==="preferences"&&e.jsx("button",{type:"button",className:"inline-flex items-center justify-center w-6 h-6 rounded-lg text-[var(--widget-text-secondary)] hover:text-[var(--widget-text)] hover:bg-[var(--widget-bg-hover)] transition-colors",onClick:()=>n("notifications"),"aria-label":"Back to notifications","data-testid":"back-button",children:e.jsx(je,{className:"w-5 h-5"})}),e.jsx("button",{type:"button",className:"inline-flex items-center justify-center w-6 h-6 rounded-lg text-[var(--widget-text-secondary)] hover:text-[var(--widget-text)] hover:bg-[var(--widget-bg-hover)] transition-colors",onClick:r,"aria-label":"Close notifications","data-testid":"close-button",children:e.jsx(Q,{className:"w-5 h-5"})})]})]}),a==="notifications"?e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"flex-shrink-0 px-3 py-2 border-b border-border bg-widget-background",children:e.jsxs("div",{className:"relative",children:[e.jsx("div",{className:"absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none",children:e.jsx(fe,{className:"w-5 h-5 text-[var(--widget-text-tertiary)]"})}),e.jsx("input",{type:"text",className:`\r
63
- w-full pl-10 pr-3 py-1 \r
64
- bg-[var(--widget-bg-secondary)] \r
65
- border border-[var(--widget-border)] \r
66
- rounded-lg \r
67
- text-sm text-[var(--widget-text)] \r
68
- placeholder:text-[var(--widget-text-tertiary)]\r
69
- focus:outline-none focus:ring-2 focus:ring-[var(--widget-primary)] focus:border-transparent\r
70
- transition-colors\r
71
- `,placeholder:"Search notifications...",value:p,onChange:b=>L(b.target.value),"aria-label":"Search notifications"})]})}),e.jsx(Ee,{notifications:l,activeTab:g,onTabChange:b=>i(b),size:y}),e.jsx("div",{className:"flex-1 min-h-0",children:e.jsx($,{fallback:e.jsx(Ie,{}),children:e.jsx(Se,{notifications:re,onNotificationAction:m})})}),R>0&&e.jsx("div",{className:"flex-shrink-0 px-3 py-2 border-t border-border bg-widget-hover",children:e.jsx("button",{type:"button",className:"w-full px-4 py-2 text-sm font-medium text-[var(--widget-primary)] hover:text-[var(--widget-primary-hover)] hover:bg-[var(--widget-primary-light)] rounded-lg transition-colors",onClick:()=>{const b=l.filter(j=>!j.isRead).map(j=>j.id);te(b)},"aria-label":`Mark all ${R} notifications as read`,children:"Mark all as read"})})]}):e.jsx("div",{className:"flex-1 overflow-y-auto widget-scrollbar",children:e.jsx($,{fallback:e.jsx(U,{}),children:f&&x?e.jsx(ee,{preferences:f,onPreferenceChange:x,isLoading:o,onBack:()=>n("notifications")}):e.jsx(U,{})})})]})]})};exports.BellComponent=he;exports.ComponentErrorBoundary=$;exports.InboxPopover=Re;exports.LoadingFallback=Ae;exports.MdError=ge;exports.MdRefresh=Ne;exports.NotificationItem=Z;exports.PreferencesView=ee;exports.SDKConnectionFallback=Te;
72
- //# sourceMappingURL=components-ytSNU0U3.cjs.map
@@ -1,2 +0,0 @@
1
- "use strict";const u=require("react"),j=()=>window.__notificationSDK?.client,N=({preferences:t,onPreferencesChange:o,onError:e})=>{const i=j(),[c,n]=u.useState(!1),[f,l]=u.useState(null),h=u.useRef(),v=u.useRef({}),E=u.useCallback((g,A)=>{try{l(null);const r={...t},a=g.split(".");let p=r;for(let s=0;s<a.length-1;s++)p[a[s]]===void 0&&(p[a[s]]={}),p=p[a[s]];p[a[a.length-1]]=A,o(r),v.current[g]=A,h.current&&clearTimeout(h.current),n(!0),h.current=setTimeout(async()=>{try{if(!i)throw new Error("Notification client not available");const s=i.subscriberId,b=i.tenantId,S=i.environmentId;if(!s||!b||S)throw new Error("SubscriberId or TenantId not available in NotificationClient.");const m={emailEnabled:r.channels.email,pushEnabled:r.channels.push,inAppEnabled:r.channels.inApp,smsEnabled:r.channels.sms};r.subscriptions.length>0&&(m.categories={},r.subscriptions.forEach(d=>{m.categories[d.workflowId]={emailEnabled:d.channels.email,pushEnabled:d.channels.push,inAppEnabled:d.channels.inApp,smsEnabled:d.channels.sms}})),m.deliverySchedule={timezone:r.deliverySchedule.timezone,quietHours:r.deliverySchedule.quietHours,weekdays:r.deliverySchedule.weekdays},await i.preferences.update(b,s,m),v.current={},l(null)}catch(s){const b=s instanceof Error?s:new Error("Failed to save preferences");process.env.NODE_ENV,l(b),e?.(b)}finally{n(!1)}},500)}catch(r){const a=r instanceof Error?r:new Error("Failed to update preference");l(a),e?.(a),n(!1)}},[t,o,i,e]);return u.useEffect(()=>()=>{h.current&&clearTimeout(h.current)},[]),{updatePreference:E,isSaving:c,error:f}},y=t=>!(!t||typeof t!="object"||["notificationId","channel","renderedContent","read","archived"].filter(i=>!(i in t)).length>0||typeof t.channel!="string"||typeof t.read!="boolean"||typeof t.archived!="boolean"||typeof t.renderedContent!="object"||t.renderedContent===null),D=(t,o,e)=>({type:"custom",label:t.label,icon:void 0,handler:async()=>{try{if(t.url){const i=t.target||"_self";window.open(t.url,i)}t.markAsReadOnClick}catch(i){throw i}}}),R=()=>{const t=(e,i)=>{if(!e||typeof e!="object")return{subject:"",body:""};let c="",n="";return e.push?(c=e.push.title||"",n=e.push.body||""):e.email?(c=e.email.subject||"",n=e.email.html||e.email.text||""):e.in_app?(c=e.in_app.title||"",n=e.in_app.message||""):e.sms?(c="SMS",n=e.sms.message||""):i==="in_app"?(c=e.title||"",n=e.message||""):(c=e.title||e.subject||"",n=e.message||e.body||e.text||""),{subject:c,body:n}},o=(e,i,c)=>{if(!e)return[];const n=[];return Array.isArray(e)?(e.forEach(f=>{n.push(D(f,i||"",c))}),n):(e.primary&&n.push({type:"custom",label:e.primary.label||"Primary Action",icon:void 0,handler:async()=>{}}),e.secondary&&n.push({type:"custom",label:e.secondary.label||"Secondary Action",icon:void 0,handler:async()=>{}}),n)};return{toWidgetNotification(e){const{subject:i,body:c}=t(e.renderedContent,e.channel);return{id:e.notificationId,subject:i||"Notification",body:c||"",isRead:e.read,isArchived:e.archived,timestamp:e.createdAt?new Date(e.createdAt):new Date,tags:[],actions:o(e.actions),metadata:{channel:e.channel,renderedContent:e.renderedContent}}},toWidgetNotificationFromWebSocket(e){if(!y(e)){const n=e?.renderedContent&&typeof e.renderedContent=="object"?e.renderedContent:{},{subject:f,body:l}=t(n,e?.channel);return{id:e?.notificationId||`notification-${Date.now()}`,subject:f||"Notification",body:l||"",isRead:e?.read||!1,isArchived:e?.archived||!1,timestamp:e?.createdAt?new Date(e.createdAt):new Date,tags:[],actions:[],metadata:{channel:e?.channel||"in_app",renderedContent:n}}}const{subject:i,body:c}=t(e.renderedContent,e.channel);return{id:e.notificationId,subject:i||"Notification",body:c||"",isRead:e.read||!1,isArchived:e.archived||!1,timestamp:e.createdAt?new Date(e.createdAt):new Date,tags:[],actions:o(e.actions,e.notificationId),metadata:{channel:e.channel,renderedContent:e.renderedContent}}},validateWebSocketPayload:y}};exports.createNotificationMapper=R;exports.useLivePreferences=N;
2
- //# sourceMappingURL=hooks-CACL0Qzv.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"hooks-CACL0Qzv.cjs","sources":["../src/hooks/useLivePreferences.ts","../src/utils/notification-mapper.ts"],"sourcesContent":["import { useCallback, useRef, useState, useEffect } from 'react';\r\nimport { NotificationPreferences } from '../types/core';\r\n\r\nconst useNotificationsClient = () => {\r\n return (window as any).__notificationSDK?.client;\r\n};\r\n\r\nexport interface UseLivePreferencesProps {\r\n preferences: NotificationPreferences;\r\n onPreferencesChange: (preferences: NotificationPreferences) => void;\r\n onError?: (error: Error) => void;\r\n}\r\n\r\nexport interface UseLivePreferencesResult {\r\n updatePreference: (path: string, value: any) => void;\r\n isSaving: boolean;\r\n error: Error | null;\r\n}\r\n\r\nexport const useLivePreferences = ({\r\n preferences,\r\n onPreferencesChange,\r\n onError,\r\n}: UseLivePreferencesProps): UseLivePreferencesResult => {\r\n const notificationClient = useNotificationsClient();\r\n const [isSaving, setIsSaving] = useState(false);\r\n const [error, setError] = useState<Error | null>(null);\r\n const saveTimeoutRef = useRef<NodeJS.Timeout>();\r\n const pendingUpdatesRef = useRef<{ [key: string]: any }>({});\r\n\r\n const updatePreference = useCallback(\r\n (path: string, value: any) => {\r\n try {\r\n setError(null);\r\n\r\n const updatedPreferences = { ...preferences };\r\n const pathParts = path.split('.');\r\n\r\n let current: any = updatedPreferences;\r\n for (let i = 0; i < pathParts.length - 1; i++) {\r\n if (current[pathParts[i]] === undefined) {\r\n current[pathParts[i]] = {};\r\n }\r\n current = current[pathParts[i]];\r\n }\r\n current[pathParts[pathParts.length - 1]] = value;\r\n\r\n onPreferencesChange(updatedPreferences);\r\n\r\n pendingUpdatesRef.current[path] = value;\r\n\r\n if (saveTimeoutRef.current) {\r\n clearTimeout(saveTimeoutRef.current);\r\n }\r\n\r\n setIsSaving(true);\r\n\r\n saveTimeoutRef.current = setTimeout(async () => {\r\n try {\r\n if (!notificationClient) {\r\n throw new Error('Notification client not available');\r\n }\r\n\r\n const subscriberId = (notificationClient as any).subscriberId;\r\n const tenantId = (notificationClient as any).tenantId;\r\n const environmentId = (notificationClient as any).environmentId;\r\n\r\n if (!subscriberId || !tenantId || environmentId) {\r\n throw new Error('SubscriberId or TenantId not available in NotificationClient.');\r\n }\r\n\r\n const savePayload: any = {\r\n emailEnabled: updatedPreferences.channels.email,\r\n pushEnabled: updatedPreferences.channels.push,\r\n inAppEnabled: updatedPreferences.channels.inApp,\r\n smsEnabled: updatedPreferences.channels.sms,\r\n };\r\n\r\n if (updatedPreferences.subscriptions.length > 0) {\r\n savePayload.categories = {};\r\n updatedPreferences.subscriptions.forEach(sub => {\r\n savePayload.categories[sub.workflowId] = {\r\n emailEnabled: sub.channels.email,\r\n pushEnabled: sub.channels.push,\r\n inAppEnabled: sub.channels.inApp,\r\n smsEnabled: sub.channels.sms,\r\n };\r\n });\r\n }\r\n\r\n savePayload.deliverySchedule = {\r\n timezone: updatedPreferences.deliverySchedule.timezone,\r\n quietHours: updatedPreferences.deliverySchedule.quietHours,\r\n weekdays: updatedPreferences.deliverySchedule.weekdays,\r\n };\r\n\r\n await notificationClient.preferences.update(tenantId, subscriberId, savePayload);\r\n\r\n pendingUpdatesRef.current = {};\r\n setError(null);\r\n } catch (err: any) {\r\n const error = err instanceof Error ? err : new Error('Failed to save preferences');\r\n\r\n if (process.env.NODE_ENV === 'development') {\r\n console.error('Failed to save preferences:', error);\r\n }\r\n\r\n setError(error);\r\n onError?.(error);\r\n\r\n } finally {\r\n setIsSaving(false);\r\n }\r\n }, 500);\r\n } catch (err: any) {\r\n const error = err instanceof Error ? err : new Error('Failed to update preference');\r\n setError(error);\r\n onError?.(error);\r\n setIsSaving(false);\r\n }\r\n },\r\n [preferences, onPreferencesChange, notificationClient, onError]\r\n );\r\n\r\n useEffect(() => {\r\n return () => {\r\n if (saveTimeoutRef.current) {\r\n clearTimeout(saveTimeoutRef.current);\r\n }\r\n };\r\n }, []);\r\n\r\n return {\r\n updatePreference,\r\n isSaving,\r\n error,\r\n };\r\n};","import type { RenderedNotificationItem, RenderedNotificationActionMap, NotificationAction as SDKNotificationAction } from '@edusight/notification-sdk';\r\nimport type { Notification, NotificationAction } from '../types/core';\r\n\r\nexport interface WebSocketNotificationReceivedPayload extends RenderedNotificationItem {}\r\n\r\nexport interface NotificationMapper {\r\n toWidgetNotification(renderedItem: RenderedNotificationItem): Notification;\r\n toWidgetNotificationFromWebSocket(wsPayload: any): Notification;\r\n validateWebSocketPayload(payload: any): payload is WebSocketNotificationReceivedPayload;\r\n}\r\n\r\nconst validateWebSocketPayload = (payload: any): payload is WebSocketNotificationReceivedPayload => {\r\n if (!payload || typeof payload !== 'object') {\r\n console.warn('Invalid WebSocket payload: not an object', payload);\r\n return false;\r\n }\r\n\r\n const requiredFields = ['notificationId', 'channel', 'renderedContent', 'read', 'archived'];\r\n const missingFields = requiredFields.filter(field => !(field in payload));\r\n\r\n if (missingFields.length > 0) {\r\n console.warn('WebSocket payload missing required fields:', missingFields, payload);\r\n return false;\r\n }\r\n\r\n if (typeof payload.channel !== 'string') {\r\n console.warn('WebSocket payload channel is invalid', payload);\r\n return false;\r\n }\r\n\r\n if (typeof payload.read !== 'boolean' || typeof payload.archived !== 'boolean') {\r\n console.warn('WebSocket payload read/archived flags are invalid', payload);\r\n return false;\r\n }\r\n\r\n if (typeof payload.renderedContent !== 'object' || payload.renderedContent === null) {\r\n console.warn('WebSocket payload renderedContent is not an object', payload);\r\n return false;\r\n }\r\n\r\n return true;\r\n};\r\n\r\n\r\nconst mapSDKActionToWidgetAction = (\r\n sdkAction: SDKNotificationAction,\r\n notificationId: string,\r\n onActionExecute?: (actionId: string, notificationId: string) => Promise<void>\r\n): NotificationAction => {\r\n return {\r\n type: 'custom',\r\n label: sdkAction.label,\r\n icon: undefined,\r\n handler: async () => {\r\n try {\r\n if (onActionExecute) {\r\n await onActionExecute(sdkAction.id, notificationId);\r\n }\r\n\r\n if (sdkAction.url) {\r\n const target = sdkAction.target || '_self';\r\n window.open(sdkAction.url, target);\r\n }\r\n\r\n if (sdkAction.markAsReadOnClick) {\r\n // This will be handled by the widget's action handler\r\n }\r\n } catch (error) {\r\n console.error('Error executing action:', error);\r\n throw error;\r\n }\r\n },\r\n };\r\n};\r\n\r\nexport const createNotificationMapper = (): NotificationMapper => {\r\n const extractSubjectAndBody = (\r\n renderedContent: Record<string, any>,\r\n channel?: string\r\n ): { subject: string; body: string } => {\r\n if (!renderedContent || typeof renderedContent !== 'object') {\r\n return { subject: '', body: '' };\r\n }\r\n\r\n let subject = '';\r\n let body = '';\r\n\r\n if (renderedContent.push) {\r\n subject = renderedContent.push.title || '';\r\n body = renderedContent.push.body || '';\r\n } else if (renderedContent.email) {\r\n subject = renderedContent.email.subject || '';\r\n body = renderedContent.email.html || renderedContent.email.text || '';\r\n } else if (renderedContent.in_app) {\r\n subject = renderedContent.in_app.title || '';\r\n body = renderedContent.in_app.message || '';\r\n } else if (renderedContent.sms) {\r\n subject = 'SMS';\r\n body = renderedContent.sms.message || '';\r\n } else if (channel === 'in_app') {\r\n subject = renderedContent.title || '';\r\n body = renderedContent.message || '';\r\n } else {\r\n subject = renderedContent.title || renderedContent.subject || '';\r\n body = renderedContent.message || renderedContent.body || renderedContent.text || '';\r\n }\r\n\r\n return { subject, body };\r\n };\r\n\r\n const mapActionsToNotificationActions = (\r\n actions?: RenderedNotificationActionMap | SDKNotificationAction[],\r\n notificationId?: string,\r\n onActionExecute?: (actionId: string, notificationId: string) => Promise<void>\r\n ): NotificationAction[] => {\r\n if (!actions) return [];\r\n\r\n const result: NotificationAction[] = [];\r\n\r\n if (Array.isArray(actions)) {\r\n actions.forEach((sdkAction) => {\r\n result.push(mapSDKActionToWidgetAction(sdkAction, notificationId || '', onActionExecute));\r\n });\r\n return result;\r\n }\r\n\r\n if (actions.primary) {\r\n result.push({\r\n type: 'custom',\r\n label: actions.primary.label || 'Primary Action',\r\n icon: undefined,\r\n handler: async () => {\r\n },\r\n });\r\n }\r\n\r\n if (actions.secondary) {\r\n result.push({\r\n type: 'custom',\r\n label: actions.secondary.label || 'Secondary Action',\r\n icon: undefined,\r\n handler: async () => {\r\n },\r\n });\r\n }\r\n\r\n return result;\r\n };\r\n\r\n return {\r\n toWidgetNotification(renderedItem: RenderedNotificationItem): Notification {\r\n const { subject, body } = extractSubjectAndBody(renderedItem.renderedContent, renderedItem.channel);\r\n\r\n return {\r\n id: renderedItem.notificationId,\r\n subject: subject || 'Notification',\r\n body: body || '',\r\n isRead: renderedItem.read,\r\n isArchived: renderedItem.archived,\r\n timestamp: renderedItem.createdAt ? new Date(renderedItem.createdAt) : new Date(),\r\n tags: [],\r\n actions: mapActionsToNotificationActions(renderedItem.actions),\r\n metadata: {\r\n channel: renderedItem.channel,\r\n renderedContent: renderedItem.renderedContent,\r\n },\r\n };\r\n },\r\n\r\n toWidgetNotificationFromWebSocket(wsPayload: any): Notification {\r\n if (!validateWebSocketPayload(wsPayload)) {\r\n console.error('Invalid WebSocket payload structure, using fallback', wsPayload);\r\n const fallbackRenderedContent =\r\n wsPayload?.renderedContent && typeof wsPayload.renderedContent === 'object'\r\n ? wsPayload.renderedContent\r\n : {};\r\n const { subject, body } = extractSubjectAndBody(fallbackRenderedContent, wsPayload?.channel);\r\n return {\r\n id: wsPayload?.notificationId || `notification-${Date.now()}`,\r\n subject: subject || 'Notification',\r\n body: body || '',\r\n isRead: wsPayload?.read || false,\r\n isArchived: wsPayload?.archived || false,\r\n timestamp: wsPayload?.createdAt ? new Date(wsPayload.createdAt) : new Date(),\r\n tags: [],\r\n actions: [],\r\n metadata: {\r\n channel: wsPayload?.channel || 'in_app',\r\n renderedContent: fallbackRenderedContent,\r\n },\r\n };\r\n }\r\n\r\n const { subject, body } = extractSubjectAndBody(wsPayload.renderedContent, wsPayload.channel);\r\n\r\n return {\r\n id: wsPayload.notificationId,\r\n subject: subject || 'Notification',\r\n body: body || '',\r\n isRead: wsPayload.read || false,\r\n isArchived: wsPayload.archived || false,\r\n timestamp: wsPayload.createdAt ? new Date(wsPayload.createdAt) : new Date(),\r\n tags: [],\r\n actions: mapActionsToNotificationActions(wsPayload.actions, wsPayload.notificationId),\r\n metadata: {\r\n channel: wsPayload.channel,\r\n renderedContent: wsPayload.renderedContent,\r\n },\r\n };\r\n },\r\n\r\n validateWebSocketPayload,\r\n };\r\n};\r\n"],"names":["useNotificationsClient","useLivePreferences","preferences","onPreferencesChange","onError","notificationClient","isSaving","setIsSaving","useState","error","setError","saveTimeoutRef","useRef","pendingUpdatesRef","updatePreference","useCallback","path","value","updatedPreferences","pathParts","current","i","subscriberId","tenantId","environmentId","savePayload","sub","err","useEffect","validateWebSocketPayload","payload","field","mapSDKActionToWidgetAction","sdkAction","notificationId","onActionExecute","target","createNotificationMapper","extractSubjectAndBody","renderedContent","channel","subject","body","mapActionsToNotificationActions","actions","result","renderedItem","wsPayload","fallbackRenderedContent"],"mappings":"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"}