@ozdao/martyrs 0.2.489 → 0.2.491

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 (366) hide show
  1. package/dist/_virtual/index.cjs +4 -4
  2. package/dist/_virtual/index.js +4 -4
  3. package/dist/_virtual/index2.cjs +4 -4
  4. package/dist/_virtual/index2.js +4 -4
  5. package/dist/auth.server.cjs +2 -51
  6. package/dist/auth.server.js +1 -50
  7. package/dist/builder.cjs +90 -4
  8. package/dist/builder.js +90 -4
  9. package/dist/main-BhCqlPMQ.cjs +11 -0
  10. package/dist/{main-IVRL6IjM.js → main-YBlKbx0g.js} +1308 -1285
  11. package/dist/martyrs/src/components/Block/Block.vue.cjs +1 -1
  12. package/dist/martyrs/src/components/Block/Block.vue.js +1 -1
  13. package/dist/martyrs/src/components/Button/Button.vue2.cjs +48 -21
  14. package/dist/martyrs/src/components/Button/Button.vue2.cjs.map +1 -1
  15. package/dist/martyrs/src/components/Button/Button.vue2.js +49 -22
  16. package/dist/martyrs/src/components/Button/Button.vue2.js.map +1 -1
  17. package/dist/martyrs/src/components/Chips/{Chips.vue2.cjs → Chips.vue.cjs} +2 -2
  18. package/dist/martyrs/src/components/Chips/Chips.vue.cjs.map +1 -0
  19. package/dist/martyrs/src/components/Chips/{Chips.vue2.js → Chips.vue.js} +2 -2
  20. package/dist/martyrs/src/components/Chips/Chips.vue.js.map +1 -0
  21. package/dist/martyrs/src/components/Dropdown/{Dropdown.vue.cjs → Dropdown.vue2.cjs} +2 -2
  22. package/dist/martyrs/src/components/Dropdown/Dropdown.vue2.cjs.map +1 -0
  23. package/dist/martyrs/src/components/Dropdown/{Dropdown.vue.js → Dropdown.vue2.js} +2 -2
  24. package/dist/martyrs/src/components/Dropdown/{Dropdown.vue.cjs.map → Dropdown.vue2.js.map} +1 -1
  25. package/dist/martyrs/src/components/Feed/Carousel.vue.cjs +1 -1
  26. package/dist/martyrs/src/components/Feed/Carousel.vue.js +1 -1
  27. package/dist/martyrs/src/components/Feed/Feed.vue.cjs +2 -2
  28. package/dist/martyrs/src/components/Feed/Feed.vue.js +2 -2
  29. package/dist/martyrs/src/components/FieldTags/FieldTags.vue.cjs +1 -1
  30. package/dist/martyrs/src/components/FieldTags/FieldTags.vue.js +1 -1
  31. package/dist/martyrs/src/components/Loader/{Loader.vue2.cjs → Loader.vue.cjs} +3 -3
  32. package/dist/martyrs/src/components/Loader/Loader.vue.cjs.map +1 -0
  33. package/dist/martyrs/src/components/Loader/{Loader.vue2.js → Loader.vue.js} +3 -3
  34. package/dist/martyrs/src/components/Loader/Loader.vue.js.map +1 -0
  35. package/dist/martyrs/src/components/LocationMarker/LocationMarker.vue2.cjs +1 -1
  36. package/dist/martyrs/src/components/LocationMarker/LocationMarker.vue2.js +1 -1
  37. package/dist/martyrs/src/components/Tooltip/{Tooltip.vue2.cjs → Tooltip.vue.cjs} +2 -2
  38. package/dist/martyrs/src/components/Tooltip/{Tooltip.vue2.js.map → Tooltip.vue.cjs.map} +1 -1
  39. package/dist/martyrs/src/components/Tooltip/{Tooltip.vue2.js → Tooltip.vue.js} +2 -2
  40. package/dist/martyrs/src/components/Tooltip/Tooltip.vue.js.map +1 -0
  41. package/dist/martyrs/src/components/UploadImageMultiple/UploadImageMultiple.vue.cjs +1 -1
  42. package/dist/martyrs/src/components/UploadImageMultiple/UploadImageMultiple.vue.js +1 -1
  43. package/dist/martyrs/src/modules/auth/views/components/pages/Profile.vue.cjs +2 -2
  44. package/dist/martyrs/src/modules/auth/views/components/pages/Profile.vue.js +2 -2
  45. package/dist/martyrs/src/modules/community/components/blocks/CardBlogpost.vue.cjs +1 -1
  46. package/dist/martyrs/src/modules/community/components/blocks/CardBlogpost.vue.js +1 -1
  47. package/dist/martyrs/src/modules/community/components/pages/BlogPost.vue.cjs +2 -2
  48. package/dist/martyrs/src/modules/community/components/pages/BlogPost.vue.js +2 -2
  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/events/components/blocks/CardEvent.vue.cjs +1 -1
  52. package/dist/martyrs/src/modules/events/components/blocks/CardEvent.vue.js +1 -1
  53. package/dist/martyrs/src/modules/events/components/pages/EditEvent.vue.cjs +1 -1
  54. package/dist/martyrs/src/modules/events/components/pages/EditEvent.vue.js +1 -1
  55. package/dist/martyrs/src/modules/events/components/pages/Event.vue.cjs +3 -3
  56. package/dist/martyrs/src/modules/events/components/pages/Event.vue.js +3 -3
  57. package/dist/martyrs/src/modules/events/components/sections/Feed.vue.cjs +1 -1
  58. package/dist/martyrs/src/modules/events/components/sections/Feed.vue.js +1 -1
  59. package/dist/martyrs/src/modules/events/components/sections/List.vue.cjs +1 -1
  60. package/dist/martyrs/src/modules/events/components/sections/List.vue.js +1 -1
  61. package/dist/martyrs/src/modules/gallery/components/sections/BackofficeGallery.vue.cjs +1 -1
  62. package/dist/martyrs/src/modules/gallery/components/sections/BackofficeGallery.vue.js +1 -1
  63. package/dist/martyrs/src/modules/globals/globals.client.cjs +1 -2
  64. package/dist/martyrs/src/modules/globals/globals.client.cjs.map +1 -1
  65. package/dist/martyrs/src/modules/globals/globals.client.js +1 -2
  66. package/dist/martyrs/src/modules/globals/globals.client.js.map +1 -1
  67. package/dist/martyrs/src/modules/globals/views/classes/globals.i18n.cjs +1 -1
  68. package/dist/martyrs/src/modules/globals/views/classes/globals.i18n.js +1 -1
  69. package/dist/martyrs/src/modules/globals/views/components/blocks/CardHeader.vue.cjs +3 -3
  70. package/dist/martyrs/src/modules/globals/views/components/blocks/CardHeader.vue.js +3 -3
  71. package/dist/martyrs/src/modules/globals/views/components/blocks/PopupDateSelector.vue.cjs +1 -1
  72. package/dist/martyrs/src/modules/globals/views/components/blocks/PopupDateSelector.vue.js +1 -1
  73. package/dist/martyrs/src/modules/globals/views/components/layouts/Client.vue.cjs +10 -1
  74. package/dist/martyrs/src/modules/globals/views/components/layouts/Client.vue.cjs.map +1 -1
  75. package/dist/martyrs/src/modules/globals/views/components/layouts/Client.vue.js +10 -1
  76. package/dist/martyrs/src/modules/globals/views/components/layouts/Client.vue.js.map +1 -1
  77. package/dist/martyrs/src/modules/globals/views/components/partials/Navigation.vue.cjs +1 -1
  78. package/dist/martyrs/src/modules/globals/views/components/partials/Navigation.vue.js +1 -1
  79. package/dist/martyrs/src/modules/marketplace/views/components/sections/SectionMenu.vue.cjs +1 -1
  80. package/dist/martyrs/src/modules/marketplace/views/components/sections/SectionMenu.vue.js +1 -1
  81. package/dist/martyrs/src/modules/music/components/forms/ArtistForm.vue.cjs +1 -1
  82. package/dist/martyrs/src/modules/music/components/forms/ArtistForm.vue.js +1 -1
  83. package/dist/martyrs/src/modules/music/components/layouts/MusicLayout.vue.cjs +2 -2
  84. package/dist/martyrs/src/modules/music/components/layouts/MusicLayout.vue.js +2 -2
  85. package/dist/martyrs/src/modules/music/components/pages/Album.vue.cjs +2 -2
  86. package/dist/martyrs/src/modules/music/components/pages/Album.vue.js +2 -2
  87. package/dist/martyrs/src/modules/music/components/pages/Artist.vue.cjs +1 -1
  88. package/dist/martyrs/src/modules/music/components/pages/Artist.vue.js +1 -1
  89. package/dist/martyrs/src/modules/music/components/pages/Playlist.vue.cjs +2 -2
  90. package/dist/martyrs/src/modules/music/components/pages/Playlist.vue.js +2 -2
  91. package/dist/martyrs/src/modules/music/components/pages/SearchResults.vue.cjs +1 -1
  92. package/dist/martyrs/src/modules/music/components/pages/SearchResults.vue.js +1 -1
  93. package/dist/martyrs/src/modules/music/components/pages/Track.vue.cjs +2 -2
  94. package/dist/martyrs/src/modules/music/components/pages/Track.vue.js +2 -2
  95. package/dist/martyrs/src/modules/music/components/pages/TrackCreate.vue.cjs +1 -1
  96. package/dist/martyrs/src/modules/music/components/pages/TrackCreate.vue.js +1 -1
  97. package/dist/martyrs/src/modules/notifications/components/layouts/NotificationsLayout.vue.cjs +22 -8
  98. package/dist/martyrs/src/modules/notifications/components/layouts/NotificationsLayout.vue.cjs.map +1 -1
  99. package/dist/martyrs/src/modules/notifications/components/layouts/NotificationsLayout.vue.js +23 -9
  100. package/dist/martyrs/src/modules/notifications/components/layouts/NotificationsLayout.vue.js.map +1 -1
  101. package/dist/martyrs/src/modules/notifications/components/pages/Notifications.vue.cjs +13 -15
  102. package/dist/martyrs/src/modules/notifications/components/pages/Notifications.vue.cjs.map +1 -1
  103. package/dist/martyrs/src/modules/notifications/components/pages/Notifications.vue.js +14 -16
  104. package/dist/martyrs/src/modules/notifications/components/pages/Notifications.vue.js.map +1 -1
  105. package/dist/martyrs/src/modules/notifications/components/sections/NotificationPreferences.vue.cjs +2 -2
  106. package/dist/martyrs/src/modules/notifications/components/sections/NotificationPreferences.vue.cjs.map +1 -1
  107. package/dist/martyrs/src/modules/notifications/components/sections/NotificationPreferences.vue.js +2 -2
  108. package/dist/martyrs/src/modules/notifications/components/sections/NotificationPreferences.vue.js.map +1 -1
  109. package/dist/martyrs/src/modules/notifications/components/sections/NotificationsList.vue.cjs +2 -2
  110. package/dist/martyrs/src/modules/notifications/components/sections/NotificationsList.vue.cjs.map +1 -1
  111. package/dist/martyrs/src/modules/notifications/components/sections/NotificationsList.vue.js +2 -2
  112. package/dist/martyrs/src/modules/notifications/components/sections/NotificationsList.vue.js.map +1 -1
  113. package/dist/martyrs/src/modules/notifications/notifications.client.cjs +1 -1
  114. package/dist/martyrs/src/modules/notifications/notifications.client.cjs.map +1 -1
  115. package/dist/martyrs/src/modules/notifications/notifications.client.js +7 -7
  116. package/dist/martyrs/src/modules/notifications/notifications.client.js.map +1 -1
  117. package/dist/martyrs/src/modules/notifications/router/notifications.router.js +4 -4
  118. package/dist/martyrs/src/modules/notifications/router/notifications.router.js.map +1 -1
  119. package/dist/martyrs/src/modules/notifications/store/notifications.store.cjs +7 -10
  120. package/dist/martyrs/src/modules/notifications/store/notifications.store.cjs.map +1 -1
  121. package/dist/martyrs/src/modules/notifications/store/notifications.store.js +7 -10
  122. package/dist/martyrs/src/modules/notifications/store/notifications.store.js.map +1 -1
  123. package/dist/martyrs/src/modules/orders/components/blocks/CardOrderUser.vue.cjs +1 -1
  124. package/dist/martyrs/src/modules/orders/components/blocks/CardOrderUser.vue.js +1 -1
  125. package/dist/martyrs/src/modules/orders/components/pages/OrderBackoffice.vue.cjs +1 -1
  126. package/dist/martyrs/src/modules/orders/components/pages/OrderBackoffice.vue.js +1 -1
  127. package/dist/martyrs/src/modules/orders/components/partials/ShopCart.vue.cjs +0 -1
  128. package/dist/martyrs/src/modules/orders/components/partials/ShopCart.vue.cjs.map +1 -1
  129. package/dist/martyrs/src/modules/orders/components/partials/ShopCart.vue.js +0 -1
  130. package/dist/martyrs/src/modules/orders/components/partials/ShopCart.vue.js.map +1 -1
  131. package/dist/martyrs/src/modules/orders/components/sections/FormDelivery.vue.cjs +2 -2
  132. package/dist/martyrs/src/modules/orders/components/sections/FormDelivery.vue.js +2 -2
  133. package/dist/martyrs/src/modules/organizations/components/blocks/CardOrganization.vue.cjs +1 -1
  134. package/dist/martyrs/src/modules/organizations/components/blocks/CardOrganization.vue.js +1 -1
  135. package/dist/martyrs/src/modules/organizations/components/pages/DepartmentEdit.vue.cjs +1 -1
  136. package/dist/martyrs/src/modules/organizations/components/pages/DepartmentEdit.vue.js +1 -1
  137. package/dist/martyrs/src/modules/organizations/components/pages/Members.vue.cjs +1 -1
  138. package/dist/martyrs/src/modules/organizations/components/pages/Members.vue.js +1 -1
  139. package/dist/martyrs/src/modules/organizations/components/sections/DetailsTabSection.vue.cjs +2 -2
  140. package/dist/martyrs/src/modules/organizations/components/sections/DetailsTabSection.vue.js +2 -2
  141. package/dist/martyrs/src/modules/organizations/components/sections/Documents.vue.cjs +1 -1
  142. package/dist/martyrs/src/modules/organizations/components/sections/Documents.vue.js +1 -1
  143. package/dist/martyrs/src/modules/organizations/components/sections/Organizations.vue.cjs +1 -1
  144. package/dist/martyrs/src/modules/organizations/components/sections/Organizations.vue.js +1 -1
  145. package/dist/martyrs/src/modules/pages/views/components/blocks/CardPage.vue.cjs +1 -1
  146. package/dist/martyrs/src/modules/pages/views/components/blocks/CardPage.vue.js +1 -1
  147. package/dist/martyrs/src/modules/pages/views/components/pages/PageEdit.vue.cjs +1 -1
  148. package/dist/martyrs/src/modules/pages/views/components/pages/PageEdit.vue.js +1 -1
  149. package/dist/martyrs/src/modules/products/components/blocks/ProductDiscounts.vue.cjs +2 -2
  150. package/dist/martyrs/src/modules/products/components/blocks/ProductDiscounts.vue.js +2 -2
  151. package/dist/martyrs/src/modules/products/components/elements/Image360.vue.cjs +1 -1
  152. package/dist/martyrs/src/modules/products/components/elements/Image360.vue.js +1 -1
  153. package/dist/martyrs/src/modules/products/components/pages/Categories.vue.cjs +1 -1
  154. package/dist/martyrs/src/modules/products/components/pages/Categories.vue.js +1 -1
  155. package/dist/martyrs/src/modules/products/components/pages/CategoryEdit.vue.cjs +2 -2
  156. package/dist/martyrs/src/modules/products/components/pages/CategoryEdit.vue.js +2 -2
  157. package/dist/martyrs/src/modules/products/components/pages/Product.vue.cjs +1 -1
  158. package/dist/martyrs/src/modules/products/components/pages/Product.vue.js +1 -1
  159. package/dist/martyrs/src/modules/products/components/pages/ProductRecommmendation.vue.cjs +1 -1
  160. package/dist/martyrs/src/modules/products/components/pages/ProductRecommmendation.vue.js +1 -1
  161. package/dist/martyrs/src/modules/spots/components/blocks/CardSpot.vue.cjs +1 -1
  162. package/dist/martyrs/src/modules/spots/components/blocks/CardSpot.vue.js +1 -1
  163. package/dist/martyrs/src/modules/spots/components/layouts/Spots.vue.cjs +1 -1
  164. package/dist/martyrs/src/modules/spots/components/layouts/Spots.vue.js +1 -1
  165. package/dist/martyrs/src/modules/wallet/views/components/pages/Wallet.vue.cjs +3 -3
  166. package/dist/martyrs/src/modules/wallet/views/components/pages/Wallet.vue.js +3 -3
  167. package/dist/martyrs.cjs.js +1 -1
  168. package/dist/martyrs.css +1 -1
  169. package/dist/martyrs.es.js +1 -1
  170. package/dist/notifications.server.cjs +142 -44
  171. package/dist/notifications.server.js +142 -44
  172. package/dist/orders.server.cjs +155 -102
  173. package/dist/orders.server.js +155 -102
  174. package/dist/products.server.cjs +4 -0
  175. package/dist/products.server.js +4 -0
  176. package/dist/profile.schema-BGAe5VN5.js +92 -0
  177. package/dist/profile.schema-pidHrksV.cjs +91 -0
  178. package/dist/style.css +65 -247
  179. package/dist/{web-BXhlxo6M.cjs → web-BBmMBRv-.cjs} +1 -1
  180. package/dist/{web-Czi05iGG.js → web-Dqu-aCL5.js} +1 -1
  181. package/package.json +1 -1
  182. package/src/builder/rspack/rspack.config.spa.client.js +46 -1
  183. package/src/builder/rspack/rspack.config.ssr.client.js +43 -0
  184. package/src/builder/templates/page.js +1 -1
  185. package/src/components/Button/Button.vue +230 -196
  186. package/src/components/Loader/Loader.vue +1 -1
  187. package/src/modules/auth/controllers/middlewares/visitor.logger.js +22 -0
  188. package/src/modules/globals/globals.client.js +1 -1
  189. package/src/modules/globals/views/components/layouts/Client.vue +10 -9
  190. package/src/modules/notifications/FIXES.md +4 -0
  191. package/src/modules/notifications/components/layouts/NotificationsLayout.vue +33 -32
  192. package/src/modules/notifications/components/pages/Notifications.vue +10 -51
  193. package/src/modules/notifications/components/sections/NotificationPreferences.vue +1 -11
  194. package/src/modules/notifications/components/sections/NotificationsList.vue +1 -1
  195. package/src/modules/notifications/controllers/notifications.controller.js +50 -4
  196. package/src/modules/notifications/notifications.client.js +1 -1
  197. package/src/modules/notifications/notifications.server.js +18 -7
  198. package/src/modules/notifications/routes/notifications.routes.js +4 -2
  199. package/src/modules/notifications/services/notification.service.js +109 -38
  200. package/src/modules/notifications/services/telegram.service.js +1 -0
  201. package/src/modules/notifications/services/whatsapp.service.js +1 -0
  202. package/src/modules/notifications/store/notifications.store.js +25 -16
  203. package/src/modules/orders/components/partials/ShopCart.vue +0 -1
  204. package/src/modules/orders/controllers/orders.controller.js +195 -85
  205. package/src/modules/products/controllers/products.controller.js +4 -0
  206. package/dist/main-CmuUC0tl.cjs +0 -11
  207. package/dist/martyrs/src/components/Chips/Chips.vue2.cjs.map +0 -1
  208. package/dist/martyrs/src/components/Chips/Chips.vue2.js.map +0 -1
  209. package/dist/martyrs/src/components/Dropdown/Dropdown.vue.js.map +0 -1
  210. package/dist/martyrs/src/components/Loader/Loader.vue2.cjs.map +0 -1
  211. package/dist/martyrs/src/components/Loader/Loader.vue2.js.map +0 -1
  212. package/dist/martyrs/src/components/Tooltip/Tooltip.vue2.cjs.map +0 -1
  213. package/dist/martyrs/src/modules/globals/views/plugins/store-debugger/StoreDebugger.vue.cjs +0 -200
  214. package/dist/martyrs/src/modules/globals/views/plugins/store-debugger/StoreDebugger.vue.cjs.map +0 -1
  215. package/dist/martyrs/src/modules/globals/views/plugins/store-debugger/StoreDebugger.vue.js +0 -200
  216. package/dist/martyrs/src/modules/globals/views/plugins/store-debugger/StoreDebugger.vue.js.map +0 -1
  217. package/dist/martyrs/src/modules/globals/views/plugins/store-debugger/store-debugger.plugin.cjs +0 -21
  218. package/dist/martyrs/src/modules/globals/views/plugins/store-debugger/store-debugger.plugin.cjs.map +0 -1
  219. package/dist/martyrs/src/modules/globals/views/plugins/store-debugger/store-debugger.plugin.js +0 -21
  220. package/dist/martyrs/src/modules/globals/views/plugins/store-debugger/store-debugger.plugin.js.map +0 -1
  221. package/dist/node_modules/date-fns/_lib/addLeadingZeros.cjs +0 -9
  222. package/dist/node_modules/date-fns/_lib/addLeadingZeros.cjs.map +0 -1
  223. package/dist/node_modules/date-fns/_lib/addLeadingZeros.js +0 -9
  224. package/dist/node_modules/date-fns/_lib/addLeadingZeros.js.map +0 -1
  225. package/dist/node_modules/date-fns/_lib/defaultOptions.cjs +0 -8
  226. package/dist/node_modules/date-fns/_lib/defaultOptions.cjs.map +0 -1
  227. package/dist/node_modules/date-fns/_lib/defaultOptions.js +0 -8
  228. package/dist/node_modules/date-fns/_lib/defaultOptions.js.map +0 -1
  229. package/dist/node_modules/date-fns/_lib/format/formatters.cjs +0 -653
  230. package/dist/node_modules/date-fns/_lib/format/formatters.cjs.map +0 -1
  231. package/dist/node_modules/date-fns/_lib/format/formatters.js +0 -653
  232. package/dist/node_modules/date-fns/_lib/format/formatters.js.map +0 -1
  233. package/dist/node_modules/date-fns/_lib/format/lightFormatters.cjs +0 -63
  234. package/dist/node_modules/date-fns/_lib/format/lightFormatters.cjs.map +0 -1
  235. package/dist/node_modules/date-fns/_lib/format/lightFormatters.js +0 -63
  236. package/dist/node_modules/date-fns/_lib/format/lightFormatters.js.map +0 -1
  237. package/dist/node_modules/date-fns/_lib/format/longFormatters.cjs +0 -59
  238. package/dist/node_modules/date-fns/_lib/format/longFormatters.cjs.map +0 -1
  239. package/dist/node_modules/date-fns/_lib/format/longFormatters.js +0 -59
  240. package/dist/node_modules/date-fns/_lib/format/longFormatters.js.map +0 -1
  241. package/dist/node_modules/date-fns/_lib/getTimezoneOffsetInMilliseconds.cjs +0 -21
  242. package/dist/node_modules/date-fns/_lib/getTimezoneOffsetInMilliseconds.cjs.map +0 -1
  243. package/dist/node_modules/date-fns/_lib/getTimezoneOffsetInMilliseconds.js +0 -21
  244. package/dist/node_modules/date-fns/_lib/getTimezoneOffsetInMilliseconds.js.map +0 -1
  245. package/dist/node_modules/date-fns/_lib/normalizeDates.cjs +0 -12
  246. package/dist/node_modules/date-fns/_lib/normalizeDates.cjs.map +0 -1
  247. package/dist/node_modules/date-fns/_lib/normalizeDates.js +0 -12
  248. package/dist/node_modules/date-fns/_lib/normalizeDates.js.map +0 -1
  249. package/dist/node_modules/date-fns/_lib/protectedTokens.cjs +0 -24
  250. package/dist/node_modules/date-fns/_lib/protectedTokens.cjs.map +0 -1
  251. package/dist/node_modules/date-fns/_lib/protectedTokens.js +0 -24
  252. package/dist/node_modules/date-fns/_lib/protectedTokens.js.map +0 -1
  253. package/dist/node_modules/date-fns/constants.cjs +0 -9
  254. package/dist/node_modules/date-fns/constants.cjs.map +0 -1
  255. package/dist/node_modules/date-fns/constants.js +0 -9
  256. package/dist/node_modules/date-fns/constants.js.map +0 -1
  257. package/dist/node_modules/date-fns/constructFrom.cjs +0 -13
  258. package/dist/node_modules/date-fns/constructFrom.cjs.map +0 -1
  259. package/dist/node_modules/date-fns/constructFrom.js +0 -13
  260. package/dist/node_modules/date-fns/constructFrom.js.map +0 -1
  261. package/dist/node_modules/date-fns/differenceInCalendarDays.cjs +0 -21
  262. package/dist/node_modules/date-fns/differenceInCalendarDays.cjs.map +0 -1
  263. package/dist/node_modules/date-fns/differenceInCalendarDays.js +0 -21
  264. package/dist/node_modules/date-fns/differenceInCalendarDays.js.map +0 -1
  265. package/dist/node_modules/date-fns/format.cjs +0 -80
  266. package/dist/node_modules/date-fns/format.cjs.map +0 -1
  267. package/dist/node_modules/date-fns/format.js +0 -80
  268. package/dist/node_modules/date-fns/format.js.map +0 -1
  269. package/dist/node_modules/date-fns/getDayOfYear.cjs +0 -14
  270. package/dist/node_modules/date-fns/getDayOfYear.cjs.map +0 -1
  271. package/dist/node_modules/date-fns/getDayOfYear.js +0 -14
  272. package/dist/node_modules/date-fns/getDayOfYear.js.map +0 -1
  273. package/dist/node_modules/date-fns/getISOWeek.cjs +0 -14
  274. package/dist/node_modules/date-fns/getISOWeek.cjs.map +0 -1
  275. package/dist/node_modules/date-fns/getISOWeek.js +0 -14
  276. package/dist/node_modules/date-fns/getISOWeek.js.map +0 -1
  277. package/dist/node_modules/date-fns/getISOWeekYear.cjs +0 -27
  278. package/dist/node_modules/date-fns/getISOWeekYear.cjs.map +0 -1
  279. package/dist/node_modules/date-fns/getISOWeekYear.js +0 -27
  280. package/dist/node_modules/date-fns/getISOWeekYear.js.map +0 -1
  281. package/dist/node_modules/date-fns/getWeek.cjs +0 -14
  282. package/dist/node_modules/date-fns/getWeek.cjs.map +0 -1
  283. package/dist/node_modules/date-fns/getWeek.js +0 -14
  284. package/dist/node_modules/date-fns/getWeek.js.map +0 -1
  285. package/dist/node_modules/date-fns/getWeekYear.cjs +0 -31
  286. package/dist/node_modules/date-fns/getWeekYear.cjs.map +0 -1
  287. package/dist/node_modules/date-fns/getWeekYear.js +0 -31
  288. package/dist/node_modules/date-fns/getWeekYear.js.map +0 -1
  289. package/dist/node_modules/date-fns/isDate.cjs +0 -8
  290. package/dist/node_modules/date-fns/isDate.cjs.map +0 -1
  291. package/dist/node_modules/date-fns/isDate.js +0 -8
  292. package/dist/node_modules/date-fns/isDate.js.map +0 -1
  293. package/dist/node_modules/date-fns/isValid.cjs +0 -10
  294. package/dist/node_modules/date-fns/isValid.cjs.map +0 -1
  295. package/dist/node_modules/date-fns/isValid.js +0 -10
  296. package/dist/node_modules/date-fns/isValid.js.map +0 -1
  297. package/dist/node_modules/date-fns/locale/_lib/buildFormatLongFn.cjs +0 -11
  298. package/dist/node_modules/date-fns/locale/_lib/buildFormatLongFn.cjs.map +0 -1
  299. package/dist/node_modules/date-fns/locale/_lib/buildFormatLongFn.js +0 -11
  300. package/dist/node_modules/date-fns/locale/_lib/buildFormatLongFn.js.map +0 -1
  301. package/dist/node_modules/date-fns/locale/_lib/buildLocalizeFn.cjs +0 -21
  302. package/dist/node_modules/date-fns/locale/_lib/buildLocalizeFn.cjs.map +0 -1
  303. package/dist/node_modules/date-fns/locale/_lib/buildLocalizeFn.js +0 -21
  304. package/dist/node_modules/date-fns/locale/_lib/buildLocalizeFn.js.map +0 -1
  305. package/dist/node_modules/date-fns/locale/_lib/buildMatchFn.cjs +0 -44
  306. package/dist/node_modules/date-fns/locale/_lib/buildMatchFn.cjs.map +0 -1
  307. package/dist/node_modules/date-fns/locale/_lib/buildMatchFn.js +0 -44
  308. package/dist/node_modules/date-fns/locale/_lib/buildMatchFn.js.map +0 -1
  309. package/dist/node_modules/date-fns/locale/_lib/buildMatchPatternFn.cjs +0 -17
  310. package/dist/node_modules/date-fns/locale/_lib/buildMatchPatternFn.cjs.map +0 -1
  311. package/dist/node_modules/date-fns/locale/_lib/buildMatchPatternFn.js +0 -17
  312. package/dist/node_modules/date-fns/locale/_lib/buildMatchPatternFn.js.map +0 -1
  313. package/dist/node_modules/date-fns/locale/en-US/_lib/formatDistance.cjs +0 -86
  314. package/dist/node_modules/date-fns/locale/en-US/_lib/formatDistance.cjs.map +0 -1
  315. package/dist/node_modules/date-fns/locale/en-US/_lib/formatDistance.js +0 -86
  316. package/dist/node_modules/date-fns/locale/en-US/_lib/formatDistance.js.map +0 -1
  317. package/dist/node_modules/date-fns/locale/en-US/_lib/formatLong.cjs +0 -37
  318. package/dist/node_modules/date-fns/locale/en-US/_lib/formatLong.cjs.map +0 -1
  319. package/dist/node_modules/date-fns/locale/en-US/_lib/formatLong.js +0 -37
  320. package/dist/node_modules/date-fns/locale/en-US/_lib/formatLong.js.map +0 -1
  321. package/dist/node_modules/date-fns/locale/en-US/_lib/formatRelative.cjs +0 -13
  322. package/dist/node_modules/date-fns/locale/en-US/_lib/formatRelative.cjs.map +0 -1
  323. package/dist/node_modules/date-fns/locale/en-US/_lib/formatRelative.js +0 -13
  324. package/dist/node_modules/date-fns/locale/en-US/_lib/formatRelative.js.map +0 -1
  325. package/dist/node_modules/date-fns/locale/en-US/_lib/localize.cjs +0 -165
  326. package/dist/node_modules/date-fns/locale/en-US/_lib/localize.cjs.map +0 -1
  327. package/dist/node_modules/date-fns/locale/en-US/_lib/localize.js +0 -165
  328. package/dist/node_modules/date-fns/locale/en-US/_lib/localize.js.map +0 -1
  329. package/dist/node_modules/date-fns/locale/en-US/_lib/match.cjs +0 -123
  330. package/dist/node_modules/date-fns/locale/en-US/_lib/match.cjs.map +0 -1
  331. package/dist/node_modules/date-fns/locale/en-US/_lib/match.js +0 -123
  332. package/dist/node_modules/date-fns/locale/en-US/_lib/match.js.map +0 -1
  333. package/dist/node_modules/date-fns/locale/en-US.cjs +0 -22
  334. package/dist/node_modules/date-fns/locale/en-US.cjs.map +0 -1
  335. package/dist/node_modules/date-fns/locale/en-US.js +0 -22
  336. package/dist/node_modules/date-fns/locale/en-US.js.map +0 -1
  337. package/dist/node_modules/date-fns/startOfDay.cjs +0 -11
  338. package/dist/node_modules/date-fns/startOfDay.cjs.map +0 -1
  339. package/dist/node_modules/date-fns/startOfDay.js +0 -11
  340. package/dist/node_modules/date-fns/startOfDay.js.map +0 -1
  341. package/dist/node_modules/date-fns/startOfISOWeek.cjs +0 -9
  342. package/dist/node_modules/date-fns/startOfISOWeek.cjs.map +0 -1
  343. package/dist/node_modules/date-fns/startOfISOWeek.js +0 -9
  344. package/dist/node_modules/date-fns/startOfISOWeek.js.map +0 -1
  345. package/dist/node_modules/date-fns/startOfISOWeekYear.cjs +0 -15
  346. package/dist/node_modules/date-fns/startOfISOWeekYear.cjs.map +0 -1
  347. package/dist/node_modules/date-fns/startOfISOWeekYear.js +0 -15
  348. package/dist/node_modules/date-fns/startOfISOWeekYear.js.map +0 -1
  349. package/dist/node_modules/date-fns/startOfWeek.cjs +0 -18
  350. package/dist/node_modules/date-fns/startOfWeek.cjs.map +0 -1
  351. package/dist/node_modules/date-fns/startOfWeek.js +0 -18
  352. package/dist/node_modules/date-fns/startOfWeek.js.map +0 -1
  353. package/dist/node_modules/date-fns/startOfWeekYear.cjs +0 -20
  354. package/dist/node_modules/date-fns/startOfWeekYear.cjs.map +0 -1
  355. package/dist/node_modules/date-fns/startOfWeekYear.js +0 -20
  356. package/dist/node_modules/date-fns/startOfWeekYear.js.map +0 -1
  357. package/dist/node_modules/date-fns/startOfYear.cjs +0 -12
  358. package/dist/node_modules/date-fns/startOfYear.cjs.map +0 -1
  359. package/dist/node_modules/date-fns/startOfYear.js +0 -12
  360. package/dist/node_modules/date-fns/startOfYear.js.map +0 -1
  361. package/dist/node_modules/date-fns/toDate.cjs +0 -9
  362. package/dist/node_modules/date-fns/toDate.cjs.map +0 -1
  363. package/dist/node_modules/date-fns/toDate.js +0 -9
  364. package/dist/node_modules/date-fns/toDate.js.map +0 -1
  365. package/dist/profile.schema-DchVS-Jr.js +0 -21
  366. package/dist/profile.schema-yQuIzngl.cjs +0 -20
@@ -1 +1 @@
1
- {"version":3,"file":"NotificationsLayout.vue.js","sources":["../../../../../../../src/modules/notifications/components/layouts/NotificationsLayout.vue"],"sourcesContent":["<template>\n <div class=\"notifications-layout\">\n <div >\n </div> \n \n <div class=\"\">\n <router-view></router-view>\n </div>\n \n <div v-if=\"notificationManager && !isConnected\" class=\"connection-status\">\n <div class=\"connection-warning\">\n <span class=\"warning-icon\">⚠️</span>\n <span class=\"warning-text\">\n Notification service disconnected. \n <button @click=\"reconnect\" class=\"reconnect-btn\">Reconnect</button>\n </span>\n </div>\n </div>\n </div>\n</template>\n\n<script setup>\nimport { computed, inject } from 'vue';\n\n// Get notification manager from store\nconst store = inject('store');\n\nconst notificationManager = computed(() => store.notificationManager || null);\n\nconst isConnected = computed(() => {\n return notificationManager.value?.wsHandler?.isConnected || false;\n});\n\n// Methods\nconst reconnect = () => {\n if (notificationManager.value) {\n notificationManager.value.initialize();\n }\n};\n</script>\n\n<style scoped>\n.notifications-layout {\n display: flex;\n flex-direction: column;\n height: 100%;\n}\n\n.tabs {\n display: flex;\n gap: 1rem;\n}\n\n.tab-button {\n padding: 0.5rem 1rem;\n border: none;\n background: none;\n cursor: pointer;\n font-weight: 500;\n border-bottom: 2px solid transparent;\n}\n\n.tab-button.active {\n border-bottom: 2px solid var(--primary-color, #0066cc);\n color: var(--primary-color, #0066cc);\n}\n\n</style>"],"names":[],"mappings":";;;;;;;;;;;AAyBA,UAAM,QAAQ,OAAO,OAAO;AAE5B,UAAM,sBAAsB,SAAS,MAAM,MAAM,uBAAuB,IAAI;AAE5E,UAAM,cAAc,SAAS,MAAM;;AACjC,eAAO,+BAAoB,UAApB,mBAA2B,cAA3B,mBAAsC,gBAAe;AAAA,IAC9D,CAAC;AAGD,UAAM,YAAY,MAAM;AACtB,UAAI,oBAAoB,OAAO;AAC7B,4BAAoB,MAAM,WAAY;AAAA,MAC1C;AAAA,IACA;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"NotificationsLayout.vue.js","sources":["../../../../../../../src/modules/notifications/components/layouts/NotificationsLayout.vue"],"sourcesContent":["<template>\n <div class=\"notifications-layout\">\n <div class=\"\">\n <router-view></router-view>\n </div>\n \n <div v-if=\"!wsConnected\" class=\"connection-status\">\n <div class=\"connection-warning\">\n <span class=\"warning-icon\">⚠️</span>\n <span class=\"warning-text\">\n Notification service disconnected. \n <button @click=\"reconnect\" class=\"reconnect-btn\">Reconnect</button>\n </span>\n </div>\n </div>\n </div>\n</template>\n\n<script setup>\nimport { computed, inject, ref, onMounted, onUnmounted } from 'vue';\nimport globalWebSocket from '@martyrs/src/modules/globals/views/classes/globals.websocket.js';\n\n// Get notification manager from store\nconst store = inject('store');\n\nconst notificationManager = computed(() => store.notificationManager || null);\n\n// Реактивное состояние WebSocket\nconst wsConnected = ref(globalWebSocket.isConnected);\n\n// ID слушателей для очистки\nconst openListenerId = ref(null);\nconst closeListenerId = ref(null);\n\nonMounted(() => {\n // Подписываемся на события WebSocket\n openListenerId.value = globalWebSocket.addEventListener('open', () => {\n wsConnected.value = true;\n });\n \n closeListenerId.value = globalWebSocket.addEventListener('close', () => {\n wsConnected.value = false;\n });\n \n // Устанавливаем начальное состояние\n wsConnected.value = globalWebSocket.isConnected;\n});\n\nonUnmounted(() => {\n // Очищаем слушатели\n if (openListenerId.value) {\n globalWebSocket.removeEventListener('open', openListenerId.value);\n }\n if (closeListenerId.value) {\n globalWebSocket.removeEventListener('close', closeListenerId.value);\n }\n});\n\n\n// Methods\nconst reconnect = () => {\n if (notificationManager.value) {\n notificationManager.value.initialize();\n }\n};\n</script>\n\n<style scoped>\n</style>"],"names":[],"mappings":";;;;;;;;;;;AAuBA,UAAM,QAAQ,OAAO,OAAO;AAE5B,UAAM,sBAAsB,SAAS,MAAM,MAAM,uBAAuB,IAAI;AAG5E,UAAM,cAAc,IAAI,gBAAgB,WAAW;AAGnD,UAAM,iBAAiB,IAAI,IAAI;AAC/B,UAAM,kBAAkB,IAAI,IAAI;AAEhC,cAAU,MAAM;AAEd,qBAAe,QAAQ,gBAAgB,iBAAiB,QAAQ,MAAM;AACpE,oBAAY,QAAQ;AAAA,MACxB,CAAG;AAED,sBAAgB,QAAQ,gBAAgB,iBAAiB,SAAS,MAAM;AACtE,oBAAY,QAAQ;AAAA,MACxB,CAAG;AAGD,kBAAY,QAAQ,gBAAgB;AAAA,IACtC,CAAC;AAED,gBAAY,MAAM;AAEhB,UAAI,eAAe,OAAO;AACxB,wBAAgB,oBAAoB,QAAQ,eAAe,KAAK;AAAA,MACpE;AACE,UAAI,gBAAgB,OAAO;AACzB,wBAAgB,oBAAoB,SAAS,gBAAgB,KAAK;AAAA,MACtE;AAAA,IACA,CAAC;AAID,UAAM,YAAY,MAAM;AACtB,UAAI,oBAAoB,OAAO;AAC7B,4BAAoB,MAAM,WAAY;AAAA,MAC1C;AAAA,IACA;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -2,12 +2,11 @@
2
2
  Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
3
3
  const vue = require("vue");
4
4
  const vueRouter = require("vue-router");
5
+ const Tab = require("../../../../components/Tab/Tab.vue2.cjs");
5
6
  const NotificationsList = require("../sections/NotificationsList.vue.cjs");
6
7
  const NotificationPreferences = require("../sections/NotificationPreferences.vue.cjs");
7
- const _pluginVue_exportHelper = require("../../../../../../_virtual/_plugin-vue_export-helper.cjs");
8
8
  const _hoisted_1 = { class: "notifications-page pd-small" };
9
- const _hoisted_2 = { class: "tabs" };
10
- const _hoisted_3 = { class: "tab-content" };
9
+ const _hoisted_2 = { class: "tab-content" };
11
10
  const _sfc_main = {
12
11
  __name: "Notifications",
13
12
  setup(__props) {
@@ -16,23 +15,22 @@ const _sfc_main = {
16
15
  const activeTab = vue.ref(route.query.tab || "all");
17
16
  return (_ctx, _cache) => {
18
17
  return vue.openBlock(), vue.createElementBlock("div", _hoisted_1, [
18
+ vue.createVNode(Tab.default, {
19
+ selected: activeTab.value,
20
+ "onUpdate:selected": _cache[0] || (_cache[0] = ($event) => activeTab.value = $event),
21
+ tabs: [
22
+ { label: `All Notifications${vue.unref(unreadCount) > 0 ? ` (${vue.unref(unreadCount)})` : ""}`, value: "all" },
23
+ { label: "Notification Settings", value: "preferences" }
24
+ ],
25
+ class: "flex-child-default gap-micro scroll-hide bg-light radius-medium h-max pd-thin mn-b-thin o-x-scroll",
26
+ classTab: "bg-white"
27
+ }, null, 8, ["selected", "tabs"]),
19
28
  vue.createElementVNode("div", _hoisted_2, [
20
- vue.createElementVNode("button", {
21
- class: vue.normalizeClass({ active: activeTab.value === "all" }),
22
- onClick: _cache[0] || (_cache[0] = ($event) => activeTab.value = "all")
23
- }, " All Notifications " + vue.toDisplayString(vue.unref(unreadCount) > 0 ? `(${vue.unref(unreadCount)})` : ""), 3),
24
- vue.createElementVNode("button", {
25
- class: vue.normalizeClass({ active: activeTab.value === "preferences" }),
26
- onClick: _cache[1] || (_cache[1] = ($event) => activeTab.value = "preferences")
27
- }, " Notification Settings ", 2)
28
- ]),
29
- vue.createElementVNode("div", _hoisted_3, [
30
29
  activeTab.value === "all" ? (vue.openBlock(), vue.createBlock(NotificationsList.default, { key: 0 })) : activeTab.value === "preferences" ? (vue.openBlock(), vue.createBlock(NotificationPreferences.default, { key: 1 })) : vue.createCommentVNode("", true)
31
30
  ])
32
31
  ]);
33
32
  };
34
33
  }
35
34
  };
36
- const Notifications = /* @__PURE__ */ _pluginVue_exportHelper.default(_sfc_main, [["__scopeId", "data-v-c7013c43"]]);
37
- exports.default = Notifications;
35
+ exports.default = _sfc_main;
38
36
  //# sourceMappingURL=Notifications.vue.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"Notifications.vue.cjs","sources":["../../../../../../../src/modules/notifications/components/pages/Notifications.vue"],"sourcesContent":["<template>\n <div class=\"notifications-page pd-small\">\n <div class=\"tabs\">\n <button \n :class=\"{ active: activeTab === 'all' }\" \n @click=\"activeTab = 'all'\"\n >\n All Notifications {{ unreadCount > 0 ? `(${unreadCount})` : '' }}\n </button>\n <button \n :class=\"{ active: activeTab === 'preferences' }\" \n @click=\"activeTab = 'preferences'\"\n >\n Notification Settings\n </button>\n </div>\n \n <div class=\"tab-content\">\n <notifications-list v-if=\"activeTab === 'all'\" />\n <notification-preferences v-else-if=\"activeTab === 'preferences'\" />\n </div>\n </div>\n</template>\n\n<script setup>\nimport { ref, inject } from 'vue';\nimport { useRoute } from 'vue-router';\nimport NotificationsList from '../sections/NotificationsList.vue';\nimport NotificationPreferences from '../sections/NotificationPreferences.vue';\n\n// Get route and notification state\nconst route = useRoute();\nconst { unreadCount } = inject('useNotifications')();\n\n// Set initial active tab based on route query param or default to 'all'\nconst activeTab = ref(route.query.tab || 'all');\n</script>\n\n<style scoped>\n.notifications-page {\n}\n\n.tabs {\n display: flex;\n margin-bottom: 24px;\n border-bottom: 1px solid #e0e0e0;\n}\n\n.tabs button {\n background: none;\n border: none;\n padding: 12px 24px;\n font-size: 1rem;\n cursor: pointer;\n position: relative;\n color: #666;\n}\n\n.tabs button.active {\n color: #2196F3;\n font-weight: 500;\n}\n\n.tabs button.active::after {\n content: '';\n position: absolute;\n bottom: -1px;\n left: 0;\n width: 100%;\n height: 2px;\n background-color: #2196F3;\n}\n\n.tab-content {\n padding: 16px 0;\n}\n</style>"],"names":["useRoute","inject","ref"],"mappings":";;;;;;;;;;;;;AA+BA,UAAM,QAAQA,UAAAA,SAAU;AACxB,UAAM,EAAE,YAAa,IAAGC,WAAO,kBAAkB,EAAG;AAGpD,UAAM,YAAYC,IAAAA,IAAI,MAAM,MAAM,OAAO,KAAK;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"Notifications.vue.cjs","sources":["../../../../../../../src/modules/notifications/components/pages/Notifications.vue"],"sourcesContent":["<template>\n <div class=\"notifications-page pd-small\">\n <Tab\n v-model:selected=\"activeTab\"\n :tabs=\"[\n { label: `All Notifications${unreadCount > 0 ? ` (${unreadCount})` : ''}`, value: 'all' },\n { label: 'Notification Settings', value: 'preferences' }\n ]\"\n class=\"flex-child-default gap-micro scroll-hide bg-light radius-medium h-max pd-thin mn-b-thin o-x-scroll\"\n classTab=\"bg-white\"\n />\n \n <div class=\"tab-content\">\n <notifications-list v-if=\"activeTab === 'all'\" />\n <notification-preferences v-else-if=\"activeTab === 'preferences'\" />\n </div>\n </div>\n</template>\n\n<script setup>\nimport { ref, inject } from 'vue';\nimport { useRoute } from 'vue-router';\nimport Tab from \"@martyrs/src/components/Tab/Tab.vue\";\nimport NotificationsList from '../sections/NotificationsList.vue';\nimport NotificationPreferences from '../sections/NotificationPreferences.vue';\n\n// Get route and notification state\nconst route = useRoute();\nconst { unreadCount } = inject('useNotifications')();\n\n// Set initial active tab based on route query param or default to 'all'\nconst activeTab = ref(route.query.tab || 'all');\n</script>\n\n<style scoped>\n</style>"],"names":["useRoute","inject","ref"],"mappings":";;;;;;;;;;;;AA2BA,UAAM,QAAQA,UAAAA,SAAU;AACxB,UAAM,EAAE,YAAa,IAAGC,WAAO,kBAAkB,EAAG;AAGpD,UAAM,YAAYC,IAAAA,IAAI,MAAM,MAAM,OAAO,KAAK;;;;;;;;;;;;;;;;;;;;;"}
@@ -1,11 +1,10 @@
1
- import { inject, ref, createElementBlock, openBlock, createElementVNode, normalizeClass, toDisplayString, unref, createBlock, createCommentVNode } from "vue";
1
+ import { inject, ref, createElementBlock, openBlock, createVNode, createElementVNode, unref, createBlock, createCommentVNode } from "vue";
2
2
  import { useRoute } from "vue-router";
3
+ import _sfc_main$1 from "../../../../components/Tab/Tab.vue2.js";
3
4
  import NotificationsList from "../sections/NotificationsList.vue.js";
4
5
  import NotificationPreferences from "../sections/NotificationPreferences.vue.js";
5
- import _export_sfc from "../../../../../../_virtual/_plugin-vue_export-helper.js";
6
6
  const _hoisted_1 = { class: "notifications-page pd-small" };
7
- const _hoisted_2 = { class: "tabs" };
8
- const _hoisted_3 = { class: "tab-content" };
7
+ const _hoisted_2 = { class: "tab-content" };
9
8
  const _sfc_main = {
10
9
  __name: "Notifications",
11
10
  setup(__props) {
@@ -14,25 +13,24 @@ const _sfc_main = {
14
13
  const activeTab = ref(route.query.tab || "all");
15
14
  return (_ctx, _cache) => {
16
15
  return openBlock(), createElementBlock("div", _hoisted_1, [
16
+ createVNode(_sfc_main$1, {
17
+ selected: activeTab.value,
18
+ "onUpdate:selected": _cache[0] || (_cache[0] = ($event) => activeTab.value = $event),
19
+ tabs: [
20
+ { label: `All Notifications${unref(unreadCount) > 0 ? ` (${unref(unreadCount)})` : ""}`, value: "all" },
21
+ { label: "Notification Settings", value: "preferences" }
22
+ ],
23
+ class: "flex-child-default gap-micro scroll-hide bg-light radius-medium h-max pd-thin mn-b-thin o-x-scroll",
24
+ classTab: "bg-white"
25
+ }, null, 8, ["selected", "tabs"]),
17
26
  createElementVNode("div", _hoisted_2, [
18
- createElementVNode("button", {
19
- class: normalizeClass({ active: activeTab.value === "all" }),
20
- onClick: _cache[0] || (_cache[0] = ($event) => activeTab.value = "all")
21
- }, " All Notifications " + toDisplayString(unref(unreadCount) > 0 ? `(${unref(unreadCount)})` : ""), 3),
22
- createElementVNode("button", {
23
- class: normalizeClass({ active: activeTab.value === "preferences" }),
24
- onClick: _cache[1] || (_cache[1] = ($event) => activeTab.value = "preferences")
25
- }, " Notification Settings ", 2)
26
- ]),
27
- createElementVNode("div", _hoisted_3, [
28
27
  activeTab.value === "all" ? (openBlock(), createBlock(NotificationsList, { key: 0 })) : activeTab.value === "preferences" ? (openBlock(), createBlock(NotificationPreferences, { key: 1 })) : createCommentVNode("", true)
29
28
  ])
30
29
  ]);
31
30
  };
32
31
  }
33
32
  };
34
- const Notifications = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-c7013c43"]]);
35
33
  export {
36
- Notifications as default
34
+ _sfc_main as default
37
35
  };
38
36
  //# sourceMappingURL=Notifications.vue.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Notifications.vue.js","sources":["../../../../../../../src/modules/notifications/components/pages/Notifications.vue"],"sourcesContent":["<template>\n <div class=\"notifications-page pd-small\">\n <div class=\"tabs\">\n <button \n :class=\"{ active: activeTab === 'all' }\" \n @click=\"activeTab = 'all'\"\n >\n All Notifications {{ unreadCount > 0 ? `(${unreadCount})` : '' }}\n </button>\n <button \n :class=\"{ active: activeTab === 'preferences' }\" \n @click=\"activeTab = 'preferences'\"\n >\n Notification Settings\n </button>\n </div>\n \n <div class=\"tab-content\">\n <notifications-list v-if=\"activeTab === 'all'\" />\n <notification-preferences v-else-if=\"activeTab === 'preferences'\" />\n </div>\n </div>\n</template>\n\n<script setup>\nimport { ref, inject } from 'vue';\nimport { useRoute } from 'vue-router';\nimport NotificationsList from '../sections/NotificationsList.vue';\nimport NotificationPreferences from '../sections/NotificationPreferences.vue';\n\n// Get route and notification state\nconst route = useRoute();\nconst { unreadCount } = inject('useNotifications')();\n\n// Set initial active tab based on route query param or default to 'all'\nconst activeTab = ref(route.query.tab || 'all');\n</script>\n\n<style scoped>\n.notifications-page {\n}\n\n.tabs {\n display: flex;\n margin-bottom: 24px;\n border-bottom: 1px solid #e0e0e0;\n}\n\n.tabs button {\n background: none;\n border: none;\n padding: 12px 24px;\n font-size: 1rem;\n cursor: pointer;\n position: relative;\n color: #666;\n}\n\n.tabs button.active {\n color: #2196F3;\n font-weight: 500;\n}\n\n.tabs button.active::after {\n content: '';\n position: absolute;\n bottom: -1px;\n left: 0;\n width: 100%;\n height: 2px;\n background-color: #2196F3;\n}\n\n.tab-content {\n padding: 16px 0;\n}\n</style>"],"names":[],"mappings":";;;;;;;;;;;AA+BA,UAAM,QAAQ,SAAU;AACxB,UAAM,EAAE,YAAa,IAAG,OAAO,kBAAkB,EAAG;AAGpD,UAAM,YAAY,IAAI,MAAM,MAAM,OAAO,KAAK;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"Notifications.vue.js","sources":["../../../../../../../src/modules/notifications/components/pages/Notifications.vue"],"sourcesContent":["<template>\n <div class=\"notifications-page pd-small\">\n <Tab\n v-model:selected=\"activeTab\"\n :tabs=\"[\n { label: `All Notifications${unreadCount > 0 ? ` (${unreadCount})` : ''}`, value: 'all' },\n { label: 'Notification Settings', value: 'preferences' }\n ]\"\n class=\"flex-child-default gap-micro scroll-hide bg-light radius-medium h-max pd-thin mn-b-thin o-x-scroll\"\n classTab=\"bg-white\"\n />\n \n <div class=\"tab-content\">\n <notifications-list v-if=\"activeTab === 'all'\" />\n <notification-preferences v-else-if=\"activeTab === 'preferences'\" />\n </div>\n </div>\n</template>\n\n<script setup>\nimport { ref, inject } from 'vue';\nimport { useRoute } from 'vue-router';\nimport Tab from \"@martyrs/src/components/Tab/Tab.vue\";\nimport NotificationsList from '../sections/NotificationsList.vue';\nimport NotificationPreferences from '../sections/NotificationPreferences.vue';\n\n// Get route and notification state\nconst route = useRoute();\nconst { unreadCount } = inject('useNotifications')();\n\n// Set initial active tab based on route query param or default to 'all'\nconst activeTab = ref(route.query.tab || 'all');\n</script>\n\n<style scoped>\n</style>"],"names":[],"mappings":";;;;;;;;;;AA2BA,UAAM,QAAQ,SAAU;AACxB,UAAM,EAAE,YAAa,IAAG,OAAO,kBAAkB,EAAG;AAGpD,UAAM,YAAY,IAAI,MAAM,MAAM,OAAO,KAAK;;;;;;;;;;;;;;;;;;;;"}
@@ -117,7 +117,7 @@ const _sfc_main = {
117
117
  });
118
118
  return (_ctx, _cache) => {
119
119
  return vue.openBlock(), vue.createElementBlock("div", _hoisted_1, [
120
- _cache[2] || (_cache[2] = vue.createElementVNode("h2", null, "Notification Preferences", -1)),
120
+ _cache[2] || (_cache[2] = vue.createElementVNode("h2", { class: "mn-b-small" }, "Notification Preferences", -1)),
121
121
  _cache[3] || (_cache[3] = vue.createElementVNode("p", { class: "description" }, "Choose how you want to receive notifications", -1)),
122
122
  vue.unref(loading) ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_2, _cache[0] || (_cache[0] = [
123
123
  vue.createElementVNode("div", { class: "loading-spinner" }, "🔄", -1),
@@ -162,6 +162,6 @@ const _sfc_main = {
162
162
  };
163
163
  }
164
164
  };
165
- const NotificationPreferences = /* @__PURE__ */ _pluginVue_exportHelper.default(_sfc_main, [["__scopeId", "data-v-8f705373"]]);
165
+ const NotificationPreferences = /* @__PURE__ */ _pluginVue_exportHelper.default(_sfc_main, [["__scopeId", "data-v-420a3f66"]]);
166
166
  exports.default = NotificationPreferences;
167
167
  //# sourceMappingURL=NotificationPreferences.vue.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"NotificationPreferences.vue.cjs","sources":["../../../../../../../src/modules/notifications/components/sections/NotificationPreferences.vue"],"sourcesContent":["<template>\n <div class=\"notification-preferences\">\n <h2>Notification Preferences</h2>\n <p class=\"description\">Choose how you want to receive notifications</p>\n \n <div v-if=\"loading\" class=\"preferences-loading\">\n <div class=\"loading-spinner\">🔄</div>\n <p>Loading preferences...</p>\n </div>\n \n <div v-else class=\"preferences-form\">\n <div \n v-for=\"(enabled, channelType) in preferences\" \n :key=\"channelType\" \n class=\"preference-item\"\n >\n <div class=\"preference-info\">\n <div class=\"preference-icon\">{{ getChannelIcon(channelType) }}</div>\n <div class=\"preference-details\">\n <h3>{{ getChannelName(channelType) }}</h3>\n <p>{{ getChannelDescription(channelType) }}</p>\n </div>\n </div>\n <label class=\"toggle-switch\">\n <input\n type=\"checkbox\"\n :checked=\"enabled\"\n @change=\"updatePreference(channelType, $event.target.checked)\"\n >\n <span class=\"toggle-slider\"></span>\n </label>\n </div>\n \n <div class=\"form-actions\">\n <button \n class=\"save-btn\" \n :disabled=\"!hasChanges || saving\" \n @click=\"savePreferences\"\n >\n {{ saving ? 'Saving...' : 'Save Changes' }}\n </button>\n <button \n v-if=\"hasChanges\" \n class=\"cancel-btn\" \n @click=\"resetChanges\"\n >\n Cancel\n </button>\n </div>\n </div>\n </div>\n</template>\n\n<script setup>\nimport { ref, reactive, computed, onMounted, inject } from 'vue';\n\n// Get notification preferences functionality\nconst { \n preferences: storePreferences,\n loading,\n getPreferences,\n updatePreferences\n} = inject('useNotifications')();\n\n// Local reactive state for form\nconst preferences = reactive({...storePreferences.value});\nconst originalPreferences = ref({});\nconst saving = ref(false);\n\n// Computed properties\nconst hasChanges = computed(() => {\n return Object.keys(preferences).some(key => \n preferences[key] !== originalPreferences.value[key]\n );\n});\n\n// Methods\nconst updatePreference = (channelType, value) => {\n preferences[channelType] = value;\n};\n\nconst savePreferences = async () => {\n try {\n saving.value = true;\n await updatePreferences(preferences);\n originalPreferences.value = {...preferences};\n saving.value = false;\n } catch (error) {\n console.error('Error saving preferences:', error);\n saving.value = false;\n }\n};\n\nconst resetChanges = () => {\n Object.keys(preferences).forEach(key => {\n preferences[key] = originalPreferences.value[key];\n });\n};\n\nconst getChannelIcon = (channelType) => {\n switch (channelType) {\n case 'web': return '🖥️';\n case 'push': return '📱';\n case 'email': return '📧';\n case 'sms': return '📱';\n case 'telegram': return '📬';\n case 'whatsapp': return '💬';\n default: return '🔔';\n }\n};\n\nconst getChannelName = (channelType) => {\n switch (channelType) {\n case 'web': return 'Web Notifications';\n case 'push': return 'Mobile Push Notifications';\n case 'email': return 'Email Notifications';\n case 'sms': return 'SMS Notifications';\n case 'telegram': return 'Telegram Messages';\n case 'whatsapp': return 'WhatsApp Messages';\n default: return channelType;\n }\n};\n\nconst getChannelDescription = (channelType) => {\n switch (channelType) {\n case 'web': \n return 'Real-time notifications in your browser';\n case 'push': \n return 'Notifications on your mobile device even when the app is closed';\n case 'email': \n return 'Receive notifications in your email inbox';\n case 'sms': \n return 'Get text messages for important notifications';\n case 'telegram': \n return 'Receive notifications via Telegram bot';\n case 'whatsapp': \n return 'Get notifications as WhatsApp messages';\n default: \n return '';\n }\n};\n\n// Lifecycle\nonMounted(async () => {\n await getPreferences();\n \n // Copy store preferences to local state\n Object.keys(storePreferences.value).forEach(key => {\n preferences[key] = storePreferences.value[key];\n });\n \n // Create a deep copy of the original preferences\n originalPreferences.value = {...preferences};\n});\n</script>\n\n<style scoped>\n.notification-preferences {\n max-width: 800px;\n margin: 0 auto;\n padding: 24px;\n}\n\nh2 {\n margin-top: 0;\n margin-bottom: 8px;\n}\n\n.description {\n color: #666;\n margin-bottom: 24px;\n}\n\n.preferences-loading {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 48px 0;\n}\n\n.loading-spinner {\n font-size: 2rem;\n margin-bottom: 16px;\n animation: spin 2s linear infinite;\n}\n\n@keyframes spin {\n 0% { transform: rotate(0deg); }\n 100% { transform: rotate(360deg); }\n}\n\n.preference-item {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px;\n border-bottom: 1px solid #eee;\n}\n\n.preference-item:last-child {\n border-bottom: none;\n}\n\n.preference-info {\n display: flex;\n align-items: center;\n flex: 1;\n}\n\n.preference-icon {\n font-size: 1.5rem;\n margin-right: 16px;\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.preference-details h3 {\n margin: 0 0 4px 0;\n font-size: 1rem;\n}\n\n.preference-details p {\n margin: 0;\n color: #666;\n font-size: 0.875rem;\n}\n\n/* Toggle switch styles */\n.toggle-switch {\n position: relative;\n display: inline-block;\n width: 50px;\n height: 24px;\n}\n\n.toggle-switch input {\n opacity: 0;\n width: 0;\n height: 0;\n}\n\n.toggle-slider {\n position: absolute;\n cursor: pointer;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background-color: #ccc;\n transition: .4s;\n border-radius: 24px;\n}\n\n.toggle-slider:before {\n position: absolute;\n content: \"\";\n height: 16px;\n width: 16px;\n left: 4px;\n bottom: 4px;\n background-color: white;\n transition: .4s;\n border-radius: 50%;\n}\n\ninput:checked + .toggle-slider {\n background-color: #2196F3;\n}\n\ninput:checked + .toggle-slider:before {\n transform: translateX(26px);\n}\n\n.form-actions {\n margin-top: 24px;\n display: flex;\n justify-content: flex-end;\n gap: 16px;\n}\n\n.save-btn, .cancel-btn {\n padding: 8px 16px;\n border-radius: 4px;\n cursor: pointer;\n}\n\n.save-btn {\n background-color: #2196F3;\n border: none;\n color: white;\n}\n\n.save-btn:disabled {\n background-color: #ccc;\n cursor: not-allowed;\n}\n\n.cancel-btn {\n background-color: white;\n border: 1px solid #ccc;\n}\n</style>"],"names":["inject","reactive","ref","computed","onMounted"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAyDA,UAAM;AAAA,MACJ,aAAa;AAAA,MACb;AAAA,MACA;AAAA,MACA;AAAA,IACF,IAAIA,IAAAA,OAAO,kBAAkB,EAAG;AAGhC,UAAM,cAAcC,IAAAA,SAAS,EAAC,GAAG,iBAAiB,MAAK,CAAC;AACxD,UAAM,sBAAsBC,IAAG,IAAC,EAAE;AAClC,UAAM,SAASA,IAAG,IAAC,KAAK;AAGxB,UAAM,aAAaC,IAAQ,SAAC,MAAM;AAChC,aAAO,OAAO,KAAK,WAAW,EAAE;AAAA,QAAK,SACnC,YAAY,GAAG,MAAM,oBAAoB,MAAM,GAAG;AAAA,MACnD;AAAA,IACH,CAAC;AAGD,UAAM,mBAAmB,CAAC,aAAa,UAAU;AAC/C,kBAAY,WAAW,IAAI;AAAA,IAC7B;AAEA,UAAM,kBAAkB,YAAY;AAClC,UAAI;AACF,eAAO,QAAQ;AACf,cAAM,kBAAkB,WAAW;AACnC,4BAAoB,QAAQ,EAAC,GAAG,YAAW;AAC3C,eAAO,QAAQ;AAAA,MAChB,SAAQ,OAAO;AACd,gBAAQ,MAAM,6BAA6B,KAAK;AAChD,eAAO,QAAQ;AAAA,MACnB;AAAA,IACA;AAEA,UAAM,eAAe,MAAM;AACzB,aAAO,KAAK,WAAW,EAAE,QAAQ,SAAO;AACtC,oBAAY,GAAG,IAAI,oBAAoB,MAAM,GAAG;AAAA,MACpD,CAAG;AAAA,IACH;AAEA,UAAM,iBAAiB,CAAC,gBAAgB;AACtC,cAAQ,aAAW;AAAA,QACjB,KAAK;AAAO,iBAAO;AAAA,QACnB,KAAK;AAAQ,iBAAO;AAAA,QACpB,KAAK;AAAS,iBAAO;AAAA,QACrB,KAAK;AAAO,iBAAO;AAAA,QACnB,KAAK;AAAY,iBAAO;AAAA,QACxB,KAAK;AAAY,iBAAO;AAAA,QACxB;AAAS,iBAAO;AAAA,MACpB;AAAA,IACA;AAEA,UAAM,iBAAiB,CAAC,gBAAgB;AACtC,cAAQ,aAAW;AAAA,QACjB,KAAK;AAAO,iBAAO;AAAA,QACnB,KAAK;AAAQ,iBAAO;AAAA,QACpB,KAAK;AAAS,iBAAO;AAAA,QACrB,KAAK;AAAO,iBAAO;AAAA,QACnB,KAAK;AAAY,iBAAO;AAAA,QACxB,KAAK;AAAY,iBAAO;AAAA,QACxB;AAAS,iBAAO;AAAA,MACpB;AAAA,IACA;AAEA,UAAM,wBAAwB,CAAC,gBAAgB;AAC7C,cAAQ,aAAW;AAAA,QACjB,KAAK;AACH,iBAAO;AAAA,QACT,KAAK;AACH,iBAAO;AAAA,QACT,KAAK;AACH,iBAAO;AAAA,QACT,KAAK;AACH,iBAAO;AAAA,QACT,KAAK;AACH,iBAAO;AAAA,QACT,KAAK;AACH,iBAAO;AAAA,QACT;AACE,iBAAO;AAAA,MACb;AAAA,IACA;AAGAC,QAAAA,UAAU,YAAY;AACpB,YAAM,eAAgB;AAGtB,aAAO,KAAK,iBAAiB,KAAK,EAAE,QAAQ,SAAO;AACjD,oBAAY,GAAG,IAAI,iBAAiB,MAAM,GAAG;AAAA,MACjD,CAAG;AAGD,0BAAoB,QAAQ,EAAC,GAAG,YAAW;AAAA,IAC7C,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"NotificationPreferences.vue.cjs","sources":["../../../../../../../src/modules/notifications/components/sections/NotificationPreferences.vue"],"sourcesContent":["<template>\n <div class=\"notification-preferences\">\n <h2 class=\"mn-b-small\">Notification Preferences</h2>\n <p class=\"description\">Choose how you want to receive notifications</p>\n \n <div v-if=\"loading\" class=\"preferences-loading\">\n <div class=\"loading-spinner\">🔄</div>\n <p>Loading preferences...</p>\n </div>\n \n <div v-else class=\"preferences-form\">\n <div \n v-for=\"(enabled, channelType) in preferences\" \n :key=\"channelType\" \n class=\"preference-item\"\n >\n <div class=\"preference-info\">\n <div class=\"preference-icon\">{{ getChannelIcon(channelType) }}</div>\n <div class=\"preference-details\">\n <h3>{{ getChannelName(channelType) }}</h3>\n <p>{{ getChannelDescription(channelType) }}</p>\n </div>\n </div>\n <label class=\"toggle-switch\">\n <input\n type=\"checkbox\"\n :checked=\"enabled\"\n @change=\"updatePreference(channelType, $event.target.checked)\"\n >\n <span class=\"toggle-slider\"></span>\n </label>\n </div>\n \n <div class=\"form-actions\">\n <button \n class=\"save-btn\" \n :disabled=\"!hasChanges || saving\" \n @click=\"savePreferences\"\n >\n {{ saving ? 'Saving...' : 'Save Changes' }}\n </button>\n <button \n v-if=\"hasChanges\" \n class=\"cancel-btn\" \n @click=\"resetChanges\"\n >\n Cancel\n </button>\n </div>\n </div>\n </div>\n</template>\n\n<script setup>\nimport { ref, reactive, computed, onMounted, inject } from 'vue';\n\n// Get notification preferences functionality\nconst { \n preferences: storePreferences,\n loading,\n getPreferences,\n updatePreferences\n} = inject('useNotifications')();\n\n// Local reactive state for form\nconst preferences = reactive({...storePreferences.value});\nconst originalPreferences = ref({});\nconst saving = ref(false);\n\n// Computed properties\nconst hasChanges = computed(() => {\n return Object.keys(preferences).some(key => \n preferences[key] !== originalPreferences.value[key]\n );\n});\n\n// Methods\nconst updatePreference = (channelType, value) => {\n preferences[channelType] = value;\n};\n\nconst savePreferences = async () => {\n try {\n saving.value = true;\n await updatePreferences(preferences);\n originalPreferences.value = {...preferences};\n saving.value = false;\n } catch (error) {\n console.error('Error saving preferences:', error);\n saving.value = false;\n }\n};\n\nconst resetChanges = () => {\n Object.keys(preferences).forEach(key => {\n preferences[key] = originalPreferences.value[key];\n });\n};\n\nconst getChannelIcon = (channelType) => {\n switch (channelType) {\n case 'web': return '🖥️';\n case 'push': return '📱';\n case 'email': return '📧';\n case 'sms': return '📱';\n case 'telegram': return '📬';\n case 'whatsapp': return '💬';\n default: return '🔔';\n }\n};\n\nconst getChannelName = (channelType) => {\n switch (channelType) {\n case 'web': return 'Web Notifications';\n case 'push': return 'Mobile Push Notifications';\n case 'email': return 'Email Notifications';\n case 'sms': return 'SMS Notifications';\n case 'telegram': return 'Telegram Messages';\n case 'whatsapp': return 'WhatsApp Messages';\n default: return channelType;\n }\n};\n\nconst getChannelDescription = (channelType) => {\n switch (channelType) {\n case 'web': \n return 'Real-time notifications in your browser';\n case 'push': \n return 'Notifications on your mobile device even when the app is closed';\n case 'email': \n return 'Receive notifications in your email inbox';\n case 'sms': \n return 'Get text messages for important notifications';\n case 'telegram': \n return 'Receive notifications via Telegram bot';\n case 'whatsapp': \n return 'Get notifications as WhatsApp messages';\n default: \n return '';\n }\n};\n\n// Lifecycle\nonMounted(async () => {\n await getPreferences();\n \n // Copy store preferences to local state\n Object.keys(storePreferences.value).forEach(key => {\n preferences[key] = storePreferences.value[key];\n });\n \n // Create a deep copy of the original preferences\n originalPreferences.value = {...preferences};\n});\n</script>\n\n<style scoped>\n\n.description {\n color: #666;\n margin-bottom: 24px;\n}\n\n.preferences-loading {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 48px 0;\n}\n\n.loading-spinner {\n font-size: 2rem;\n margin-bottom: 16px;\n animation: spin 2s linear infinite;\n}\n\n@keyframes spin {\n 0% { transform: rotate(0deg); }\n 100% { transform: rotate(360deg); }\n}\n\n.preference-item {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px;\n border-bottom: 1px solid #eee;\n}\n\n.preference-item:last-child {\n border-bottom: none;\n}\n\n.preference-info {\n display: flex;\n align-items: center;\n flex: 1;\n}\n\n.preference-icon {\n font-size: 1.5rem;\n margin-right: 16px;\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.preference-details h3 {\n margin: 0 0 4px 0;\n font-size: 1rem;\n}\n\n.preference-details p {\n margin: 0;\n color: #666;\n font-size: 0.875rem;\n}\n\n/* Toggle switch styles */\n.toggle-switch {\n position: relative;\n display: inline-block;\n width: 50px;\n height: 24px;\n}\n\n.toggle-switch input {\n opacity: 0;\n width: 0;\n height: 0;\n}\n\n.toggle-slider {\n position: absolute;\n cursor: pointer;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background-color: #ccc;\n transition: .4s;\n border-radius: 24px;\n}\n\n.toggle-slider:before {\n position: absolute;\n content: \"\";\n height: 16px;\n width: 16px;\n left: 4px;\n bottom: 4px;\n background-color: white;\n transition: .4s;\n border-radius: 50%;\n}\n\ninput:checked + .toggle-slider {\n background-color: #2196F3;\n}\n\ninput:checked + .toggle-slider:before {\n transform: translateX(26px);\n}\n\n.form-actions {\n margin-top: 24px;\n display: flex;\n justify-content: flex-end;\n gap: 16px;\n}\n\n.save-btn, .cancel-btn {\n padding: 8px 16px;\n border-radius: 4px;\n cursor: pointer;\n}\n\n.save-btn {\n background-color: #2196F3;\n border: none;\n color: white;\n}\n\n.save-btn:disabled {\n background-color: #ccc;\n cursor: not-allowed;\n}\n\n.cancel-btn {\n background-color: white;\n border: 1px solid #ccc;\n}\n</style>"],"names":["inject","reactive","ref","computed","onMounted"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAyDA,UAAM;AAAA,MACJ,aAAa;AAAA,MACb;AAAA,MACA;AAAA,MACA;AAAA,IACF,IAAIA,IAAAA,OAAO,kBAAkB,EAAG;AAGhC,UAAM,cAAcC,IAAAA,SAAS,EAAC,GAAG,iBAAiB,MAAK,CAAC;AACxD,UAAM,sBAAsBC,IAAG,IAAC,EAAE;AAClC,UAAM,SAASA,IAAG,IAAC,KAAK;AAGxB,UAAM,aAAaC,IAAQ,SAAC,MAAM;AAChC,aAAO,OAAO,KAAK,WAAW,EAAE;AAAA,QAAK,SACnC,YAAY,GAAG,MAAM,oBAAoB,MAAM,GAAG;AAAA,MACnD;AAAA,IACH,CAAC;AAGD,UAAM,mBAAmB,CAAC,aAAa,UAAU;AAC/C,kBAAY,WAAW,IAAI;AAAA,IAC7B;AAEA,UAAM,kBAAkB,YAAY;AAClC,UAAI;AACF,eAAO,QAAQ;AACf,cAAM,kBAAkB,WAAW;AACnC,4BAAoB,QAAQ,EAAC,GAAG,YAAW;AAC3C,eAAO,QAAQ;AAAA,MAChB,SAAQ,OAAO;AACd,gBAAQ,MAAM,6BAA6B,KAAK;AAChD,eAAO,QAAQ;AAAA,MACnB;AAAA,IACA;AAEA,UAAM,eAAe,MAAM;AACzB,aAAO,KAAK,WAAW,EAAE,QAAQ,SAAO;AACtC,oBAAY,GAAG,IAAI,oBAAoB,MAAM,GAAG;AAAA,MACpD,CAAG;AAAA,IACH;AAEA,UAAM,iBAAiB,CAAC,gBAAgB;AACtC,cAAQ,aAAW;AAAA,QACjB,KAAK;AAAO,iBAAO;AAAA,QACnB,KAAK;AAAQ,iBAAO;AAAA,QACpB,KAAK;AAAS,iBAAO;AAAA,QACrB,KAAK;AAAO,iBAAO;AAAA,QACnB,KAAK;AAAY,iBAAO;AAAA,QACxB,KAAK;AAAY,iBAAO;AAAA,QACxB;AAAS,iBAAO;AAAA,MACpB;AAAA,IACA;AAEA,UAAM,iBAAiB,CAAC,gBAAgB;AACtC,cAAQ,aAAW;AAAA,QACjB,KAAK;AAAO,iBAAO;AAAA,QACnB,KAAK;AAAQ,iBAAO;AAAA,QACpB,KAAK;AAAS,iBAAO;AAAA,QACrB,KAAK;AAAO,iBAAO;AAAA,QACnB,KAAK;AAAY,iBAAO;AAAA,QACxB,KAAK;AAAY,iBAAO;AAAA,QACxB;AAAS,iBAAO;AAAA,MACpB;AAAA,IACA;AAEA,UAAM,wBAAwB,CAAC,gBAAgB;AAC7C,cAAQ,aAAW;AAAA,QACjB,KAAK;AACH,iBAAO;AAAA,QACT,KAAK;AACH,iBAAO;AAAA,QACT,KAAK;AACH,iBAAO;AAAA,QACT,KAAK;AACH,iBAAO;AAAA,QACT,KAAK;AACH,iBAAO;AAAA,QACT,KAAK;AACH,iBAAO;AAAA,QACT;AACE,iBAAO;AAAA,MACb;AAAA,IACA;AAGAC,QAAAA,UAAU,YAAY;AACpB,YAAM,eAAgB;AAGtB,aAAO,KAAK,iBAAiB,KAAK,EAAE,QAAQ,SAAO;AACjD,oBAAY,GAAG,IAAI,iBAAiB,MAAM,GAAG;AAAA,MACjD,CAAG;AAGD,0BAAoB,QAAQ,EAAC,GAAG,YAAW;AAAA,IAC7C,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -115,7 +115,7 @@ const _sfc_main = {
115
115
  });
116
116
  return (_ctx, _cache) => {
117
117
  return openBlock(), createElementBlock("div", _hoisted_1, [
118
- _cache[2] || (_cache[2] = createElementVNode("h2", null, "Notification Preferences", -1)),
118
+ _cache[2] || (_cache[2] = createElementVNode("h2", { class: "mn-b-small" }, "Notification Preferences", -1)),
119
119
  _cache[3] || (_cache[3] = createElementVNode("p", { class: "description" }, "Choose how you want to receive notifications", -1)),
120
120
  unref(loading) ? (openBlock(), createElementBlock("div", _hoisted_2, _cache[0] || (_cache[0] = [
121
121
  createElementVNode("div", { class: "loading-spinner" }, "🔄", -1),
@@ -160,7 +160,7 @@ const _sfc_main = {
160
160
  };
161
161
  }
162
162
  };
163
- const NotificationPreferences = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-8f705373"]]);
163
+ const NotificationPreferences = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-420a3f66"]]);
164
164
  export {
165
165
  NotificationPreferences as default
166
166
  };
@@ -1 +1 @@
1
- {"version":3,"file":"NotificationPreferences.vue.js","sources":["../../../../../../../src/modules/notifications/components/sections/NotificationPreferences.vue"],"sourcesContent":["<template>\n <div class=\"notification-preferences\">\n <h2>Notification Preferences</h2>\n <p class=\"description\">Choose how you want to receive notifications</p>\n \n <div v-if=\"loading\" class=\"preferences-loading\">\n <div class=\"loading-spinner\">🔄</div>\n <p>Loading preferences...</p>\n </div>\n \n <div v-else class=\"preferences-form\">\n <div \n v-for=\"(enabled, channelType) in preferences\" \n :key=\"channelType\" \n class=\"preference-item\"\n >\n <div class=\"preference-info\">\n <div class=\"preference-icon\">{{ getChannelIcon(channelType) }}</div>\n <div class=\"preference-details\">\n <h3>{{ getChannelName(channelType) }}</h3>\n <p>{{ getChannelDescription(channelType) }}</p>\n </div>\n </div>\n <label class=\"toggle-switch\">\n <input\n type=\"checkbox\"\n :checked=\"enabled\"\n @change=\"updatePreference(channelType, $event.target.checked)\"\n >\n <span class=\"toggle-slider\"></span>\n </label>\n </div>\n \n <div class=\"form-actions\">\n <button \n class=\"save-btn\" \n :disabled=\"!hasChanges || saving\" \n @click=\"savePreferences\"\n >\n {{ saving ? 'Saving...' : 'Save Changes' }}\n </button>\n <button \n v-if=\"hasChanges\" \n class=\"cancel-btn\" \n @click=\"resetChanges\"\n >\n Cancel\n </button>\n </div>\n </div>\n </div>\n</template>\n\n<script setup>\nimport { ref, reactive, computed, onMounted, inject } from 'vue';\n\n// Get notification preferences functionality\nconst { \n preferences: storePreferences,\n loading,\n getPreferences,\n updatePreferences\n} = inject('useNotifications')();\n\n// Local reactive state for form\nconst preferences = reactive({...storePreferences.value});\nconst originalPreferences = ref({});\nconst saving = ref(false);\n\n// Computed properties\nconst hasChanges = computed(() => {\n return Object.keys(preferences).some(key => \n preferences[key] !== originalPreferences.value[key]\n );\n});\n\n// Methods\nconst updatePreference = (channelType, value) => {\n preferences[channelType] = value;\n};\n\nconst savePreferences = async () => {\n try {\n saving.value = true;\n await updatePreferences(preferences);\n originalPreferences.value = {...preferences};\n saving.value = false;\n } catch (error) {\n console.error('Error saving preferences:', error);\n saving.value = false;\n }\n};\n\nconst resetChanges = () => {\n Object.keys(preferences).forEach(key => {\n preferences[key] = originalPreferences.value[key];\n });\n};\n\nconst getChannelIcon = (channelType) => {\n switch (channelType) {\n case 'web': return '🖥️';\n case 'push': return '📱';\n case 'email': return '📧';\n case 'sms': return '📱';\n case 'telegram': return '📬';\n case 'whatsapp': return '💬';\n default: return '🔔';\n }\n};\n\nconst getChannelName = (channelType) => {\n switch (channelType) {\n case 'web': return 'Web Notifications';\n case 'push': return 'Mobile Push Notifications';\n case 'email': return 'Email Notifications';\n case 'sms': return 'SMS Notifications';\n case 'telegram': return 'Telegram Messages';\n case 'whatsapp': return 'WhatsApp Messages';\n default: return channelType;\n }\n};\n\nconst getChannelDescription = (channelType) => {\n switch (channelType) {\n case 'web': \n return 'Real-time notifications in your browser';\n case 'push': \n return 'Notifications on your mobile device even when the app is closed';\n case 'email': \n return 'Receive notifications in your email inbox';\n case 'sms': \n return 'Get text messages for important notifications';\n case 'telegram': \n return 'Receive notifications via Telegram bot';\n case 'whatsapp': \n return 'Get notifications as WhatsApp messages';\n default: \n return '';\n }\n};\n\n// Lifecycle\nonMounted(async () => {\n await getPreferences();\n \n // Copy store preferences to local state\n Object.keys(storePreferences.value).forEach(key => {\n preferences[key] = storePreferences.value[key];\n });\n \n // Create a deep copy of the original preferences\n originalPreferences.value = {...preferences};\n});\n</script>\n\n<style scoped>\n.notification-preferences {\n max-width: 800px;\n margin: 0 auto;\n padding: 24px;\n}\n\nh2 {\n margin-top: 0;\n margin-bottom: 8px;\n}\n\n.description {\n color: #666;\n margin-bottom: 24px;\n}\n\n.preferences-loading {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 48px 0;\n}\n\n.loading-spinner {\n font-size: 2rem;\n margin-bottom: 16px;\n animation: spin 2s linear infinite;\n}\n\n@keyframes spin {\n 0% { transform: rotate(0deg); }\n 100% { transform: rotate(360deg); }\n}\n\n.preference-item {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px;\n border-bottom: 1px solid #eee;\n}\n\n.preference-item:last-child {\n border-bottom: none;\n}\n\n.preference-info {\n display: flex;\n align-items: center;\n flex: 1;\n}\n\n.preference-icon {\n font-size: 1.5rem;\n margin-right: 16px;\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.preference-details h3 {\n margin: 0 0 4px 0;\n font-size: 1rem;\n}\n\n.preference-details p {\n margin: 0;\n color: #666;\n font-size: 0.875rem;\n}\n\n/* Toggle switch styles */\n.toggle-switch {\n position: relative;\n display: inline-block;\n width: 50px;\n height: 24px;\n}\n\n.toggle-switch input {\n opacity: 0;\n width: 0;\n height: 0;\n}\n\n.toggle-slider {\n position: absolute;\n cursor: pointer;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background-color: #ccc;\n transition: .4s;\n border-radius: 24px;\n}\n\n.toggle-slider:before {\n position: absolute;\n content: \"\";\n height: 16px;\n width: 16px;\n left: 4px;\n bottom: 4px;\n background-color: white;\n transition: .4s;\n border-radius: 50%;\n}\n\ninput:checked + .toggle-slider {\n background-color: #2196F3;\n}\n\ninput:checked + .toggle-slider:before {\n transform: translateX(26px);\n}\n\n.form-actions {\n margin-top: 24px;\n display: flex;\n justify-content: flex-end;\n gap: 16px;\n}\n\n.save-btn, .cancel-btn {\n padding: 8px 16px;\n border-radius: 4px;\n cursor: pointer;\n}\n\n.save-btn {\n background-color: #2196F3;\n border: none;\n color: white;\n}\n\n.save-btn:disabled {\n background-color: #ccc;\n cursor: not-allowed;\n}\n\n.cancel-btn {\n background-color: white;\n border: 1px solid #ccc;\n}\n</style>"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;AAyDA,UAAM;AAAA,MACJ,aAAa;AAAA,MACb;AAAA,MACA;AAAA,MACA;AAAA,IACF,IAAI,OAAO,kBAAkB,EAAG;AAGhC,UAAM,cAAc,SAAS,EAAC,GAAG,iBAAiB,MAAK,CAAC;AACxD,UAAM,sBAAsB,IAAI,EAAE;AAClC,UAAM,SAAS,IAAI,KAAK;AAGxB,UAAM,aAAa,SAAS,MAAM;AAChC,aAAO,OAAO,KAAK,WAAW,EAAE;AAAA,QAAK,SACnC,YAAY,GAAG,MAAM,oBAAoB,MAAM,GAAG;AAAA,MACnD;AAAA,IACH,CAAC;AAGD,UAAM,mBAAmB,CAAC,aAAa,UAAU;AAC/C,kBAAY,WAAW,IAAI;AAAA,IAC7B;AAEA,UAAM,kBAAkB,YAAY;AAClC,UAAI;AACF,eAAO,QAAQ;AACf,cAAM,kBAAkB,WAAW;AACnC,4BAAoB,QAAQ,EAAC,GAAG,YAAW;AAC3C,eAAO,QAAQ;AAAA,MAChB,SAAQ,OAAO;AACd,gBAAQ,MAAM,6BAA6B,KAAK;AAChD,eAAO,QAAQ;AAAA,MACnB;AAAA,IACA;AAEA,UAAM,eAAe,MAAM;AACzB,aAAO,KAAK,WAAW,EAAE,QAAQ,SAAO;AACtC,oBAAY,GAAG,IAAI,oBAAoB,MAAM,GAAG;AAAA,MACpD,CAAG;AAAA,IACH;AAEA,UAAM,iBAAiB,CAAC,gBAAgB;AACtC,cAAQ,aAAW;AAAA,QACjB,KAAK;AAAO,iBAAO;AAAA,QACnB,KAAK;AAAQ,iBAAO;AAAA,QACpB,KAAK;AAAS,iBAAO;AAAA,QACrB,KAAK;AAAO,iBAAO;AAAA,QACnB,KAAK;AAAY,iBAAO;AAAA,QACxB,KAAK;AAAY,iBAAO;AAAA,QACxB;AAAS,iBAAO;AAAA,MACpB;AAAA,IACA;AAEA,UAAM,iBAAiB,CAAC,gBAAgB;AACtC,cAAQ,aAAW;AAAA,QACjB,KAAK;AAAO,iBAAO;AAAA,QACnB,KAAK;AAAQ,iBAAO;AAAA,QACpB,KAAK;AAAS,iBAAO;AAAA,QACrB,KAAK;AAAO,iBAAO;AAAA,QACnB,KAAK;AAAY,iBAAO;AAAA,QACxB,KAAK;AAAY,iBAAO;AAAA,QACxB;AAAS,iBAAO;AAAA,MACpB;AAAA,IACA;AAEA,UAAM,wBAAwB,CAAC,gBAAgB;AAC7C,cAAQ,aAAW;AAAA,QACjB,KAAK;AACH,iBAAO;AAAA,QACT,KAAK;AACH,iBAAO;AAAA,QACT,KAAK;AACH,iBAAO;AAAA,QACT,KAAK;AACH,iBAAO;AAAA,QACT,KAAK;AACH,iBAAO;AAAA,QACT,KAAK;AACH,iBAAO;AAAA,QACT;AACE,iBAAO;AAAA,MACb;AAAA,IACA;AAGA,cAAU,YAAY;AACpB,YAAM,eAAgB;AAGtB,aAAO,KAAK,iBAAiB,KAAK,EAAE,QAAQ,SAAO;AACjD,oBAAY,GAAG,IAAI,iBAAiB,MAAM,GAAG;AAAA,MACjD,CAAG;AAGD,0BAAoB,QAAQ,EAAC,GAAG,YAAW;AAAA,IAC7C,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"NotificationPreferences.vue.js","sources":["../../../../../../../src/modules/notifications/components/sections/NotificationPreferences.vue"],"sourcesContent":["<template>\n <div class=\"notification-preferences\">\n <h2 class=\"mn-b-small\">Notification Preferences</h2>\n <p class=\"description\">Choose how you want to receive notifications</p>\n \n <div v-if=\"loading\" class=\"preferences-loading\">\n <div class=\"loading-spinner\">🔄</div>\n <p>Loading preferences...</p>\n </div>\n \n <div v-else class=\"preferences-form\">\n <div \n v-for=\"(enabled, channelType) in preferences\" \n :key=\"channelType\" \n class=\"preference-item\"\n >\n <div class=\"preference-info\">\n <div class=\"preference-icon\">{{ getChannelIcon(channelType) }}</div>\n <div class=\"preference-details\">\n <h3>{{ getChannelName(channelType) }}</h3>\n <p>{{ getChannelDescription(channelType) }}</p>\n </div>\n </div>\n <label class=\"toggle-switch\">\n <input\n type=\"checkbox\"\n :checked=\"enabled\"\n @change=\"updatePreference(channelType, $event.target.checked)\"\n >\n <span class=\"toggle-slider\"></span>\n </label>\n </div>\n \n <div class=\"form-actions\">\n <button \n class=\"save-btn\" \n :disabled=\"!hasChanges || saving\" \n @click=\"savePreferences\"\n >\n {{ saving ? 'Saving...' : 'Save Changes' }}\n </button>\n <button \n v-if=\"hasChanges\" \n class=\"cancel-btn\" \n @click=\"resetChanges\"\n >\n Cancel\n </button>\n </div>\n </div>\n </div>\n</template>\n\n<script setup>\nimport { ref, reactive, computed, onMounted, inject } from 'vue';\n\n// Get notification preferences functionality\nconst { \n preferences: storePreferences,\n loading,\n getPreferences,\n updatePreferences\n} = inject('useNotifications')();\n\n// Local reactive state for form\nconst preferences = reactive({...storePreferences.value});\nconst originalPreferences = ref({});\nconst saving = ref(false);\n\n// Computed properties\nconst hasChanges = computed(() => {\n return Object.keys(preferences).some(key => \n preferences[key] !== originalPreferences.value[key]\n );\n});\n\n// Methods\nconst updatePreference = (channelType, value) => {\n preferences[channelType] = value;\n};\n\nconst savePreferences = async () => {\n try {\n saving.value = true;\n await updatePreferences(preferences);\n originalPreferences.value = {...preferences};\n saving.value = false;\n } catch (error) {\n console.error('Error saving preferences:', error);\n saving.value = false;\n }\n};\n\nconst resetChanges = () => {\n Object.keys(preferences).forEach(key => {\n preferences[key] = originalPreferences.value[key];\n });\n};\n\nconst getChannelIcon = (channelType) => {\n switch (channelType) {\n case 'web': return '🖥️';\n case 'push': return '📱';\n case 'email': return '📧';\n case 'sms': return '📱';\n case 'telegram': return '📬';\n case 'whatsapp': return '💬';\n default: return '🔔';\n }\n};\n\nconst getChannelName = (channelType) => {\n switch (channelType) {\n case 'web': return 'Web Notifications';\n case 'push': return 'Mobile Push Notifications';\n case 'email': return 'Email Notifications';\n case 'sms': return 'SMS Notifications';\n case 'telegram': return 'Telegram Messages';\n case 'whatsapp': return 'WhatsApp Messages';\n default: return channelType;\n }\n};\n\nconst getChannelDescription = (channelType) => {\n switch (channelType) {\n case 'web': \n return 'Real-time notifications in your browser';\n case 'push': \n return 'Notifications on your mobile device even when the app is closed';\n case 'email': \n return 'Receive notifications in your email inbox';\n case 'sms': \n return 'Get text messages for important notifications';\n case 'telegram': \n return 'Receive notifications via Telegram bot';\n case 'whatsapp': \n return 'Get notifications as WhatsApp messages';\n default: \n return '';\n }\n};\n\n// Lifecycle\nonMounted(async () => {\n await getPreferences();\n \n // Copy store preferences to local state\n Object.keys(storePreferences.value).forEach(key => {\n preferences[key] = storePreferences.value[key];\n });\n \n // Create a deep copy of the original preferences\n originalPreferences.value = {...preferences};\n});\n</script>\n\n<style scoped>\n\n.description {\n color: #666;\n margin-bottom: 24px;\n}\n\n.preferences-loading {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 48px 0;\n}\n\n.loading-spinner {\n font-size: 2rem;\n margin-bottom: 16px;\n animation: spin 2s linear infinite;\n}\n\n@keyframes spin {\n 0% { transform: rotate(0deg); }\n 100% { transform: rotate(360deg); }\n}\n\n.preference-item {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px;\n border-bottom: 1px solid #eee;\n}\n\n.preference-item:last-child {\n border-bottom: none;\n}\n\n.preference-info {\n display: flex;\n align-items: center;\n flex: 1;\n}\n\n.preference-icon {\n font-size: 1.5rem;\n margin-right: 16px;\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.preference-details h3 {\n margin: 0 0 4px 0;\n font-size: 1rem;\n}\n\n.preference-details p {\n margin: 0;\n color: #666;\n font-size: 0.875rem;\n}\n\n/* Toggle switch styles */\n.toggle-switch {\n position: relative;\n display: inline-block;\n width: 50px;\n height: 24px;\n}\n\n.toggle-switch input {\n opacity: 0;\n width: 0;\n height: 0;\n}\n\n.toggle-slider {\n position: absolute;\n cursor: pointer;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background-color: #ccc;\n transition: .4s;\n border-radius: 24px;\n}\n\n.toggle-slider:before {\n position: absolute;\n content: \"\";\n height: 16px;\n width: 16px;\n left: 4px;\n bottom: 4px;\n background-color: white;\n transition: .4s;\n border-radius: 50%;\n}\n\ninput:checked + .toggle-slider {\n background-color: #2196F3;\n}\n\ninput:checked + .toggle-slider:before {\n transform: translateX(26px);\n}\n\n.form-actions {\n margin-top: 24px;\n display: flex;\n justify-content: flex-end;\n gap: 16px;\n}\n\n.save-btn, .cancel-btn {\n padding: 8px 16px;\n border-radius: 4px;\n cursor: pointer;\n}\n\n.save-btn {\n background-color: #2196F3;\n border: none;\n color: white;\n}\n\n.save-btn:disabled {\n background-color: #ccc;\n cursor: not-allowed;\n}\n\n.cancel-btn {\n background-color: white;\n border: 1px solid #ccc;\n}\n</style>"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;AAyDA,UAAM;AAAA,MACJ,aAAa;AAAA,MACb;AAAA,MACA;AAAA,MACA;AAAA,IACF,IAAI,OAAO,kBAAkB,EAAG;AAGhC,UAAM,cAAc,SAAS,EAAC,GAAG,iBAAiB,MAAK,CAAC;AACxD,UAAM,sBAAsB,IAAI,EAAE;AAClC,UAAM,SAAS,IAAI,KAAK;AAGxB,UAAM,aAAa,SAAS,MAAM;AAChC,aAAO,OAAO,KAAK,WAAW,EAAE;AAAA,QAAK,SACnC,YAAY,GAAG,MAAM,oBAAoB,MAAM,GAAG;AAAA,MACnD;AAAA,IACH,CAAC;AAGD,UAAM,mBAAmB,CAAC,aAAa,UAAU;AAC/C,kBAAY,WAAW,IAAI;AAAA,IAC7B;AAEA,UAAM,kBAAkB,YAAY;AAClC,UAAI;AACF,eAAO,QAAQ;AACf,cAAM,kBAAkB,WAAW;AACnC,4BAAoB,QAAQ,EAAC,GAAG,YAAW;AAC3C,eAAO,QAAQ;AAAA,MAChB,SAAQ,OAAO;AACd,gBAAQ,MAAM,6BAA6B,KAAK;AAChD,eAAO,QAAQ;AAAA,MACnB;AAAA,IACA;AAEA,UAAM,eAAe,MAAM;AACzB,aAAO,KAAK,WAAW,EAAE,QAAQ,SAAO;AACtC,oBAAY,GAAG,IAAI,oBAAoB,MAAM,GAAG;AAAA,MACpD,CAAG;AAAA,IACH;AAEA,UAAM,iBAAiB,CAAC,gBAAgB;AACtC,cAAQ,aAAW;AAAA,QACjB,KAAK;AAAO,iBAAO;AAAA,QACnB,KAAK;AAAQ,iBAAO;AAAA,QACpB,KAAK;AAAS,iBAAO;AAAA,QACrB,KAAK;AAAO,iBAAO;AAAA,QACnB,KAAK;AAAY,iBAAO;AAAA,QACxB,KAAK;AAAY,iBAAO;AAAA,QACxB;AAAS,iBAAO;AAAA,MACpB;AAAA,IACA;AAEA,UAAM,iBAAiB,CAAC,gBAAgB;AACtC,cAAQ,aAAW;AAAA,QACjB,KAAK;AAAO,iBAAO;AAAA,QACnB,KAAK;AAAQ,iBAAO;AAAA,QACpB,KAAK;AAAS,iBAAO;AAAA,QACrB,KAAK;AAAO,iBAAO;AAAA,QACnB,KAAK;AAAY,iBAAO;AAAA,QACxB,KAAK;AAAY,iBAAO;AAAA,QACxB;AAAS,iBAAO;AAAA,MACpB;AAAA,IACA;AAEA,UAAM,wBAAwB,CAAC,gBAAgB;AAC7C,cAAQ,aAAW;AAAA,QACjB,KAAK;AACH,iBAAO;AAAA,QACT,KAAK;AACH,iBAAO;AAAA,QACT,KAAK;AACH,iBAAO;AAAA,QACT,KAAK;AACH,iBAAO;AAAA,QACT,KAAK;AACH,iBAAO;AAAA,QACT,KAAK;AACH,iBAAO;AAAA,QACT;AACE,iBAAO;AAAA,MACb;AAAA,IACA;AAGA,cAAU,YAAY;AACpB,YAAM,eAAgB;AAGtB,aAAO,KAAK,iBAAiB,KAAK,EAAE,QAAQ,SAAO;AACjD,oBAAY,GAAG,IAAI,iBAAiB,MAAM,GAAG;AAAA,MACjD,CAAG;AAGD,0BAAoB,QAAQ,EAAC,GAAG,YAAW;AAAA,IAC7C,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -103,7 +103,7 @@ const _sfc_main = {
103
103
  };
104
104
  vue.onMounted(() => {
105
105
  const userId = auth.state.user._id;
106
- if (userId && notifications.value.length === 0) {
106
+ if (userId && notifications.value.length === 0 && !loading.value) {
107
107
  getNotifications(userId);
108
108
  }
109
109
  });
@@ -137,6 +137,6 @@ const _sfc_main = {
137
137
  };
138
138
  }
139
139
  };
140
- const NotificationsList = /* @__PURE__ */ _pluginVue_exportHelper.default(_sfc_main, [["__scopeId", "data-v-4beccb18"]]);
140
+ const NotificationsList = /* @__PURE__ */ _pluginVue_exportHelper.default(_sfc_main, [["__scopeId", "data-v-5af8a2ed"]]);
141
141
  exports.default = NotificationsList;
142
142
  //# sourceMappingURL=NotificationsList.vue.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"NotificationsList.vue.cjs","sources":["../../../../../../../src/modules/notifications/components/sections/NotificationsList.vue"],"sourcesContent":["<template>\n <div class=\"notifications-list-container\">\n <div v-if=\"!MOBILE_APP\" class=\"notifications-header\">\n <h2>Notifications</h2>\n <!-- <div class=\"notifications-controls\">\n <div class=\"notifications-filter\">\n <label for=\"filter-type\">Filter: </label>\n <select id=\"filter-type\" v-model=\"filterType\">\n <option value=\"all\">All</option>\n <option value=\"unread\">Unread</option>\n <option value=\"read\">Read</option>\n <option value=\"info\">Info</option>\n <option value=\"success\">Success</option>\n <option value=\"warning\">Warning</option>\n <option value=\"error\">Error</option>\n </select>\n </div>\n <button \n v-if=\"unreadCount > 0\" \n class=\"mark-all-read-btn\"\n @click=\"markAllAsRead\"\n >\n Mark all as read\n </button>\n </div> -->\n </div>\n \n <div v-if=\"loading\" class=\"notifications-loading\">\n <div class=\"loading-spinner\">🔄</div>\n <p>Loading notifications...</p>\n </div>\n \n <div v-else-if=\"filteredNotifications.length === 0\" class=\"notifications-empty\">\n <p>{{ emptyMessage }}</p>\n </div>\n \n <div v-else class=\"notifications-items\">\n <notification-item \n v-for=\"notification in filteredNotifications\" \n :key=\"notification._id\" \n :notification=\"notification\"\n @click=\"handleNotificationClick(notification)\"\n />\n </div>\n \n <div v-if=\"!loading && notifications.length > 0\" class=\"notifications-footer\">\n <button v-if=\"lastSync\" class=\"refresh-btn\" @click=\"refreshNotifications\">\n 🔄 Last updated: {{ formatTime(lastSync) }}\n </button>\n </div>\n </div>\n</template>\n\n<script setup>\nimport { ref, computed, onMounted, inject } from 'vue';\nimport { useRouter } from 'vue-router';\nimport NotificationItem from '../blocks/NotificationItem.vue';\nimport * as auth from '@martyrs/src/modules/auth/views/store/auth.js';\n\n// Get router and notification functionality\nconst router = useRouter();\nconst { \n notifications, \n unreadCount, \n loading, \n lastSync,\n markAllAsRead, \n getNotifications,\n handleNotificationAction\n} = inject('useNotifications')();\n\n// Local state\nconst filterType = ref('all');\n\n// Computed properties\nconst filteredNotifications = computed(() => {\n let filtered = [...notifications.value];\n \n // Apply filters\n if (filterType.value === 'unread') {\n filtered = filtered.filter(n => n.status !== 'read');\n } else if (filterType.value === 'read') {\n filtered = filtered.filter(n => n.status === 'read');\n } else if (filterType.value !== 'all') {\n // Filter by notification type\n filtered = filtered.filter(n => n.type === filterType.value);\n }\n \n // Sort by creation date (newest first)\n return filtered.sort((a, b) => new Date(b.createdAt) - new Date(a.createdAt));\n});\n\nconst emptyMessage = computed(() => {\n if (notifications.value.length === 0) {\n return 'You have no notifications';\n }\n \n switch (filterType.value) {\n case 'unread':\n return 'You have no unread notifications';\n case 'read':\n return 'You have no read notifications';\n default:\n return `You have no ${filterType.value} notifications`;\n }\n});\n\n// Methods\nconst handleNotificationClick = (notification) => {\n if (notification._id) {\n handleNotificationAction({\n notificationId: notification._id,\n ...notification.metadata\n });\n }\n};\n\nconst refreshNotifications = () => {\n const userId = auth.state.user._id;\n if (userId) {\n getNotifications(userId);\n }\n};\n\n// Format relative time without external libraries\nconst formatTime = (timestamp) => {\n if (!timestamp) return '';\n \n const now = new Date();\n const date = new Date(timestamp);\n const diffSeconds = Math.floor((now - date) / 1000);\n \n // Format based on how long ago\n if (diffSeconds < 60) {\n return 'Just now';\n } else if (diffSeconds < 3600) {\n const minutes = Math.floor(diffSeconds / 60);\n return `${minutes} ${minutes === 1 ? 'minute' : 'minutes'} ago`;\n } else if (diffSeconds < 86400) {\n const hours = Math.floor(diffSeconds / 3600);\n return `${hours} ${hours === 1 ? 'hour' : 'hours'} ago`;\n } else {\n // Format date string\n return date.toLocaleDateString(undefined, {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n hour: '2-digit',\n minute: '2-digit'\n });\n }\n};\n\n// Lifecycle\nonMounted(() => {\n const userId = auth.state.user._id;\n if (userId && notifications.value.length === 0) {\n getNotifications(userId);\n }\n});\n</script>\n\n<style scoped>\n.notifications-list-container {\n width: 100%;\n max-width: 800px;\n margin: 0 auto;\n}\n\n.notifications-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 20px;\n}\n\n.notifications-controls {\n display: flex;\n align-items: center;\n gap: 16px;\n}\n\n.notifications-filter select {\n padding: 6px 12px;\n border-radius: 4px;\n border: 1px solid #ddd;\n}\n\n.mark-all-read-btn {\n background-color: #2196f3;\n color: white;\n border: none;\n padding: 6px 12px;\n border-radius: 4px;\n cursor: pointer;\n}\n\n.notifications-loading,\n.notifications-empty {\n padding: 40px 0;\n text-align: center;\n color: #666;\n}\n\n.loading-spinner {\n font-size: 2rem;\n margin-bottom: 10px;\n animation: spin 1s linear infinite;\n}\n\n@keyframes spin {\n from { transform: rotate(0deg); }\n to { transform: rotate(360deg); }\n}\n\n.notifications-items {\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.notifications-footer {\n margin-top: 20px;\n text-align: center;\n}\n\n.refresh-btn {\n background: none;\n border: none;\n color: #666;\n cursor: pointer;\n padding: 6px 12px;\n}\n\n.refresh-btn:hover {\n color: #2196f3;\n}\n</style>"],"names":["useRouter","inject","ref","computed","auth.state","onMounted"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4DeA,cAAS,UAAA;AACxB,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,IAAIC,IAAAA,OAAO,kBAAkB,EAAG;AAGhC,UAAM,aAAaC,IAAG,IAAC,KAAK;AAG5B,UAAM,wBAAwBC,IAAQ,SAAC,MAAM;AAC3C,UAAI,WAAW,CAAC,GAAG,cAAc,KAAK;AAGtC,UAAI,WAAW,UAAU,UAAU;AACjC,mBAAW,SAAS,OAAO,OAAK,EAAE,WAAW,MAAM;AAAA,MACvD,WAAa,WAAW,UAAU,QAAQ;AACtC,mBAAW,SAAS,OAAO,OAAK,EAAE,WAAW,MAAM;AAAA,MACvD,WAAa,WAAW,UAAU,OAAO;AAErC,mBAAW,SAAS,OAAO,OAAK,EAAE,SAAS,WAAW,KAAK;AAAA,MAC/D;AAGE,aAAO,SAAS,KAAK,CAAC,GAAG,MAAM,IAAI,KAAK,EAAE,SAAS,IAAI,IAAI,KAAK,EAAE,SAAS,CAAC;AAAA,IAC9E,CAAC;AAED,UAAM,eAAeA,IAAQ,SAAC,MAAM;AAClC,UAAI,cAAc,MAAM,WAAW,GAAG;AACpC,eAAO;AAAA,MACX;AAEE,cAAQ,WAAW,OAAK;AAAA,QACtB,KAAK;AACH,iBAAO;AAAA,QACT,KAAK;AACH,iBAAO;AAAA,QACT;AACE,iBAAO,eAAe,WAAW,KAAK;AAAA,MAC5C;AAAA,IACA,CAAC;AAGD,UAAM,0BAA0B,CAAC,iBAAiB;AAChD,UAAI,aAAa,KAAK;AACpB,iCAAyB;AAAA,UACvB,gBAAgB,aAAa;AAAA,UAC7B,GAAG,aAAa;AAAA,QACtB,CAAK;AAAA,MACL;AAAA,IACA;AAEA,UAAM,uBAAuB,MAAM;AACjC,YAAM,SAASC,WAAW,KAAK;AAC/B,UAAI,QAAQ;AACV,yBAAiB,MAAM;AAAA,MAC3B;AAAA,IACA;AAGA,UAAM,aAAa,CAAC,cAAc;AAChC,UAAI,CAAC,UAAW,QAAO;AAEvB,YAAM,MAAM,oBAAI,KAAM;AACtB,YAAM,OAAO,IAAI,KAAK,SAAS;AAC/B,YAAM,cAAc,KAAK,OAAO,MAAM,QAAQ,GAAI;AAGlD,UAAI,cAAc,IAAI;AACpB,eAAO;AAAA,MACX,WAAa,cAAc,MAAM;AAC7B,cAAM,UAAU,KAAK,MAAM,cAAc,EAAE;AAC3C,eAAO,GAAG,OAAO,IAAI,YAAY,IAAI,WAAW,SAAS;AAAA,MAC7D,WAAa,cAAc,OAAO;AAC9B,cAAM,QAAQ,KAAK,MAAM,cAAc,IAAI;AAC3C,eAAO,GAAG,KAAK,IAAI,UAAU,IAAI,SAAS,OAAO;AAAA,MACrD,OAAS;AAEL,eAAO,KAAK,mBAAmB,QAAW;AAAA,UACxC,MAAM;AAAA,UACN,OAAO;AAAA,UACP,KAAK;AAAA,UACL,MAAM;AAAA,UACN,QAAQ;AAAA,QACd,CAAK;AAAA,MACL;AAAA,IACA;AAGAC,QAAAA,UAAU,MAAM;AACd,YAAM,SAASD,WAAW,KAAK;AAC/B,UAAI,UAAU,cAAc,MAAM,WAAW,GAAG;AAC9C,yBAAiB,MAAM;AAAA,MAC3B;AAAA,IACA,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"NotificationsList.vue.cjs","sources":["../../../../../../../src/modules/notifications/components/sections/NotificationsList.vue"],"sourcesContent":["<template>\n <div class=\"notifications-list-container\">\n <div v-if=\"!MOBILE_APP\" class=\"notifications-header\">\n <h2>Notifications</h2>\n <!-- <div class=\"notifications-controls\">\n <div class=\"notifications-filter\">\n <label for=\"filter-type\">Filter: </label>\n <select id=\"filter-type\" v-model=\"filterType\">\n <option value=\"all\">All</option>\n <option value=\"unread\">Unread</option>\n <option value=\"read\">Read</option>\n <option value=\"info\">Info</option>\n <option value=\"success\">Success</option>\n <option value=\"warning\">Warning</option>\n <option value=\"error\">Error</option>\n </select>\n </div>\n <button \n v-if=\"unreadCount > 0\" \n class=\"mark-all-read-btn\"\n @click=\"markAllAsRead\"\n >\n Mark all as read\n </button>\n </div> -->\n </div>\n \n <div v-if=\"loading\" class=\"notifications-loading\">\n <div class=\"loading-spinner\">🔄</div>\n <p>Loading notifications...</p>\n </div>\n \n <div v-else-if=\"filteredNotifications.length === 0\" class=\"notifications-empty\">\n <p>{{ emptyMessage }}</p>\n </div>\n \n <div v-else class=\"notifications-items\">\n <notification-item \n v-for=\"notification in filteredNotifications\" \n :key=\"notification._id\" \n :notification=\"notification\"\n @click=\"handleNotificationClick(notification)\"\n />\n </div>\n \n <div v-if=\"!loading && notifications.length > 0\" class=\"notifications-footer\">\n <button v-if=\"lastSync\" class=\"refresh-btn\" @click=\"refreshNotifications\">\n 🔄 Last updated: {{ formatTime(lastSync) }}\n </button>\n </div>\n </div>\n</template>\n\n<script setup>\nimport { ref, computed, onMounted, inject } from 'vue';\nimport { useRouter } from 'vue-router';\nimport NotificationItem from '../blocks/NotificationItem.vue';\nimport * as auth from '@martyrs/src/modules/auth/views/store/auth.js';\n\n// Get router and notification functionality\nconst router = useRouter();\nconst { \n notifications, \n unreadCount, \n loading, \n lastSync,\n markAllAsRead, \n getNotifications,\n handleNotificationAction\n} = inject('useNotifications')();\n\n// Local state\nconst filterType = ref('all');\n\n// Computed properties\nconst filteredNotifications = computed(() => {\n let filtered = [...notifications.value];\n \n // Apply filters\n if (filterType.value === 'unread') {\n filtered = filtered.filter(n => n.status !== 'read');\n } else if (filterType.value === 'read') {\n filtered = filtered.filter(n => n.status === 'read');\n } else if (filterType.value !== 'all') {\n // Filter by notification type\n filtered = filtered.filter(n => n.type === filterType.value);\n }\n \n // Sort by creation date (newest first)\n return filtered.sort((a, b) => new Date(b.createdAt) - new Date(a.createdAt));\n});\n\nconst emptyMessage = computed(() => {\n if (notifications.value.length === 0) {\n return 'You have no notifications';\n }\n \n switch (filterType.value) {\n case 'unread':\n return 'You have no unread notifications';\n case 'read':\n return 'You have no read notifications';\n default:\n return `You have no ${filterType.value} notifications`;\n }\n});\n\n// Methods\nconst handleNotificationClick = (notification) => {\n if (notification._id) {\n handleNotificationAction({\n notificationId: notification._id,\n ...notification.metadata\n });\n }\n};\n\nconst refreshNotifications = () => {\n const userId = auth.state.user._id;\n if (userId) {\n getNotifications(userId);\n }\n};\n\n// Format relative time without external libraries\nconst formatTime = (timestamp) => {\n if (!timestamp) return '';\n \n const now = new Date();\n const date = new Date(timestamp);\n const diffSeconds = Math.floor((now - date) / 1000);\n \n // Format based on how long ago\n if (diffSeconds < 60) {\n return 'Just now';\n } else if (diffSeconds < 3600) {\n const minutes = Math.floor(diffSeconds / 60);\n return `${minutes} ${minutes === 1 ? 'minute' : 'minutes'} ago`;\n } else if (diffSeconds < 86400) {\n const hours = Math.floor(diffSeconds / 3600);\n return `${hours} ${hours === 1 ? 'hour' : 'hours'} ago`;\n } else {\n // Format date string\n return date.toLocaleDateString(undefined, {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n hour: '2-digit',\n minute: '2-digit'\n });\n }\n};\n\n// Lifecycle\nonMounted(() => {\n const userId = auth.state.user._id;\n if (userId && notifications.value.length === 0 && !loading.value) {\n getNotifications(userId);\n }\n});\n</script>\n\n<style scoped>\n.notifications-list-container {\n width: 100%;\n max-width: 800px;\n margin: 0 auto;\n}\n\n.notifications-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 20px;\n}\n\n.notifications-controls {\n display: flex;\n align-items: center;\n gap: 16px;\n}\n\n.notifications-filter select {\n padding: 6px 12px;\n border-radius: 4px;\n border: 1px solid #ddd;\n}\n\n.mark-all-read-btn {\n background-color: #2196f3;\n color: white;\n border: none;\n padding: 6px 12px;\n border-radius: 4px;\n cursor: pointer;\n}\n\n.notifications-loading,\n.notifications-empty {\n padding: 40px 0;\n text-align: center;\n color: #666;\n}\n\n.loading-spinner {\n font-size: 2rem;\n margin-bottom: 10px;\n animation: spin 1s linear infinite;\n}\n\n@keyframes spin {\n from { transform: rotate(0deg); }\n to { transform: rotate(360deg); }\n}\n\n.notifications-items {\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.notifications-footer {\n margin-top: 20px;\n text-align: center;\n}\n\n.refresh-btn {\n background: none;\n border: none;\n color: #666;\n cursor: pointer;\n padding: 6px 12px;\n}\n\n.refresh-btn:hover {\n color: #2196f3;\n}\n</style>"],"names":["useRouter","inject","ref","computed","auth.state","onMounted"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4DeA,cAAS,UAAA;AACxB,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,IAAIC,IAAAA,OAAO,kBAAkB,EAAG;AAGhC,UAAM,aAAaC,IAAG,IAAC,KAAK;AAG5B,UAAM,wBAAwBC,IAAQ,SAAC,MAAM;AAC3C,UAAI,WAAW,CAAC,GAAG,cAAc,KAAK;AAGtC,UAAI,WAAW,UAAU,UAAU;AACjC,mBAAW,SAAS,OAAO,OAAK,EAAE,WAAW,MAAM;AAAA,MACvD,WAAa,WAAW,UAAU,QAAQ;AACtC,mBAAW,SAAS,OAAO,OAAK,EAAE,WAAW,MAAM;AAAA,MACvD,WAAa,WAAW,UAAU,OAAO;AAErC,mBAAW,SAAS,OAAO,OAAK,EAAE,SAAS,WAAW,KAAK;AAAA,MAC/D;AAGE,aAAO,SAAS,KAAK,CAAC,GAAG,MAAM,IAAI,KAAK,EAAE,SAAS,IAAI,IAAI,KAAK,EAAE,SAAS,CAAC;AAAA,IAC9E,CAAC;AAED,UAAM,eAAeA,IAAQ,SAAC,MAAM;AAClC,UAAI,cAAc,MAAM,WAAW,GAAG;AACpC,eAAO;AAAA,MACX;AAEE,cAAQ,WAAW,OAAK;AAAA,QACtB,KAAK;AACH,iBAAO;AAAA,QACT,KAAK;AACH,iBAAO;AAAA,QACT;AACE,iBAAO,eAAe,WAAW,KAAK;AAAA,MAC5C;AAAA,IACA,CAAC;AAGD,UAAM,0BAA0B,CAAC,iBAAiB;AAChD,UAAI,aAAa,KAAK;AACpB,iCAAyB;AAAA,UACvB,gBAAgB,aAAa;AAAA,UAC7B,GAAG,aAAa;AAAA,QACtB,CAAK;AAAA,MACL;AAAA,IACA;AAEA,UAAM,uBAAuB,MAAM;AACjC,YAAM,SAASC,WAAW,KAAK;AAC/B,UAAI,QAAQ;AACV,yBAAiB,MAAM;AAAA,MAC3B;AAAA,IACA;AAGA,UAAM,aAAa,CAAC,cAAc;AAChC,UAAI,CAAC,UAAW,QAAO;AAEvB,YAAM,MAAM,oBAAI,KAAM;AACtB,YAAM,OAAO,IAAI,KAAK,SAAS;AAC/B,YAAM,cAAc,KAAK,OAAO,MAAM,QAAQ,GAAI;AAGlD,UAAI,cAAc,IAAI;AACpB,eAAO;AAAA,MACX,WAAa,cAAc,MAAM;AAC7B,cAAM,UAAU,KAAK,MAAM,cAAc,EAAE;AAC3C,eAAO,GAAG,OAAO,IAAI,YAAY,IAAI,WAAW,SAAS;AAAA,MAC7D,WAAa,cAAc,OAAO;AAC9B,cAAM,QAAQ,KAAK,MAAM,cAAc,IAAI;AAC3C,eAAO,GAAG,KAAK,IAAI,UAAU,IAAI,SAAS,OAAO;AAAA,MACrD,OAAS;AAEL,eAAO,KAAK,mBAAmB,QAAW;AAAA,UACxC,MAAM;AAAA,UACN,OAAO;AAAA,UACP,KAAK;AAAA,UACL,MAAM;AAAA,UACN,QAAQ;AAAA,QACd,CAAK;AAAA,MACL;AAAA,IACA;AAGAC,QAAAA,UAAU,MAAM;AACd,YAAM,SAASD,WAAW,KAAK;AAC/B,UAAI,UAAU,cAAc,MAAM,WAAW,KAAK,CAAC,QAAQ,OAAO;AAChE,yBAAiB,MAAM;AAAA,MAC3B;AAAA,IACA,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -101,7 +101,7 @@ const _sfc_main = {
101
101
  };
102
102
  onMounted(() => {
103
103
  const userId = state.user._id;
104
- if (userId && notifications.value.length === 0) {
104
+ if (userId && notifications.value.length === 0 && !loading.value) {
105
105
  getNotifications(userId);
106
106
  }
107
107
  });
@@ -135,7 +135,7 @@ const _sfc_main = {
135
135
  };
136
136
  }
137
137
  };
138
- const NotificationsList = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-4beccb18"]]);
138
+ const NotificationsList = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-5af8a2ed"]]);
139
139
  export {
140
140
  NotificationsList as default
141
141
  };
@@ -1 +1 @@
1
- {"version":3,"file":"NotificationsList.vue.js","sources":["../../../../../../../src/modules/notifications/components/sections/NotificationsList.vue"],"sourcesContent":["<template>\n <div class=\"notifications-list-container\">\n <div v-if=\"!MOBILE_APP\" class=\"notifications-header\">\n <h2>Notifications</h2>\n <!-- <div class=\"notifications-controls\">\n <div class=\"notifications-filter\">\n <label for=\"filter-type\">Filter: </label>\n <select id=\"filter-type\" v-model=\"filterType\">\n <option value=\"all\">All</option>\n <option value=\"unread\">Unread</option>\n <option value=\"read\">Read</option>\n <option value=\"info\">Info</option>\n <option value=\"success\">Success</option>\n <option value=\"warning\">Warning</option>\n <option value=\"error\">Error</option>\n </select>\n </div>\n <button \n v-if=\"unreadCount > 0\" \n class=\"mark-all-read-btn\"\n @click=\"markAllAsRead\"\n >\n Mark all as read\n </button>\n </div> -->\n </div>\n \n <div v-if=\"loading\" class=\"notifications-loading\">\n <div class=\"loading-spinner\">🔄</div>\n <p>Loading notifications...</p>\n </div>\n \n <div v-else-if=\"filteredNotifications.length === 0\" class=\"notifications-empty\">\n <p>{{ emptyMessage }}</p>\n </div>\n \n <div v-else class=\"notifications-items\">\n <notification-item \n v-for=\"notification in filteredNotifications\" \n :key=\"notification._id\" \n :notification=\"notification\"\n @click=\"handleNotificationClick(notification)\"\n />\n </div>\n \n <div v-if=\"!loading && notifications.length > 0\" class=\"notifications-footer\">\n <button v-if=\"lastSync\" class=\"refresh-btn\" @click=\"refreshNotifications\">\n 🔄 Last updated: {{ formatTime(lastSync) }}\n </button>\n </div>\n </div>\n</template>\n\n<script setup>\nimport { ref, computed, onMounted, inject } from 'vue';\nimport { useRouter } from 'vue-router';\nimport NotificationItem from '../blocks/NotificationItem.vue';\nimport * as auth from '@martyrs/src/modules/auth/views/store/auth.js';\n\n// Get router and notification functionality\nconst router = useRouter();\nconst { \n notifications, \n unreadCount, \n loading, \n lastSync,\n markAllAsRead, \n getNotifications,\n handleNotificationAction\n} = inject('useNotifications')();\n\n// Local state\nconst filterType = ref('all');\n\n// Computed properties\nconst filteredNotifications = computed(() => {\n let filtered = [...notifications.value];\n \n // Apply filters\n if (filterType.value === 'unread') {\n filtered = filtered.filter(n => n.status !== 'read');\n } else if (filterType.value === 'read') {\n filtered = filtered.filter(n => n.status === 'read');\n } else if (filterType.value !== 'all') {\n // Filter by notification type\n filtered = filtered.filter(n => n.type === filterType.value);\n }\n \n // Sort by creation date (newest first)\n return filtered.sort((a, b) => new Date(b.createdAt) - new Date(a.createdAt));\n});\n\nconst emptyMessage = computed(() => {\n if (notifications.value.length === 0) {\n return 'You have no notifications';\n }\n \n switch (filterType.value) {\n case 'unread':\n return 'You have no unread notifications';\n case 'read':\n return 'You have no read notifications';\n default:\n return `You have no ${filterType.value} notifications`;\n }\n});\n\n// Methods\nconst handleNotificationClick = (notification) => {\n if (notification._id) {\n handleNotificationAction({\n notificationId: notification._id,\n ...notification.metadata\n });\n }\n};\n\nconst refreshNotifications = () => {\n const userId = auth.state.user._id;\n if (userId) {\n getNotifications(userId);\n }\n};\n\n// Format relative time without external libraries\nconst formatTime = (timestamp) => {\n if (!timestamp) return '';\n \n const now = new Date();\n const date = new Date(timestamp);\n const diffSeconds = Math.floor((now - date) / 1000);\n \n // Format based on how long ago\n if (diffSeconds < 60) {\n return 'Just now';\n } else if (diffSeconds < 3600) {\n const minutes = Math.floor(diffSeconds / 60);\n return `${minutes} ${minutes === 1 ? 'minute' : 'minutes'} ago`;\n } else if (diffSeconds < 86400) {\n const hours = Math.floor(diffSeconds / 3600);\n return `${hours} ${hours === 1 ? 'hour' : 'hours'} ago`;\n } else {\n // Format date string\n return date.toLocaleDateString(undefined, {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n hour: '2-digit',\n minute: '2-digit'\n });\n }\n};\n\n// Lifecycle\nonMounted(() => {\n const userId = auth.state.user._id;\n if (userId && notifications.value.length === 0) {\n getNotifications(userId);\n }\n});\n</script>\n\n<style scoped>\n.notifications-list-container {\n width: 100%;\n max-width: 800px;\n margin: 0 auto;\n}\n\n.notifications-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 20px;\n}\n\n.notifications-controls {\n display: flex;\n align-items: center;\n gap: 16px;\n}\n\n.notifications-filter select {\n padding: 6px 12px;\n border-radius: 4px;\n border: 1px solid #ddd;\n}\n\n.mark-all-read-btn {\n background-color: #2196f3;\n color: white;\n border: none;\n padding: 6px 12px;\n border-radius: 4px;\n cursor: pointer;\n}\n\n.notifications-loading,\n.notifications-empty {\n padding: 40px 0;\n text-align: center;\n color: #666;\n}\n\n.loading-spinner {\n font-size: 2rem;\n margin-bottom: 10px;\n animation: spin 1s linear infinite;\n}\n\n@keyframes spin {\n from { transform: rotate(0deg); }\n to { transform: rotate(360deg); }\n}\n\n.notifications-items {\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.notifications-footer {\n margin-top: 20px;\n text-align: center;\n}\n\n.refresh-btn {\n background: none;\n border: none;\n color: #666;\n cursor: pointer;\n padding: 6px 12px;\n}\n\n.refresh-btn:hover {\n color: #2196f3;\n}\n</style>"],"names":["auth.state"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4De,cAAS;AACxB,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,IAAI,OAAO,kBAAkB,EAAG;AAGhC,UAAM,aAAa,IAAI,KAAK;AAG5B,UAAM,wBAAwB,SAAS,MAAM;AAC3C,UAAI,WAAW,CAAC,GAAG,cAAc,KAAK;AAGtC,UAAI,WAAW,UAAU,UAAU;AACjC,mBAAW,SAAS,OAAO,OAAK,EAAE,WAAW,MAAM;AAAA,MACvD,WAAa,WAAW,UAAU,QAAQ;AACtC,mBAAW,SAAS,OAAO,OAAK,EAAE,WAAW,MAAM;AAAA,MACvD,WAAa,WAAW,UAAU,OAAO;AAErC,mBAAW,SAAS,OAAO,OAAK,EAAE,SAAS,WAAW,KAAK;AAAA,MAC/D;AAGE,aAAO,SAAS,KAAK,CAAC,GAAG,MAAM,IAAI,KAAK,EAAE,SAAS,IAAI,IAAI,KAAK,EAAE,SAAS,CAAC;AAAA,IAC9E,CAAC;AAED,UAAM,eAAe,SAAS,MAAM;AAClC,UAAI,cAAc,MAAM,WAAW,GAAG;AACpC,eAAO;AAAA,MACX;AAEE,cAAQ,WAAW,OAAK;AAAA,QACtB,KAAK;AACH,iBAAO;AAAA,QACT,KAAK;AACH,iBAAO;AAAA,QACT;AACE,iBAAO,eAAe,WAAW,KAAK;AAAA,MAC5C;AAAA,IACA,CAAC;AAGD,UAAM,0BAA0B,CAAC,iBAAiB;AAChD,UAAI,aAAa,KAAK;AACpB,iCAAyB;AAAA,UACvB,gBAAgB,aAAa;AAAA,UAC7B,GAAG,aAAa;AAAA,QACtB,CAAK;AAAA,MACL;AAAA,IACA;AAEA,UAAM,uBAAuB,MAAM;AACjC,YAAM,SAASA,MAAW,KAAK;AAC/B,UAAI,QAAQ;AACV,yBAAiB,MAAM;AAAA,MAC3B;AAAA,IACA;AAGA,UAAM,aAAa,CAAC,cAAc;AAChC,UAAI,CAAC,UAAW,QAAO;AAEvB,YAAM,MAAM,oBAAI,KAAM;AACtB,YAAM,OAAO,IAAI,KAAK,SAAS;AAC/B,YAAM,cAAc,KAAK,OAAO,MAAM,QAAQ,GAAI;AAGlD,UAAI,cAAc,IAAI;AACpB,eAAO;AAAA,MACX,WAAa,cAAc,MAAM;AAC7B,cAAM,UAAU,KAAK,MAAM,cAAc,EAAE;AAC3C,eAAO,GAAG,OAAO,IAAI,YAAY,IAAI,WAAW,SAAS;AAAA,MAC7D,WAAa,cAAc,OAAO;AAC9B,cAAM,QAAQ,KAAK,MAAM,cAAc,IAAI;AAC3C,eAAO,GAAG,KAAK,IAAI,UAAU,IAAI,SAAS,OAAO;AAAA,MACrD,OAAS;AAEL,eAAO,KAAK,mBAAmB,QAAW;AAAA,UACxC,MAAM;AAAA,UACN,OAAO;AAAA,UACP,KAAK;AAAA,UACL,MAAM;AAAA,UACN,QAAQ;AAAA,QACd,CAAK;AAAA,MACL;AAAA,IACA;AAGA,cAAU,MAAM;AACd,YAAM,SAASA,MAAW,KAAK;AAC/B,UAAI,UAAU,cAAc,MAAM,WAAW,GAAG;AAC9C,yBAAiB,MAAM;AAAA,MAC3B;AAAA,IACA,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"NotificationsList.vue.js","sources":["../../../../../../../src/modules/notifications/components/sections/NotificationsList.vue"],"sourcesContent":["<template>\n <div class=\"notifications-list-container\">\n <div v-if=\"!MOBILE_APP\" class=\"notifications-header\">\n <h2>Notifications</h2>\n <!-- <div class=\"notifications-controls\">\n <div class=\"notifications-filter\">\n <label for=\"filter-type\">Filter: </label>\n <select id=\"filter-type\" v-model=\"filterType\">\n <option value=\"all\">All</option>\n <option value=\"unread\">Unread</option>\n <option value=\"read\">Read</option>\n <option value=\"info\">Info</option>\n <option value=\"success\">Success</option>\n <option value=\"warning\">Warning</option>\n <option value=\"error\">Error</option>\n </select>\n </div>\n <button \n v-if=\"unreadCount > 0\" \n class=\"mark-all-read-btn\"\n @click=\"markAllAsRead\"\n >\n Mark all as read\n </button>\n </div> -->\n </div>\n \n <div v-if=\"loading\" class=\"notifications-loading\">\n <div class=\"loading-spinner\">🔄</div>\n <p>Loading notifications...</p>\n </div>\n \n <div v-else-if=\"filteredNotifications.length === 0\" class=\"notifications-empty\">\n <p>{{ emptyMessage }}</p>\n </div>\n \n <div v-else class=\"notifications-items\">\n <notification-item \n v-for=\"notification in filteredNotifications\" \n :key=\"notification._id\" \n :notification=\"notification\"\n @click=\"handleNotificationClick(notification)\"\n />\n </div>\n \n <div v-if=\"!loading && notifications.length > 0\" class=\"notifications-footer\">\n <button v-if=\"lastSync\" class=\"refresh-btn\" @click=\"refreshNotifications\">\n 🔄 Last updated: {{ formatTime(lastSync) }}\n </button>\n </div>\n </div>\n</template>\n\n<script setup>\nimport { ref, computed, onMounted, inject } from 'vue';\nimport { useRouter } from 'vue-router';\nimport NotificationItem from '../blocks/NotificationItem.vue';\nimport * as auth from '@martyrs/src/modules/auth/views/store/auth.js';\n\n// Get router and notification functionality\nconst router = useRouter();\nconst { \n notifications, \n unreadCount, \n loading, \n lastSync,\n markAllAsRead, \n getNotifications,\n handleNotificationAction\n} = inject('useNotifications')();\n\n// Local state\nconst filterType = ref('all');\n\n// Computed properties\nconst filteredNotifications = computed(() => {\n let filtered = [...notifications.value];\n \n // Apply filters\n if (filterType.value === 'unread') {\n filtered = filtered.filter(n => n.status !== 'read');\n } else if (filterType.value === 'read') {\n filtered = filtered.filter(n => n.status === 'read');\n } else if (filterType.value !== 'all') {\n // Filter by notification type\n filtered = filtered.filter(n => n.type === filterType.value);\n }\n \n // Sort by creation date (newest first)\n return filtered.sort((a, b) => new Date(b.createdAt) - new Date(a.createdAt));\n});\n\nconst emptyMessage = computed(() => {\n if (notifications.value.length === 0) {\n return 'You have no notifications';\n }\n \n switch (filterType.value) {\n case 'unread':\n return 'You have no unread notifications';\n case 'read':\n return 'You have no read notifications';\n default:\n return `You have no ${filterType.value} notifications`;\n }\n});\n\n// Methods\nconst handleNotificationClick = (notification) => {\n if (notification._id) {\n handleNotificationAction({\n notificationId: notification._id,\n ...notification.metadata\n });\n }\n};\n\nconst refreshNotifications = () => {\n const userId = auth.state.user._id;\n if (userId) {\n getNotifications(userId);\n }\n};\n\n// Format relative time without external libraries\nconst formatTime = (timestamp) => {\n if (!timestamp) return '';\n \n const now = new Date();\n const date = new Date(timestamp);\n const diffSeconds = Math.floor((now - date) / 1000);\n \n // Format based on how long ago\n if (diffSeconds < 60) {\n return 'Just now';\n } else if (diffSeconds < 3600) {\n const minutes = Math.floor(diffSeconds / 60);\n return `${minutes} ${minutes === 1 ? 'minute' : 'minutes'} ago`;\n } else if (diffSeconds < 86400) {\n const hours = Math.floor(diffSeconds / 3600);\n return `${hours} ${hours === 1 ? 'hour' : 'hours'} ago`;\n } else {\n // Format date string\n return date.toLocaleDateString(undefined, {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n hour: '2-digit',\n minute: '2-digit'\n });\n }\n};\n\n// Lifecycle\nonMounted(() => {\n const userId = auth.state.user._id;\n if (userId && notifications.value.length === 0 && !loading.value) {\n getNotifications(userId);\n }\n});\n</script>\n\n<style scoped>\n.notifications-list-container {\n width: 100%;\n max-width: 800px;\n margin: 0 auto;\n}\n\n.notifications-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 20px;\n}\n\n.notifications-controls {\n display: flex;\n align-items: center;\n gap: 16px;\n}\n\n.notifications-filter select {\n padding: 6px 12px;\n border-radius: 4px;\n border: 1px solid #ddd;\n}\n\n.mark-all-read-btn {\n background-color: #2196f3;\n color: white;\n border: none;\n padding: 6px 12px;\n border-radius: 4px;\n cursor: pointer;\n}\n\n.notifications-loading,\n.notifications-empty {\n padding: 40px 0;\n text-align: center;\n color: #666;\n}\n\n.loading-spinner {\n font-size: 2rem;\n margin-bottom: 10px;\n animation: spin 1s linear infinite;\n}\n\n@keyframes spin {\n from { transform: rotate(0deg); }\n to { transform: rotate(360deg); }\n}\n\n.notifications-items {\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.notifications-footer {\n margin-top: 20px;\n text-align: center;\n}\n\n.refresh-btn {\n background: none;\n border: none;\n color: #666;\n cursor: pointer;\n padding: 6px 12px;\n}\n\n.refresh-btn:hover {\n color: #2196f3;\n}\n</style>"],"names":["auth.state"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4De,cAAS;AACxB,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,IAAI,OAAO,kBAAkB,EAAG;AAGhC,UAAM,aAAa,IAAI,KAAK;AAG5B,UAAM,wBAAwB,SAAS,MAAM;AAC3C,UAAI,WAAW,CAAC,GAAG,cAAc,KAAK;AAGtC,UAAI,WAAW,UAAU,UAAU;AACjC,mBAAW,SAAS,OAAO,OAAK,EAAE,WAAW,MAAM;AAAA,MACvD,WAAa,WAAW,UAAU,QAAQ;AACtC,mBAAW,SAAS,OAAO,OAAK,EAAE,WAAW,MAAM;AAAA,MACvD,WAAa,WAAW,UAAU,OAAO;AAErC,mBAAW,SAAS,OAAO,OAAK,EAAE,SAAS,WAAW,KAAK;AAAA,MAC/D;AAGE,aAAO,SAAS,KAAK,CAAC,GAAG,MAAM,IAAI,KAAK,EAAE,SAAS,IAAI,IAAI,KAAK,EAAE,SAAS,CAAC;AAAA,IAC9E,CAAC;AAED,UAAM,eAAe,SAAS,MAAM;AAClC,UAAI,cAAc,MAAM,WAAW,GAAG;AACpC,eAAO;AAAA,MACX;AAEE,cAAQ,WAAW,OAAK;AAAA,QACtB,KAAK;AACH,iBAAO;AAAA,QACT,KAAK;AACH,iBAAO;AAAA,QACT;AACE,iBAAO,eAAe,WAAW,KAAK;AAAA,MAC5C;AAAA,IACA,CAAC;AAGD,UAAM,0BAA0B,CAAC,iBAAiB;AAChD,UAAI,aAAa,KAAK;AACpB,iCAAyB;AAAA,UACvB,gBAAgB,aAAa;AAAA,UAC7B,GAAG,aAAa;AAAA,QACtB,CAAK;AAAA,MACL;AAAA,IACA;AAEA,UAAM,uBAAuB,MAAM;AACjC,YAAM,SAASA,MAAW,KAAK;AAC/B,UAAI,QAAQ;AACV,yBAAiB,MAAM;AAAA,MAC3B;AAAA,IACA;AAGA,UAAM,aAAa,CAAC,cAAc;AAChC,UAAI,CAAC,UAAW,QAAO;AAEvB,YAAM,MAAM,oBAAI,KAAM;AACtB,YAAM,OAAO,IAAI,KAAK,SAAS;AAC/B,YAAM,cAAc,KAAK,OAAO,MAAM,QAAQ,GAAI;AAGlD,UAAI,cAAc,IAAI;AACpB,eAAO;AAAA,MACX,WAAa,cAAc,MAAM;AAC7B,cAAM,UAAU,KAAK,MAAM,cAAc,EAAE;AAC3C,eAAO,GAAG,OAAO,IAAI,YAAY,IAAI,WAAW,SAAS;AAAA,MAC7D,WAAa,cAAc,OAAO;AAC9B,cAAM,QAAQ,KAAK,MAAM,cAAc,IAAI;AAC3C,eAAO,GAAG,KAAK,IAAI,UAAU,IAAI,SAAS,OAAO;AAAA,MACrD,OAAS;AAEL,eAAO,KAAK,mBAAmB,QAAW;AAAA,UACxC,MAAM;AAAA,UACN,OAAO;AAAA,UACP,KAAK;AAAA,UACL,MAAM;AAAA,UACN,QAAQ;AAAA,QACd,CAAK;AAAA,MACL;AAAA,IACA;AAGA,cAAU,MAAM;AACd,YAAM,SAASA,MAAW,KAAK;AAC/B,UAAI,UAAU,cAAc,MAAM,WAAW,KAAK,CAAC,QAAQ,OAAO;AAChE,yBAAiB,MAAM;AAAA,MAC3B;AAAA,IACA,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -139,7 +139,7 @@ class NotificationManager {
139
139
  console.warn("Разрешение на уведомления не получено");
140
140
  return;
141
141
  }
142
- const registration = await navigator.serviceWorker.register("/sw.js");
142
+ const registration = await navigator.serviceWorker.ready;
143
143
  const subscription = await registration.pushManager.subscribe({
144
144
  userVisibleOnly: true,
145
145
  applicationServerKey: "BJtNnRrx05VQS0abnkHC-8gHJWpnmoqC_iQveENCmZOZIs-adWzqAiqFCdGVVd7CbiaLW-Q5iuIBDRgM9G-VnKg"
@@ -1 +1 @@
1
- {"version":3,"file":"notifications.client.cjs","sources":["../../../../../src/modules/notifications/notifications.client.js"],"sourcesContent":["import { toRefs, watch } from 'vue';\n// Router import\nimport routerNotifications from './router/notifications.router.js';\n// Store\nimport * as storeNotifications from './store/notifications.store.js';\n// Auth store import\n// Global WebSocket import\nimport globalWebSocket from '@martyrs/src/modules/globals/views/classes/globals.websocket.js';\n// Layouts\nimport NotificationsLayout from './components/layouts/NotificationsLayout.vue';\n// Sections\nimport NotificationPreferences from './components/sections/NotificationPreferences.vue';\nimport NotificationsList from './components/sections/NotificationsList.vue';\n// Pages\nimport Notifications from './components/pages/Notifications.vue';\n// Components\nimport NotificationItem from './components/blocks/NotificationItem.vue';\nimport NotificationBadge from './components/elements/NotificationBadge.vue';\n\n/**\n * Capacitor Push Notification handler\n */\nclass CapacitorPushHandler {\n constructor(store) {\n this.store = store;\n this.pushNotifications = null;\n this.device = null;\n this.isInitialized = false;\n }\n\n /**\n * Initialize Capacitor plugins\n */\n async initialize() {\n // Skip if running in SSR\n if (typeof window === 'undefined') {\n return false;\n }\n\n try {\n // Dynamic imports to prevent errors in web environment\n const { Capacitor } = await import('@capacitor/core');\n const { PushNotifications } = await import('@capacitor/push-notifications');\n const { Device } = await import('@capacitor/device');\n\n this.capacitor = Capacitor;\n this.pushNotifications = PushNotifications;\n this.device = Device;\n\n // Only proceed if running on a native platform\n if (!this.capacitor.isNativePlatform()) {\n return false;\n }\n\n this.isInitialized = true;\n return true;\n } catch (error) {\n console.error('Error importing Capacitor plugins:', error);\n return false;\n }\n }\n\n /**\n * Request permission and register for push notifications\n */\n async requestPermissions() {\n // Skip if running in SSR\n if (typeof window === 'undefined') {\n return false;\n }\n\n if (!this.isInitialized) {\n const initialized = await this.initialize();\n if (!initialized) return false;\n }\n\n try {\n // Request permission\n const permissionResult = await this.pushNotifications.requestPermissions();\n if (permissionResult.receive !== 'granted') {\n console.log('Push notification permission denied');\n return false;\n }\n\n // Set up event listeners\n this._setupListeners();\n\n // Register with Apple/Google\n await this.pushNotifications.register();\n return true;\n } catch (error) {\n console.error('Error requesting push notification permissions:', error);\n return false;\n }\n }\n\n /**\n * Setup push notification event listeners\n */\n _setupListeners() {\n // Registration event\n this.pushNotifications.addListener('registration', this._handleRegistration.bind(this));\n\n // Notification received event\n this.pushNotifications.addListener('pushNotificationReceived', this._handleNotificationReceived.bind(this));\n\n // Notification action performed event\n this.pushNotifications.addListener('pushNotificationActionPerformed', this._handleNotificationAction.bind(this));\n }\n\n /**\n * Handle registration token received\n */\n async _handleRegistration(token) {\n try {\n // Get device info\n const deviceInfo = await this.device.getInfo();\n const deviceId = await this.device.getId();\n\n // Prepare device data\n const deviceData = {\n deviceId: deviceId.uuid,\n deviceType: deviceInfo.platform.toLowerCase(),\n deviceToken: token.value,\n };\n\n // Register device with backend\n await this.store.notifications.actions.registerDevice(deviceData);\n } catch (error) {\n console.error('Error handling push registration:', error);\n }\n }\n\n /**\n * Handle received notification\n */\n _handleNotificationReceived(notification) {\n // Add notification to store\n this.store.notifications.actions.addLocalNotification({\n title: notification.title,\n body: notification.body,\n data: notification.data || {},\n });\n }\n\n /**\n * Handle notification action (when user taps on notification)\n */\n _handleNotificationAction(actionData) {\n if (actionData.notification && actionData.notification.data) {\n this.store.notifications.actions.handleNotificationAction(actionData.notification.data);\n }\n }\n\n /**\n * Remove push notification listeners\n */\n removeListeners() {\n if (typeof window === 'undefined') {\n return;\n }\n\n if (this.pushNotifications) {\n this.pushNotifications.removeAllListeners();\n }\n }\n}\n\n/**\n * Notification Manager for coordinating WebSocket and Push notifications\n */\n\nclass NotificationManager {\n constructor(store, options = {}) {\n this.store = store;\n this.options = options;\n this.pushHandler = new CapacitorPushHandler(store);\n this.initialized = false;\n this.isServer = typeof window === 'undefined';\n }\n\n async registerWebPush(store) {\n if (!('Notification' in window) || !('serviceWorker' in navigator) || !('PushManager' in window)) {\n console.warn('Web Push не поддерживается в браузере');\n return;\n }\n\n const permission = await Notification.requestPermission();\n if (permission !== 'granted') {\n console.warn('Разрешение на уведомления не получено');\n return;\n }\n\n const registration = await navigator.serviceWorker.register('/sw.js');\n const subscription = await registration.pushManager.subscribe({\n userVisibleOnly: true,\n applicationServerKey: 'BJtNnRrx05VQS0abnkHC-8gHJWpnmoqC_iQveENCmZOZIs-adWzqAiqFCdGVVd7CbiaLW-Q5iuIBDRgM9G-VnKg',\n });\n\n console.log('New subscription:', JSON.stringify(subscription));\n\n // Отправь подписку на сервер\n await store.notifications.actions.registerDevice({\n deviceToken: JSON.stringify(subscription),\n deviceType: 'web',\n });\n }\n\n async initialize() {\n if (this.initialized || this.isServer) return;\n\n const userId = this.store.auth.state.user?._id;\n if (!userId) {\n console.warn('Cannot initialize notifications: No user ID found in auth store');\n return;\n }\n\n console.log('Connecting to websockets via notifications');\n await globalWebSocket.connect(userId);\n\n globalWebSocket.removeModuleListeners('notification');\n\n await globalWebSocket.subscribeModule('notification');\n\n globalWebSocket.addEventListener(\n 'notification',\n data => {\n this.store.notifications.actions.addLocalNotification(data.data);\n },\n { module: 'notification' }\n );\n\n // 🎯 Опционально включаем push\n if (this.options.enablePush !== false) {\n await this.pushHandler.requestPermissions();\n await this.registerWebPush(this.store);\n }\n\n this.initialized = true;\n\n // ✅ Загружаем список уведомлений из API\n await this.store.notifications.actions.getNotifications(userId);\n }\n\n disconnect() {\n if (this.isServer) return;\n\n globalWebSocket.removeModuleListeners('notification');\n this.pushHandler.removeListeners();\n this.initialized = false;\n }\n}\n\n/**\n * Server-side utility for pre-fetching notification data\n */\nconst SSRUtils = {\n /**\n * Pre-fetch notifications for SSR\n * @param {Object} store - Store instance\n * @param {Object} context - SSR context\n */\n async prefetchNotifications(store, context) {\n try {\n const userId = store.auth.state.user?._id;\n if (userId) {\n // Fetch notifications without WebSocket or push setup\n await store.notifications.actions.getNotifications(userId);\n }\n } catch (error) {\n console.error('Error pre-fetching notifications for SSR:', error);\n }\n },\n};\n\n/**\n * Function to initialize the notifications module\n * @param {Object} app - Vue app instance\n * @param {Object} store - Vuex/Pinia store\n * @param {Object} router - Vue Router instance\n * @param {Object} options - Configuration options\n */\nfunction initializeNotifications(app, store, router, options = {}) {\n // Add routes and store\n const route = options.route || 'User Profile Root';\n router.addRoute(route, routerNotifications);\n store.addStore('notifications', storeNotifications);\n\n // Initialize global WebSocket if needed\n if (options.wsUrl) {\n globalWebSocket.initialize({ wsUrl: options.wsUrl });\n }\n\n // Create notification manager\n const notificationManager = new NotificationManager(store, {\n enablePush: options.enablePush !== false,\n maxReconnectAttempts: options.maxReconnectAttempts || 5,\n reconnectDelay: options.reconnectDelay || 3000,\n pingInterval: options.pingInterval || 30000,\n });\n\n // Attach notification manager to store for access in components\n store.notificationManager = notificationManager;\n\n // Don't auto-initialize on server\n const isServer = typeof window === 'undefined';\n const autoInit = !isServer && options.autoInit !== false;\n\n if (autoInit) {\n // Initialize after auth is confirmed\n const isAuthenticated = store.auth.state.access.status;\n const userId = store.auth.state.user?._id;\n\n if (isAuthenticated && userId) {\n notificationManager.initialize();\n }\n\n // Watch for user login/logout using auth store\n watch(\n () => store.auth.state.access.status,\n isAuthenticated => {\n if (isAuthenticated) {\n notificationManager.initialize();\n } else {\n notificationManager.disconnect();\n store.notifications.mutations.resetNotifications();\n }\n }\n );\n }\n\n // Provide composable for components to access notification functionality\n app.provide('useNotifications', () => {\n return {\n ...toRefs(store.notifications.state),\n ...store.notifications.actions,\n ...store.notifications.mutations,\n init: notificationManager.initialize.bind(notificationManager),\n disconnect: notificationManager.disconnect.bind(notificationManager),\n isServer,\n };\n });\n\n return notificationManager;\n}\n\n// Module export\nconst ModuleNotifications = {\n initialize: initializeNotifications,\n SSR: SSRUtils, // Export SSR utilities\n views: {\n store: {\n storeNotifications,\n },\n router: {\n routerNotifications,\n },\n components: {\n // Elements\n NotificationBadge,\n // Blocks\n NotificationItem,\n // Sections\n NotificationsList,\n NotificationPreferences,\n // Pages\n Notifications,\n // Layouts\n NotificationsLayout,\n },\n },\n};\n\n// Component exports\nexport {\n // Elements\n NotificationBadge,\n // Blocks\n NotificationItem,\n NotificationPreferences,\n // Pages\n Notifications,\n // Layouts\n NotificationsLayout,\n // Sections\n NotificationsList,\n // SSR Utilities\n SSRUtils,\n};\n\nexport default ModuleNotifications;\n"],"names":["globalWebSocket","routerNotifications","storeNotifications","watch","isAuthenticated","toRefs","NotificationBadge","NotificationItem","NotificationsList","NotificationPreferences","Notifications","NotificationsLayout"],"mappings":"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"}
1
+ {"version":3,"file":"notifications.client.cjs","sources":["../../../../../src/modules/notifications/notifications.client.js"],"sourcesContent":["import { toRefs, watch } from 'vue';\n// Router import\nimport routerNotifications from './router/notifications.router.js';\n// Store\nimport * as storeNotifications from './store/notifications.store.js';\n// Auth store import\n// Global WebSocket import\nimport globalWebSocket from '@martyrs/src/modules/globals/views/classes/globals.websocket.js';\n// Layouts\nimport NotificationsLayout from './components/layouts/NotificationsLayout.vue';\n// Sections\nimport NotificationPreferences from './components/sections/NotificationPreferences.vue';\nimport NotificationsList from './components/sections/NotificationsList.vue';\n// Pages\nimport Notifications from './components/pages/Notifications.vue';\n// Components\nimport NotificationItem from './components/blocks/NotificationItem.vue';\nimport NotificationBadge from './components/elements/NotificationBadge.vue';\n\n/**\n * Capacitor Push Notification handler\n */\nclass CapacitorPushHandler {\n constructor(store) {\n this.store = store;\n this.pushNotifications = null;\n this.device = null;\n this.isInitialized = false;\n }\n\n /**\n * Initialize Capacitor plugins\n */\n async initialize() {\n // Skip if running in SSR\n if (typeof window === 'undefined') {\n return false;\n }\n\n try {\n // Dynamic imports to prevent errors in web environment\n const { Capacitor } = await import('@capacitor/core');\n const { PushNotifications } = await import('@capacitor/push-notifications');\n const { Device } = await import('@capacitor/device');\n\n this.capacitor = Capacitor;\n this.pushNotifications = PushNotifications;\n this.device = Device;\n\n // Only proceed if running on a native platform\n if (!this.capacitor.isNativePlatform()) {\n return false;\n }\n\n this.isInitialized = true;\n return true;\n } catch (error) {\n console.error('Error importing Capacitor plugins:', error);\n return false;\n }\n }\n\n /**\n * Request permission and register for push notifications\n */\n async requestPermissions() {\n // Skip if running in SSR\n if (typeof window === 'undefined') {\n return false;\n }\n\n if (!this.isInitialized) {\n const initialized = await this.initialize();\n if (!initialized) return false;\n }\n\n try {\n // Request permission\n const permissionResult = await this.pushNotifications.requestPermissions();\n if (permissionResult.receive !== 'granted') {\n console.log('Push notification permission denied');\n return false;\n }\n\n // Set up event listeners\n this._setupListeners();\n\n // Register with Apple/Google\n await this.pushNotifications.register();\n return true;\n } catch (error) {\n console.error('Error requesting push notification permissions:', error);\n return false;\n }\n }\n\n /**\n * Setup push notification event listeners\n */\n _setupListeners() {\n // Registration event\n this.pushNotifications.addListener('registration', this._handleRegistration.bind(this));\n\n // Notification received event\n this.pushNotifications.addListener('pushNotificationReceived', this._handleNotificationReceived.bind(this));\n\n // Notification action performed event\n this.pushNotifications.addListener('pushNotificationActionPerformed', this._handleNotificationAction.bind(this));\n }\n\n /**\n * Handle registration token received\n */\n async _handleRegistration(token) {\n try {\n // Get device info\n const deviceInfo = await this.device.getInfo();\n const deviceId = await this.device.getId();\n\n // Prepare device data\n const deviceData = {\n deviceId: deviceId.uuid,\n deviceType: deviceInfo.platform.toLowerCase(),\n deviceToken: token.value,\n };\n\n // Register device with backend\n await this.store.notifications.actions.registerDevice(deviceData);\n } catch (error) {\n console.error('Error handling push registration:', error);\n }\n }\n\n /**\n * Handle received notification\n */\n _handleNotificationReceived(notification) {\n // Add notification to store\n this.store.notifications.actions.addLocalNotification({\n title: notification.title,\n body: notification.body,\n data: notification.data || {},\n });\n }\n\n /**\n * Handle notification action (when user taps on notification)\n */\n _handleNotificationAction(actionData) {\n if (actionData.notification && actionData.notification.data) {\n this.store.notifications.actions.handleNotificationAction(actionData.notification.data);\n }\n }\n\n /**\n * Remove push notification listeners\n */\n removeListeners() {\n if (typeof window === 'undefined') {\n return;\n }\n\n if (this.pushNotifications) {\n this.pushNotifications.removeAllListeners();\n }\n }\n}\n\n/**\n * Notification Manager for coordinating WebSocket and Push notifications\n */\n\nclass NotificationManager {\n constructor(store, options = {}) {\n this.store = store;\n this.options = options;\n this.pushHandler = new CapacitorPushHandler(store);\n this.initialized = false;\n this.isServer = typeof window === 'undefined';\n }\n\n async registerWebPush(store) {\n if (!('Notification' in window) || !('serviceWorker' in navigator) || !('PushManager' in window)) {\n console.warn('Web Push не поддерживается в браузере');\n return;\n }\n\n const permission = await Notification.requestPermission();\n if (permission !== 'granted') {\n console.warn('Разрешение на уведомления не получено');\n return;\n }\n\n const registration = await navigator.serviceWorker.ready;\n const subscription = await registration.pushManager.subscribe({\n userVisibleOnly: true,\n applicationServerKey: 'BJtNnRrx05VQS0abnkHC-8gHJWpnmoqC_iQveENCmZOZIs-adWzqAiqFCdGVVd7CbiaLW-Q5iuIBDRgM9G-VnKg',\n });\n\n console.log('New subscription:', JSON.stringify(subscription));\n\n // Отправь подписку на сервер\n await store.notifications.actions.registerDevice({\n deviceToken: JSON.stringify(subscription),\n deviceType: 'web',\n });\n }\n\n async initialize() {\n if (this.initialized || this.isServer) return;\n\n const userId = this.store.auth.state.user?._id;\n if (!userId) {\n console.warn('Cannot initialize notifications: No user ID found in auth store');\n return;\n }\n\n console.log('Connecting to websockets via notifications');\n await globalWebSocket.connect(userId);\n\n globalWebSocket.removeModuleListeners('notification');\n\n await globalWebSocket.subscribeModule('notification');\n\n globalWebSocket.addEventListener(\n 'notification',\n data => {\n this.store.notifications.actions.addLocalNotification(data.data);\n },\n { module: 'notification' }\n );\n\n // 🎯 Опционально включаем push\n if (this.options.enablePush !== false) {\n await this.pushHandler.requestPermissions();\n await this.registerWebPush(this.store);\n }\n\n this.initialized = true;\n\n // ✅ Загружаем список уведомлений из API\n await this.store.notifications.actions.getNotifications(userId);\n }\n\n disconnect() {\n if (this.isServer) return;\n\n globalWebSocket.removeModuleListeners('notification');\n this.pushHandler.removeListeners();\n this.initialized = false;\n }\n}\n\n/**\n * Server-side utility for pre-fetching notification data\n */\nconst SSRUtils = {\n /**\n * Pre-fetch notifications for SSR\n * @param {Object} store - Store instance\n * @param {Object} context - SSR context\n */\n async prefetchNotifications(store, context) {\n try {\n const userId = store.auth.state.user?._id;\n if (userId) {\n // Fetch notifications without WebSocket or push setup\n await store.notifications.actions.getNotifications(userId);\n }\n } catch (error) {\n console.error('Error pre-fetching notifications for SSR:', error);\n }\n },\n};\n\n/**\n * Function to initialize the notifications module\n * @param {Object} app - Vue app instance\n * @param {Object} store - Vuex/Pinia store\n * @param {Object} router - Vue Router instance\n * @param {Object} options - Configuration options\n */\nfunction initializeNotifications(app, store, router, options = {}) {\n // Add routes and store\n const route = options.route || 'User Profile Root';\n router.addRoute(route, routerNotifications);\n store.addStore('notifications', storeNotifications);\n\n // Initialize global WebSocket if needed\n if (options.wsUrl) {\n globalWebSocket.initialize({ wsUrl: options.wsUrl });\n }\n\n // Create notification manager\n const notificationManager = new NotificationManager(store, {\n enablePush: options.enablePush !== false,\n maxReconnectAttempts: options.maxReconnectAttempts || 5,\n reconnectDelay: options.reconnectDelay || 3000,\n pingInterval: options.pingInterval || 30000,\n });\n\n // Attach notification manager to store for access in components\n store.notificationManager = notificationManager;\n\n // Don't auto-initialize on server\n const isServer = typeof window === 'undefined';\n const autoInit = !isServer && options.autoInit !== false;\n\n if (autoInit) {\n // Initialize after auth is confirmed\n const isAuthenticated = store.auth.state.access.status;\n const userId = store.auth.state.user?._id;\n\n if (isAuthenticated && userId) {\n notificationManager.initialize();\n }\n\n // Watch for user login/logout using auth store\n watch(\n () => store.auth.state.access.status,\n isAuthenticated => {\n if (isAuthenticated) {\n notificationManager.initialize();\n } else {\n notificationManager.disconnect();\n store.notifications.mutations.resetNotifications();\n }\n }\n );\n }\n\n // Provide composable for components to access notification functionality\n app.provide('useNotifications', () => {\n return {\n ...toRefs(store.notifications.state),\n ...store.notifications.actions,\n ...store.notifications.mutations,\n init: notificationManager.initialize.bind(notificationManager),\n disconnect: notificationManager.disconnect.bind(notificationManager),\n isServer,\n };\n });\n\n return notificationManager;\n}\n\n// Module export\nconst ModuleNotifications = {\n initialize: initializeNotifications,\n SSR: SSRUtils, // Export SSR utilities\n views: {\n store: {\n storeNotifications,\n },\n router: {\n routerNotifications,\n },\n components: {\n // Elements\n NotificationBadge,\n // Blocks\n NotificationItem,\n // Sections\n NotificationsList,\n NotificationPreferences,\n // Pages\n Notifications,\n // Layouts\n NotificationsLayout,\n },\n },\n};\n\n// Component exports\nexport {\n // Elements\n NotificationBadge,\n // Blocks\n NotificationItem,\n NotificationPreferences,\n // Pages\n Notifications,\n // Layouts\n NotificationsLayout,\n // Sections\n NotificationsList,\n // SSR Utilities\n SSRUtils,\n};\n\nexport default ModuleNotifications;\n"],"names":["globalWebSocket","routerNotifications","storeNotifications","watch","isAuthenticated","toRefs","NotificationBadge","NotificationItem","NotificationsList","NotificationPreferences","Notifications","NotificationsLayout"],"mappings":"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"}
@@ -2,10 +2,10 @@ import { watch, toRefs } from "vue";
2
2
  import nofitications from "./router/notifications.router.js";
3
3
  import * as notifications_store from "./store/notifications.store.js";
4
4
  import globalWebSocket from "../globals/views/classes/globals.websocket.js";
5
- import NotificationsLayout from "./components/layouts/NotificationsLayout.vue.js";
5
+ import _sfc_main from "./components/layouts/NotificationsLayout.vue.js";
6
6
  import NotificationPreferences from "./components/sections/NotificationPreferences.vue.js";
7
7
  import NotificationsList from "./components/sections/NotificationsList.vue.js";
8
- import Notifications from "./components/pages/Notifications.vue.js";
8
+ import _sfc_main$1 from "./components/pages/Notifications.vue.js";
9
9
  import NotificationItem from "./components/blocks/NotificationItem.vue.js";
10
10
  import NotificationBadge from "./components/elements/NotificationBadge.vue.js";
11
11
  class CapacitorPushHandler {
@@ -137,7 +137,7 @@ class NotificationManager {
137
137
  console.warn("Разрешение на уведомления не получено");
138
138
  return;
139
139
  }
140
- const registration = await navigator.serviceWorker.register("/sw.js");
140
+ const registration = await navigator.serviceWorker.ready;
141
141
  const subscription = await registration.pushManager.subscribe({
142
142
  userVisibleOnly: true,
143
143
  applicationServerKey: "BJtNnRrx05VQS0abnkHC-8gHJWpnmoqC_iQveENCmZOZIs-adWzqAiqFCdGVVd7CbiaLW-Q5iuIBDRgM9G-VnKg"
@@ -266,9 +266,9 @@ const ModuleNotifications = {
266
266
  NotificationsList,
267
267
  NotificationPreferences,
268
268
  // Pages
269
- Notifications,
269
+ Notifications: _sfc_main$1,
270
270
  // Layouts
271
- NotificationsLayout
271
+ NotificationsLayout: _sfc_main
272
272
  }
273
273
  }
274
274
  };
@@ -276,8 +276,8 @@ export {
276
276
  NotificationBadge,
277
277
  NotificationItem,
278
278
  NotificationPreferences,
279
- Notifications,
280
- NotificationsLayout,
279
+ _sfc_main$1 as Notifications,
280
+ _sfc_main as NotificationsLayout,
281
281
  NotificationsList,
282
282
  SSRUtils,
283
283
  ModuleNotifications as default