@ozdao/martyrs 0.2.431 → 0.2.433

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.
Files changed (189) hide show
  1. package/dist/chats.server.js +19 -0
  2. package/dist/chats.server.mjs +19 -0
  3. package/dist/martyrs/src/components/Button/{Button.vue2.cjs → Button.vue.cjs} +2 -2
  4. package/dist/martyrs/src/components/Button/{Button.vue2.js.map → Button.vue.cjs.map} +1 -1
  5. package/dist/martyrs/src/components/Button/{Button.vue2.js → Button.vue.js} +2 -2
  6. package/dist/martyrs/src/components/Button/Button.vue.js.map +1 -0
  7. package/dist/martyrs/src/components/Dropdown/{Dropdown.vue.cjs → Dropdown.vue2.cjs} +2 -2
  8. package/dist/martyrs/src/components/Dropdown/Dropdown.vue2.cjs.map +1 -0
  9. package/dist/martyrs/src/components/Dropdown/{Dropdown.vue.js → Dropdown.vue2.js} +2 -2
  10. package/dist/martyrs/src/components/Dropdown/{Dropdown.vue.cjs.map → Dropdown.vue2.js.map} +1 -1
  11. package/dist/martyrs/src/components/Feed/Feed.vue.cjs +1 -1
  12. package/dist/martyrs/src/components/Feed/Feed.vue.js +1 -1
  13. package/dist/martyrs/src/components/Menu/{Menu.vue.cjs → Menu.vue2.cjs} +2 -2
  14. package/dist/martyrs/src/components/Menu/Menu.vue2.cjs.map +1 -0
  15. package/dist/martyrs/src/components/Menu/{Menu.vue.js → Menu.vue2.js} +2 -2
  16. package/dist/martyrs/src/components/Menu/Menu.vue2.js.map +1 -0
  17. package/dist/martyrs/src/components/SelectMulti/{SelectMulti.vue.cjs → SelectMulti.vue2.cjs} +2 -2
  18. package/dist/martyrs/src/components/SelectMulti/SelectMulti.vue2.cjs.map +1 -0
  19. package/dist/martyrs/src/components/SelectMulti/{SelectMulti.vue.js → SelectMulti.vue2.js} +2 -2
  20. package/dist/martyrs/src/components/SelectMulti/{SelectMulti.vue.cjs.map → SelectMulti.vue2.js.map} +1 -1
  21. package/dist/martyrs/src/components/Tab/{Tab.vue2.cjs → Tab.vue.cjs} +2 -2
  22. package/dist/martyrs/src/components/Tab/{Tab.vue2.js.map → Tab.vue.cjs.map} +1 -1
  23. package/dist/martyrs/src/components/Tab/{Tab.vue2.js → Tab.vue.js} +2 -2
  24. package/dist/martyrs/src/components/Tab/Tab.vue.js.map +1 -0
  25. package/dist/martyrs/src/modules/auth/views/components/layouts/Auth.vue.cjs +2 -2
  26. package/dist/martyrs/src/modules/auth/views/components/layouts/Auth.vue.js +2 -2
  27. package/dist/martyrs/src/modules/auth/views/components/pages/EnterPassword.vue.cjs +2 -2
  28. package/dist/martyrs/src/modules/auth/views/components/pages/EnterPassword.vue.js +2 -2
  29. package/dist/martyrs/src/modules/auth/views/components/pages/Invite.vue.cjs +2 -2
  30. package/dist/martyrs/src/modules/auth/views/components/pages/Invite.vue.js +2 -2
  31. package/dist/martyrs/src/modules/auth/views/components/pages/Profile.vue.cjs +3 -3
  32. package/dist/martyrs/src/modules/auth/views/components/pages/Profile.vue.js +3 -3
  33. package/dist/martyrs/src/modules/auth/views/components/pages/ProfileBlogposts.vue.cjs +1 -1
  34. package/dist/martyrs/src/modules/auth/views/components/pages/ProfileBlogposts.vue.js +1 -1
  35. package/dist/martyrs/src/modules/auth/views/components/pages/ProfileEdit.vue.cjs +2 -2
  36. package/dist/martyrs/src/modules/auth/views/components/pages/ProfileEdit.vue.js +2 -2
  37. package/dist/martyrs/src/modules/auth/views/components/pages/ResetPassword.vue.cjs +2 -2
  38. package/dist/martyrs/src/modules/auth/views/components/pages/ResetPassword.vue.js +2 -2
  39. package/dist/martyrs/src/modules/auth/views/components/pages/SignIn.vue.cjs +2 -2
  40. package/dist/martyrs/src/modules/auth/views/components/pages/SignIn.vue.js +2 -2
  41. package/dist/martyrs/src/modules/auth/views/components/pages/SignUp.vue.cjs +2 -2
  42. package/dist/martyrs/src/modules/auth/views/components/pages/SignUp.vue.js +2 -2
  43. package/dist/martyrs/src/modules/auth/views/components/sections/ProfileEditCredentials.vue.cjs +1 -1
  44. package/dist/martyrs/src/modules/auth/views/components/sections/ProfileEditCredentials.vue.js +1 -1
  45. package/dist/martyrs/src/modules/backoffice/components/partials/Sidebar.vue.cjs +1 -1
  46. package/dist/martyrs/src/modules/backoffice/components/partials/Sidebar.vue.js +1 -1
  47. package/dist/martyrs/src/modules/community/components/pages/BlogPost.vue.cjs +1 -1
  48. package/dist/martyrs/src/modules/community/components/pages/BlogPost.vue.js +1 -1
  49. package/dist/martyrs/src/modules/community/components/pages/CreateBlogPost.vue.cjs +1 -1
  50. package/dist/martyrs/src/modules/community/components/pages/CreateBlogPost.vue.js +1 -1
  51. package/dist/martyrs/src/modules/community/components/sections/HotPosts.vue.cjs +1 -1
  52. package/dist/martyrs/src/modules/community/components/sections/HotPosts.vue.js +1 -1
  53. package/dist/martyrs/src/modules/events/components/elements/ButtonCheck.vue.cjs +1 -1
  54. package/dist/martyrs/src/modules/events/components/elements/ButtonCheck.vue.js +1 -1
  55. package/dist/martyrs/src/modules/events/components/elements/ButtonJoin.vue.cjs +1 -1
  56. package/dist/martyrs/src/modules/events/components/elements/ButtonJoin.vue.js +1 -1
  57. package/dist/martyrs/src/modules/events/components/pages/EditEvent.vue.cjs +2 -2
  58. package/dist/martyrs/src/modules/events/components/pages/EditEvent.vue.js +2 -2
  59. package/dist/martyrs/src/modules/events/components/pages/EditEventTickets.vue.cjs +1 -1
  60. package/dist/martyrs/src/modules/events/components/pages/EditEventTickets.vue.js +1 -1
  61. package/dist/martyrs/src/modules/events/components/pages/EventsBackoffice.vue.cjs +1 -1
  62. package/dist/martyrs/src/modules/events/components/pages/EventsBackoffice.vue.js +1 -1
  63. package/dist/martyrs/src/modules/events/components/sections/EventsHot.vue.cjs +1 -1
  64. package/dist/martyrs/src/modules/events/components/sections/EventsHot.vue.js +1 -1
  65. package/dist/martyrs/src/modules/gallery/components/sections/BackofficeGallery.vue.cjs +2 -2
  66. package/dist/martyrs/src/modules/gallery/components/sections/BackofficeGallery.vue.js +2 -2
  67. package/dist/martyrs/src/modules/globals/views/components/blocks/CardHeader.vue.cjs +2 -2
  68. package/dist/martyrs/src/modules/globals/views/components/blocks/CardHeader.vue.js +2 -2
  69. package/dist/martyrs/src/modules/globals/views/components/blocks/PopupDateSelector.vue.cjs +1 -1
  70. package/dist/martyrs/src/modules/globals/views/components/blocks/PopupDateSelector.vue.js +1 -1
  71. package/dist/martyrs/src/modules/globals/views/components/layouts/Client.vue.cjs +1 -1
  72. package/dist/martyrs/src/modules/globals/views/components/layouts/Client.vue.js +1 -1
  73. package/dist/martyrs/src/modules/globals/views/components/partials/Header.vue.cjs +1 -1
  74. package/dist/martyrs/src/modules/globals/views/components/partials/Header.vue.js +1 -1
  75. package/dist/martyrs/src/modules/globals/views/components/partials/Navigation.vue.cjs +1 -1
  76. package/dist/martyrs/src/modules/globals/views/components/partials/Navigation.vue.js +1 -1
  77. package/dist/martyrs/src/modules/globals/views/components/partials/NavigationBar.vue.cjs +1 -1
  78. package/dist/martyrs/src/modules/globals/views/components/partials/NavigationBar.vue.js +1 -1
  79. package/dist/martyrs/src/modules/globals/views/components/sections/SectionPageTitle.vue.cjs +1 -1
  80. package/dist/martyrs/src/modules/globals/views/components/sections/SectionPageTitle.vue.js +1 -1
  81. package/dist/martyrs/src/modules/landing/landing.client.cjs +0 -6
  82. package/dist/martyrs/src/modules/landing/landing.client.cjs.map +1 -1
  83. package/dist/martyrs/src/modules/landing/landing.client.js +0 -6
  84. package/dist/martyrs/src/modules/landing/landing.client.js.map +1 -1
  85. package/dist/martyrs/src/modules/notifications/components/layouts/NotificationsLayout.vue.cjs +1 -1
  86. package/dist/martyrs/src/modules/notifications/components/layouts/NotificationsLayout.vue.cjs.map +1 -1
  87. package/dist/martyrs/src/modules/notifications/components/layouts/NotificationsLayout.vue.js +1 -1
  88. package/dist/martyrs/src/modules/notifications/components/layouts/NotificationsLayout.vue.js.map +1 -1
  89. package/dist/martyrs/src/modules/notifications/notifications.client.cjs +248 -135
  90. package/dist/martyrs/src/modules/notifications/notifications.client.cjs.map +1 -1
  91. package/dist/martyrs/src/modules/notifications/notifications.client.js +248 -135
  92. package/dist/martyrs/src/modules/notifications/notifications.client.js.map +1 -1
  93. package/dist/martyrs/src/modules/orders/components/pages/OrderBackoffice.vue.cjs +1 -1
  94. package/dist/martyrs/src/modules/orders/components/pages/OrderBackoffice.vue.js +1 -1
  95. package/dist/martyrs/src/modules/orders/components/pages/OrderCreateBackoffice.vue.cjs +3 -3
  96. package/dist/martyrs/src/modules/orders/components/pages/OrderCreateBackoffice.vue.js +3 -3
  97. package/dist/martyrs/src/modules/orders/components/pages/Orders.vue.cjs +1 -1
  98. package/dist/martyrs/src/modules/orders/components/pages/Orders.vue.js +1 -1
  99. package/dist/martyrs/src/modules/orders/components/sections/FormAddCustomer.vue.cjs +1 -1
  100. package/dist/martyrs/src/modules/orders/components/sections/FormAddCustomer.vue.js +1 -1
  101. package/dist/martyrs/src/modules/orders/components/sections/FormDelivery.vue.cjs +1 -1
  102. package/dist/martyrs/src/modules/orders/components/sections/FormDelivery.vue.js +1 -1
  103. package/dist/martyrs/src/modules/organizations/components/elements/ButtonToggleMembership.vue.cjs +1 -1
  104. package/dist/martyrs/src/modules/organizations/components/elements/ButtonToggleMembership.vue.js +1 -1
  105. package/dist/martyrs/src/modules/organizations/components/pages/DepartmentEdit.vue.cjs +2 -2
  106. package/dist/martyrs/src/modules/organizations/components/pages/DepartmentEdit.vue.js +2 -2
  107. package/dist/martyrs/src/modules/organizations/components/pages/Members.vue.cjs +2 -2
  108. package/dist/martyrs/src/modules/organizations/components/pages/Members.vue.js +2 -2
  109. package/dist/martyrs/src/modules/organizations/components/pages/Organization.vue.cjs +2 -2
  110. package/dist/martyrs/src/modules/organizations/components/pages/Organization.vue.js +2 -2
  111. package/dist/martyrs/src/modules/organizations/components/pages/OrganizationBackoffice.vue.cjs +2 -2
  112. package/dist/martyrs/src/modules/organizations/components/pages/OrganizationBackoffice.vue.js +2 -2
  113. package/dist/martyrs/src/modules/organizations/components/pages/OrganizationEdit.vue.cjs +3 -3
  114. package/dist/martyrs/src/modules/organizations/components/pages/OrganizationEdit.vue.js +3 -3
  115. package/dist/martyrs/src/modules/organizations/components/pages/Organizations.vue.cjs +1 -1
  116. package/dist/martyrs/src/modules/organizations/components/pages/Organizations.vue.js +1 -1
  117. package/dist/martyrs/src/modules/organizations/components/sections/DetailsTabSection.vue.cjs +1 -1
  118. package/dist/martyrs/src/modules/organizations/components/sections/DetailsTabSection.vue.js +1 -1
  119. package/dist/martyrs/src/modules/organizations/components/sections/Documents.vue.cjs +1 -1
  120. package/dist/martyrs/src/modules/organizations/components/sections/Documents.vue.js +1 -1
  121. package/dist/martyrs/src/modules/organizations/components/sections/MembersAdd.vue.cjs +1 -1
  122. package/dist/martyrs/src/modules/organizations/components/sections/MembersAdd.vue.js +1 -1
  123. package/dist/martyrs/src/modules/organizations/components/sections/Organizations.vue.cjs +2 -2
  124. package/dist/martyrs/src/modules/organizations/components/sections/Organizations.vue.js +2 -2
  125. package/dist/martyrs/src/modules/pages/views/components/blocks/CardPage.vue.cjs +1 -1
  126. package/dist/martyrs/src/modules/pages/views/components/blocks/CardPage.vue.js +1 -1
  127. package/dist/martyrs/src/modules/pages/views/components/pages/PageEdit.vue.cjs +1 -1
  128. package/dist/martyrs/src/modules/pages/views/components/pages/PageEdit.vue.js +1 -1
  129. package/dist/martyrs/src/modules/pages/views/components/partials/SidebarPages.vue.cjs +1 -1
  130. package/dist/martyrs/src/modules/pages/views/components/partials/SidebarPages.vue.js +1 -1
  131. package/dist/martyrs/src/modules/products/components/blocks/CardPosition.vue.cjs +1 -1
  132. package/dist/martyrs/src/modules/products/components/blocks/CardPosition.vue.js +1 -1
  133. package/dist/martyrs/src/modules/products/components/pages/Categories.vue.cjs +2 -2
  134. package/dist/martyrs/src/modules/products/components/pages/Categories.vue.js +2 -2
  135. package/dist/martyrs/src/modules/products/components/pages/CategoryEdit.vue.cjs +2 -2
  136. package/dist/martyrs/src/modules/products/components/pages/CategoryEdit.vue.js +2 -2
  137. package/dist/martyrs/src/modules/products/components/pages/EditLeftover.vue.cjs +1 -1
  138. package/dist/martyrs/src/modules/products/components/pages/EditLeftover.vue.js +1 -1
  139. package/dist/martyrs/src/modules/products/components/pages/Leftovers.vue.cjs +1 -1
  140. package/dist/martyrs/src/modules/products/components/pages/Leftovers.vue.js +1 -1
  141. package/dist/martyrs/src/modules/products/components/pages/Product.vue.cjs +2 -2
  142. package/dist/martyrs/src/modules/products/components/pages/Product.vue.js +2 -2
  143. package/dist/martyrs/src/modules/products/components/pages/ProductEdit.vue.cjs +2 -2
  144. package/dist/martyrs/src/modules/products/components/pages/ProductEdit.vue.js +2 -2
  145. package/dist/martyrs/src/modules/products/components/pages/Products.vue.cjs +1 -1
  146. package/dist/martyrs/src/modules/products/components/pages/Products.vue.js +1 -1
  147. package/dist/martyrs/src/modules/products/components/sections/EditProductInfo.vue.cjs +1 -1
  148. package/dist/martyrs/src/modules/products/components/sections/EditProductInfo.vue.js +1 -1
  149. package/dist/martyrs/src/modules/products/components/sections/SectionProduct.vue.cjs +2 -2
  150. package/dist/martyrs/src/modules/products/components/sections/SectionProduct.vue.js +2 -2
  151. package/dist/martyrs/src/modules/rents/views/components/pages/GanttChart.vue.cjs +1 -1
  152. package/dist/martyrs/src/modules/rents/views/components/pages/GanttChart.vue.js +1 -1
  153. package/dist/martyrs/src/modules/rents/views/components/pages/Rents.vue.cjs +1 -1
  154. package/dist/martyrs/src/modules/rents/views/components/pages/Rents.vue.js +1 -1
  155. package/dist/martyrs/src/modules/rents/views/components/pages/RentsEdit.vue.cjs +1 -1
  156. package/dist/martyrs/src/modules/rents/views/components/pages/RentsEdit.vue.js +1 -1
  157. package/dist/martyrs/src/modules/reports/components/sections/FormReport.vue.cjs +1 -1
  158. package/dist/martyrs/src/modules/reports/components/sections/FormReport.vue.js +1 -1
  159. package/dist/martyrs/src/modules/spots/components/layouts/Spots.vue.cjs +1 -1
  160. package/dist/martyrs/src/modules/spots/components/layouts/Spots.vue.js +1 -1
  161. package/dist/martyrs/src/modules/spots/components/pages/Map.vue.cjs +1 -1
  162. package/dist/martyrs/src/modules/spots/components/pages/Map.vue.js +1 -1
  163. package/dist/martyrs/src/modules/spots/components/pages/SpotEdit.vue.cjs +2 -2
  164. package/dist/martyrs/src/modules/spots/components/pages/SpotEdit.vue.js +2 -2
  165. package/dist/style.css +4 -92
  166. package/package.json +1 -1
  167. package/src/modules/chats/routes/chats.routes.js +19 -19
  168. package/src/modules/landing/landing.client.js +6 -6
  169. package/src/modules/notifications/components/layouts/NotificationsLayout.vue +2 -0
  170. package/src/modules/notifications/notifications.client.js +351 -167
  171. package/src/modules/notifications/notifications2.client.js +256 -0
  172. package/dist/martyrs/src/components/Button/Button.vue2.cjs.map +0 -1
  173. package/dist/martyrs/src/components/Dropdown/Dropdown.vue.js.map +0 -1
  174. package/dist/martyrs/src/components/Menu/Menu.vue.cjs.map +0 -1
  175. package/dist/martyrs/src/components/Menu/Menu.vue.js.map +0 -1
  176. package/dist/martyrs/src/components/SelectMulti/SelectMulti.vue.js.map +0 -1
  177. package/dist/martyrs/src/components/Tab/Tab.vue2.cjs.map +0 -1
  178. package/dist/martyrs/src/modules/landing/components/sections/SectionFeaturesImages.vue.cjs +0 -101
  179. package/dist/martyrs/src/modules/landing/components/sections/SectionFeaturesImages.vue.cjs.map +0 -1
  180. package/dist/martyrs/src/modules/landing/components/sections/SectionFeaturesImages.vue.js +0 -101
  181. package/dist/martyrs/src/modules/landing/components/sections/SectionFeaturesImages.vue.js.map +0 -1
  182. package/dist/martyrs/src/modules/landing/components/sections/SectionHeroToken.vue.cjs +0 -85
  183. package/dist/martyrs/src/modules/landing/components/sections/SectionHeroToken.vue.cjs.map +0 -1
  184. package/dist/martyrs/src/modules/landing/components/sections/SectionHeroToken.vue.js +0 -85
  185. package/dist/martyrs/src/modules/landing/components/sections/SectionHeroToken.vue.js.map +0 -1
  186. package/dist/martyrs/src/modules/landing/components/sections/SectionRoadmap.vue.cjs +0 -97
  187. package/dist/martyrs/src/modules/landing/components/sections/SectionRoadmap.vue.cjs.map +0 -1
  188. package/dist/martyrs/src/modules/landing/components/sections/SectionRoadmap.vue.js +0 -97
  189. package/dist/martyrs/src/modules/landing/components/sections/SectionRoadmap.vue.js.map +0 -1
@@ -1,168 +1,322 @@
1
1
  import { watch, toRefs } from "vue";
2
- import routerNotifications from './router/notifications.router.js';
3
- import * as storeNotifications from './store/notifications.store.js';
2
+ // Router import
3
+ import routerNotifications from './router/notifications.router.js';
4
+ // Store
5
+ import * as storeNotifications from './store/notifications.store.js';
6
+ // Auth store import
4
7
  import * as auth from '@martyrs/src/modules/auth/views/store/auth';
8
+ // Global WebSocket import
5
9
  import globalWebSocket from '@martyrs/src/modules/globals/views/classes/globals.websocket.js';
6
- import NotificationsLayout from './components/layouts/NotificationsLayout.vue';
7
- import NotificationsList from './components/sections/NotificationsList.vue';
8
- import NotificationPreferences from './components/sections/NotificationPreferences.vue';
9
- import Notifications from './components/pages/Notifications.vue';
10
- import NotificationBadge from './components/elements/NotificationBadge.vue';
11
- import NotificationItem from './components/blocks/NotificationItem.vue';
10
+ // Layouts
11
+ import NotificationsLayout from './components/layouts/NotificationsLayout.vue';
12
+ // Sections
13
+ import NotificationsList from './components/sections/NotificationsList.vue';
14
+ import NotificationPreferences from './components/sections/NotificationPreferences.vue';
15
+ // Pages
16
+ import Notifications from './components/pages/Notifications.vue';
17
+ // Components
18
+ import NotificationBadge from './components/elements/NotificationBadge.vue';
19
+ import NotificationItem from './components/blocks/NotificationItem.vue';
20
+
21
+ /**
22
+ * WebSocket notification handler that uses the global WebSocket connection
23
+ */
24
+ class WebSocketNotificationHandler {
25
+ constructor(store, options = {}) {
26
+ this.store = store;
27
+ this.options = options;
28
+ this.moduleName = 'notifications';
29
+ this.listeners = [];
30
+ }
12
31
 
13
- // WebSocket notification handlers
14
- const wsNotificationHandlers = {
15
- connect: (store, userId, options = {}) => {
16
- if (typeof window === 'undefined' || !userId) return Promise.resolve(false);
17
-
18
- return globalWebSocket.connect(userId).then(() => {
19
- const moduleName = 'notifications';
20
- const listeners = [];
32
+ /**
33
+ * Connect to notifications channel
34
+ */
35
+ connect(userId) {
36
+ // Skip if running in SSR
37
+ if (typeof window === 'undefined' || !userId) {
38
+ return Promise.resolve(false);
39
+ }
21
40
 
22
- const addListener = (event, handler) => {
23
- listeners.push(globalWebSocket.addEventListener(event, handler, { module: moduleName }));
24
- };
41
+ // First ensure the global WebSocket is connected
42
+ return globalWebSocket.connect(userId).then(() => {
43
+ // Register event listeners
44
+ this._registerListeners();
45
+ return true;
46
+ });
47
+ }
25
48
 
26
- addListener('notification', (data) => {
27
- if (!data || !data.data) return;
28
- const notification = data.data;
29
-
30
- store.notifications.actions.addLocalNotification({
31
- _id: notification._id,
32
- title: notification.title,
33
- body: notification.body,
34
- type: notification.type || 'info',
35
- metadata: notification.metadata || {},
36
- status: 'unread',
37
- createdAt: notification.createdAt || new Date().toISOString(),
38
- updatedAt: notification.updatedAt || new Date().toISOString()
39
- });
40
- });
49
+ /**
50
+ * Disconnect notification listeners
51
+ */
52
+ disconnect() {
53
+ globalWebSocket.removeModuleListeners(this.moduleName);
54
+ }
41
55
 
42
- addListener('notification_read', (data) => {
43
- store.notifications.actions.syncNotificationStatus(data.notificationId, 'read');
44
- });
56
+ /**
57
+ * Register notification event listeners
58
+ */
59
+ _registerListeners() {
60
+ // Listen for notification events
61
+ this.listeners.push(
62
+ globalWebSocket.addEventListener('notification', this._processNotification.bind(this), {
63
+ module: this.moduleName
64
+ })
65
+ );
66
+
67
+ // Listen for notification read status changes
68
+ this.listeners.push(
69
+ globalWebSocket.addEventListener('notification_read', (data) => {
70
+ this.store.notifications.actions.syncNotificationStatus(data.notificationId, 'read');
71
+ }, { module: this.moduleName })
72
+ );
73
+ }
45
74
 
46
- return { listeners, moduleName };
75
+ /**
76
+ * Process incoming notification
77
+ */
78
+ _processNotification(data) {
79
+ if (!data || !data.data) return;
80
+
81
+ const notification = data.data;
82
+
83
+ // Add notification to store
84
+ this.store.notifications.actions.addLocalNotification({
85
+ _id: notification._id,
86
+ title: notification.title,
87
+ body: notification.body,
88
+ type: notification.type || 'info',
89
+ metadata: notification.metadata || {},
90
+ status: 'unread',
91
+ createdAt: notification.createdAt || new Date().toISOString(),
92
+ updatedAt: notification.updatedAt || new Date().toISOString()
47
93
  });
48
- },
49
-
50
- disconnect: (moduleName, listeners) => {
51
- if (listeners) {
52
- globalWebSocket.removeModuleListeners(moduleName);
53
- }
54
94
  }
55
- };
95
+ }
96
+
97
+ /**
98
+ * Capacitor Push Notification handler
99
+ */
100
+ class CapacitorPushHandler {
101
+ constructor(store) {
102
+ this.store = store;
103
+ this.pushNotifications = null;
104
+ this.device = null;
105
+ this.isInitialized = false;
106
+ }
56
107
 
57
- // Capacitor Push Notification handlers
58
- const pushNotificationHandlers = {
59
- initialize: async () => {
60
- if (typeof window === 'undefined') return false;
108
+ /**
109
+ * Initialize Capacitor plugins
110
+ */
111
+ async initialize() {
112
+ // Skip if running in SSR
113
+ if (typeof window === 'undefined') {
114
+ return false;
115
+ }
61
116
 
62
117
  try {
118
+ // Dynamic imports to prevent errors in web environment
63
119
  const { Capacitor } = await import('@capacitor/core');
64
120
  const { PushNotifications } = await import('@capacitor/push-notifications');
65
121
  const { Device } = await import('@capacitor/device');
66
-
67
- if (!Capacitor.isNativePlatform()) return false;
68
-
69
- return { pushNotifications: PushNotifications, device: Device };
122
+
123
+ this.capacitor = Capacitor;
124
+ this.pushNotifications = PushNotifications;
125
+ this.device = Device;
126
+
127
+ // Only proceed if running on a native platform
128
+ if (!this.capacitor.isNativePlatform()) {
129
+ return false;
130
+ }
131
+
132
+ this.isInitialized = true;
133
+ return true;
70
134
  } catch (error) {
71
135
  console.error('Error importing Capacitor plugins:', error);
72
136
  return false;
73
137
  }
74
- },
75
-
76
- requestPermissions: async (store) => {
77
- if (typeof window === 'undefined') return false;
78
-
79
- const plugins = await pushNotificationHandlers.initialize();
80
- if (!plugins) return false;
81
-
82
- const { pushNotifications, device } = plugins;
138
+ }
83
139
 
84
- const permissionResult = await pushNotifications.requestPermissions();
85
- if (permissionResult.receive !== 'granted') {
86
- console.log('Push notification permission denied');
140
+ /**
141
+ * Request permission and register for push notifications
142
+ */
143
+ async requestPermissions() {
144
+ // Skip if running in SSR
145
+ if (typeof window === 'undefined') {
87
146
  return false;
88
147
  }
89
148
 
90
- const setupListeners = () => {
91
- pushNotifications.addListener('registration', async (token) => {
92
- try {
93
- const deviceInfo = await device.getInfo();
94
- const deviceId = await device.getId();
95
-
96
- const deviceData = {
97
- deviceId: deviceId.uuid,
98
- deviceType: deviceInfo.platform.toLowerCase(),
99
- deviceToken: token.value
100
- };
149
+ if (!this.isInitialized) {
150
+ const initialized = await this.initialize();
151
+ if (!initialized) return false;
152
+ }
101
153
 
102
- await store.notifications.actions.registerDevice(deviceData);
103
- } catch (error) {
104
- console.error('Error handling push registration:', error);
105
- }
106
- });
154
+ try {
155
+ // Request permission
156
+ const permissionResult = await this.pushNotifications.requestPermissions();
157
+ if (permissionResult.receive !== 'granted') {
158
+ console.log('Push notification permission denied');
159
+ return false;
160
+ }
161
+
162
+ // Set up event listeners
163
+ this._setupListeners();
164
+
165
+ // Register with Apple/Google
166
+ await this.pushNotifications.register();
167
+ return true;
168
+ } catch (error) {
169
+ console.error('Error requesting push notification permissions:', error);
170
+ return false;
171
+ }
172
+ }
107
173
 
108
- pushNotifications.addListener('pushNotificationReceived', (notification) => {
109
- store.notifications.actions.addLocalNotification({
110
- title: notification.title,
111
- body: notification.body,
112
- data: notification.data || {}
113
- });
114
- });
174
+ /**
175
+ * Setup push notification event listeners
176
+ */
177
+ _setupListeners() {
178
+ // Registration event
179
+ this.pushNotifications.addListener('registration',
180
+ this._handleRegistration.bind(this)
181
+ );
182
+
183
+ // Notification received event
184
+ this.pushNotifications.addListener('pushNotificationReceived',
185
+ this._handleNotificationReceived.bind(this)
186
+ );
187
+
188
+ // Notification action performed event
189
+ this.pushNotifications.addListener('pushNotificationActionPerformed',
190
+ this._handleNotificationAction.bind(this)
191
+ );
192
+ }
115
193
 
116
- pushNotifications.addListener('pushNotificationActionPerformed', (actionData) => {
117
- if (actionData.notification && actionData.notification.data) {
118
- store.notifications.actions.handleNotificationAction(actionData.notification.data);
119
- }
120
- });
121
- };
194
+ /**
195
+ * Handle registration token received
196
+ */
197
+ async _handleRegistration(token) {
198
+ try {
199
+ // Get device info
200
+ const deviceInfo = await this.device.getInfo();
201
+ const deviceId = await this.device.getId();
202
+
203
+ // Prepare device data
204
+ const deviceData = {
205
+ deviceId: deviceId.uuid,
206
+ deviceType: deviceInfo.platform.toLowerCase(),
207
+ deviceToken: token.value
208
+ };
209
+
210
+ // Register device with backend
211
+ await this.store.notifications.actions.registerDevice(deviceData);
212
+ } catch (error) {
213
+ console.error('Error handling push registration:', error);
214
+ }
215
+ }
122
216
 
123
- setupListeners();
124
- await pushNotifications.register();
125
- return true;
126
- },
217
+ /**
218
+ * Handle received notification
219
+ */
220
+ _handleNotificationReceived(notification) {
221
+ // Add notification to store
222
+ this.store.notifications.actions.addLocalNotification({
223
+ title: notification.title,
224
+ body: notification.body,
225
+ data: notification.data || {}
226
+ });
227
+ }
127
228
 
128
- removeListeners: (pushNotifications) => {
129
- if (typeof window === 'undefined' || !pushNotifications) return;
130
- pushNotifications.removeAllListeners();
229
+ /**
230
+ * Handle notification action (when user taps on notification)
231
+ */
232
+ _handleNotificationAction(actionData) {
233
+ if (actionData.notification && actionData.notification.data) {
234
+ this.store.notifications.actions.handleNotificationAction(
235
+ actionData.notification.data
236
+ );
237
+ }
131
238
  }
132
- };
133
239
 
134
- // Notification utilities
135
- const notificationUtils = {
136
- initialize: async (store, options = {}) => {
137
- if (typeof window === 'undefined') return;
240
+ /**
241
+ * Remove push notification listeners
242
+ */
243
+ removeListeners() {
244
+ if (typeof window === 'undefined') {
245
+ return;
246
+ }
247
+
248
+ if (this.pushNotifications) {
249
+ this.pushNotifications.removeAllListeners();
250
+ }
251
+ }
252
+ }
253
+
254
+ /**
255
+ * Notification Manager for coordinating WebSocket and Push notifications
256
+ */
257
+ class NotificationManager {
258
+ constructor(store, options = {}) {
259
+ this.store = store;
260
+ this.options = options;
261
+ this.wsHandler = new WebSocketNotificationHandler(store, options);
262
+ this.pushHandler = new CapacitorPushHandler(store);
263
+ this.initialized = false;
264
+ this.isServer = typeof window === 'undefined';
265
+ }
138
266
 
139
- const userId = store.auth.state.user?._id;
267
+ /**
268
+ * Initialize notifications
269
+ */
270
+ async initialize() {
271
+ if (this.initialized || this.isServer) return;
272
+
273
+ // Get current user ID from auth store instead of localStorage
274
+ const userId = this.store.auth.state.user?._id;
140
275
  if (!userId) {
141
276
  console.warn('Cannot initialize notifications: No user ID found in auth store');
142
277
  return;
143
278
  }
144
-
145
- let wsListeners = null;
146
- if (options.enablePush !== false) {
147
- await pushNotificationHandlers.requestPermissions(store);
279
+
280
+ // Initialize WebSocket for realtime notifications
281
+ await this.wsHandler.connect(userId);
282
+
283
+ // Initialize push notifications for mobile if enabled
284
+ if (this.options.enablePush !== false) {
285
+ await this.pushHandler.requestPermissions();
148
286
  }
287
+
288
+ this.initialized = true;
289
+
290
+ // Fetch existing notifications
291
+ await this.store.notifications.actions.getNotifications(userId);
292
+ }
149
293
 
150
- wsListeners = await wsNotificationHandlers.connect(store, userId, options);
151
-
152
- await store.notifications.actions.getNotifications(userId);
153
-
154
- return {
155
- disconnect: () => {
156
- wsNotificationHandlers.disconnect(wsListeners?.moduleName, wsListeners?.listeners);
157
- pushNotificationHandlers.removeListeners(globalThis.pushNotifications);
158
- }
159
- };
160
- },
161
-
162
- prefetchForSSR: async (store, context) => {
294
+ /**
295
+ * Disconnect and clean up
296
+ */
297
+ disconnect() {
298
+ if (this.isServer) return;
299
+
300
+ this.wsHandler.disconnect();
301
+ this.pushHandler.removeListeners();
302
+ this.initialized = false;
303
+ }
304
+ }
305
+
306
+ /**
307
+ * Server-side utility for pre-fetching notification data
308
+ */
309
+ const SSRUtils = {
310
+ /**
311
+ * Pre-fetch notifications for SSR
312
+ * @param {Object} store - Store instance
313
+ * @param {Object} context - SSR context
314
+ */
315
+ async prefetchNotifications(store, context) {
163
316
  try {
164
317
  const userId = store.auth.state.user?._id;
165
318
  if (userId) {
319
+ // Fetch notifications without WebSocket or push setup
166
320
  await store.notifications.actions.getNotifications(userId);
167
321
  }
168
322
  } catch (error) {
@@ -171,86 +325,116 @@ const notificationUtils = {
171
325
  }
172
326
  };
173
327
 
174
- // Main initialization function
175
- const initializeNotifications = (app, store, router, options = {}) => {
328
+ /**
329
+ * Function to initialize the notifications module
330
+ * @param {Object} app - Vue app instance
331
+ * @param {Object} store - Vuex/Pinia store
332
+ * @param {Object} router - Vue Router instance
333
+ * @param {Object} options - Configuration options
334
+ */
335
+ function initializeNotifications(app, store, router, options = {}) {
336
+ // Add routes and store
176
337
  const route = options.route || 'User Profile Root';
177
338
  router.addRoute(route, routerNotifications);
178
339
  store.addStore('notifications', storeNotifications);
179
-
340
+
341
+ // Initialize global WebSocket if needed
180
342
  if (options.wsUrl) {
181
343
  globalWebSocket.initialize({ wsUrl: options.wsUrl });
182
344
  }
183
-
345
+
346
+ // Create notification manager
347
+ const notificationManager = new NotificationManager(store, {
348
+ enablePush: options.enablePush !== false,
349
+ maxReconnectAttempts: options.maxReconnectAttempts || 5,
350
+ reconnectDelay: options.reconnectDelay || 3000,
351
+ pingInterval: options.pingInterval || 30000
352
+ });
353
+
354
+ // Attach notification manager to store for access in components
355
+ store.notificationManager = notificationManager;
356
+
357
+ // Don't auto-initialize on server
184
358
  const isServer = typeof window === 'undefined';
185
359
  const autoInit = !isServer && options.autoInit !== false;
186
-
187
- let notificationManager = null;
188
-
360
+
189
361
  if (autoInit) {
190
- const initNotifications = async () => {
191
- if (store.auth.state.isAuthenticated && store.auth.state.user?._id) {
192
- notificationManager = await notificationUtils.initialize(store, {
193
- enablePush: options.enablePush !== false,
194
- maxReconnectAttempts: options.maxReconnectAttempts || 5,
195
- reconnectDelay: options.reconnectDelay || 3000,
196
- pingInterval: options.pingInterval || 30000
197
- });
198
- }
199
- };
200
-
362
+ // Initialize after auth is confirmed
363
+ const isAuthenticated = store.auth.state.isAuthenticated;
364
+ const userId = store.auth.state.user?._id;
365
+
366
+ if (isAuthenticated && userId) {
367
+ notificationManager.initialize();
368
+ }
369
+
370
+ // Watch for user login/logout using auth store
201
371
  watch(() => store.auth.state.isAuthenticated, (isAuthenticated) => {
202
372
  if (isAuthenticated) {
203
- initNotifications();
204
- } else if (notificationManager) {
373
+ notificationManager.initialize();
374
+ } else {
205
375
  notificationManager.disconnect();
206
376
  store.notifications.mutations.resetNotifications();
207
- notificationManager = null;
208
377
  }
209
378
  });
210
-
211
- if (store.auth.state.isAuthenticated) {
212
- initNotifications();
213
- }
214
379
  }
380
+
381
+ // Provide composable for components to access notification functionality
382
+ app.provide('useNotifications', () => {
383
+ return {
384
+ ...toRefs(store.notifications.state),
385
+ ...store.notifications.actions,
386
+ ...store.notifications.mutations,
387
+ init: notificationManager.initialize.bind(notificationManager),
388
+ disconnect: notificationManager.disconnect.bind(notificationManager),
389
+ isServer
390
+ };
391
+ });
392
+
393
+ return notificationManager;
394
+ }
215
395
 
216
- app.provide('useNotifications', () => ({
217
- ...toRefs(store.notifications.state),
218
- ...store.notifications.actions,
219
- ...store.notifications.mutations,
220
- init: () => notificationUtils.initialize(store, options),
221
- disconnect: () => notificationManager?.disconnect(),
222
- isServer
223
- }));
224
-
225
- return {
226
- SSR: { prefetchNotifications: notificationUtils.prefetchForSSR }
227
- };
228
- };
229
-
396
+ // Module export
230
397
  const ModuleNotifications = {
231
398
  initialize: initializeNotifications,
399
+ SSR: SSRUtils, // Export SSR utilities
232
400
  views: {
233
- store: { storeNotifications },
234
- router: { routerNotifications },
401
+ store: {
402
+ storeNotifications,
403
+ },
404
+ router: {
405
+ routerNotifications
406
+ },
235
407
  components: {
408
+ // Elements
236
409
  NotificationBadge,
410
+ // Blocks
237
411
  NotificationItem,
412
+ // Sections
238
413
  NotificationsList,
239
414
  NotificationPreferences,
415
+ // Pages
240
416
  Notifications,
417
+ // Layouts
241
418
  NotificationsLayout
242
419
  }
243
420
  }
244
421
  };
245
422
 
423
+ // Component exports
246
424
  export {
425
+ // Elements
247
426
  NotificationBadge,
427
+ // Blocks
248
428
  NotificationItem,
429
+ // Sections
249
430
  NotificationsList,
250
431
  NotificationPreferences,
432
+ // Pages
251
433
  Notifications,
434
+ // Layouts
252
435
  NotificationsLayout,
253
- notificationUtils as SSRUtils
436
+ // SSR Utilities
437
+ SSRUtils
254
438
  };
255
439
 
256
- export default ModuleNotifications;
440
+ export default ModuleNotifications;