@edusight/notification-widget 1.0.43 → 1.0.45
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs.js +2 -2
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +267 -248
- package/dist/index.esm.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const c=require("react/jsx-runtime"),H=require("@edusight/notification-sdk"),i=require("react"),z=require("socket.io-client"),A=require("./hooks-C6Z38jT_.cjs"),b=require("./components-CJcM_JjP.cjs"),$=()=>window.__notificationSDK?.client,J=({onPreferencesLoaded:t,onError:n})=>{const p=$(),[w,l]=i.useState(!0),[f,d]=i.useState(null),[r,u]=i.useState(null),E=i.useCallback(async()=>{try{if(l(!0),d(null),!p)throw new Error("Notification client not available");const m=window.__notificationSDK?.config;if(!m)throw new Error("SDK configuration not available");const{subscriberId:g,tenantId:k,environmentId:I}=m;if(!g||!k||!I)throw new Error("SubscriberId, TenantId or EnvironmentId not available in config");const S=await p.preferences.get(k,g,I);let a=null;try{a=await p.preferences.getSchedule(k,g,I)}catch{}const _={channels:{email:S.emailEnabled??!0,push:S.pushEnabled??!0,sms:S.smsEnabled??!1,inApp:S.inAppEnabled??!0},subscriptions:[],deliverySchedule:{enabled:a?.isEnabled||!1,timezone:"UTC",quietHours:{start:S.quietHoursStart??"22:00",end:S.quietHoursEnd??"08:00"},weekdays:a?.weeklySchedule?[!!a.weeklySchedule.monday,!!a.weeklySchedule.tuesday,!!a.weeklySchedule.wednesday,!!a.weeklySchedule.thursday,!!a.weeklySchedule.friday,!!a.weeklySchedule.saturday,!!a.weeklySchedule.sunday]:[!0,!0,!0,!0,!0,!1,!1],weeklySchedule:a?.weeklySchedule||void 0}};S.categories&&Object.entries(S.categories).forEach(([N,C])=>{_.subscriptions.push({workflowId:N,name:N,enabled:!0,channels:{email:C.emailEnabled??!0,push:C.pushEnabled??!0,sms:C.smsEnabled??!1,inApp:C.inAppEnabled??!0}})}),u(_),t(_)}catch(m){const g=m instanceof Error?m:new Error("Failed to load preferences");m?.response?.status===404||m?.status===404||(d(g),n?.(g));const I={channels:{email:!0,push:!0,sms:!1,inApp:!0},subscriptions:[],deliverySchedule:{enabled:!1,timezone:"UTC",quietHours:{start:"22:00",end:"08:00"},weekdays:[!0,!0,!0,!0,!0,!1,!1]}};u(I),t(I)}finally{l(!1)}},[p,t,n]);return i.useEffect(()=>{p&&E()},[p,E]),{isLoading:w,error:f,preferences:r}},G=()=>window.__notificationSDK?.client,Q=()=>{const t=G(),[n,p]=i.useState([]),[w,l]=i.useState(!1),[f,d]=i.useState(!0),[r,u]=i.useState(0),E=5,m=i.useCallback(async()=>{if(!(!t||w||!f))try{l(!0);const k=window.__notificationSDK?.config;if(!k)return;const I=await t.preferences.listSpecific(k.tenantId,k.subscriberId,{includeWorkflows:!0,includeTemplates:!1,activeOnly:!0,limit:E,offset:r}),S=(I.items||[]).map(a=>({workflowId:a.identifier,name:a.name,enabled:a.preference.enabled,channels:{email:a.preference.channels.email||!1,push:a.preference.channels.push||!1,inApp:a.preference.channels.in_app||!1,sms:a.preference.channels.sms||!1}}));p(a=>{const _=new Set(a.map(C=>C.workflowId)),N=S.filter(C=>!_.has(C.workflowId));return[...a,...N]}),u(a=>a+E),(S.length<E||I.total!==void 0&&n.length+S.length>=I.total)&&d(!1)}catch{}finally{l(!1)}},[t,r,f,w,n.length]);return i.useEffect(()=>{t&&r===0&&n.length===0&&m()},[t,m,r,n.length]),{specificPreferences:n,isLoading:w,hasMore:f,loadMore:m,refetch:async()=>{p([]),u(0),d(!0)}}},X=({error:t,onRetry:n})=>c.jsxs("div",{className:"p-4 bg-[var(--widget-error)]/10 border border-[var(--widget-error)]/20 rounded-lg",role:"alert","data-testid":"error-boundary-fallback",children:[c.jsxs("div",{className:"flex items-center mb-2",children:[c.jsx(b.MdError,{className:"w-6 h-6 text-[var(--widget-error)] mr-2","aria-hidden":"true"}),c.jsx("h3",{className:"text-sm font-medium text-[var(--widget-error)]",children:"Something went wrong"})]}),c.jsx("p",{className:"text-sm mb-3 text-[var(--widget-error)]/80",children:"The notification widget encountered an error and couldn't load properly."}),process.env.NODE_ENV==="development"&&t&&c.jsxs("details",{className:"mb-3",children:[c.jsx("summary",{className:"text-xs cursor-pointer text-[var(--widget-error)] hover:text-[var(--widget-error)]/80 transition-colors",children:"Error details (development only)"}),c.jsxs("pre",{className:"mt-2 text-xs bg-[var(--widget-error)]/5 p-2 rounded overflow-auto max-h-32 text-[var(--widget-error)]",children:[t.message,t.stack&&`
|
|
2
2
|
|
|
3
|
-
${t.stack}`]})]}),s.jsxs("button",{type:"button",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",onClick:n,"data-testid":"error-retry-button",children:[s.jsx(m.MdRefresh,{className:"mr-1 w-4 h-4","aria-hidden":"true"}),"Try again"]})]});class D extends i.Component{constructor(n){super(n),this.handleRetry=()=>{this.setState({hasError:!1,error:null,errorInfo:null})},this.state={hasError:!1,error:null,errorInfo:null}}static getDerivedStateFromError(n){return{hasError:!0,error:n}}componentDidCatch(n,p){this.setState({errorInfo:p}),this.props.onError&&this.props.onError(n,p)}render(){return this.state.hasError?s.jsx(J,{error:this.state.error,onRetry:this.handleRetry}):this.props.children}}const P=i.createContext(null),G=()=>{const t=i.useContext(P);if(!t)throw new Error("useSDK must be used within a NotificationWidget");return t},Q={notifications:[],unreadCount:0,preferences:{channels:{email:!0,push:!0,sms:!1,inApp:!0},subscriptions:[],deliverySchedule:{timezone:"UTC",quietHours:{start:"22:00",end:"08:00"},weekdays:[!0,!0,!0,!0,!0,!1,!1]}},ui:{isOpen:!1,currentView:"notifications",selectedNotifications:[],isLoading:!1,error:null},websocket:{connected:!1,reconnecting:!1}},X=({config:t,children:n})=>{const[p,w]=i.useState({client:null,isInitialized:!1,error:null});return i.useEffect(()=>{let c=!0;return(async()=>{try{const l=window.__notificationSDK;if(l?.client&&JSON.stringify(l.config)===JSON.stringify(t)){c&&w({client:l.client,isInitialized:!0,error:null});return}const r=new B.NotificationClient({apiUrl:t.baseUrl,apiKey:t.apiKey,tenantId:t.tenantId,environmentId:t.environmentId});window.__notificationSDK={client:r,config:t},c&&w({client:r,isInitialized:!0,error:null})}catch(l){c&&w({client:null,isInitialized:!1,error:l})}})(),()=>{c=!1}},[t]),s.jsx(P.Provider,{value:p,children:n})},Y=(t,n)=>{switch(n.type){case"SET_NOTIFICATIONS":return{...t,notifications:n.payload,unreadCount:n.payload.filter(f=>!f.isRead).length};case"ADD_NOTIFICATION":const p=[n.payload,...t.notifications];return{...t,notifications:p,unreadCount:p.filter(f=>!f.isRead).length};case"UPDATE_NOTIFICATION":const w=t.notifications.map(f=>f.id===n.payload.id?{...f,...n.payload.updates}:f);return{...t,notifications:w,unreadCount:w.filter(f=>!f.isRead).length};case"DELETE_NOTIFICATION":const c=t.notifications.filter(f=>f.id!==n.payload);return{...t,notifications:c,unreadCount:c.filter(f=>!f.isRead).length};case"SET_PREFERENCES":return{...t,preferences:n.payload};case"SET_UI_STATE":return{...t,ui:{...t.ui,...n.payload}};case"SET_WEBSOCKET_STATE":return{...t,websocket:{...t.websocket,...n.payload}};default:return t}},Z=({position:t="right",size:n="medium",theme:p="light",className:w="",onError:c,onMorePreferencesClick:f})=>{const[l,r]=i.useReducer(Y,Q),{client:u,isInitialized:y,error:h}=G(),g=i.useRef(null),k=i.useCallback(e=>{r({type:"SET_PREFERENCES",payload:e})},[]),T=i.useCallback(e=>{c&&c(e)},[c]),{error:E}=z({onPreferencesLoaded:k,onError:T}),{specificPreferences:d,isLoading:_,hasMore:N,loadMore:C}=$(),{updatePreference:j,isSaving:A,error:O}=v.useLivePreferences({preferences:l.preferences,onPreferencesChange:k,onError:T});i.useEffect(()=>{if(d.length>0){const o=[...l.preferences.subscriptions];let a=!1;d.forEach(I=>{const S=o.findIndex(b=>b.workflowId===I.workflowId);if(S===-1)o.push(I),a=!0;else{const b=o[S];b.name===b.workflowId&&I.name&&I.name!==I.workflowId&&(o[S]={...b,name:I.name},a=!0)}}),a&&r({type:"SET_PREFERENCES",payload:{...l.preferences,subscriptions:o}})}},[d]);const K=i.useMemo(()=>d.map(e=>l.preferences.subscriptions.find(a=>a.workflowId===e.workflowId)||e),[d,l.preferences.subscriptions]),x=i.useCallback(e=>{try{const o=v.createNotificationMapper();switch(e.type){case"notification_received":{const a=e.data;if(!o.validateWebSocketPayload(a))break;const I=o.toWidgetNotificationFromWebSocket(a);r({type:"ADD_NOTIFICATION",payload:I});break}case"notification_updated":r({type:"UPDATE_NOTIFICATION",payload:{id:e.data.id||e.data.notificationId,updates:e.data}});break;case"notification_deleted":r({type:"DELETE_NOTIFICATION",payload:e.data.id||e.data.notificationId});break;case"preferences_updated":r({type:"SET_PREFERENCES",payload:e.data});break;default:}}catch{}},[]),R=i.useCallback(async()=>{if(!(!u||!y||g.current))try{r({type:"SET_WEBSOCKET_STATE",payload:{reconnecting:!0}});const e=window.__notificationSDK?.config;if(!e)throw new Error("SDK configuration not available for WebSocket connection");const I=`${u.getApiHost()}/v1/notifications`,S=q.io(I,{query:{tenantId:e.tenantId,subscriberId:e.subscriberId,environmentId:e.environmentId},transports:["websocket"],autoConnect:!1,reconnection:!0,reconnectionAttempts:10,reconnectionDelay:1e3,reconnectionDelayMax:5e3});g.current=S,S.on("notification",b=>{x({type:"notification_received",data:b})}),S.on("connect",()=>{r({type:"SET_WEBSOCKET_STATE",payload:{connected:!0,reconnecting:!1}})}),S.on("disconnect",b=>{r({type:"SET_WEBSOCKET_STATE",payload:{connected:!1,reconnecting:!1}})}),S.on("reconnect_attempt",b=>{r({type:"SET_WEBSOCKET_STATE",payload:{connected:!1,reconnecting:!0}})}),S.on("connect_error",b=>{r({type:"SET_WEBSOCKET_STATE",payload:{connected:!1,reconnecting:!1}}),c&&c(b)}),S.connect()}catch(e){r({type:"SET_WEBSOCKET_STATE",payload:{connected:!1,reconnecting:!1}}),c&&c(e)}},[u,y,x,c]),W=i.useCallback(()=>{if(g.current)try{g.current.disconnect&&g.current.disconnect(),g.current=null,r({type:"SET_WEBSOCKET_STATE",payload:{connected:!1,reconnecting:!1}})}catch{}},[]),F=i.useCallback(()=>{r({type:"SET_UI_STATE",payload:{isOpen:!l.ui.isOpen}})},[l.ui.isOpen]),M=i.useCallback(()=>{r({type:"SET_UI_STATE",payload:{isOpen:!1}})},[]),L=i.useCallback(e=>{r({type:"SET_UI_STATE",payload:{currentView:e}})},[]),U=i.useCallback(async(e,o)=>{if(!u||!y)return;const a=window.__notificationSDK?.config;if(a){if(!e)throw new Error("notificationId is required");try{switch(o.type){case"mark_read":await u.inbox.markAsRead(e,a.tenantId,a.environmentId,a.subscriberId);break;case"mark_unread":await u.inbox.markAsUnread(e,a.tenantId,a.environmentId,a.subscriberId);break;case"archive":await u.inbox.archive(e,a.tenantId,a.environmentId,a.subscriberId);break;case"delete":await u.inbox.delete(e,a.tenantId,a.environmentId,a.subscriberId);break;default:o.handler&&await o.handler(e);break}switch(o.type){case"mark_read":r({type:"UPDATE_NOTIFICATION",payload:{id:e,updates:{isRead:!0}}});break;case"mark_unread":r({type:"UPDATE_NOTIFICATION",payload:{id:e,updates:{isRead:!1}}});break;case"archive":r({type:"UPDATE_NOTIFICATION",payload:{id:e,updates:{isArchived:!0}}});break;case"delete":r({type:"DELETE_NOTIFICATION",payload:e});break}}catch(I){c&&c(I)}}},[u]);return i.useEffect(()=>{if(!u||!y)return;(async()=>{try{r({type:"SET_UI_STATE",payload:{isLoading:!0}});const o=window.__notificationSDK?.config;if(!o)throw new Error("SDK configuration not available");const a=v.createNotificationMapper(),S=((await u.inbox.getRenderedNotifications({channel:"in_app",limit:50,offset:0},o.tenantId,o.environmentId,o.subscriberId))?.items||[]).map(b=>a.toWidgetNotification(b));r({type:"SET_NOTIFICATIONS",payload:S}),r({type:"SET_UI_STATE",payload:{isLoading:!1,error:null}})}catch(o){r({type:"SET_UI_STATE",payload:{isLoading:!1,error:o}}),c&&c(o)}})()},[u,y,c]),i.useEffect(()=>(u&&y&&R(),()=>{W()}),[u]),i.useEffect(()=>{if(!u||!y||l.websocket.connected)return;const e=setInterval(async()=>{try{const o=window.__notificationSDK?.config;if(!o)return;const a=v.createNotificationMapper(),S=((await u.inbox.getRenderedNotifications({channel:"in_app",limit:50,offset:0},o.tenantId,o.environmentId,o.subscriberId))?.items||[]).map(b=>a.toWidgetNotification(b));r({type:"SET_NOTIFICATIONS",payload:S})}catch{}},3e4);return()=>clearInterval(e)},[u,l.websocket.connected]),i.useEffect(()=>{const e=o=>{if(o.key==="notification_widget_sync"&&o.newValue)try{const a=JSON.parse(o.newValue);x(a)}catch{}};return window.addEventListener("storage",e),()=>window.removeEventListener("storage",e)},[x]),i.useEffect(()=>{r({type:"SET_UI_STATE",payload:{isLoading:A}})},[A]),i.useEffect(()=>{const e=h||O||E;e&&r({type:"SET_UI_STATE",payload:{error:e}})},[h,O,E]),!y&&!h?s.jsx("div",{className:`mx-widget-root relative inline-block ${w}`,"data-mx-widget":"root","data-widget-size":n||"small","data-theme":p,"data-testid":"notification-widget",children:s.jsx(m.ComponentErrorBoundary,{componentName:"BellComponent",children:s.jsx(m.BellComponent,{unreadCount:0,onClick:()=>{},size:n,disabled:!0})})}):h?s.jsx("div",{className:`mx-widget-root relative inline-block ${w}`,"data-mx-widget":"root","data-widget-size":n||"small","data-theme":p,"data-testid":"notification-widget",children:s.jsx(m.ComponentErrorBoundary,{componentName:"BellComponent",fallback:s.jsx(m.SDKConnectionFallback,{error:h.message,onRetry:()=>window.location.reload()}),children:s.jsx(m.BellComponent,{unreadCount:0,onClick:()=>{},size:n,disabled:!0})})}):s.jsxs("div",{className:`mx-widget-root min-w-[20rem] relative inline-block ${w}`,"data-mx-widget":"root","data-widget-size":n||"small","data-theme":p,"data-testid":"notification-widget",children:[s.jsx(m.ComponentErrorBoundary,{componentName:"BellComponent",children:s.jsx(m.BellComponent,{unreadCount:l.unreadCount,onClick:F,size:n,disabled:l.ui.isLoading})}),s.jsx(m.ComponentErrorBoundary,{componentName:"InboxPopover",fallback:s.jsx(m.LoadingFallback,{message:"Unable to load notifications"}),children:s.jsx(m.InboxPopover,{isOpen:l.ui.isOpen,onClose:M,position:t,currentView:l.ui.currentView,onViewChange:L,notifications:l.notifications,onNotificationAction:U,preferences:l.preferences,onPreferenceChange:j,isPreferencesLoading:A,specificPreferences:K,onLoadMoreSpecific:C,hasMoreSpecific:N,isListLoading:_,onMorePreferencesClick:f})})]})},ee=({sdkConfig:t,...n})=>s.jsx(D,{onError:n.onError,children:s.jsx(X,{config:t,children:s.jsx(Z,{...n})})}),te="3.0.0",ne="@edusight/notification-widget";exports.BellComponent=m.BellComponent;exports.InboxPopover=m.InboxPopover;exports.NotificationItem=m.NotificationItem;exports.PreferencesView=m.PreferencesView;exports.NotificationWidget=ee;exports.NotificationWidgetErrorBoundary=D;exports.VERSION=te;exports.WIDGET_NAME=ne;
|
|
3
|
+
${t.stack}`]})]}),c.jsxs("button",{type:"button",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",onClick:n,"data-testid":"error-retry-button",children:[c.jsx(b.MdRefresh,{className:"mr-1 w-4 h-4","aria-hidden":"true"}),"Try again"]})]});class j extends i.Component{constructor(n){super(n),this.handleRetry=()=>{this.setState({hasError:!1,error:null,errorInfo:null})},this.state={hasError:!1,error:null,errorInfo:null}}static getDerivedStateFromError(n){return{hasError:!0,error:n}}componentDidCatch(n,p){this.setState({errorInfo:p}),this.props.onError&&this.props.onError(n,p)}render(){return this.state.hasError?c.jsx(X,{error:this.state.error,onRetry:this.handleRetry}):this.props.children}}const K=i.createContext(null),Y=()=>{const t=i.useContext(K);if(!t)throw new Error("useSDK must be used within a NotificationWidget");return t},Z={notifications:[],unreadCount:0,preferences:{channels:{email:!0,push:!0,sms:!1,inApp:!0},subscriptions:[],deliverySchedule:{timezone:"UTC",quietHours:{start:"22:00",end:"08:00"},weekdays:[!0,!0,!0,!0,!0,!1,!1]}},ui:{isOpen:!1,currentView:"notifications",selectedNotifications:[],isLoading:!1,error:null},websocket:{connected:!1,reconnecting:!1}},ee=({config:t,children:n})=>{const[p,w]=i.useState({client:null,isInitialized:!1,error:null});return i.useEffect(()=>{let l=!0;return(async()=>{try{const d=window.__notificationSDK;if(d?.client&&JSON.stringify(d.config)===JSON.stringify(t)){l&&w({client:d.client,isInitialized:!0,error:null});return}const r=new H.NotificationClient({apiUrl:t.baseUrl,apiKey:t.apiKey,tenantId:t.tenantId,environmentId:t.environmentId});window.__notificationSDK={client:r,config:t},l&&w({client:r,isInitialized:!0,error:null})}catch(d){l&&w({client:null,isInitialized:!1,error:d})}})(),()=>{l=!1}},[t]),c.jsx(K.Provider,{value:p,children:n})},te=(t,n)=>{switch(n.type){case"SET_NOTIFICATIONS":return{...t,notifications:n.payload,unreadCount:n.payload.filter(f=>!f.isRead).length};case"ADD_NOTIFICATION":const p=[n.payload,...t.notifications];return{...t,notifications:p,unreadCount:p.filter(f=>!f.isRead).length};case"UPDATE_NOTIFICATION":const w=t.notifications.map(f=>f.id===n.payload.id?{...f,...n.payload.updates}:f);return{...t,notifications:w,unreadCount:w.filter(f=>!f.isRead).length};case"DELETE_NOTIFICATION":const l=t.notifications.filter(f=>f.id!==n.payload);return{...t,notifications:l,unreadCount:l.filter(f=>!f.isRead).length};case"SET_PREFERENCES":return{...t,preferences:n.payload};case"SET_UI_STATE":return{...t,ui:{...t.ui,...n.payload}};case"SET_WEBSOCKET_STATE":return{...t,websocket:{...t.websocket,...n.payload}};default:return t}},ne=({position:t="right",size:n="medium",theme:p="light",className:w="",onError:l,onMorePreferencesClick:f})=>{const[d,r]=i.useReducer(te,Z),{client:u,isInitialized:E,error:m}=Y(),g=i.useRef(null),k=i.useCallback(e=>{r({type:"SET_PREFERENCES",payload:e})},[]),I=i.useCallback(e=>{l&&l(e)},[l]),{error:S}=J({onPreferencesLoaded:k,onError:I}),{specificPreferences:a,isLoading:_,hasMore:N,loadMore:C}=Q(),{updatePreference:R,isSaving:D,error:P}=A.useLivePreferences({preferences:d.preferences,onPreferencesChange:k,onError:I});i.useEffect(()=>{if(a.length>0){const o=[...d.preferences.subscriptions];let s=!1;a.forEach(T=>{const y=o.findIndex(h=>h.workflowId===T.workflowId);if(y===-1)o.push(T),s=!0;else{const h=o[y],x={...h,name:T.name||h.name,enabled:T.enabled,channels:T.channels};(h.name!==x.name||h.enabled!==x.enabled||JSON.stringify(h.channels)!==JSON.stringify(x.channels))&&(o[y]=x,s=!0)}}),s&&r({type:"SET_PREFERENCES",payload:{...d.preferences,subscriptions:o}})}},[a]);const W=i.useMemo(()=>a.map(e=>d.preferences.subscriptions.find(s=>s.workflowId===e.workflowId)||e),[a,d.preferences.subscriptions]),O=i.useCallback(e=>{try{const o=A.createNotificationMapper();switch(e.type){case"notification_received":{const s=e.data;if(!o.validateWebSocketPayload(s))break;const T=o.toWidgetNotificationFromWebSocket(s);r({type:"ADD_NOTIFICATION",payload:T});break}case"notification_updated":r({type:"UPDATE_NOTIFICATION",payload:{id:e.data.id||e.data.notificationId,updates:e.data}});break;case"notification_deleted":r({type:"DELETE_NOTIFICATION",payload:e.data.id||e.data.notificationId});break;case"preferences_updated":r({type:"SET_PREFERENCES",payload:e.data});break;default:}}catch{}},[]),F=i.useCallback(async()=>{if(!(!u||!E||g.current))try{r({type:"SET_WEBSOCKET_STATE",payload:{reconnecting:!0}});const e=window.__notificationSDK?.config;if(!e)throw new Error("SDK configuration not available for WebSocket connection");const T=`${u.getApiHost()}/v1/notifications`,y=z.io(T,{query:{tenantId:e.tenantId,subscriberId:e.subscriberId,environmentId:e.environmentId},transports:["websocket","polling"],autoConnect:!1,reconnection:!0,reconnectionAttempts:10,reconnectionDelay:1e3,reconnectionDelayMax:5e3});g.current=y;let h=null;const x=()=>{h&&clearInterval(h),h=setInterval(()=>{y.connected&&y.emit("ping",{timestamp:new Date().toISOString()})},12e4)},V=()=>{h&&(clearInterval(h),h=null)};y.on("notification",v=>{O({type:"notification_received",data:v})}),y.on("connect",()=>{r({type:"SET_WEBSOCKET_STATE",payload:{connected:!0,reconnecting:!1}}),x()}),y.on("disconnect",v=>{r({type:"SET_WEBSOCKET_STATE",payload:{connected:!1,reconnecting:!1}}),V()}),y.on("reconnect_attempt",v=>{r({type:"SET_WEBSOCKET_STATE",payload:{connected:!1,reconnecting:!0}})}),y.on("connect_error",v=>{r({type:"SET_WEBSOCKET_STATE",payload:{connected:!1,reconnecting:!1}}),l&&l(v)}),y.connect()}catch(e){r({type:"SET_WEBSOCKET_STATE",payload:{connected:!1,reconnecting:!1}}),l&&l(e)}},[u,E,O,l]),M=i.useCallback(()=>{if(g.current)try{g.current.disconnect&&g.current.disconnect(),g.current=null,r({type:"SET_WEBSOCKET_STATE",payload:{connected:!1,reconnecting:!1}})}catch{}},[]),L=i.useCallback(()=>{r({type:"SET_UI_STATE",payload:{isOpen:!d.ui.isOpen}})},[d.ui.isOpen]),U=i.useCallback(()=>{r({type:"SET_UI_STATE",payload:{isOpen:!1}})},[]),B=i.useCallback(e=>{r({type:"SET_UI_STATE",payload:{currentView:e}})},[]),q=i.useCallback(async(e,o)=>{if(!u||!E)return;const s=window.__notificationSDK?.config;if(s){if(!e)throw new Error("notificationId is required");try{switch(o.type){case"mark_read":await u.inbox.markAsRead(e,s.tenantId,s.environmentId,s.subscriberId);break;case"mark_unread":await u.inbox.markAsUnread(e,s.tenantId,s.environmentId,s.subscriberId);break;case"archive":await u.inbox.archive(e,s.tenantId,s.environmentId,s.subscriberId);break;case"delete":await u.inbox.delete(e,s.tenantId,s.environmentId,s.subscriberId);break;default:o.handler&&await o.handler(e);break}switch(o.type){case"mark_read":r({type:"UPDATE_NOTIFICATION",payload:{id:e,updates:{isRead:!0}}});break;case"mark_unread":r({type:"UPDATE_NOTIFICATION",payload:{id:e,updates:{isRead:!1}}});break;case"archive":r({type:"UPDATE_NOTIFICATION",payload:{id:e,updates:{isArchived:!0}}});break;case"delete":r({type:"DELETE_NOTIFICATION",payload:e});break}}catch(T){l&&l(T)}}},[u]);return i.useEffect(()=>{if(!u||!E)return;(async()=>{try{r({type:"SET_UI_STATE",payload:{isLoading:!0}});const o=window.__notificationSDK?.config;if(!o)throw new Error("SDK configuration not available");const s=A.createNotificationMapper(),y=((await u.inbox.getRenderedNotifications({channel:"in_app",limit:50,offset:0},o.tenantId,o.environmentId,o.subscriberId))?.items||[]).map(h=>s.toWidgetNotification(h));r({type:"SET_NOTIFICATIONS",payload:y}),r({type:"SET_UI_STATE",payload:{isLoading:!1,error:null}})}catch(o){r({type:"SET_UI_STATE",payload:{isLoading:!1,error:o}}),l&&l(o)}})()},[u,E,l]),i.useEffect(()=>(u&&E&&F(),()=>{M()}),[u]),i.useEffect(()=>{if(!u||!E||d.websocket.connected)return;const e=setInterval(async()=>{try{const o=window.__notificationSDK?.config;if(!o)return;const s=A.createNotificationMapper(),y=((await u.inbox.getRenderedNotifications({channel:"in_app",limit:50,offset:0},o.tenantId,o.environmentId,o.subscriberId))?.items||[]).map(h=>s.toWidgetNotification(h));r({type:"SET_NOTIFICATIONS",payload:y})}catch{}},3e4);return()=>clearInterval(e)},[u,d.websocket.connected]),i.useEffect(()=>{const e=o=>{if(o.key==="notification_widget_sync"&&o.newValue)try{const s=JSON.parse(o.newValue);O(s)}catch{}};return window.addEventListener("storage",e),()=>window.removeEventListener("storage",e)},[O]),i.useEffect(()=>{r({type:"SET_UI_STATE",payload:{isLoading:D}})},[D]),i.useEffect(()=>{const e=m||P||S;e&&r({type:"SET_UI_STATE",payload:{error:e}})},[m,P,S]),!E&&!m?c.jsx("div",{className:`mx-widget-root relative inline-block ${w}`,"data-mx-widget":"root","data-widget-size":n||"small","data-theme":p,"data-testid":"notification-widget",children:c.jsx(b.ComponentErrorBoundary,{componentName:"BellComponent",children:c.jsx(b.BellComponent,{unreadCount:0,onClick:()=>{},size:n,disabled:!0})})}):m?c.jsx("div",{className:`mx-widget-root relative inline-block ${w}`,"data-mx-widget":"root","data-widget-size":n||"small","data-theme":p,"data-testid":"notification-widget",children:c.jsx(b.ComponentErrorBoundary,{componentName:"BellComponent",fallback:c.jsx(b.SDKConnectionFallback,{error:m.message,onRetry:()=>window.location.reload()}),children:c.jsx(b.BellComponent,{unreadCount:0,onClick:()=>{},size:n,disabled:!0})})}):c.jsxs("div",{className:`mx-widget-root min-w-[20rem] relative inline-block ${w}`,"data-mx-widget":"root","data-widget-size":n||"small","data-theme":p,"data-testid":"notification-widget",children:[c.jsx(b.ComponentErrorBoundary,{componentName:"BellComponent",children:c.jsx(b.BellComponent,{unreadCount:d.unreadCount,onClick:L,size:n,disabled:d.ui.isLoading})}),c.jsx(b.ComponentErrorBoundary,{componentName:"InboxPopover",fallback:c.jsx(b.LoadingFallback,{message:"Unable to load notifications"}),children:c.jsx(b.InboxPopover,{isOpen:d.ui.isOpen,onClose:U,position:t,currentView:d.ui.currentView,onViewChange:B,notifications:d.notifications,onNotificationAction:q,preferences:d.preferences,onPreferenceChange:R,isPreferencesLoading:D,specificPreferences:W,onLoadMoreSpecific:C,hasMoreSpecific:N,isListLoading:_,onMorePreferencesClick:f})})]})},re=({sdkConfig:t,...n})=>c.jsx(j,{onError:n.onError,children:c.jsx(ee,{config:t,children:c.jsx(ne,{...n})})}),ie="3.0.0",oe="@edusight/notification-widget";exports.BellComponent=b.BellComponent;exports.InboxPopover=b.InboxPopover;exports.NotificationItem=b.NotificationItem;exports.PreferencesView=b.PreferencesView;exports.NotificationWidget=re;exports.NotificationWidgetErrorBoundary=j;exports.VERSION=ie;exports.WIDGET_NAME=oe;
|
|
4
4
|
//# sourceMappingURL=index.cjs.js.map
|
package/dist/index.cjs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs.js","sources":["../src/hooks/usePreferencesSync.ts","../src/hooks/useSpecificPreferences.ts","../src/components/ErrorBoundary.tsx","../src/components/NotificationWidget.tsx","../src/index.ts"],"sourcesContent":["import { useEffect, useState, useCallback } from 'react';\n\nimport { NotificationPreferences } from '../types/core';\n\nconst useNotificationsClient = () => {\n return (window as any).__notificationSDK?.client;\n};\n\nexport interface UsePreferencesSyncProps {\n onPreferencesLoaded: (preferences: NotificationPreferences) => void;\n onError?: (error: Error) => void;\n}\n\nexport interface UsePreferencesSyncResult {\n isLoading: boolean;\n error: Error | null;\n preferences: NotificationPreferences | null;\n}\n\nexport const usePreferencesSync = ({\n onPreferencesLoaded,\n onError,\n}: UsePreferencesSyncProps): UsePreferencesSyncResult => {\n const notificationClient = useNotificationsClient();\n const [isLoading, setIsLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n const [preferences, setPreferences] = useState<NotificationPreferences | null>(null);\n\n const loadPreferences = useCallback(async () => {\n try {\n setIsLoading(true);\n setError(null);\n\n if (!notificationClient) {\n throw new Error('Notification client not available');\n }\n\n const config = (window as any).__notificationSDK?.config;\n\n if (!config) {\n throw new Error('SDK configuration not available');\n }\n\n const { subscriberId, tenantId, environmentId } = config;\n\n if (!subscriberId || !tenantId || !environmentId) {\n throw new Error('SubscriberId, TenantId or EnvironmentId not available in config');\n }\n\n const servicePreferences = await notificationClient.preferences.get(\n tenantId,\n subscriberId,\n environmentId,\n );\n\n // Fetch schedule separately\n let schedule = null;\n try {\n schedule = await notificationClient.preferences.getSchedule(\n tenantId,\n subscriberId,\n environmentId,\n );\n } catch (e) {\n console.warn('Failed to fetch schedule, using defaults:', e);\n }\n\n const mappedPreferences: NotificationPreferences = {\n channels: {\n email: servicePreferences.emailEnabled ?? true,\n push: servicePreferences.pushEnabled ?? true,\n sms: servicePreferences.smsEnabled ?? false,\n inApp: servicePreferences.inAppEnabled ?? true,\n },\n subscriptions: [],\n deliverySchedule: {\n enabled: schedule?.isEnabled || false,\n timezone: 'UTC',\n quietHours: {\n start: servicePreferences.quietHoursStart ?? '22:00',\n end: servicePreferences.quietHoursEnd ?? '08:00',\n },\n weekdays: schedule?.weeklySchedule\n ? [\n !!schedule.weeklySchedule.monday,\n !!schedule.weeklySchedule.tuesday,\n !!schedule.weeklySchedule.wednesday,\n !!schedule.weeklySchedule.thursday,\n !!schedule.weeklySchedule.friday,\n !!schedule.weeklySchedule.saturday,\n !!schedule.weeklySchedule.sunday,\n ]\n : [true, true, true, true, true, false, false],\n weeklySchedule: schedule?.weeklySchedule || undefined,\n },\n };\n\n if (servicePreferences.categories) {\n Object.entries(servicePreferences.categories).forEach(([workflowId, categoryPrefs]) => {\n mappedPreferences.subscriptions.push({\n workflowId,\n name: workflowId,\n enabled: true,\n channels: {\n email: (categoryPrefs as any).emailEnabled ?? true,\n push: (categoryPrefs as any).pushEnabled ?? true,\n sms: (categoryPrefs as any).smsEnabled ?? false,\n inApp: (categoryPrefs as any).inAppEnabled ?? true,\n },\n });\n });\n }\n\n setPreferences(mappedPreferences);\n onPreferencesLoaded(mappedPreferences);\n } catch (err: any) {\n const error = err instanceof Error ? err : new Error('Failed to load preferences');\n\n // If 404, it means preferences don't exist yet for this user.\n // We'll use defaults and suppress the error callback.\n const isNotFound = (err as any)?.response?.status === 404 || (err as any)?.status === 404;\n\n if (!isNotFound) {\n setError(error);\n onError?.(error);\n } else {\n console.warn('Preferences not found for user (404), using defaults.');\n }\n\n const defaultPreferences: NotificationPreferences = {\n channels: {\n email: true,\n push: true,\n sms: false,\n inApp: true,\n },\n subscriptions: [],\n deliverySchedule: {\n enabled: false,\n timezone: 'UTC',\n quietHours: {\n start: '22:00',\n end: '08:00',\n },\n weekdays: [true, true, true, true, true, false, false],\n },\n };\n setPreferences(defaultPreferences);\n onPreferencesLoaded(defaultPreferences);\n } finally {\n setIsLoading(false);\n }\n }, [notificationClient, onPreferencesLoaded, onError]);\n\n useEffect(() => {\n if (notificationClient) {\n loadPreferences();\n }\n }, [notificationClient, loadPreferences]);\n\n return {\n isLoading,\n error,\n preferences,\n };\n};\n","import { useState, useCallback, useEffect } from 'react';\n\nimport { WorkflowSubscription } from '../types/core';\n\nconst useNotificationsClient = () => {\n return (window as any).__notificationSDK?.client;\n};\n\nexport interface UseSpecificPreferencesResult {\n specificPreferences: WorkflowSubscription[];\n isLoading: boolean;\n hasMore: boolean;\n loadMore: () => Promise<void>;\n refetch: () => Promise<void>;\n}\n\nexport const useSpecificPreferences = (): UseSpecificPreferencesResult => {\n const client = useNotificationsClient();\n const [items, setItems] = useState<WorkflowSubscription[]>([]);\n const [isLoading, setIsLoading] = useState(false);\n const [hasMore, setHasMore] = useState(true);\n const [offset, setOffset] = useState(0);\n const LIMIT = 5;\n\n const loadMore = useCallback(async () => {\n if (!client || isLoading || !hasMore) return;\n\n try {\n setIsLoading(true);\n const sdkConfig = (window as any).__notificationSDK?.config;\n if (!sdkConfig) return;\n\n const response = await client.preferences.listSpecific(\n sdkConfig.tenantId,\n sdkConfig.subscriberId,\n {\n includeWorkflows: true,\n includeTemplates: false,\n activeOnly: true,\n limit: LIMIT,\n offset: offset,\n },\n );\n\n const newItems = (response.items || []).map((item: any) => ({\n workflowId: item.identifier,\n name: item.name,\n enabled: item.preference.enabled,\n channels: item.preference.channels,\n }));\n\n setItems((prev) => {\n // Determine uniqueness by workflowId to avoid duplicates if offset logic overlaps or double fetch\n const existingIds = new Set(prev.map((i) => i.workflowId));\n const uniqueNewItems = newItems.filter((i: any) => !existingIds.has(i.workflowId));\n return [...prev, ...uniqueNewItems];\n });\n\n setOffset((prev) => prev + LIMIT);\n\n // Check if we reached the end\n if (\n newItems.length < LIMIT ||\n (response.total !== undefined && items.length + newItems.length >= response.total)\n ) {\n setHasMore(false);\n }\n } catch (error) {\n console.error('Failed to load specific preferences:', error);\n // Don't disable hasMore on error, user can retry by scrolling\n } finally {\n setIsLoading(false);\n }\n }, [client, offset, hasMore, isLoading, items.length]);\n\n // Initial load\n useEffect(() => {\n if (client && offset === 0 && items.length === 0) {\n loadMore();\n }\n }, [client, loadMore, offset, items.length]);\n\n const refetch = async () => {\n setItems([]);\n setOffset(0);\n setHasMore(true);\n // Note: The effect will trigger loadMore because offset becomes 0 and items becomes empty\n };\n\n return {\n specificPreferences: items,\n isLoading,\n hasMore,\n loadMore,\n refetch,\n };\n};\n","import React, { Component, ErrorInfo, ReactNode } from 'react';\nimport { MdError, MdRefresh } from 'react-icons/md';\n\nimport { ErrorBoundaryState } from '../types/core';\n\ninterface ErrorBoundaryProps {\n children: ReactNode;\n onError?: (error: Error, errorInfo: ErrorInfo) => void;\n}\n\nconst ErrorFallback: React.FC<{\n error: Error | null;\n onRetry: () => void;\n}> = ({ error, onRetry }) => (\n <div\n className=\"p-4 bg-[var(--widget-error)]/10 border border-[var(--widget-error)]/20 rounded-lg\"\n role=\"alert\"\n data-testid=\"error-boundary-fallback\"\n >\n <div className=\"flex items-center mb-2\">\n <MdError className=\"w-6 h-6 text-[var(--widget-error)] mr-2\" aria-hidden=\"true\" />\n <h3 className=\"text-sm font-medium text-[var(--widget-error)]\">Something went wrong</h3>\n </div>\n\n <p className=\"text-sm mb-3 text-[var(--widget-error)]/80\">\n The notification widget encountered an error and couldn't load properly.\n </p>\n\n {process.env.NODE_ENV === 'development' && error && (\n <details className=\"mb-3\">\n <summary className=\"text-xs cursor-pointer text-[var(--widget-error)] hover:text-[var(--widget-error)]/80 transition-colors\">\n Error details (development only)\n </summary>\n <pre className=\"mt-2 text-xs bg-[var(--widget-error)]/5 p-2 rounded overflow-auto max-h-32 text-[var(--widget-error)]\">\n {error.message}\n {error.stack && `\\n\\n${error.stack}`}\n </pre>\n </details>\n )}\n\n <button\n type=\"button\"\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\"\n onClick={onRetry}\n data-testid=\"error-retry-button\"\n >\n <MdRefresh className=\"mr-1 w-4 h-4\" aria-hidden=\"true\" />\n Try again\n </button>\n </div>\n);\n\nexport class NotificationWidgetErrorBoundary extends Component<\n ErrorBoundaryProps,\n ErrorBoundaryState\n> {\n constructor(props: ErrorBoundaryProps) {\n super(props);\n this.state = {\n hasError: false,\n error: null,\n errorInfo: null,\n };\n }\n\n static getDerivedStateFromError(error: Error): Partial<ErrorBoundaryState> {\n return {\n hasError: true,\n error,\n };\n }\n\n componentDidCatch(error: Error, errorInfo: ErrorInfo) {\n this.setState({\n errorInfo,\n });\n\n console.error('NotificationWidget Error Boundary caught an error:', {\n message: error.message,\n stack: error.stack,\n componentStack: errorInfo.componentStack,\n timestamp: new Date().toISOString(),\n });\n\n if (this.props.onError) {\n this.props.onError(error, errorInfo);\n }\n }\n\n handleRetry = () => {\n this.setState({\n hasError: false,\n error: null,\n errorInfo: null,\n });\n };\n\n render() {\n if (this.state.hasError) {\n return <ErrorFallback error={this.state.error} onRetry={this.handleRetry} />;\n }\n\n return this.props.children;\n }\n}\n\nexport const useErrorHandler = () => {\n return (error: Error, errorInfo?: ErrorInfo) => {\n console.error('Widget error:', {\n message: error.message,\n stack: error.stack,\n errorInfo,\n timestamp: new Date().toISOString(),\n });\n };\n};\n","import { NotificationClient } from '@edusight/notification-sdk';\nimport React, {\n useReducer,\n useEffect,\n useCallback,\n createContext,\n useContext,\n useRef,\n} from 'react';\nimport { io as ioClient } from 'socket.io-client';\n\nimport { useLivePreferences } from '../hooks/useLivePreferences';\nimport { usePreferencesSync } from '../hooks/usePreferencesSync';\nimport { useSpecificPreferences } from '../hooks/useSpecificPreferences';\nimport {\n NotificationWidgetProps,\n WidgetState,\n WidgetAction,\n SDKConfiguration,\n} from '../types/core';\nimport { createNotificationMapper } from '../utils/notification-mapper';\n\nimport { BellComponent } from './BellComponent';\nimport { ComponentErrorBoundary } from './ComponentErrorBoundary';\nimport { NotificationWidgetErrorBoundary } from './ErrorBoundary';\nimport { SDKConnectionFallback, LoadingFallback } from './FallbackComponents';\nimport { InboxPopover } from './InboxPopover';\n\ninterface SDKContextType {\n client: any;\n isInitialized: boolean;\n error: Error | null;\n}\n\nconst SDKContext = createContext<SDKContextType | null>(null);\n\nexport const useSDK = () => {\n const context = useContext(SDKContext);\n if (!context) {\n throw new Error('useSDK must be used within a NotificationWidget');\n }\n return context;\n};\n\nconst initialState: WidgetState = {\n notifications: [],\n unreadCount: 0,\n preferences: {\n channels: {\n email: true,\n push: true,\n sms: false,\n inApp: true,\n },\n subscriptions: [],\n deliverySchedule: {\n timezone: 'UTC',\n quietHours: {\n start: '22:00',\n end: '08:00',\n },\n weekdays: [true, true, true, true, true, false, false],\n },\n },\n ui: {\n isOpen: false,\n currentView: 'notifications',\n selectedNotifications: [],\n isLoading: false,\n error: null,\n },\n websocket: {\n connected: false,\n reconnecting: false,\n },\n};\n\nconst SDKProvider: React.FC<{ config: SDKConfiguration; children: React.ReactNode }> = ({\n config,\n children,\n}) => {\n const [sdkState, setSdkState] = React.useState<SDKContextType>({\n client: null,\n isInitialized: false,\n error: null,\n });\n\n useEffect(() => {\n let isMounted = true;\n\n const initializeSDK = async () => {\n try {\n const existingSDK = (window as any).__notificationSDK;\n\n // Check if we can reuse the existing SDK instance\n if (existingSDK?.client) {\n // Compare new config with existing config to determine if we need to re-initialize\n // We use simple JSON stringify as configs are simple objects with strings/numbers\n const isConfigMatch = JSON.stringify(existingSDK.config) === JSON.stringify(config);\n\n if (isConfigMatch) {\n if (isMounted) {\n setSdkState({\n client: existingSDK.client,\n isInitialized: true,\n error: null,\n });\n }\n return;\n } else {\n console.log('[NotificationWidget] Config changed, re-initializing SDK', {\n old: existingSDK.config,\n new: config,\n });\n }\n }\n\n const client = new NotificationClient({\n apiUrl: config.baseUrl,\n apiKey: config.apiKey,\n tenantId: config.tenantId,\n environmentId: config.environmentId,\n });\n\n (window as any).__notificationSDK = { client, config };\n\n if (isMounted) {\n setSdkState({\n client,\n isInitialized: true,\n error: null,\n });\n }\n } catch (error) {\n console.error('Failed to initialize SDK:', error);\n if (isMounted) {\n setSdkState({\n client: null,\n isInitialized: false,\n error: error as Error,\n });\n }\n }\n };\n\n initializeSDK();\n\n return () => {\n isMounted = false;\n };\n }, [config]);\n\n return <SDKContext.Provider value={sdkState}>{children}</SDKContext.Provider>;\n};\n\nconst widgetReducer = (state: WidgetState, action: WidgetAction): WidgetState => {\n switch (action.type) {\n case 'SET_NOTIFICATIONS':\n return {\n ...state,\n notifications: action.payload,\n unreadCount: action.payload.filter((n) => !n.isRead).length,\n };\n\n case 'ADD_NOTIFICATION':\n const newNotifications = [action.payload, ...state.notifications];\n return {\n ...state,\n notifications: newNotifications,\n unreadCount: newNotifications.filter((n) => !n.isRead).length,\n };\n\n case 'UPDATE_NOTIFICATION':\n const updatedNotifications = state.notifications.map((n) =>\n n.id === action.payload.id ? { ...n, ...action.payload.updates } : n,\n );\n return {\n ...state,\n notifications: updatedNotifications,\n unreadCount: updatedNotifications.filter((n) => !n.isRead).length,\n };\n\n case 'DELETE_NOTIFICATION':\n const filteredNotifications = state.notifications.filter((n) => n.id !== action.payload);\n return {\n ...state,\n notifications: filteredNotifications,\n unreadCount: filteredNotifications.filter((n) => !n.isRead).length,\n };\n\n case 'SET_PREFERENCES':\n return {\n ...state,\n preferences: action.payload,\n };\n\n case 'SET_UI_STATE':\n return {\n ...state,\n ui: { ...state.ui, ...action.payload },\n };\n\n case 'SET_WEBSOCKET_STATE':\n return {\n ...state,\n websocket: { ...state.websocket, ...action.payload },\n };\n\n default:\n return state;\n }\n};\n\nconst NotificationWidgetInternal: React.FC<Omit<NotificationWidgetProps, 'sdkConfig'>> = ({\n position = 'right',\n size = 'medium',\n theme = 'light',\n className = '',\n\n onError,\n onMorePreferencesClick,\n}) => {\n const [state, dispatch] = useReducer(widgetReducer, initialState);\n const { client, isInitialized, error: sdkError } = useSDK();\n const websocketRef = useRef<any>(null);\n\n const handlePreferencesChange = useCallback((preferences: any) => {\n dispatch({\n type: 'SET_PREFERENCES',\n payload: preferences,\n });\n }, []);\n\n const handleWidgetError = useCallback(\n (error: Error) => {\n console.error('Widget error:', error);\n if (onError) {\n onError(error);\n }\n },\n [onError],\n );\n\n const { error: preferencesLoadError } = usePreferencesSync({\n onPreferencesLoaded: handlePreferencesChange,\n onError: handleWidgetError,\n });\n\n const {\n specificPreferences,\n isLoading: isSpecificLoading,\n hasMore: hasMoreSpecific,\n loadMore: loadMoreSpecific,\n } = useSpecificPreferences();\n\n const {\n updatePreference,\n isSaving,\n error: preferencesError,\n } = useLivePreferences({\n preferences: state.preferences,\n onPreferencesChange: handlePreferencesChange,\n onError: handleWidgetError,\n });\n\n // Merge specific preferences into state when they load\n useEffect(() => {\n if (specificPreferences.length > 0) {\n const currentSubs = state.preferences.subscriptions;\n const newSubs = [...currentSubs];\n let changed = false;\n\n specificPreferences.forEach((sp) => {\n const existingIdx = newSubs.findIndex((s) => s.workflowId === sp.workflowId);\n\n // If not in state, add it\n if (existingIdx === -1) {\n newSubs.push(sp);\n changed = true;\n } else {\n // If existing name is just the ID (default), update with real name from specific prefs\n const existing = newSubs[existingIdx];\n if (existing.name === existing.workflowId && sp.name && sp.name !== sp.workflowId) {\n newSubs[existingIdx] = { ...existing, name: sp.name };\n changed = true;\n }\n }\n });\n\n if (changed) {\n dispatch({\n type: 'SET_PREFERENCES',\n payload: {\n ...state.preferences,\n subscriptions: newSubs,\n },\n });\n }\n }\n }, [specificPreferences]); // Depend on specificPreferences list changes (load more)\n\n // Create display list that respects order from hook but values from state\n const displaySpecificPreferences = React.useMemo(() => {\n return specificPreferences.map((sp) => {\n const found = state.preferences.subscriptions.find((s) => s.workflowId === sp.workflowId);\n return found || sp;\n });\n }, [specificPreferences, state.preferences.subscriptions]);\n\n const handleWebSocketEvent = useCallback((event: any) => {\n try {\n const notificationMapper = createNotificationMapper();\n\n switch (event.type) {\n case 'notification_received': {\n const wsPayload = event.data;\n\n if (!notificationMapper.validateWebSocketPayload(wsPayload)) {\n console.error('Invalid WebSocket notification payload, skipping', wsPayload);\n break;\n }\n\n const mappedNotification =\n notificationMapper.toWidgetNotificationFromWebSocket(wsPayload);\n dispatch({\n type: 'ADD_NOTIFICATION',\n payload: mappedNotification,\n });\n break;\n }\n\n case 'notification_updated':\n dispatch({\n type: 'UPDATE_NOTIFICATION',\n payload: {\n id: event.data.id || event.data.notificationId,\n updates: event.data,\n },\n });\n break;\n\n case 'notification_deleted':\n dispatch({\n type: 'DELETE_NOTIFICATION',\n payload: event.data.id || event.data.notificationId,\n });\n break;\n\n case 'preferences_updated':\n dispatch({\n type: 'SET_PREFERENCES',\n payload: event.data,\n });\n break;\n\n default:\n console.log('Unknown WebSocket event type:', event.type);\n }\n } catch (error) {\n console.error('Error handling WebSocket event:', error);\n }\n }, []);\n\n const connectWebSocket = useCallback(async () => {\n if (!client || !isInitialized || websocketRef.current) return;\n\n try {\n dispatch({\n type: 'SET_WEBSOCKET_STATE',\n payload: { reconnecting: true },\n });\n\n const sdkConfig = (window as any).__notificationSDK?.config;\n if (!sdkConfig) {\n throw new Error('SDK configuration not available for WebSocket connection');\n }\n\n const baseUrl = client.getApiHost();\n const namespace = '/v1/notifications';\n const fullUrl = `${baseUrl}${namespace}`;\n\n console.log('Connecting to Socket.IO at:', fullUrl);\n\n const socket = ioClient(fullUrl, {\n query: {\n tenantId: sdkConfig.tenantId,\n subscriberId: sdkConfig.subscriberId,\n environmentId: sdkConfig.environmentId,\n },\n transports: ['websocket'],\n autoConnect: false,\n reconnection: true,\n reconnectionAttempts: 10,\n reconnectionDelay: 1000,\n reconnectionDelayMax: 5000,\n });\n\n websocketRef.current = socket;\n\n socket.on('notification', (payload: any) => {\n console.log('Received notification:', payload);\n handleWebSocketEvent({\n type: 'notification_received',\n data: payload,\n });\n });\n\n socket.on('connect', () => {\n console.log('Socket.IO connected successfully');\n dispatch({\n type: 'SET_WEBSOCKET_STATE',\n payload: { connected: true, reconnecting: false },\n });\n });\n\n socket.on('disconnect', (reason: any) => {\n console.log('Socket.IO disconnected:', reason);\n dispatch({\n type: 'SET_WEBSOCKET_STATE',\n payload: { connected: false, reconnecting: false },\n });\n });\n\n socket.on('reconnect_attempt', (attempt: any) => {\n console.log('Socket.IO reconnection attempt:', attempt);\n dispatch({\n type: 'SET_WEBSOCKET_STATE',\n payload: { connected: false, reconnecting: true },\n });\n });\n\n socket.on('connect_error', (error: any) => {\n console.error('Socket.IO connection error:', error);\n dispatch({\n type: 'SET_WEBSOCKET_STATE',\n payload: { connected: false, reconnecting: false },\n });\n if (onError) {\n onError(error);\n }\n });\n\n socket.connect();\n } catch (error) {\n console.error('Failed to connect WebSocket:', error);\n dispatch({\n type: 'SET_WEBSOCKET_STATE',\n payload: { connected: false, reconnecting: false },\n });\n if (onError) {\n onError(error as Error);\n }\n }\n }, [client, isInitialized, handleWebSocketEvent, onError]);\n\n const disconnectWebSocket = useCallback(() => {\n if (websocketRef.current) {\n try {\n if (websocketRef.current.disconnect) {\n websocketRef.current.disconnect();\n }\n websocketRef.current = null;\n dispatch({\n type: 'SET_WEBSOCKET_STATE',\n payload: { connected: false, reconnecting: false },\n });\n } catch (error) {\n console.error('Error disconnecting WebSocket:', error);\n }\n }\n }, []);\n\n const handleBellClick = useCallback(() => {\n dispatch({\n type: 'SET_UI_STATE',\n payload: { isOpen: !state.ui.isOpen },\n });\n }, [state.ui.isOpen]);\n\n const handlePopoverClose = useCallback(() => {\n dispatch({\n type: 'SET_UI_STATE',\n payload: { isOpen: false },\n });\n }, []);\n\n const handleViewChange = useCallback((view: 'notifications' | 'preferences') => {\n dispatch({\n type: 'SET_UI_STATE',\n payload: { currentView: view },\n });\n }, []);\n\n const handleNotificationAction = useCallback(\n async (id: string, action: any) => {\n if (!client || !isInitialized) {\n console.error('SDK not initialized');\n return;\n }\n\n const sdkConfig = (window as any).__notificationSDK?.config;\n if (!sdkConfig) {\n console.error('SDK configuration not available');\n return;\n }\n\n if (!id) {\n console.error('notificationId is required');\n throw new Error('notificationId is required');\n }\n\n try {\n switch (action.type) {\n case 'mark_read':\n await client.inbox.markAsRead(\n id,\n sdkConfig.tenantId,\n sdkConfig.environmentId,\n sdkConfig.subscriberId,\n );\n break;\n case 'mark_unread':\n await client.inbox.markAsUnread(\n id,\n sdkConfig.tenantId,\n sdkConfig.environmentId,\n sdkConfig.subscriberId,\n );\n break;\n case 'archive':\n await client.inbox.archive(\n id,\n sdkConfig.tenantId,\n sdkConfig.environmentId,\n sdkConfig.subscriberId,\n );\n break;\n case 'delete':\n await client.inbox.delete(\n id,\n sdkConfig.tenantId,\n sdkConfig.environmentId,\n sdkConfig.subscriberId,\n );\n break;\n default:\n if (action.handler) {\n await action.handler(id);\n }\n break;\n }\n\n switch (action.type) {\n case 'mark_read':\n dispatch({\n type: 'UPDATE_NOTIFICATION',\n payload: { id, updates: { isRead: true } },\n });\n break;\n case 'mark_unread':\n dispatch({\n type: 'UPDATE_NOTIFICATION',\n payload: { id, updates: { isRead: false } },\n });\n break;\n case 'archive':\n dispatch({\n type: 'UPDATE_NOTIFICATION',\n payload: { id, updates: { isArchived: true } },\n });\n break;\n case 'delete':\n dispatch({\n type: 'DELETE_NOTIFICATION',\n payload: id,\n });\n break;\n }\n } catch (error) {\n console.error('Error performing notification action:', error);\n if (onError) {\n onError(error as Error);\n }\n }\n },\n [client],\n );\n\n useEffect(() => {\n if (!client || !isInitialized) return;\n\n const loadNotifications = async () => {\n try {\n dispatch({\n type: 'SET_UI_STATE',\n payload: { isLoading: true },\n });\n\n const sdkConfig = (window as any).__notificationSDK?.config;\n if (!sdkConfig) {\n throw new Error('SDK configuration not available');\n }\n\n const notificationMapper = createNotificationMapper();\n const response = await client.inbox.getRenderedNotifications(\n {\n channel: 'in_app',\n limit: 50,\n offset: 0,\n },\n sdkConfig.tenantId,\n sdkConfig.environmentId,\n sdkConfig.subscriberId,\n );\n\n const coreNotifications = (response?.items || []).map((item: any) =>\n notificationMapper.toWidgetNotification(item),\n );\n\n dispatch({\n type: 'SET_NOTIFICATIONS',\n payload: coreNotifications,\n });\n\n dispatch({\n type: 'SET_UI_STATE',\n payload: { isLoading: false, error: null },\n });\n } catch (error) {\n console.error('Failed to load notifications:', error);\n dispatch({\n type: 'SET_UI_STATE',\n payload: {\n isLoading: false,\n error: error as Error,\n },\n });\n if (onError) {\n onError(error as Error);\n }\n }\n };\n\n loadNotifications();\n }, [client, isInitialized, onError]);\n\n useEffect(() => {\n if (client && isInitialized) {\n connectWebSocket();\n }\n\n return () => {\n disconnectWebSocket();\n };\n }, [client]);\n\n useEffect(() => {\n if (!client || !isInitialized) return;\n\n if (state.websocket.connected) return;\n\n const pollInterval = setInterval(async () => {\n try {\n const sdkConfig = (window as any).__notificationSDK?.config;\n if (!sdkConfig) {\n return;\n }\n\n const notificationMapper = createNotificationMapper();\n const response = await client.inbox.getRenderedNotifications(\n {\n channel: 'in_app',\n limit: 50,\n offset: 0,\n },\n sdkConfig.tenantId,\n sdkConfig.environmentId,\n sdkConfig.subscriberId,\n );\n\n const coreNotifications = (response?.items || []).map((item: any) =>\n notificationMapper.toWidgetNotification(item),\n );\n\n dispatch({\n type: 'SET_NOTIFICATIONS',\n payload: coreNotifications,\n });\n } catch (error) {\n console.error('Polling failed:', error);\n }\n }, 30000);\n\n return () => clearInterval(pollInterval);\n }, [client, state.websocket.connected]);\n\n useEffect(() => {\n const handleStorageChange = (event: StorageEvent) => {\n if (event.key === 'notification_widget_sync' && event.newValue) {\n try {\n const syncData = JSON.parse(event.newValue);\n handleWebSocketEvent(syncData);\n } catch (error) {\n console.error('Error parsing sync data:', error);\n }\n }\n };\n\n window.addEventListener('storage', handleStorageChange);\n return () => window.removeEventListener('storage', handleStorageChange);\n }, [handleWebSocketEvent]);\n\n useEffect(() => {\n dispatch({\n type: 'SET_UI_STATE',\n payload: { isLoading: isSaving },\n });\n }, [isSaving]);\n\n useEffect(() => {\n const error = sdkError || preferencesError || preferencesLoadError;\n if (error) {\n dispatch({\n type: 'SET_UI_STATE',\n payload: { error: error },\n });\n }\n }, [sdkError, preferencesError, preferencesLoadError]);\n\n if (!isInitialized && !sdkError) {\n return (\n <div\n className={`mx-widget-root relative inline-block ${className}`}\n data-mx-widget=\"root\"\n data-widget-size={size || 'small'}\n data-theme={theme}\n data-testid=\"notification-widget\"\n >\n <ComponentErrorBoundary componentName=\"BellComponent\">\n <BellComponent unreadCount={0} onClick={() => { }} size={size} disabled={true} />\n </ComponentErrorBoundary>\n </div>\n );\n }\n\n if (sdkError) {\n return (\n <div\n className={`mx-widget-root relative inline-block ${className}`}\n data-mx-widget=\"root\"\n data-widget-size={size || 'small'}\n data-theme={theme}\n data-testid=\"notification-widget\"\n >\n <ComponentErrorBoundary\n componentName=\"BellComponent\"\n fallback={\n <SDKConnectionFallback\n error={sdkError.message}\n onRetry={() => window.location.reload()}\n />\n }\n >\n <BellComponent unreadCount={0} onClick={() => { }} size={size} disabled={true} />\n </ComponentErrorBoundary>\n </div>\n );\n }\n\n return (\n <div\n className={`mx-widget-root min-w-[20rem] relative inline-block ${className}`}\n data-mx-widget=\"root\"\n data-widget-size={size || 'small'}\n data-theme={theme}\n data-testid=\"notification-widget\"\n >\n <ComponentErrorBoundary componentName=\"BellComponent\">\n <BellComponent\n unreadCount={state.unreadCount}\n onClick={handleBellClick}\n size={size}\n disabled={state.ui.isLoading}\n />\n </ComponentErrorBoundary>\n\n <ComponentErrorBoundary\n componentName=\"InboxPopover\"\n fallback={<LoadingFallback message=\"Unable to load notifications\" />}\n >\n <InboxPopover\n isOpen={state.ui.isOpen}\n onClose={handlePopoverClose}\n position={position}\n currentView={state.ui.currentView}\n onViewChange={handleViewChange}\n notifications={state.notifications}\n onNotificationAction={handleNotificationAction}\n preferences={state.preferences}\n onPreferenceChange={updatePreference}\n isPreferencesLoading={isSaving}\n specificPreferences={displaySpecificPreferences}\n onLoadMoreSpecific={loadMoreSpecific}\n hasMoreSpecific={hasMoreSpecific}\n isListLoading={isSpecificLoading}\n onMorePreferencesClick={onMorePreferencesClick}\n />\n </ComponentErrorBoundary>\n </div>\n );\n};\n\nexport const NotificationWidget: React.FC<NotificationWidgetProps> = ({ sdkConfig, ...props }) => {\n return (\n <NotificationWidgetErrorBoundary onError={props.onError}>\n <SDKProvider config={sdkConfig}>\n <NotificationWidgetInternal {...props} />\n </SDKProvider>\n </NotificationWidgetErrorBoundary>\n );\n};\n","export { NotificationWidget } from './components/NotificationWidget';\n\nexport { BellComponent } from './components/BellComponent';\nexport { InboxPopover } from './components/InboxPopover';\nexport { NotificationItem } from './components/NotificationItem';\nexport { PreferencesView } from './components/PreferencesView';\n\nexport { NotificationWidgetErrorBoundary } from './components/ErrorBoundary';\n\nexport type * from './types/core';\n\nexport type {\n Notification as SDKNotification,\n NotificationFilters,\n} from '@edusight/notification-sdk';\n\nimport '../src/styles/index.css';\n\nexport const VERSION = '3.0.0';\nexport const WIDGET_NAME = '@edusight/notification-widget';\n"],"names":["useNotificationsClient","usePreferencesSync","onPreferencesLoaded","onError","notificationClient","isLoading","setIsLoading","useState","error","setError","preferences","setPreferences","loadPreferences","useCallback","config","subscriberId","tenantId","environmentId","servicePreferences","schedule","mappedPreferences","workflowId","categoryPrefs","err","defaultPreferences","useEffect","useSpecificPreferences","client","items","setItems","hasMore","setHasMore","offset","setOffset","LIMIT","loadMore","sdkConfig","response","newItems","item","prev","existingIds","i","uniqueNewItems","ErrorFallback","onRetry","jsxs","jsx","MdError","MdRefresh","NotificationWidgetErrorBoundary","Component","props","errorInfo","SDKContext","createContext","useSDK","context","useContext","initialState","SDKProvider","children","sdkState","setSdkState","React","isMounted","existingSDK","NotificationClient","widgetReducer","state","action","n","newNotifications","updatedNotifications","filteredNotifications","NotificationWidgetInternal","position","size","theme","className","onMorePreferencesClick","dispatch","useReducer","isInitialized","sdkError","websocketRef","useRef","handlePreferencesChange","handleWidgetError","preferencesLoadError","specificPreferences","isSpecificLoading","hasMoreSpecific","loadMoreSpecific","updatePreference","isSaving","preferencesError","useLivePreferences","newSubs","changed","sp","existingIdx","s","existing","displaySpecificPreferences","handleWebSocketEvent","event","notificationMapper","createNotificationMapper","wsPayload","mappedNotification","connectWebSocket","fullUrl","socket","ioClient","payload","reason","attempt","disconnectWebSocket","handleBellClick","handlePopoverClose","handleViewChange","view","handleNotificationAction","id","coreNotifications","pollInterval","handleStorageChange","syncData","ComponentErrorBoundary","BellComponent","SDKConnectionFallback","LoadingFallback","InboxPopover","NotificationWidget","VERSION","WIDGET_NAME"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs.js","sources":["../src/hooks/usePreferencesSync.ts","../src/hooks/useSpecificPreferences.ts","../src/components/ErrorBoundary.tsx","../src/components/NotificationWidget.tsx","../src/index.ts"],"sourcesContent":["import { useEffect, useState, useCallback } from 'react';\n\nimport { NotificationPreferences } from '../types/core';\n\nconst useNotificationsClient = () => {\n return (window as any).__notificationSDK?.client;\n};\n\nexport interface UsePreferencesSyncProps {\n onPreferencesLoaded: (preferences: NotificationPreferences) => void;\n onError?: (error: Error) => void;\n}\n\nexport interface UsePreferencesSyncResult {\n isLoading: boolean;\n error: Error | null;\n preferences: NotificationPreferences | null;\n}\n\nexport const usePreferencesSync = ({\n onPreferencesLoaded,\n onError,\n}: UsePreferencesSyncProps): UsePreferencesSyncResult => {\n const notificationClient = useNotificationsClient();\n const [isLoading, setIsLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n const [preferences, setPreferences] = useState<NotificationPreferences | null>(null);\n\n const loadPreferences = useCallback(async () => {\n try {\n setIsLoading(true);\n setError(null);\n\n if (!notificationClient) {\n throw new Error('Notification client not available');\n }\n\n const config = (window as any).__notificationSDK?.config;\n\n if (!config) {\n throw new Error('SDK configuration not available');\n }\n\n const { subscriberId, tenantId, environmentId } = config;\n\n if (!subscriberId || !tenantId || !environmentId) {\n throw new Error('SubscriberId, TenantId or EnvironmentId not available in config');\n }\n\n const servicePreferences = await notificationClient.preferences.get(\n tenantId,\n subscriberId,\n environmentId,\n );\n\n // Fetch schedule separately\n let schedule = null;\n try {\n schedule = await notificationClient.preferences.getSchedule(\n tenantId,\n subscriberId,\n environmentId,\n );\n } catch (e) {\n console.warn('Failed to fetch schedule, using defaults:', e);\n }\n\n const mappedPreferences: NotificationPreferences = {\n channels: {\n email: servicePreferences.emailEnabled ?? true,\n push: servicePreferences.pushEnabled ?? true,\n sms: servicePreferences.smsEnabled ?? false,\n inApp: servicePreferences.inAppEnabled ?? true,\n },\n subscriptions: [],\n deliverySchedule: {\n enabled: schedule?.isEnabled || false,\n timezone: 'UTC',\n quietHours: {\n start: servicePreferences.quietHoursStart ?? '22:00',\n end: servicePreferences.quietHoursEnd ?? '08:00',\n },\n weekdays: schedule?.weeklySchedule\n ? [\n !!schedule.weeklySchedule.monday,\n !!schedule.weeklySchedule.tuesday,\n !!schedule.weeklySchedule.wednesday,\n !!schedule.weeklySchedule.thursday,\n !!schedule.weeklySchedule.friday,\n !!schedule.weeklySchedule.saturday,\n !!schedule.weeklySchedule.sunday,\n ]\n : [true, true, true, true, true, false, false],\n weeklySchedule: schedule?.weeklySchedule || undefined,\n },\n };\n\n if (servicePreferences.categories) {\n Object.entries(servicePreferences.categories).forEach(([workflowId, categoryPrefs]) => {\n mappedPreferences.subscriptions.push({\n workflowId,\n name: workflowId,\n enabled: true,\n channels: {\n email: (categoryPrefs as any).emailEnabled ?? true,\n push: (categoryPrefs as any).pushEnabled ?? true,\n sms: (categoryPrefs as any).smsEnabled ?? false,\n inApp: (categoryPrefs as any).inAppEnabled ?? true,\n },\n });\n });\n }\n\n setPreferences(mappedPreferences);\n onPreferencesLoaded(mappedPreferences);\n } catch (err: any) {\n const error = err instanceof Error ? err : new Error('Failed to load preferences');\n\n // If 404, it means preferences don't exist yet for this user.\n // We'll use defaults and suppress the error callback.\n const isNotFound = (err as any)?.response?.status === 404 || (err as any)?.status === 404;\n\n if (!isNotFound) {\n setError(error);\n onError?.(error);\n } else {\n console.warn('Preferences not found for user (404), using defaults.');\n }\n\n const defaultPreferences: NotificationPreferences = {\n channels: {\n email: true,\n push: true,\n sms: false,\n inApp: true,\n },\n subscriptions: [],\n deliverySchedule: {\n enabled: false,\n timezone: 'UTC',\n quietHours: {\n start: '22:00',\n end: '08:00',\n },\n weekdays: [true, true, true, true, true, false, false],\n },\n };\n setPreferences(defaultPreferences);\n onPreferencesLoaded(defaultPreferences);\n } finally {\n setIsLoading(false);\n }\n }, [notificationClient, onPreferencesLoaded, onError]);\n\n useEffect(() => {\n if (notificationClient) {\n loadPreferences();\n }\n }, [notificationClient, loadPreferences]);\n\n return {\n isLoading,\n error,\n preferences,\n };\n};\n","import { useState, useCallback, useEffect } from 'react';\n\nimport { WorkflowSubscription } from '../types/core';\n\nconst useNotificationsClient = () => {\n return (window as any).__notificationSDK?.client;\n};\n\nexport interface UseSpecificPreferencesResult {\n specificPreferences: WorkflowSubscription[];\n isLoading: boolean;\n hasMore: boolean;\n loadMore: () => Promise<void>;\n refetch: () => Promise<void>;\n}\n\nexport const useSpecificPreferences = (): UseSpecificPreferencesResult => {\n const client = useNotificationsClient();\n const [items, setItems] = useState<WorkflowSubscription[]>([]);\n const [isLoading, setIsLoading] = useState(false);\n const [hasMore, setHasMore] = useState(true);\n const [offset, setOffset] = useState(0);\n const LIMIT = 5;\n\n const loadMore = useCallback(async () => {\n if (!client || isLoading || !hasMore) return;\n\n try {\n setIsLoading(true);\n const sdkConfig = (window as any).__notificationSDK?.config;\n if (!sdkConfig) return;\n\n const response = await client.preferences.listSpecific(\n sdkConfig.tenantId,\n sdkConfig.subscriberId,\n {\n includeWorkflows: true,\n includeTemplates: false,\n activeOnly: true,\n limit: LIMIT,\n offset: offset,\n },\n );\n\n const newItems = (response.items || []).map((item: any) => ({\n workflowId: item.identifier,\n name: item.name,\n enabled: item.preference.enabled,\n channels: {\n email: item.preference.channels.email || false,\n push: item.preference.channels.push || false,\n inApp: item.preference.channels.in_app || false,\n sms: item.preference.channels.sms || false,\n },\n }));\n\n setItems((prev) => {\n const existingIds = new Set(prev.map((i) => i.workflowId));\n const uniqueNewItems = newItems.filter((i: any) => !existingIds.has(i.workflowId));\n return [...prev, ...uniqueNewItems];\n });\n\n setOffset((prev) => prev + LIMIT);\n\n if (\n newItems.length < LIMIT ||\n (response.total !== undefined && items.length + newItems.length >= response.total)\n ) {\n setHasMore(false);\n }\n } catch (error) {\n console.error('Failed to load specific preferences:', error);\n } finally {\n setIsLoading(false);\n }\n }, [client, offset, hasMore, isLoading, items.length]);\n\n useEffect(() => {\n if (client && offset === 0 && items.length === 0) {\n loadMore();\n }\n }, [client, loadMore, offset, items.length]);\n\n const refetch = async () => {\n setItems([]);\n setOffset(0);\n setHasMore(true);\n };\n\n return {\n specificPreferences: items,\n isLoading,\n hasMore,\n loadMore,\n refetch,\n };\n};\n","import React, { Component, ErrorInfo, ReactNode } from 'react';\nimport { MdError, MdRefresh } from 'react-icons/md';\n\nimport { ErrorBoundaryState } from '../types/core';\n\ninterface ErrorBoundaryProps {\n children: ReactNode;\n onError?: (error: Error, errorInfo: ErrorInfo) => void;\n}\n\nconst ErrorFallback: React.FC<{\n error: Error | null;\n onRetry: () => void;\n}> = ({ error, onRetry }) => (\n <div\n className=\"p-4 bg-[var(--widget-error)]/10 border border-[var(--widget-error)]/20 rounded-lg\"\n role=\"alert\"\n data-testid=\"error-boundary-fallback\"\n >\n <div className=\"flex items-center mb-2\">\n <MdError className=\"w-6 h-6 text-[var(--widget-error)] mr-2\" aria-hidden=\"true\" />\n <h3 className=\"text-sm font-medium text-[var(--widget-error)]\">Something went wrong</h3>\n </div>\n\n <p className=\"text-sm mb-3 text-[var(--widget-error)]/80\">\n The notification widget encountered an error and couldn't load properly.\n </p>\n\n {process.env.NODE_ENV === 'development' && error && (\n <details className=\"mb-3\">\n <summary className=\"text-xs cursor-pointer text-[var(--widget-error)] hover:text-[var(--widget-error)]/80 transition-colors\">\n Error details (development only)\n </summary>\n <pre className=\"mt-2 text-xs bg-[var(--widget-error)]/5 p-2 rounded overflow-auto max-h-32 text-[var(--widget-error)]\">\n {error.message}\n {error.stack && `\\n\\n${error.stack}`}\n </pre>\n </details>\n )}\n\n <button\n type=\"button\"\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\"\n onClick={onRetry}\n data-testid=\"error-retry-button\"\n >\n <MdRefresh className=\"mr-1 w-4 h-4\" aria-hidden=\"true\" />\n Try again\n </button>\n </div>\n);\n\nexport class NotificationWidgetErrorBoundary extends Component<\n ErrorBoundaryProps,\n ErrorBoundaryState\n> {\n constructor(props: ErrorBoundaryProps) {\n super(props);\n this.state = {\n hasError: false,\n error: null,\n errorInfo: null,\n };\n }\n\n static getDerivedStateFromError(error: Error): Partial<ErrorBoundaryState> {\n return {\n hasError: true,\n error,\n };\n }\n\n componentDidCatch(error: Error, errorInfo: ErrorInfo) {\n this.setState({\n errorInfo,\n });\n\n console.error('NotificationWidget Error Boundary caught an error:', {\n message: error.message,\n stack: error.stack,\n componentStack: errorInfo.componentStack,\n timestamp: new Date().toISOString(),\n });\n\n if (this.props.onError) {\n this.props.onError(error, errorInfo);\n }\n }\n\n handleRetry = () => {\n this.setState({\n hasError: false,\n error: null,\n errorInfo: null,\n });\n };\n\n render() {\n if (this.state.hasError) {\n return <ErrorFallback error={this.state.error} onRetry={this.handleRetry} />;\n }\n\n return this.props.children;\n }\n}\n\nexport const useErrorHandler = () => {\n return (error: Error, errorInfo?: ErrorInfo) => {\n console.error('Widget error:', {\n message: error.message,\n stack: error.stack,\n errorInfo,\n timestamp: new Date().toISOString(),\n });\n };\n};\n","import { NotificationClient } from '@edusight/notification-sdk';\nimport React, {\n useReducer,\n useEffect,\n useCallback,\n createContext,\n useContext,\n useRef,\n} from 'react';\nimport { io as ioClient } from 'socket.io-client';\n\nimport { useLivePreferences } from '../hooks/useLivePreferences';\nimport { usePreferencesSync } from '../hooks/usePreferencesSync';\nimport { useSpecificPreferences } from '../hooks/useSpecificPreferences';\nimport {\n NotificationWidgetProps,\n WidgetState,\n WidgetAction,\n SDKConfiguration,\n} from '../types/core';\nimport { createNotificationMapper } from '../utils/notification-mapper';\n\nimport { BellComponent } from './BellComponent';\nimport { ComponentErrorBoundary } from './ComponentErrorBoundary';\nimport { NotificationWidgetErrorBoundary } from './ErrorBoundary';\nimport { SDKConnectionFallback, LoadingFallback } from './FallbackComponents';\nimport { InboxPopover } from './InboxPopover';\n\ninterface SDKContextType {\n client: any;\n isInitialized: boolean;\n error: Error | null;\n}\n\nconst SDKContext = createContext<SDKContextType | null>(null);\n\nexport const useSDK = () => {\n const context = useContext(SDKContext);\n if (!context) {\n throw new Error('useSDK must be used within a NotificationWidget');\n }\n return context;\n};\n\nconst initialState: WidgetState = {\n notifications: [],\n unreadCount: 0,\n preferences: {\n channels: {\n email: true,\n push: true,\n sms: false,\n inApp: true,\n },\n subscriptions: [],\n deliverySchedule: {\n timezone: 'UTC',\n quietHours: {\n start: '22:00',\n end: '08:00',\n },\n weekdays: [true, true, true, true, true, false, false],\n },\n },\n ui: {\n isOpen: false,\n currentView: 'notifications',\n selectedNotifications: [],\n isLoading: false,\n error: null,\n },\n websocket: {\n connected: false,\n reconnecting: false,\n },\n};\n\nconst SDKProvider: React.FC<{ config: SDKConfiguration; children: React.ReactNode }> = ({\n config,\n children,\n}) => {\n const [sdkState, setSdkState] = React.useState<SDKContextType>({\n client: null,\n isInitialized: false,\n error: null,\n });\n\n useEffect(() => {\n let isMounted = true;\n\n const initializeSDK = async () => {\n try {\n const existingSDK = (window as any).__notificationSDK;\n\n // Check if we can reuse the existing SDK instance\n if (existingSDK?.client) {\n // Compare new config with existing config to determine if we need to re-initialize\n // We use simple JSON stringify as configs are simple objects with strings/numbers\n const isConfigMatch = JSON.stringify(existingSDK.config) === JSON.stringify(config);\n\n if (isConfigMatch) {\n if (isMounted) {\n setSdkState({\n client: existingSDK.client,\n isInitialized: true,\n error: null,\n });\n }\n return;\n } else {\n console.log('[NotificationWidget] Config changed, re-initializing SDK', {\n old: existingSDK.config,\n new: config,\n });\n }\n }\n\n const client = new NotificationClient({\n apiUrl: config.baseUrl,\n apiKey: config.apiKey,\n tenantId: config.tenantId,\n environmentId: config.environmentId,\n });\n\n (window as any).__notificationSDK = { client, config };\n\n if (isMounted) {\n setSdkState({\n client,\n isInitialized: true,\n error: null,\n });\n }\n } catch (error) {\n console.error('Failed to initialize SDK:', error);\n if (isMounted) {\n setSdkState({\n client: null,\n isInitialized: false,\n error: error as Error,\n });\n }\n }\n };\n\n initializeSDK();\n\n return () => {\n isMounted = false;\n };\n }, [config]);\n\n return <SDKContext.Provider value={sdkState}>{children}</SDKContext.Provider>;\n};\n\nconst widgetReducer = (state: WidgetState, action: WidgetAction): WidgetState => {\n switch (action.type) {\n case 'SET_NOTIFICATIONS':\n return {\n ...state,\n notifications: action.payload,\n unreadCount: action.payload.filter((n) => !n.isRead).length,\n };\n\n case 'ADD_NOTIFICATION':\n const newNotifications = [action.payload, ...state.notifications];\n return {\n ...state,\n notifications: newNotifications,\n unreadCount: newNotifications.filter((n) => !n.isRead).length,\n };\n\n case 'UPDATE_NOTIFICATION':\n const updatedNotifications = state.notifications.map((n) =>\n n.id === action.payload.id ? { ...n, ...action.payload.updates } : n,\n );\n return {\n ...state,\n notifications: updatedNotifications,\n unreadCount: updatedNotifications.filter((n) => !n.isRead).length,\n };\n\n case 'DELETE_NOTIFICATION':\n const filteredNotifications = state.notifications.filter((n) => n.id !== action.payload);\n return {\n ...state,\n notifications: filteredNotifications,\n unreadCount: filteredNotifications.filter((n) => !n.isRead).length,\n };\n\n case 'SET_PREFERENCES':\n return {\n ...state,\n preferences: action.payload,\n };\n\n case 'SET_UI_STATE':\n return {\n ...state,\n ui: { ...state.ui, ...action.payload },\n };\n\n case 'SET_WEBSOCKET_STATE':\n return {\n ...state,\n websocket: { ...state.websocket, ...action.payload },\n };\n\n default:\n return state;\n }\n};\n\nconst NotificationWidgetInternal: React.FC<Omit<NotificationWidgetProps, 'sdkConfig'>> = ({\n position = 'right',\n size = 'medium',\n theme = 'light',\n className = '',\n\n onError,\n onMorePreferencesClick,\n}) => {\n const [state, dispatch] = useReducer(widgetReducer, initialState);\n const { client, isInitialized, error: sdkError } = useSDK();\n const websocketRef = useRef<any>(null);\n\n const handlePreferencesChange = useCallback((preferences: any) => {\n dispatch({\n type: 'SET_PREFERENCES',\n payload: preferences,\n });\n }, []);\n\n const handleWidgetError = useCallback(\n (error: Error) => {\n console.error('Widget error:', error);\n if (onError) {\n onError(error);\n }\n },\n [onError],\n );\n\n const { error: preferencesLoadError } = usePreferencesSync({\n onPreferencesLoaded: handlePreferencesChange,\n onError: handleWidgetError,\n });\n\n const {\n specificPreferences,\n isLoading: isSpecificLoading,\n hasMore: hasMoreSpecific,\n loadMore: loadMoreSpecific,\n } = useSpecificPreferences();\n\n const {\n updatePreference,\n isSaving,\n error: preferencesError,\n } = useLivePreferences({\n preferences: state.preferences,\n onPreferencesChange: handlePreferencesChange,\n onError: handleWidgetError,\n });\n\n useEffect(() => {\n if (specificPreferences.length > 0) {\n const currentSubs = state.preferences.subscriptions;\n const newSubs = [...currentSubs];\n let changed = false;\n\n specificPreferences.forEach((sp) => {\n const existingIdx = newSubs.findIndex((s) => s.workflowId === sp.workflowId);\n\n if (existingIdx === -1) {\n newSubs.push(sp);\n changed = true;\n } else {\n const existing = newSubs[existingIdx];\n const updated = {\n ...existing,\n name: sp.name || existing.name,\n enabled: sp.enabled,\n channels: sp.channels,\n };\n\n if (\n existing.name !== updated.name ||\n existing.enabled !== updated.enabled ||\n JSON.stringify(existing.channels) !== JSON.stringify(updated.channels)\n ) {\n newSubs[existingIdx] = updated;\n changed = true;\n }\n }\n });\n\n if (changed) {\n dispatch({\n type: 'SET_PREFERENCES',\n payload: {\n ...state.preferences,\n subscriptions: newSubs,\n },\n });\n }\n }\n }, [specificPreferences]);\n\n const displaySpecificPreferences = React.useMemo(() => {\n return specificPreferences.map((sp) => {\n const found = state.preferences.subscriptions.find((s) => s.workflowId === sp.workflowId);\n return found || sp;\n });\n }, [specificPreferences, state.preferences.subscriptions]);\n\n const handleWebSocketEvent = useCallback((event: any) => {\n try {\n const notificationMapper = createNotificationMapper();\n\n switch (event.type) {\n case 'notification_received': {\n const wsPayload = event.data;\n\n if (!notificationMapper.validateWebSocketPayload(wsPayload)) {\n console.error('Invalid WebSocket notification payload, skipping', wsPayload);\n break;\n }\n\n const mappedNotification =\n notificationMapper.toWidgetNotificationFromWebSocket(wsPayload);\n dispatch({\n type: 'ADD_NOTIFICATION',\n payload: mappedNotification,\n });\n break;\n }\n\n case 'notification_updated':\n dispatch({\n type: 'UPDATE_NOTIFICATION',\n payload: {\n id: event.data.id || event.data.notificationId,\n updates: event.data,\n },\n });\n break;\n\n case 'notification_deleted':\n dispatch({\n type: 'DELETE_NOTIFICATION',\n payload: event.data.id || event.data.notificationId,\n });\n break;\n\n case 'preferences_updated':\n dispatch({\n type: 'SET_PREFERENCES',\n payload: event.data,\n });\n break;\n\n default:\n console.log('Unknown WebSocket event type:', event.type);\n }\n } catch (error) {\n console.error('Error handling WebSocket event:', error);\n }\n }, []);\n\n const connectWebSocket = useCallback(async () => {\n if (!client || !isInitialized || websocketRef.current) return;\n\n try {\n dispatch({\n type: 'SET_WEBSOCKET_STATE',\n payload: { reconnecting: true },\n });\n\n const sdkConfig = (window as any).__notificationSDK?.config;\n if (!sdkConfig) {\n throw new Error('SDK configuration not available for WebSocket connection');\n }\n\n const baseUrl = client.getApiHost();\n const namespace = '/v1/notifications';\n const fullUrl = `${baseUrl}${namespace}`;\n\n console.log('Connecting to Socket.IO at:', fullUrl);\n\n const socket = ioClient(fullUrl, {\n query: {\n tenantId: sdkConfig.tenantId,\n subscriberId: sdkConfig.subscriberId,\n environmentId: sdkConfig.environmentId,\n },\n transports: ['websocket', 'polling'],\n autoConnect: false,\n reconnection: true,\n reconnectionAttempts: 10,\n reconnectionDelay: 1000,\n reconnectionDelayMax: 5000,\n });\n\n websocketRef.current = socket;\n let heartbeatInterval: any = null;\n\n const startHeartbeat = () => {\n if (heartbeatInterval) clearInterval(heartbeatInterval);\n heartbeatInterval = setInterval(() => {\n if (socket.connected) {\n socket.emit('ping', { timestamp: new Date().toISOString() });\n }\n }, 120000);\n };\n\n const stopHeartbeat = () => {\n if (heartbeatInterval) {\n clearInterval(heartbeatInterval);\n heartbeatInterval = null;\n }\n };\n\n socket.on('notification', (payload: any) => {\n console.log('Received notification:', payload);\n handleWebSocketEvent({\n type: 'notification_received',\n data: payload,\n });\n });\n\n socket.on('connect', () => {\n console.log('Socket.IO connected successfully');\n dispatch({\n type: 'SET_WEBSOCKET_STATE',\n payload: { connected: true, reconnecting: false },\n });\n startHeartbeat();\n });\n\n socket.on('disconnect', (reason: any) => {\n console.log('Socket.IO disconnected:', reason);\n dispatch({\n type: 'SET_WEBSOCKET_STATE',\n payload: { connected: false, reconnecting: false },\n });\n stopHeartbeat();\n });\n\n socket.on('reconnect_attempt', (attempt: any) => {\n console.log('Socket.IO reconnection attempt:', attempt);\n dispatch({\n type: 'SET_WEBSOCKET_STATE',\n payload: { connected: false, reconnecting: true },\n });\n });\n\n socket.on('connect_error', (error: any) => {\n console.error('Socket.IO connection error:', error);\n dispatch({\n type: 'SET_WEBSOCKET_STATE',\n payload: { connected: false, reconnecting: false },\n });\n if (onError) {\n onError(error);\n }\n });\n\n socket.connect();\n } catch (error) {\n console.error('Failed to connect WebSocket:', error);\n dispatch({\n type: 'SET_WEBSOCKET_STATE',\n payload: { connected: false, reconnecting: false },\n });\n if (onError) {\n onError(error as Error);\n }\n }\n }, [client, isInitialized, handleWebSocketEvent, onError]);\n\n const disconnectWebSocket = useCallback(() => {\n if (websocketRef.current) {\n try {\n if (websocketRef.current.disconnect) {\n websocketRef.current.disconnect();\n }\n websocketRef.current = null;\n dispatch({\n type: 'SET_WEBSOCKET_STATE',\n payload: { connected: false, reconnecting: false },\n });\n } catch (error) {\n console.error('Error disconnecting WebSocket:', error);\n }\n }\n }, []);\n\n const handleBellClick = useCallback(() => {\n dispatch({\n type: 'SET_UI_STATE',\n payload: { isOpen: !state.ui.isOpen },\n });\n }, [state.ui.isOpen]);\n\n const handlePopoverClose = useCallback(() => {\n dispatch({\n type: 'SET_UI_STATE',\n payload: { isOpen: false },\n });\n }, []);\n\n const handleViewChange = useCallback((view: 'notifications' | 'preferences') => {\n dispatch({\n type: 'SET_UI_STATE',\n payload: { currentView: view },\n });\n }, []);\n\n const handleNotificationAction = useCallback(\n async (id: string, action: any) => {\n if (!client || !isInitialized) {\n console.error('SDK not initialized');\n return;\n }\n\n const sdkConfig = (window as any).__notificationSDK?.config;\n if (!sdkConfig) {\n console.error('SDK configuration not available');\n return;\n }\n\n if (!id) {\n console.error('notificationId is required');\n throw new Error('notificationId is required');\n }\n\n try {\n switch (action.type) {\n case 'mark_read':\n await client.inbox.markAsRead(\n id,\n sdkConfig.tenantId,\n sdkConfig.environmentId,\n sdkConfig.subscriberId,\n );\n break;\n case 'mark_unread':\n await client.inbox.markAsUnread(\n id,\n sdkConfig.tenantId,\n sdkConfig.environmentId,\n sdkConfig.subscriberId,\n );\n break;\n case 'archive':\n await client.inbox.archive(\n id,\n sdkConfig.tenantId,\n sdkConfig.environmentId,\n sdkConfig.subscriberId,\n );\n break;\n case 'delete':\n await client.inbox.delete(\n id,\n sdkConfig.tenantId,\n sdkConfig.environmentId,\n sdkConfig.subscriberId,\n );\n break;\n default:\n if (action.handler) {\n await action.handler(id);\n }\n break;\n }\n\n switch (action.type) {\n case 'mark_read':\n dispatch({\n type: 'UPDATE_NOTIFICATION',\n payload: { id, updates: { isRead: true } },\n });\n break;\n case 'mark_unread':\n dispatch({\n type: 'UPDATE_NOTIFICATION',\n payload: { id, updates: { isRead: false } },\n });\n break;\n case 'archive':\n dispatch({\n type: 'UPDATE_NOTIFICATION',\n payload: { id, updates: { isArchived: true } },\n });\n break;\n case 'delete':\n dispatch({\n type: 'DELETE_NOTIFICATION',\n payload: id,\n });\n break;\n }\n } catch (error) {\n console.error('Error performing notification action:', error);\n if (onError) {\n onError(error as Error);\n }\n }\n },\n [client],\n );\n\n useEffect(() => {\n if (!client || !isInitialized) return;\n\n const loadNotifications = async () => {\n try {\n dispatch({\n type: 'SET_UI_STATE',\n payload: { isLoading: true },\n });\n\n const sdkConfig = (window as any).__notificationSDK?.config;\n if (!sdkConfig) {\n throw new Error('SDK configuration not available');\n }\n\n const notificationMapper = createNotificationMapper();\n const response = await client.inbox.getRenderedNotifications(\n {\n channel: 'in_app',\n limit: 50,\n offset: 0,\n },\n sdkConfig.tenantId,\n sdkConfig.environmentId,\n sdkConfig.subscriberId,\n );\n\n const coreNotifications = (response?.items || []).map((item: any) =>\n notificationMapper.toWidgetNotification(item),\n );\n\n dispatch({\n type: 'SET_NOTIFICATIONS',\n payload: coreNotifications,\n });\n\n dispatch({\n type: 'SET_UI_STATE',\n payload: { isLoading: false, error: null },\n });\n } catch (error) {\n console.error('Failed to load notifications:', error);\n dispatch({\n type: 'SET_UI_STATE',\n payload: {\n isLoading: false,\n error: error as Error,\n },\n });\n if (onError) {\n onError(error as Error);\n }\n }\n };\n\n loadNotifications();\n }, [client, isInitialized, onError]);\n\n useEffect(() => {\n if (client && isInitialized) {\n connectWebSocket();\n }\n\n return () => {\n disconnectWebSocket();\n };\n }, [client]);\n\n useEffect(() => {\n if (!client || !isInitialized) return;\n\n if (state.websocket.connected) return;\n\n const pollInterval = setInterval(async () => {\n try {\n const sdkConfig = (window as any).__notificationSDK?.config;\n if (!sdkConfig) {\n return;\n }\n\n const notificationMapper = createNotificationMapper();\n const response = await client.inbox.getRenderedNotifications(\n {\n channel: 'in_app',\n limit: 50,\n offset: 0,\n },\n sdkConfig.tenantId,\n sdkConfig.environmentId,\n sdkConfig.subscriberId,\n );\n\n const coreNotifications = (response?.items || []).map((item: any) =>\n notificationMapper.toWidgetNotification(item),\n );\n\n dispatch({\n type: 'SET_NOTIFICATIONS',\n payload: coreNotifications,\n });\n } catch (error) {\n console.error('Polling failed:', error);\n }\n }, 30000);\n\n return () => clearInterval(pollInterval);\n }, [client, state.websocket.connected]);\n\n useEffect(() => {\n const handleStorageChange = (event: StorageEvent) => {\n if (event.key === 'notification_widget_sync' && event.newValue) {\n try {\n const syncData = JSON.parse(event.newValue);\n handleWebSocketEvent(syncData);\n } catch (error) {\n console.error('Error parsing sync data:', error);\n }\n }\n };\n\n window.addEventListener('storage', handleStorageChange);\n return () => window.removeEventListener('storage', handleStorageChange);\n }, [handleWebSocketEvent]);\n\n useEffect(() => {\n dispatch({\n type: 'SET_UI_STATE',\n payload: { isLoading: isSaving },\n });\n }, [isSaving]);\n\n useEffect(() => {\n const error = sdkError || preferencesError || preferencesLoadError;\n if (error) {\n dispatch({\n type: 'SET_UI_STATE',\n payload: { error: error },\n });\n }\n }, [sdkError, preferencesError, preferencesLoadError]);\n\n if (!isInitialized && !sdkError) {\n return (\n <div\n className={`mx-widget-root relative inline-block ${className}`}\n data-mx-widget=\"root\"\n data-widget-size={size || 'small'}\n data-theme={theme}\n data-testid=\"notification-widget\"\n >\n <ComponentErrorBoundary componentName=\"BellComponent\">\n <BellComponent unreadCount={0} onClick={() => { }} size={size} disabled={true} />\n </ComponentErrorBoundary>\n </div>\n );\n }\n\n if (sdkError) {\n return (\n <div\n className={`mx-widget-root relative inline-block ${className}`}\n data-mx-widget=\"root\"\n data-widget-size={size || 'small'}\n data-theme={theme}\n data-testid=\"notification-widget\"\n >\n <ComponentErrorBoundary\n componentName=\"BellComponent\"\n fallback={\n <SDKConnectionFallback\n error={sdkError.message}\n onRetry={() => window.location.reload()}\n />\n }\n >\n <BellComponent unreadCount={0} onClick={() => { }} size={size} disabled={true} />\n </ComponentErrorBoundary>\n </div>\n );\n }\n\n return (\n <div\n className={`mx-widget-root min-w-[20rem] relative inline-block ${className}`}\n data-mx-widget=\"root\"\n data-widget-size={size || 'small'}\n data-theme={theme}\n data-testid=\"notification-widget\"\n >\n <ComponentErrorBoundary componentName=\"BellComponent\">\n <BellComponent\n unreadCount={state.unreadCount}\n onClick={handleBellClick}\n size={size}\n disabled={state.ui.isLoading}\n />\n </ComponentErrorBoundary>\n\n <ComponentErrorBoundary\n componentName=\"InboxPopover\"\n fallback={<LoadingFallback message=\"Unable to load notifications\" />}\n >\n <InboxPopover\n isOpen={state.ui.isOpen}\n onClose={handlePopoverClose}\n position={position}\n currentView={state.ui.currentView}\n onViewChange={handleViewChange}\n notifications={state.notifications}\n onNotificationAction={handleNotificationAction}\n preferences={state.preferences}\n onPreferenceChange={updatePreference}\n isPreferencesLoading={isSaving}\n specificPreferences={displaySpecificPreferences}\n onLoadMoreSpecific={loadMoreSpecific}\n hasMoreSpecific={hasMoreSpecific}\n isListLoading={isSpecificLoading}\n onMorePreferencesClick={onMorePreferencesClick}\n />\n </ComponentErrorBoundary>\n </div>\n );\n};\n\nexport const NotificationWidget: React.FC<NotificationWidgetProps> = ({ sdkConfig, ...props }) => {\n return (\n <NotificationWidgetErrorBoundary onError={props.onError}>\n <SDKProvider config={sdkConfig}>\n <NotificationWidgetInternal {...props} />\n </SDKProvider>\n </NotificationWidgetErrorBoundary>\n );\n};\n","export { NotificationWidget } from './components/NotificationWidget';\n\nexport { BellComponent } from './components/BellComponent';\nexport { InboxPopover } from './components/InboxPopover';\nexport { NotificationItem } from './components/NotificationItem';\nexport { PreferencesView } from './components/PreferencesView';\n\nexport { NotificationWidgetErrorBoundary } from './components/ErrorBoundary';\n\nexport type * from './types/core';\n\nexport type {\n Notification as SDKNotification,\n NotificationFilters,\n} from '@edusight/notification-sdk';\n\nimport '../src/styles/index.css';\n\nexport const VERSION = '3.0.0';\nexport const WIDGET_NAME = '@edusight/notification-widget';\n"],"names":["useNotificationsClient","usePreferencesSync","onPreferencesLoaded","onError","notificationClient","isLoading","setIsLoading","useState","error","setError","preferences","setPreferences","loadPreferences","useCallback","config","subscriberId","tenantId","environmentId","servicePreferences","schedule","mappedPreferences","workflowId","categoryPrefs","err","defaultPreferences","useEffect","useSpecificPreferences","client","items","setItems","hasMore","setHasMore","offset","setOffset","LIMIT","loadMore","sdkConfig","response","newItems","item","prev","existingIds","i","uniqueNewItems","ErrorFallback","onRetry","jsxs","jsx","MdError","MdRefresh","NotificationWidgetErrorBoundary","Component","props","errorInfo","SDKContext","createContext","useSDK","context","useContext","initialState","SDKProvider","children","sdkState","setSdkState","React","isMounted","existingSDK","NotificationClient","widgetReducer","state","action","n","newNotifications","updatedNotifications","filteredNotifications","NotificationWidgetInternal","position","size","theme","className","onMorePreferencesClick","dispatch","useReducer","isInitialized","sdkError","websocketRef","useRef","handlePreferencesChange","handleWidgetError","preferencesLoadError","specificPreferences","isSpecificLoading","hasMoreSpecific","loadMoreSpecific","updatePreference","isSaving","preferencesError","useLivePreferences","newSubs","changed","sp","existingIdx","s","existing","updated","displaySpecificPreferences","handleWebSocketEvent","event","notificationMapper","createNotificationMapper","wsPayload","mappedNotification","connectWebSocket","fullUrl","socket","ioClient","heartbeatInterval","startHeartbeat","stopHeartbeat","payload","reason","attempt","disconnectWebSocket","handleBellClick","handlePopoverClose","handleViewChange","view","handleNotificationAction","id","coreNotifications","pollInterval","handleStorageChange","syncData","ComponentErrorBoundary","BellComponent","SDKConnectionFallback","LoadingFallback","InboxPopover","NotificationWidget","VERSION","WIDGET_NAME"],"mappings":"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"}
|