@ozdao/martyrs 0.2.581 → 0.2.582

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 (112) hide show
  1. package/dist/martyrs/src/components/Button/Button.vue.js +1 -1
  2. package/dist/martyrs/src/components/Feed/Carousel.vue.js +1 -1
  3. package/dist/martyrs/src/components/Feed/Feed.vue.js +1 -1
  4. package/dist/martyrs/src/components/Loader/{Loader.vue2.js → Loader.vue.js} +2 -2
  5. package/dist/martyrs/src/components/Loader/Loader.vue.js.map +1 -0
  6. package/dist/martyrs/src/components/LocationMarker/LocationMarker.vue.js +1 -1
  7. package/dist/martyrs/src/components/Media/Media.vue.js +1 -1
  8. package/dist/martyrs/src/components/Menu/{Menu.vue2.js → Menu.vue.js} +2 -2
  9. package/dist/martyrs/src/components/Menu/Menu.vue.js.map +1 -0
  10. package/dist/martyrs/src/components/SelectMulti/{SelectMulti.vue.js → SelectMulti.vue2.js} +2 -2
  11. package/dist/martyrs/src/components/SelectMulti/SelectMulti.vue2.js.map +1 -0
  12. package/dist/martyrs/src/components/Spoiler/{Spoiler.vue2.js → Spoiler.vue.js} +2 -2
  13. package/dist/martyrs/src/components/Spoiler/Spoiler.vue.js.map +1 -0
  14. package/dist/martyrs/src/components/Tab/{Tab.vue2.js → Tab.vue.js} +2 -2
  15. package/dist/martyrs/src/components/Tab/Tab.vue.js.map +1 -0
  16. package/dist/martyrs/src/components/UploadImage/UploadImage.vue.js +1 -1
  17. package/dist/martyrs/src/components/UploadImageMultiple/UploadImageMultiple.vue.js +1 -1
  18. package/dist/martyrs/src/modules/auth/views/components/pages/EnterPassword.vue.js +1 -1
  19. package/dist/martyrs/src/modules/auth/views/components/pages/Invite.vue.js +1 -1
  20. package/dist/martyrs/src/modules/auth/views/components/pages/Profile.vue.js +2 -2
  21. package/dist/martyrs/src/modules/auth/views/components/pages/ProfileBlogposts.vue.js +1 -1
  22. package/dist/martyrs/src/modules/auth/views/components/pages/ProfileEdit.vue.js +2 -2
  23. package/dist/martyrs/src/modules/auth/views/components/pages/ProfileEdit.vue.js.map +1 -1
  24. package/dist/martyrs/src/modules/auth/views/components/pages/ResetPassword.vue.js +1 -1
  25. package/dist/martyrs/src/modules/auth/views/components/pages/SignIn.vue.js +1 -1
  26. package/dist/martyrs/src/modules/auth/views/components/pages/SignUp.vue.js +1 -1
  27. package/dist/martyrs/src/modules/auth/views/configs/navigation.user.config.js +2 -3
  28. package/dist/martyrs/src/modules/auth/views/configs/navigation.user.config.js.map +1 -1
  29. package/dist/martyrs/src/modules/auth/views/router/users.router.js +1 -2
  30. package/dist/martyrs/src/modules/auth/views/router/users.router.js.map +1 -1
  31. package/dist/martyrs/src/modules/backoffice/components/partials/Sidebar.vue.js +1 -1
  32. package/dist/martyrs/src/modules/community/components/pages/BlogPost.vue.js +1 -1
  33. package/dist/martyrs/src/modules/core/views/classes/ws.manager.js +16 -1
  34. package/dist/martyrs/src/modules/core/views/classes/ws.manager.js.map +1 -1
  35. package/dist/martyrs/src/modules/core/views/components/blocks/CardHeader.vue.js +1 -1
  36. package/dist/martyrs/src/modules/core/views/components/blocks/PopupDateSelector.vue.js +1 -1
  37. package/dist/martyrs/src/modules/core/views/components/layouts/Client.vue.js +1 -1
  38. package/dist/martyrs/src/modules/core/views/components/partials/Navigation.vue.js +1 -1
  39. package/dist/martyrs/src/modules/core/views/components/sections/SectionPageTitle.vue.js +1 -1
  40. package/dist/martyrs/src/modules/core/views/utils/vue-app-renderer.js +7 -0
  41. package/dist/martyrs/src/modules/core/views/utils/vue-app-renderer.js.map +1 -1
  42. package/dist/martyrs/src/modules/events/components/pages/EditEvent.vue.js +2 -2
  43. package/dist/martyrs/src/modules/events/components/pages/Event.vue.js +1 -1
  44. package/dist/martyrs/src/modules/events/components/pages/EventsBackoffice.vue.js +1 -1
  45. package/dist/martyrs/src/modules/events/components/sections/Feed.vue.js +1 -1
  46. package/dist/martyrs/src/modules/events/components/sections/List.vue.js +1 -1
  47. package/dist/martyrs/src/modules/gallery/components/sections/BackofficeGallery.vue.js +1 -1
  48. package/dist/martyrs/src/modules/landing/components/sections/SectionGuide.vue.js +1 -1
  49. package/dist/martyrs/src/modules/marketplace/views/components/sections/SectionMenu.vue.js +1 -1
  50. package/dist/martyrs/src/modules/music/components/forms/ArtistForm.vue.js +1 -1
  51. package/dist/martyrs/src/modules/music/components/pages/Album.vue.js +1 -1
  52. package/dist/martyrs/src/modules/music/components/pages/Artist.vue.js +1 -1
  53. package/dist/martyrs/src/modules/music/components/pages/Playlist.vue.js +1 -1
  54. package/dist/martyrs/src/modules/music/components/pages/SearchResults.vue.js +1 -1
  55. package/dist/martyrs/src/modules/music/components/pages/Track.vue.js +1 -1
  56. package/dist/martyrs/src/modules/music/components/pages/TrackCreate.vue.js +1 -1
  57. package/dist/martyrs/src/modules/notifications/components/layouts/NotificationsLayout.vue.js +11 -40
  58. package/dist/martyrs/src/modules/notifications/components/layouts/NotificationsLayout.vue.js.map +1 -1
  59. package/dist/martyrs/src/modules/notifications/components/pages/Notifications.vue.js +26 -21
  60. package/dist/martyrs/src/modules/notifications/components/pages/Notifications.vue.js.map +1 -1
  61. package/dist/martyrs/src/modules/notifications/components/sections/NotificationPreferences.vue.js +54 -48
  62. package/dist/martyrs/src/modules/notifications/components/sections/NotificationPreferences.vue.js.map +1 -1
  63. package/dist/martyrs/src/modules/notifications/components/sections/NotificationsList.vue.js +37 -117
  64. package/dist/martyrs/src/modules/notifications/components/sections/NotificationsList.vue.js.map +1 -1
  65. package/dist/martyrs/src/modules/notifications/notifications.client.js +18 -15
  66. package/dist/martyrs/src/modules/notifications/notifications.client.js.map +1 -1
  67. package/dist/martyrs/src/modules/orders/components/forms/FormSelectCustomer.vue.js +1 -1
  68. package/dist/martyrs/src/modules/orders/components/pages/OrderCreateBackoffice.vue.js +1 -1
  69. package/dist/martyrs/src/modules/orders/components/pages/Orders.vue.js +1 -1
  70. package/dist/martyrs/src/modules/orders/components/sections/FormDelivery.vue.js +1 -1
  71. package/dist/martyrs/src/modules/organizations/components/blocks/CardDepartment.vue.js +1 -1
  72. package/dist/martyrs/src/modules/organizations/components/forms/DepartmentForm.vue.js +1 -1
  73. package/dist/martyrs/src/modules/organizations/components/pages/Department.vue.js +1 -1
  74. package/dist/martyrs/src/modules/organizations/components/pages/Organization.vue.js +1 -1
  75. package/dist/martyrs/src/modules/organizations/components/pages/OrganizationBackoffice.vue.js +2 -2
  76. package/dist/martyrs/src/modules/organizations/components/pages/OrganizationEdit.vue.js +2 -2
  77. package/dist/martyrs/src/modules/organizations/components/pages/Organizations.vue.js +1 -1
  78. package/dist/martyrs/src/modules/organizations/components/sections/Documents.vue.js +1 -1
  79. package/dist/martyrs/src/modules/organizations/components/sections/Organizations.vue.js +2 -2
  80. package/dist/martyrs/src/modules/pages/views/components/blocks/CardPage.vue.js +1 -1
  81. package/dist/martyrs/src/modules/products/components/elements/Image360.vue.js +1 -1
  82. package/dist/martyrs/src/modules/products/components/pages/Categories.vue.js +1 -1
  83. package/dist/martyrs/src/modules/products/components/pages/CategoryEdit.vue.js +1 -1
  84. package/dist/martyrs/src/modules/products/components/pages/Product.vue.js +2 -2
  85. package/dist/martyrs/src/modules/products/components/pages/ProductEdit.vue.js +2 -2
  86. package/dist/martyrs/src/modules/products/components/pages/Products.vue.js +2 -2
  87. package/dist/martyrs/src/modules/products/components/sections/FilterProducts.vue.js +1 -1
  88. package/dist/martyrs/src/modules/products/components/sections/SectionProduct.vue.js +1 -1
  89. package/dist/martyrs/src/modules/rents/views/components/pages/Gant/GanttToolbar.vue.js +1 -1
  90. package/dist/martyrs/src/modules/rents/views/components/pages/Rents.vue.js +1 -1
  91. package/dist/martyrs/src/modules/spots/components/layouts/Spots.vue.js +1 -1
  92. package/dist/martyrs/src/modules/spots/components/pages/Spot.vue.js +1 -1
  93. package/dist/martyrs/src/modules/spots/components/pages/SpotEdit.vue.js +1 -1
  94. package/dist/style.css +1 -188
  95. package/package.json +1 -1
  96. package/src/modules/auth/views/components/pages/ProfileEdit.vue +1 -1
  97. package/src/modules/auth/views/configs/navigation.user.config.js +10 -10
  98. package/src/modules/auth/views/router/users.router.js +0 -1
  99. package/src/modules/core/views/classes/ws.manager.js +20 -1
  100. package/src/modules/core/views/utils/vue-app-renderer.js +9 -3
  101. package/src/modules/notifications/components/layouts/NotificationsLayout.vue +9 -53
  102. package/src/modules/notifications/components/pages/Notifications.vue +21 -22
  103. package/src/modules/notifications/components/sections/NotificationPreferences.vue +41 -180
  104. package/src/modules/notifications/components/sections/NotificationsList.vue +39 -219
  105. package/src/modules/notifications/notifications.client.js +17 -16
  106. package/dist/martyrs/src/components/Loader/Loader.vue2.js.map +0 -1
  107. package/dist/martyrs/src/components/Menu/Menu.vue2.js.map +0 -1
  108. package/dist/martyrs/src/components/SelectMulti/SelectMulti.vue.js.map +0 -1
  109. package/dist/martyrs/src/components/Spoiler/Spoiler.vue2.js.map +0 -1
  110. package/dist/martyrs/src/components/Tab/Tab.vue2.js.map +0 -1
  111. package/dist/martyrs/src/modules/auth/views/components/blocks/ProfileCard.vue.js +0 -44
  112. package/dist/martyrs/src/modules/auth/views/components/blocks/ProfileCard.vue.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"ws.manager.js","sources":["../../../../../../../src/modules/core/views/classes/ws.manager.js"],"sourcesContent":["class WebSocketManager {\n constructor() {\n this.socket = null;\n this.isConnected = false;\n this.reconnectAttempts = 0;\n this.maxReconnectAttempts = 5;\n this.reconnectDelay = 3000;\n this.baseUrl = null;\n this.pingInterval = null;\n this.pingIntervalTime = 30000;\n this.listeners = {};\n this.userId = null;\n this.connectPromise = null;\n this.subscribedModules = new Set();\n\n // RPC-специфичные свойства\n this.rpcCallbacks = new Map();\n this.rpcTimeout = 30000; // 30 секунд таймаут по умолчанию\n this.rpcIdCounter = 0;\n }\n\n initialize(options = {}) {\n this.maxReconnectAttempts = options.maxReconnectAttempts || this.maxReconnectAttempts;\n this.reconnectDelay = options.reconnectDelay || this.reconnectDelay;\n this.baseUrl = options.wsUrl || this._getDefaultWsUrl();\n this.pingIntervalTime = options.pingInterval || this.pingIntervalTime;\n this.rpcTimeout = options.rpcTimeout || this.rpcTimeout;\n }\n\n _getDefaultWsUrl() {\n if (typeof window === 'undefined') return '/api/ws';\n \n const isSecure = window.location.protocol === 'https:';\n const protocol = isSecure ? 'wss:' : 'ws:';\n const host = window.location.hostname;\n const port = isSecure ? '' : ':8020';\n\n return `${protocol}//${host}${port}/api/ws`;\n }\n\n connect(userId = null) {\n if (typeof window === 'undefined') return Promise.resolve(false);\n this.userId = userId;\n\n // Проверяем существующее соединение\n if (this.isConnected && this.socket?.readyState === WebSocket.OPEN) {\n // If already connected but userId changed, need to reconnect\n if (this.userId !== userId) {\n console.log('[WebSocket] UserId changed, reconnecting...');\n return this.reconnectWithAuth(userId);\n }\n return Promise.resolve(this.socket);\n }\n\n // Предотвращаем создание множества промисов при параллельных вызовах\n if (this.connectPromise) {\n return this.connectPromise;\n }\n\n this.connectPromise = new Promise((resolve, reject) => {\n this.disconnect();\n\n // Используем baseUrl без параметров, так как аутентификация через cookie\n console.log('[WebSocket] Connecting to:', this.baseUrl, 'userId:', userId);\n this.socket = new WebSocket(this.baseUrl);\n\n this.socket.onopen = () => {\n this._handleOpen();\n resolve(this.socket);\n };\n\n this.socket.onmessage = this._handleMessage.bind(this);\n this.socket.onerror = err => {\n this._handleError(err);\n reject(err);\n };\n this.socket.onclose = this._handleClose.bind(this);\n\n setTimeout(() => {\n if (!this.isConnected) {\n reject(new Error('WebSocket connection timeout'));\n }\n }, 10000);\n }).finally(() => {\n this.connectPromise = null;\n });\n\n return this.connectPromise;\n }\n\n disconnect() {\n if (typeof window === 'undefined') return;\n\n if (this.socket) {\n this.socket.onopen = null;\n this.socket.onmessage = null;\n this.socket.onerror = null;\n this.socket.onclose = null;\n if (this.socket.readyState === WebSocket.OPEN || this.socket.readyState === WebSocket.CONNECTING) {\n this.socket.close();\n }\n this.socket = null;\n }\n\n if (this.pingInterval) {\n clearInterval(this.pingInterval);\n this.pingInterval = null;\n }\n\n // Отменяем все ожидающие RPC вызовы\n for (const [id, { reject }] of this.rpcCallbacks.entries()) {\n reject(new Error('WebSocket disconnected'));\n this.rpcCallbacks.delete(id);\n }\n\n this.isConnected = false;\n this.userId = null;\n this.subscribedModules.clear(); // Очищаем подписки при отключении\n }\n\n async send(data) {\n if (!this.socket || this.socket.readyState !== WebSocket.OPEN) {\n console.error('Cannot send message: WebSocket is not connected');\n return false;\n }\n\n try {\n const msg = typeof data === 'string' ? data : JSON.stringify(data);\n this.socket.send(msg);\n return true;\n } catch (err) {\n console.error('Error sending message:', err);\n return false;\n }\n }\n\n /**\n * Выполняет RPC вызов на сервере\n * @param {string} module - Имя модуля\n * @param {string} method - Имя метода\n * @param {object} params - Параметры метода\n * @param {object} [options] - Опции вызова\n * @param {number} [options.timeout] - Таймаут в миллисекундах\n * @returns {Promise<any>} - Результат вызова\n */\n rpc(module, method, params = {}, options = {}) {\n if (!this.isConnected || this.socket?.readyState !== WebSocket.OPEN) {\n return Promise.reject(new Error('WebSocket is not connected'));\n }\n\n if (!module || !method) {\n return Promise.reject(new Error('Module and method are required'));\n }\n\n // Генерируем уникальный ID для вызова\n const id = `${++this.rpcIdCounter}`;\n const timeout = options.timeout || this.rpcTimeout;\n\n return new Promise((resolve, reject) => {\n // Записываем информацию о вызове для последующей обработки ответа\n this.rpcCallbacks.set(id, {\n resolve,\n reject,\n timeoutId: setTimeout(() => {\n if (this.rpcCallbacks.has(id)) {\n this.rpcCallbacks.delete(id);\n reject(new Error(`RPC call to ${module}.${method} timed out after ${timeout}ms`));\n }\n }, timeout),\n });\n\n // Отправляем RPC запрос\n this.send({\n type: 'rpc',\n module,\n method,\n params,\n id,\n }).catch(err => {\n if (this.rpcCallbacks.has(id)) {\n clearTimeout(this.rpcCallbacks.get(id).timeoutId);\n this.rpcCallbacks.delete(id);\n reject(err);\n }\n });\n });\n }\n\n addEventListener(eventType, callback, options = {}) {\n const listenerId = `${options.module || 'global'}_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;\n if (!this.listeners[eventType]) this.listeners[eventType] = {};\n this.listeners[eventType][listenerId] = callback;\n return listenerId;\n }\n\n removeEventListener(eventType, listenerId) {\n if (this.listeners[eventType]?.[listenerId]) {\n delete this.listeners[eventType][listenerId];\n }\n }\n\n removeModuleListeners(moduleName) {\n Object.keys(this.listeners).forEach(eventType => {\n Object.keys(this.listeners[eventType]).forEach(listenerId => {\n if (listenerId.startsWith(`${moduleName}_`)) {\n delete this.listeners[eventType][listenerId];\n }\n });\n });\n }\n\n async subscribeModule(moduleName) {\n if (!moduleName) return;\n \n if (this.subscribedModules.has(moduleName)) {\n console.log(`[WebSocket] Module ${moduleName} already subscribed`);\n return;\n }\n \n console.log(`[WebSocket] Subscribing to module: ${moduleName}`);\n const success = await this.send({ type: 'subscribe', module: moduleName });\n if (success) {\n this.subscribedModules.add(moduleName);\n console.log(`[WebSocket] Successfully subscribed to module: ${moduleName}`);\n } else {\n console.log(`[WebSocket] Failed to subscribe to module: ${moduleName}`);\n }\n }\n\n async unsubscribeModule(moduleName) {\n if (!moduleName || !this.subscribedModules.has(moduleName)) return;\n const success = await this.send({ type: 'unsubscribe', module: moduleName });\n if (success) {\n this.subscribedModules.delete(moduleName);\n }\n }\n\n _resubscribeAllModules() {\n for (const moduleName of this.subscribedModules) {\n this.send({ type: 'subscribe', module: moduleName });\n }\n }\n\n _handleOpen() {\n this.isConnected = true;\n this.reconnectAttempts = 0;\n\n this.pingInterval = setInterval(() => {\n if (this.socket?.readyState === WebSocket.OPEN) {\n this.socket.send(JSON.stringify({ type: 'ping' }));\n }\n }, this.pingIntervalTime);\n\n this._resubscribeAllModules();\n this._notifyListeners('open', { isConnected: true });\n }\n\n _handleMessage(event) {\n // Проверка на типы сообщений - пропускаем бинарные сообщения\n if (typeof event.data !== 'string') {\n console.warn('Received binary message, but only JSON is supported');\n return;\n }\n\n try {\n const data = JSON.parse(event.data);\n\n // Обрабатываем ответы на RPC вызовы\n if (data.type === 'rpc_response' && data.id && this.rpcCallbacks.has(data.id)) {\n const { resolve, reject, timeoutId } = this.rpcCallbacks.get(data.id);\n clearTimeout(timeoutId);\n this.rpcCallbacks.delete(data.id);\n\n if (data.error) {\n reject(Object.assign(new Error(data.error.message), data.error));\n } else {\n resolve(data.result);\n }\n\n return;\n }\n\n // Обрабатываем обычные сообщения\n this._notifyListeners('message', data);\n if (data.type) {\n this._notifyListeners(data.type, data);\n }\n } catch (err) {\n console.error('WebSocket message error:', err);\n }\n }\n\n _handleError(error) {\n console.error('WebSocket error:', error);\n this._notifyListeners('error', { error });\n\n // Отменяем все RPC вызовы с ошибкой соединения\n for (const [id, { reject, timeoutId }] of this.rpcCallbacks.entries()) {\n clearTimeout(timeoutId);\n reject(new Error('WebSocket connection error'));\n this.rpcCallbacks.delete(id);\n }\n }\n\n _handleClose(event) {\n this.isConnected = false;\n if (this.pingInterval) {\n clearInterval(this.pingInterval);\n this.pingInterval = null;\n }\n\n // Отменяем все RPC вызовы при закрытии соединения\n for (const [id, { reject, timeoutId }] of this.rpcCallbacks.entries()) {\n clearTimeout(timeoutId);\n reject(new Error('WebSocket connection closed'));\n this.rpcCallbacks.delete(id);\n }\n\n this._notifyListeners('close', { code: event.code, reason: event.reason });\n\n // Reconnect for both authenticated and anonymous users (not just authenticated)\n if (event.code !== 1000 && this.reconnectAttempts < this.maxReconnectAttempts) {\n this.reconnectAttempts++;\n const delay = this.reconnectDelay * this.reconnectAttempts;\n console.log(`[WebSocket] Reconnecting in ${delay}ms... (attempt ${this.reconnectAttempts}/${this.maxReconnectAttempts})`);\n setTimeout(() => {\n this.connect(this.userId).catch(err => {\n console.error('Reconnection failed:', err);\n });\n }, delay);\n }\n }\n\n _notifyListeners(eventType, data) {\n Object.values(this.listeners[eventType] || {}).forEach(fn => {\n try {\n fn(data);\n } catch (err) {\n console.error(`Listener for ${eventType} failed:`, err);\n }\n });\n }\n\n isSocketConnected() {\n return this.isConnected && this.socket?.readyState === WebSocket.OPEN;\n }\n\n /**\n * Reconnect WebSocket with new authentication\n * Useful when user logs in/out\n * @param {string} userId - New user ID (optional)\n * @returns {Promise<WebSocket|boolean>}\n */\n async reconnectWithAuth(userId) {\n console.log('[WebSocket] Reconnecting with auth, userId:', userId);\n \n // Disconnect existing connection\n this.disconnect();\n \n // Small delay to ensure clean disconnect\n await new Promise(resolve => setTimeout(resolve, 100));\n \n // Connect with new userId (or null for anonymous)\n return this.connect(userId);\n }\n}\n\nconst wsManager = new WebSocketManager();\nexport { wsManager };\nexport default wsManager;\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ws.manager.js","sources":["../../../../../../../src/modules/core/views/classes/ws.manager.js"],"sourcesContent":["import { reactive } from 'vue';\n\nclass WebSocketManager {\n constructor() {\n this.socket = null;\n this.reconnectAttempts = 0;\n this.maxReconnectAttempts = 5;\n this.reconnectDelay = 3000;\n this.baseUrl = null;\n this.pingInterval = null;\n this.pingIntervalTime = 30000;\n this.listeners = {};\n this.userId = null;\n this.connectPromise = null;\n this.subscribedModules = new Set();\n\n // RPC-специфичные свойства\n this.rpcCallbacks = new Map();\n this.rpcTimeout = 30000; // 30 секунд таймаут по умолчанию\n this.rpcIdCounter = 0;\n\n // Реактивное состояние\n this.state = reactive({\n isConnected: false,\n wasConnected: false, // был ли когда-либо подключен\n });\n }\n\n // Геттер для обратной совместимости\n get isConnected() {\n return this.state.isConnected;\n }\n\n set isConnected(value) {\n this.state.isConnected = value;\n if (value) {\n this.state.wasConnected = true;\n }\n }\n\n initialize(options = {}) {\n this.maxReconnectAttempts = options.maxReconnectAttempts || this.maxReconnectAttempts;\n this.reconnectDelay = options.reconnectDelay || this.reconnectDelay;\n this.baseUrl = options.wsUrl || this._getDefaultWsUrl();\n this.pingIntervalTime = options.pingInterval || this.pingIntervalTime;\n this.rpcTimeout = options.rpcTimeout || this.rpcTimeout;\n }\n\n _getDefaultWsUrl() {\n if (typeof window === 'undefined') return '/api/ws';\n \n const isSecure = window.location.protocol === 'https:';\n const protocol = isSecure ? 'wss:' : 'ws:';\n const host = window.location.hostname;\n const port = isSecure ? '' : ':8020';\n\n return `${protocol}//${host}${port}/api/ws`;\n }\n\n connect(userId = null) {\n if (typeof window === 'undefined') return Promise.resolve(false);\n this.userId = userId;\n\n // Проверяем существующее соединение\n if (this.isConnected && this.socket?.readyState === WebSocket.OPEN) {\n // If already connected but userId changed, need to reconnect\n if (this.userId !== userId) {\n console.log('[WebSocket] UserId changed, reconnecting...');\n return this.reconnectWithAuth(userId);\n }\n return Promise.resolve(this.socket);\n }\n\n // Предотвращаем создание множества промисов при параллельных вызовах\n if (this.connectPromise) {\n return this.connectPromise;\n }\n\n this.connectPromise = new Promise((resolve, reject) => {\n this.disconnect();\n\n // Используем baseUrl без параметров, так как аутентификация через cookie\n console.log('[WebSocket] Connecting to:', this.baseUrl, 'userId:', userId);\n this.socket = new WebSocket(this.baseUrl);\n\n this.socket.onopen = () => {\n this._handleOpen();\n resolve(this.socket);\n };\n\n this.socket.onmessage = this._handleMessage.bind(this);\n this.socket.onerror = err => {\n this._handleError(err);\n reject(err);\n };\n this.socket.onclose = this._handleClose.bind(this);\n\n setTimeout(() => {\n if (!this.isConnected) {\n reject(new Error('WebSocket connection timeout'));\n }\n }, 10000);\n }).finally(() => {\n this.connectPromise = null;\n });\n\n return this.connectPromise;\n }\n\n disconnect() {\n if (typeof window === 'undefined') return;\n\n if (this.socket) {\n this.socket.onopen = null;\n this.socket.onmessage = null;\n this.socket.onerror = null;\n this.socket.onclose = null;\n if (this.socket.readyState === WebSocket.OPEN || this.socket.readyState === WebSocket.CONNECTING) {\n this.socket.close();\n }\n this.socket = null;\n }\n\n if (this.pingInterval) {\n clearInterval(this.pingInterval);\n this.pingInterval = null;\n }\n\n // Отменяем все ожидающие RPC вызовы\n for (const [id, { reject }] of this.rpcCallbacks.entries()) {\n reject(new Error('WebSocket disconnected'));\n this.rpcCallbacks.delete(id);\n }\n\n this.isConnected = false;\n this.userId = null;\n this.subscribedModules.clear(); // Очищаем подписки при отключении\n }\n\n async send(data) {\n if (!this.socket || this.socket.readyState !== WebSocket.OPEN) {\n console.error('Cannot send message: WebSocket is not connected');\n return false;\n }\n\n try {\n const msg = typeof data === 'string' ? data : JSON.stringify(data);\n this.socket.send(msg);\n return true;\n } catch (err) {\n console.error('Error sending message:', err);\n return false;\n }\n }\n\n /**\n * Выполняет RPC вызов на сервере\n * @param {string} module - Имя модуля\n * @param {string} method - Имя метода\n * @param {object} params - Параметры метода\n * @param {object} [options] - Опции вызова\n * @param {number} [options.timeout] - Таймаут в миллисекундах\n * @returns {Promise<any>} - Результат вызова\n */\n rpc(module, method, params = {}, options = {}) {\n if (!this.isConnected || this.socket?.readyState !== WebSocket.OPEN) {\n return Promise.reject(new Error('WebSocket is not connected'));\n }\n\n if (!module || !method) {\n return Promise.reject(new Error('Module and method are required'));\n }\n\n // Генерируем уникальный ID для вызова\n const id = `${++this.rpcIdCounter}`;\n const timeout = options.timeout || this.rpcTimeout;\n\n return new Promise((resolve, reject) => {\n // Записываем информацию о вызове для последующей обработки ответа\n this.rpcCallbacks.set(id, {\n resolve,\n reject,\n timeoutId: setTimeout(() => {\n if (this.rpcCallbacks.has(id)) {\n this.rpcCallbacks.delete(id);\n reject(new Error(`RPC call to ${module}.${method} timed out after ${timeout}ms`));\n }\n }, timeout),\n });\n\n // Отправляем RPC запрос\n this.send({\n type: 'rpc',\n module,\n method,\n params,\n id,\n }).catch(err => {\n if (this.rpcCallbacks.has(id)) {\n clearTimeout(this.rpcCallbacks.get(id).timeoutId);\n this.rpcCallbacks.delete(id);\n reject(err);\n }\n });\n });\n }\n\n addEventListener(eventType, callback, options = {}) {\n const listenerId = `${options.module || 'global'}_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;\n if (!this.listeners[eventType]) this.listeners[eventType] = {};\n this.listeners[eventType][listenerId] = callback;\n return listenerId;\n }\n\n removeEventListener(eventType, listenerId) {\n if (this.listeners[eventType]?.[listenerId]) {\n delete this.listeners[eventType][listenerId];\n }\n }\n\n removeModuleListeners(moduleName) {\n Object.keys(this.listeners).forEach(eventType => {\n Object.keys(this.listeners[eventType]).forEach(listenerId => {\n if (listenerId.startsWith(`${moduleName}_`)) {\n delete this.listeners[eventType][listenerId];\n }\n });\n });\n }\n\n async subscribeModule(moduleName) {\n if (!moduleName) return;\n \n if (this.subscribedModules.has(moduleName)) {\n console.log(`[WebSocket] Module ${moduleName} already subscribed`);\n return;\n }\n \n console.log(`[WebSocket] Subscribing to module: ${moduleName}`);\n const success = await this.send({ type: 'subscribe', module: moduleName });\n if (success) {\n this.subscribedModules.add(moduleName);\n console.log(`[WebSocket] Successfully subscribed to module: ${moduleName}`);\n } else {\n console.log(`[WebSocket] Failed to subscribe to module: ${moduleName}`);\n }\n }\n\n async unsubscribeModule(moduleName) {\n if (!moduleName || !this.subscribedModules.has(moduleName)) return;\n const success = await this.send({ type: 'unsubscribe', module: moduleName });\n if (success) {\n this.subscribedModules.delete(moduleName);\n }\n }\n\n _resubscribeAllModules() {\n for (const moduleName of this.subscribedModules) {\n this.send({ type: 'subscribe', module: moduleName });\n }\n }\n\n _handleOpen() {\n this.isConnected = true;\n this.reconnectAttempts = 0;\n\n this.pingInterval = setInterval(() => {\n if (this.socket?.readyState === WebSocket.OPEN) {\n this.socket.send(JSON.stringify({ type: 'ping' }));\n }\n }, this.pingIntervalTime);\n\n this._resubscribeAllModules();\n this._notifyListeners('open', { isConnected: true });\n }\n\n _handleMessage(event) {\n // Проверка на типы сообщений - пропускаем бинарные сообщения\n if (typeof event.data !== 'string') {\n console.warn('Received binary message, but only JSON is supported');\n return;\n }\n\n try {\n const data = JSON.parse(event.data);\n\n // Обрабатываем ответы на RPC вызовы\n if (data.type === 'rpc_response' && data.id && this.rpcCallbacks.has(data.id)) {\n const { resolve, reject, timeoutId } = this.rpcCallbacks.get(data.id);\n clearTimeout(timeoutId);\n this.rpcCallbacks.delete(data.id);\n\n if (data.error) {\n reject(Object.assign(new Error(data.error.message), data.error));\n } else {\n resolve(data.result);\n }\n\n return;\n }\n\n // Обрабатываем обычные сообщения\n this._notifyListeners('message', data);\n if (data.type) {\n this._notifyListeners(data.type, data);\n }\n } catch (err) {\n console.error('WebSocket message error:', err);\n }\n }\n\n _handleError(error) {\n console.error('WebSocket error:', error);\n this._notifyListeners('error', { error });\n\n // Отменяем все RPC вызовы с ошибкой соединения\n for (const [id, { reject, timeoutId }] of this.rpcCallbacks.entries()) {\n clearTimeout(timeoutId);\n reject(new Error('WebSocket connection error'));\n this.rpcCallbacks.delete(id);\n }\n }\n\n _handleClose(event) {\n this.isConnected = false;\n if (this.pingInterval) {\n clearInterval(this.pingInterval);\n this.pingInterval = null;\n }\n\n // Отменяем все RPC вызовы при закрытии соединения\n for (const [id, { reject, timeoutId }] of this.rpcCallbacks.entries()) {\n clearTimeout(timeoutId);\n reject(new Error('WebSocket connection closed'));\n this.rpcCallbacks.delete(id);\n }\n\n this._notifyListeners('close', { code: event.code, reason: event.reason });\n\n // Reconnect for both authenticated and anonymous users (not just authenticated)\n if (event.code !== 1000 && this.reconnectAttempts < this.maxReconnectAttempts) {\n this.reconnectAttempts++;\n const delay = this.reconnectDelay * this.reconnectAttempts;\n console.log(`[WebSocket] Reconnecting in ${delay}ms... (attempt ${this.reconnectAttempts}/${this.maxReconnectAttempts})`);\n setTimeout(() => {\n this.connect(this.userId).catch(err => {\n console.error('Reconnection failed:', err);\n });\n }, delay);\n }\n }\n\n _notifyListeners(eventType, data) {\n Object.values(this.listeners[eventType] || {}).forEach(fn => {\n try {\n fn(data);\n } catch (err) {\n console.error(`Listener for ${eventType} failed:`, err);\n }\n });\n }\n\n isSocketConnected() {\n return this.isConnected && this.socket?.readyState === WebSocket.OPEN;\n }\n\n /**\n * Reconnect WebSocket with new authentication\n * Useful when user logs in/out\n * @param {string} userId - New user ID (optional)\n * @returns {Promise<WebSocket|boolean>}\n */\n async reconnectWithAuth(userId) {\n console.log('[WebSocket] Reconnecting with auth, userId:', userId);\n \n // Disconnect existing connection\n this.disconnect();\n \n // Small delay to ensure clean disconnect\n await new Promise(resolve => setTimeout(resolve, 100));\n \n // Connect with new userId (or null for anonymous)\n return this.connect(userId);\n }\n}\n\nconst wsManager = new WebSocketManager();\nexport { wsManager };\nexport default wsManager;\n"],"names":[],"mappings":"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"}
@@ -6,7 +6,7 @@ import PlaceholderUserpic from "../../../../icons/placeholders/PlaceholderUserpi
6
6
  import PlaceholderOrganizationPic from "../../../../icons/placeholders/PlaceholderOrganizationPic.vue.js";
7
7
  import _sfc_main$4 from "../../../../icons/navigation/IconEllipsis.vue.js";
8
8
  import _sfc_main$5 from "../../../../reports/components/sections/FormReport.vue.js";
9
- /* empty css */
9
+ /* empty css */
10
10
  /* empty css */
11
11
  import _sfc_main$2 from "../elements/PhotoStack.vue.js";
12
12
  const _hoisted_1 = {
@@ -1,7 +1,7 @@
1
1
  import { ref, computed, watch, onMounted, createBlock, openBlock, withCtx, createElementVNode, createVNode, createElementBlock, createCommentVNode, toDisplayString, unref } from "vue";
2
2
  import { useI18n } from "vue-i18n";
3
3
  import _sfc_main$1 from "../../../../../components/Popup/Popup.vue.js";
4
- import Loader from "../../../../../components/Loader/Loader.vue2.js";
4
+ import Loader from "../../../../../components/Loader/Loader.vue.js";
5
5
  import Calendar from "../../../../../components/Calendar/Calendar.vue2.js";
6
6
  import _sfc_main$3 from "../../../../../components/Button/Button.vue.js";
7
7
  import _sfc_main$4 from "../../../../icons/actions/IconShopcartAdd.vue.js";
@@ -7,7 +7,7 @@ import _sfc_main$5 from "../../../../../components/Status/Snack.vue.js";
7
7
  import _sfc_main$1 from "../../../../../components/Popup/Popup.vue.js";
8
8
  import "vue-i18n";
9
9
  /* empty css */
10
- import Loader from "../../../../../components/Loader/Loader.vue2.js";
10
+ import Loader from "../../../../../components/Loader/Loader.vue.js";
11
11
  /* empty css */
12
12
  /* empty css */
13
13
  import _sfc_main$2 from "../partials/LocationSelection.vue.js";
@@ -4,7 +4,7 @@ import IconChevronBottom from "../../../../icons/navigation/IconChevronBottom.vu
4
4
  import { useStore } from "../../store/core.store.js";
5
5
  import { state } from "../../../../auth/views/store/auth.js";
6
6
  import _sfc_main$1 from "../../../../../components/Dropdown/Dropdown.vue.js";
7
- /* empty css */
7
+ /* empty css */
8
8
  /* empty css */
9
9
  import _export_sfc from "../../../../../../../_virtual/_plugin-vue_export-helper.js";
10
10
  const _hoisted_1 = ["onClick"];
@@ -1,5 +1,5 @@
1
1
  import { resolveComponent, createElementBlock, openBlock, createElementVNode, createBlock, createCommentVNode, toDisplayString, Fragment, renderList, normalizeClass, withCtx, createTextVNode } from "vue";
2
- import _sfc_main$1 from "../../../../../components/Tab/Tab.vue2.js";
2
+ import _sfc_main$1 from "../../../../../components/Tab/Tab.vue.js";
3
3
  const _hoisted_1 = { class: "flex-v-center flex-nowrap flex" };
4
4
  const _hoisted_2 = { class: "h2 mn-r-auto" };
5
5
  const _hoisted_3 = ["onClick"];
@@ -60,6 +60,13 @@ function renderAndMountApp({ createApp, hooks = {} }) {
60
60
  console.log("[AUTH COOKIE DEBUG] Has token?", !!initialState?.auth?.access?.token);
61
61
  console.log("[AUTH COOKIE DEBUG] Has auth but no status?", !!initialState?.auth && !initialState.auth.access?.status);
62
62
  store.setInitialState(initialState, true);
63
+ if (initialState?.auth?.user?._id && store.core?.state?.session) {
64
+ store.core.state.session.userId = initialState.auth.user._id;
65
+ store.core.state.session.token = initialState.auth.access?.token;
66
+ store.core.state.session.roles = initialState.auth.access?.roles;
67
+ store.core.state.session.accesses = initialState.auth.accesses || [];
68
+ console.log("[AUTH COOKIE DEBUG] Session hydrated with userId:", initialState.auth.user._id);
69
+ }
63
70
  if (initialState?.auth?.access?.token) {
64
71
  console.log("[AUTH COOKIE DEBUG] Setting auth token from initialState");
65
72
  setAuthToken(initialState.auth.access.token);
@@ -1 +1 @@
1
- {"version":3,"file":"vue-app-renderer.js","sources":["../../../../../../../src/modules/core/views/utils/vue-app-renderer.js"],"sourcesContent":["import { setAuthToken } from '@martyrs/src/modules/core/views/utils/axios-instance.js';\nimport { renderSSRHead } from '@unhead/ssr';\nimport { renderToString } from '@vue/server-renderer';\n\nexport function renderAndMountApp({ createApp, hooks = {} }) {\n const start = async () => {\n // [LOADING 22] Starting client-side hydration\n performance.mark('loading-22-start');\n console.log('[LOADING 22] Starting client-side hydration...');\n\n const { app, router, store, moduleManager, config } = await createApp();\n \n let serverModules = [];\n \n // Загружаем модули которые были загружены на сервере\n if (typeof window !== 'undefined') {\n try {\n const modulesElement = document.querySelector('[data-loaded-modules]');\n if (modulesElement) {\n serverModules = JSON.parse(modulesElement.innerHTML);\n }\n } catch (e) {\n console.error('Failed to parse loaded modules', e);\n }\n \n const context = { app, store, router, config };\n\n // [LOADING 23] Loading server modules for hydration\n performance.mark('loading-23-start');\n console.log(`[LOADING 23] Loading ${serverModules.length} server modules for hydration...`);\n\n for (const moduleName of serverModules) {\n try {\n await moduleManager.load(moduleName, context);\n await moduleManager.initialize(moduleName, context);\n } catch (error) {\n console.error(`Failed to load module ${moduleName}:`, error);\n }\n }\n\n performance.mark('loading-23-end');\n performance.measure('loading-23', 'loading-23-start', 'loading-23-end');\n const measure23 = performance.getEntriesByName('loading-23')[0];\n console.log(`[LOADING 23] Server modules loaded in ${measure23?.duration?.toFixed(2)}ms`);\n }\n \n // Call beforeHydration hook if provided\n if (hooks.beforeHydration) {\n hooks.beforeHydration({ app, router, store, moduleManager });\n }\n\n // [LOADING 24] Parsing and applying initialState\n performance.mark('loading-24-start');\n console.log('[LOADING 24] Parsing and applying initialState...');\n\n let initialState;\n\n try {\n const initialStateElement = document.querySelector('[data-state]');\n\n if (initialStateElement && initialStateElement.innerHTML.trim() !== '') {\n const stateContent = initialStateElement.innerHTML.trim();\n \n // Validate JSON format before parsing\n if (stateContent.startsWith('{') && stateContent.endsWith('}')) {\n initialState = JSON.parse(stateContent);\n \n // Basic validation of state structure\n if (typeof initialState !== 'object' || initialState === null) {\n throw new Error('Invalid state format');\n }\n } else {\n throw new Error('Invalid JSON format');\n }\n }\n } catch (error) {\n console.error('Failed to parse user state', error);\n initialState = null;\n }\n\n\n\n\n if (initialState) {\n console.log('[AUTH COOKIE DEBUG] Browser initialState.auth:', initialState.auth);\n console.log('[AUTH COOKIE DEBUG] Has token?', !!initialState?.auth?.access?.token);\n console.log('[AUTH COOKIE DEBUG] Has auth but no status?', !!initialState?.auth && !initialState.auth.access?.status);\n\n // Применяем начальное состояние ко всем модулям (true = гидратация)\n store.setInitialState(initialState, true);\n\n if (initialState?.auth?.access?.token) {\n console.log('[AUTH COOKIE DEBUG] Setting auth token from initialState');\n\n setAuthToken(initialState.auth.access.token);\n } else if (initialState?.auth && !initialState.auth.access?.status) {\n // Если SSR сбросил auth (из-за ошибки), удаляем куку в браузере\n console.log('[AUTH COOKIE DEBUG] SSR reset auth, removing cookie in browser');\n if (store.auth && store.auth.removeCookie) {\n await store.auth.removeCookie('user');\n }\n }\n } else {\n // Если нет initialState, сбрасываем авторизацию (если модуль auth загружен)\n if (store.auth && store.auth.actions) {\n store.auth.actions.resetState();\n // await store.auth.removeCookie('user');\n await store.auth.actions.logout();\n }\n }\n\n const savedPosition = localStorage.getItem('position');\n\n if (savedPosition) {\n store.core.state.position = JSON.parse(savedPosition);\n }\n\n // app.config.globalProperties.$i18n.locale = router.currentRoute.value.params.locale\n // app.config.globalProperties.$i18n.locale = router.currentRoute.value.params.locale\n // If user browser locae supported then change locale\n // if (i18n.global.availableLocales.includes(browserLocale)) {\n // app.config.globalProperties.$i18n.locale = browserLocale;\n // }\n\n performance.mark('loading-24-end');\n performance.measure('loading-24', 'loading-24-start', 'loading-24-end');\n const measure24 = performance.getEntriesByName('loading-24')[0];\n console.log(`[LOADING 24] InitialState parsed and applied in ${measure24?.duration?.toFixed(2)}ms`);\n\n await router.isReady();\n\n // [LOADING 25] Mounting the application\n performance.mark('loading-25-start');\n console.log('[LOADING 25] Mounting the application...');\n\n app.mount('#app');\n\n performance.mark('loading-25-end');\n performance.measure('loading-25', 'loading-25-start', 'loading-25-end');\n const measure25 = performance.getEntriesByName('loading-25')[0];\n console.log(`[LOADING 25] Application mounted in ${measure25?.duration?.toFixed(2)}ms`);\n\n // Return the objects for further use\n return { app, router, store, moduleManager };\n };\n return start();\n}\n\nexport async function render({ url, cookies, headers, ssrContext, createApp }) {\n // [LOADING 26] SSR render starting\n performance.mark('loading-26-start');\n console.log('[LOADING 26] SSR render starting...');\n\n const { app, router, store, meta } = createApp();\n\n await router.push(url);\n await router.isReady();\n\n // If user's language is supported, change the locale\n // if (language === 'en' || language === 'ru') {\n // app.config.globalProperties.$i18n.locale = language\n // }\n\n // app.config.globalProperties.$i18n.locale = router.currentRoute.value.params.locale\n\n const ctx = ssrContext || {};\n\n if (router.currentRoute.value.name?.toLowerCase() === 'notfound') {\n ctx.notFound = true;\n }\n\n let user = null;\n\n if (cookies.user) {\n try {\n user = JSON.parse(cookies.user);\n } catch (error) {\n console.error('Failed to parse user cookie', error);\n user = null;\n }\n }\n\n \n\n\n if (user) {\n // [LOADING 27] SSR auth initialization\n performance.mark('loading-27-start');\n console.log('[LOADING 27] SSR auth initialization...');\n\n if (store.auth && store.auth.actions) {\n try {\n await store.auth.actions.initialize(user);\n } catch (error) {\n console.error('[SSR] Auth initialization failed, continuing without auth:', error);\n // Сбрасываем состояние если инициализация упала\n if (store.auth.actions.resetState) {\n store.auth.actions.resetState();\n }\n }\n } else {\n console.warn('[SSR] Auth module not loaded, cannot initialize user');\n }\n\n performance.mark('loading-27-end');\n performance.measure('loading-27', 'loading-27-start', 'loading-27-end');\n const measure27 = performance.getEntriesByName('loading-27')[0];\n console.log(`[LOADING 27] SSR auth initialized in ${measure27?.duration?.toFixed(2)}ms`);\n } else {\n if (store.auth && store.auth.actions) {\n store.auth.actions.resetState();\n } else {\n console.warn('[SSR] Auth module not loaded, cannot reset state');\n }\n }\n\n // [LOADING 28] SSR renderToString\n performance.mark('loading-28-start');\n console.log('[LOADING 28] SSR renderToString starting...');\n\n // After render, ctx.modules will be populated with used module identifiers\n const html = await renderToString(app, ctx);\n\n // Добавляем атрибуты темы через meta API перед renderSSRHead\n let theme = cookies?.theme;\n if (!theme) {\n // Fallback на sec-ch-prefers-color-scheme если нет cookie\n const prefersColorScheme = headers?.['sec-ch-prefers-color-scheme'];\n theme = prefersColorScheme === 'dark' ? 'system-dark' : 'system';\n }\n\n const themeAttrs = {};\n if (theme === 'dark') {\n themeAttrs.class = 'dark-theme';\n themeAttrs['data-theme'] = 'dark';\n themeAttrs['color-scheme'] = 'dark';\n } else if (theme === 'light') {\n themeAttrs.class = 'light-theme';\n themeAttrs['data-theme'] = 'light';\n themeAttrs['color-scheme'] = 'light';\n } else {\n // system/system-dark - без класса, CSS media query сработает\n themeAttrs['color-scheme'] = 'light dark';\n }\n\n meta.push({ htmlAttrs: themeAttrs });\n\n // Синхронизируем store state с определённой темой для SSR\n store.core.state.theme.mode = (theme === 'dark') ? 'dark'\n : (theme === 'light') ? 'light'\n : 'system';\n\n const payload = await renderSSRHead(meta, {});\n const initialState = await store.getInitialState();\n\n performance.mark('loading-28-end');\n performance.measure('loading-28', 'loading-28-start', 'loading-28-end');\n const measure28 = performance.getEntriesByName('loading-28')[0];\n console.log(`[LOADING 28] SSR renderToString completed in ${measure28?.duration?.toFixed(2)}ms`);\n\n // Total SSR render time\n performance.measure('loading-26-total', 'loading-26-start', 'loading-28-end');\n const measure26Total = performance.getEntriesByName('loading-26-total')[0];\n console.log(`[LOADING 26] Total SSR render completed in ${measure26Total?.duration?.toFixed(2)}ms`);\n\n return {\n html,\n meta: payload,\n state: initialState,\n statusCode: router.currentRoute?.value?.name?.toLowerCase() === 'notfound' ? 404 : 200,\n usedModules: Array.from(ctx.modules || new Set()), // Return used modules\n };\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"vue-app-renderer.js","sources":["../../../../../../../src/modules/core/views/utils/vue-app-renderer.js"],"sourcesContent":["import { setAuthToken } from '@martyrs/src/modules/core/views/utils/axios-instance.js';\nimport { renderSSRHead } from '@unhead/ssr';\nimport { renderToString } from '@vue/server-renderer';\n\nexport function renderAndMountApp({ createApp, hooks = {} }) {\n const start = async () => {\n // [LOADING 22] Starting client-side hydration\n performance.mark('loading-22-start');\n console.log('[LOADING 22] Starting client-side hydration...');\n\n const { app, router, store, moduleManager, config } = await createApp();\n \n let serverModules = [];\n \n // Загружаем модули которые были загружены на сервере\n if (typeof window !== 'undefined') {\n try {\n const modulesElement = document.querySelector('[data-loaded-modules]');\n if (modulesElement) {\n serverModules = JSON.parse(modulesElement.innerHTML);\n }\n } catch (e) {\n console.error('Failed to parse loaded modules', e);\n }\n \n const context = { app, store, router, config };\n\n // [LOADING 23] Loading server modules for hydration\n performance.mark('loading-23-start');\n console.log(`[LOADING 23] Loading ${serverModules.length} server modules for hydration...`);\n\n for (const moduleName of serverModules) {\n try {\n await moduleManager.load(moduleName, context);\n await moduleManager.initialize(moduleName, context);\n } catch (error) {\n console.error(`Failed to load module ${moduleName}:`, error);\n }\n }\n\n performance.mark('loading-23-end');\n performance.measure('loading-23', 'loading-23-start', 'loading-23-end');\n const measure23 = performance.getEntriesByName('loading-23')[0];\n console.log(`[LOADING 23] Server modules loaded in ${measure23?.duration?.toFixed(2)}ms`);\n }\n \n // Call beforeHydration hook if provided\n if (hooks.beforeHydration) {\n hooks.beforeHydration({ app, router, store, moduleManager });\n }\n\n // [LOADING 24] Parsing and applying initialState\n performance.mark('loading-24-start');\n console.log('[LOADING 24] Parsing and applying initialState...');\n\n let initialState;\n\n try {\n const initialStateElement = document.querySelector('[data-state]');\n\n if (initialStateElement && initialStateElement.innerHTML.trim() !== '') {\n const stateContent = initialStateElement.innerHTML.trim();\n \n // Validate JSON format before parsing\n if (stateContent.startsWith('{') && stateContent.endsWith('}')) {\n initialState = JSON.parse(stateContent);\n \n // Basic validation of state structure\n if (typeof initialState !== 'object' || initialState === null) {\n throw new Error('Invalid state format');\n }\n } else {\n throw new Error('Invalid JSON format');\n }\n }\n } catch (error) {\n console.error('Failed to parse user state', error);\n initialState = null;\n }\n\n if (initialState) {\n console.log('[AUTH COOKIE DEBUG] Browser initialState.auth:', initialState.auth);\n console.log('[AUTH COOKIE DEBUG] Has token?', !!initialState?.auth?.access?.token);\n console.log('[AUTH COOKIE DEBUG] Has auth but no status?', !!initialState?.auth && !initialState.auth.access?.status);\n\n // Применяем начальное состояние ко всем модулям (true = гидратация)\n store.setInitialState(initialState, true);\n\n // Гидратация session из auth данных — напрямую в reactive state\n if (initialState?.auth?.user?._id && store.core?.state?.session) {\n store.core.state.session.userId = initialState.auth.user._id;\n store.core.state.session.token = initialState.auth.access?.token;\n store.core.state.session.roles = initialState.auth.access?.roles;\n store.core.state.session.accesses = initialState.auth.accesses || [];\n console.log('[AUTH COOKIE DEBUG] Session hydrated with userId:', initialState.auth.user._id);\n }\n\n if (initialState?.auth?.access?.token) {\n console.log('[AUTH COOKIE DEBUG] Setting auth token from initialState');\n\n setAuthToken(initialState.auth.access.token);\n } else if (initialState?.auth && !initialState.auth.access?.status) {\n // Если SSR сбросил auth (из-за ошибки), удаляем куку в браузере\n console.log('[AUTH COOKIE DEBUG] SSR reset auth, removing cookie in browser');\n if (store.auth && store.auth.removeCookie) {\n await store.auth.removeCookie('user');\n }\n }\n } else {\n // Если нет initialState, сбрасываем авторизацию (если модуль auth загружен)\n if (store.auth && store.auth.actions) {\n store.auth.actions.resetState();\n // await store.auth.removeCookie('user');\n await store.auth.actions.logout();\n }\n }\n\n const savedPosition = localStorage.getItem('position');\n\n if (savedPosition) {\n store.core.state.position = JSON.parse(savedPosition);\n }\n\n // app.config.globalProperties.$i18n.locale = router.currentRoute.value.params.locale\n // app.config.globalProperties.$i18n.locale = router.currentRoute.value.params.locale\n // If user browser locae supported then change locale\n // if (i18n.global.availableLocales.includes(browserLocale)) {\n // app.config.globalProperties.$i18n.locale = browserLocale;\n // }\n\n performance.mark('loading-24-end');\n performance.measure('loading-24', 'loading-24-start', 'loading-24-end');\n const measure24 = performance.getEntriesByName('loading-24')[0];\n console.log(`[LOADING 24] InitialState parsed and applied in ${measure24?.duration?.toFixed(2)}ms`);\n\n await router.isReady();\n\n // [LOADING 25] Mounting the application\n performance.mark('loading-25-start');\n console.log('[LOADING 25] Mounting the application...');\n\n app.mount('#app');\n\n performance.mark('loading-25-end');\n performance.measure('loading-25', 'loading-25-start', 'loading-25-end');\n const measure25 = performance.getEntriesByName('loading-25')[0];\n console.log(`[LOADING 25] Application mounted in ${measure25?.duration?.toFixed(2)}ms`);\n\n // Return the objects for further use\n return { app, router, store, moduleManager };\n };\n return start();\n}\n\nexport async function render({ url, cookies, headers, ssrContext, createApp }) {\n // [LOADING 26] SSR render starting\n performance.mark('loading-26-start');\n console.log('[LOADING 26] SSR render starting...');\n\n const { app, router, store, meta } = createApp();\n\n await router.push(url);\n await router.isReady();\n\n // If user's language is supported, change the locale\n // if (language === 'en' || language === 'ru') {\n // app.config.globalProperties.$i18n.locale = language\n // }\n\n // app.config.globalProperties.$i18n.locale = router.currentRoute.value.params.locale\n\n const ctx = ssrContext || {};\n\n if (router.currentRoute.value.name?.toLowerCase() === 'notfound') {\n ctx.notFound = true;\n }\n\n let user = null;\n\n if (cookies.user) {\n try {\n user = JSON.parse(cookies.user);\n } catch (error) {\n console.error('Failed to parse user cookie', error);\n user = null;\n }\n }\n\n \n\n\n if (user) {\n // [LOADING 27] SSR auth initialization\n performance.mark('loading-27-start');\n console.log('[LOADING 27] SSR auth initialization...');\n\n if (store.auth && store.auth.actions) {\n try {\n await store.auth.actions.initialize(user);\n } catch (error) {\n console.error('[SSR] Auth initialization failed, continuing without auth:', error);\n // Сбрасываем состояние если инициализация упала\n if (store.auth.actions.resetState) {\n store.auth.actions.resetState();\n }\n }\n } else {\n console.warn('[SSR] Auth module not loaded, cannot initialize user');\n }\n\n performance.mark('loading-27-end');\n performance.measure('loading-27', 'loading-27-start', 'loading-27-end');\n const measure27 = performance.getEntriesByName('loading-27')[0];\n console.log(`[LOADING 27] SSR auth initialized in ${measure27?.duration?.toFixed(2)}ms`);\n } else {\n if (store.auth && store.auth.actions) {\n store.auth.actions.resetState();\n } else {\n console.warn('[SSR] Auth module not loaded, cannot reset state');\n }\n }\n\n // [LOADING 28] SSR renderToString\n performance.mark('loading-28-start');\n console.log('[LOADING 28] SSR renderToString starting...');\n\n // After render, ctx.modules will be populated with used module identifiers\n const html = await renderToString(app, ctx);\n\n // Добавляем атрибуты темы через meta API перед renderSSRHead\n let theme = cookies?.theme;\n if (!theme) {\n // Fallback на sec-ch-prefers-color-scheme если нет cookie\n const prefersColorScheme = headers?.['sec-ch-prefers-color-scheme'];\n theme = prefersColorScheme === 'dark' ? 'system-dark' : 'system';\n }\n\n const themeAttrs = {};\n if (theme === 'dark') {\n themeAttrs.class = 'dark-theme';\n themeAttrs['data-theme'] = 'dark';\n themeAttrs['color-scheme'] = 'dark';\n } else if (theme === 'light') {\n themeAttrs.class = 'light-theme';\n themeAttrs['data-theme'] = 'light';\n themeAttrs['color-scheme'] = 'light';\n } else {\n // system/system-dark - без класса, CSS media query сработает\n themeAttrs['color-scheme'] = 'light dark';\n }\n\n meta.push({ htmlAttrs: themeAttrs });\n\n // Синхронизируем store state с определённой темой для SSR\n store.core.state.theme.mode = (theme === 'dark') ? 'dark'\n : (theme === 'light') ? 'light'\n : 'system';\n\n const payload = await renderSSRHead(meta, {});\n const initialState = await store.getInitialState();\n\n performance.mark('loading-28-end');\n performance.measure('loading-28', 'loading-28-start', 'loading-28-end');\n const measure28 = performance.getEntriesByName('loading-28')[0];\n console.log(`[LOADING 28] SSR renderToString completed in ${measure28?.duration?.toFixed(2)}ms`);\n\n // Total SSR render time\n performance.measure('loading-26-total', 'loading-26-start', 'loading-28-end');\n const measure26Total = performance.getEntriesByName('loading-26-total')[0];\n console.log(`[LOADING 26] Total SSR render completed in ${measure26Total?.duration?.toFixed(2)}ms`);\n\n return {\n html,\n meta: payload,\n state: initialState,\n statusCode: router.currentRoute?.value?.name?.toLowerCase() === 'notfound' ? 404 : 200,\n usedModules: Array.from(ctx.modules || new Set()), // Return used modules\n };\n}\n"],"names":[],"mappings":"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"}
@@ -8,11 +8,11 @@ import _sfc_main$5 from "../../../../components/Popup/Popup.vue.js";
8
8
  import Field from "../../../../components/Field/Field.vue.js";
9
9
  import _sfc_main$6 from "../../../../components/FieldTags/BlockTags.vue.js";
10
10
  import _sfc_main$9 from "../../../../components/Checkbox/Checkbox.vue.js";
11
- /* empty css */
11
+ /* empty css */
12
12
  import "axios";
13
13
  /* empty css */
14
14
  import UploadImage from "../../../../components/UploadImage/UploadImage.vue.js";
15
- /* empty css */
15
+ /* empty css */
16
16
  /* empty css */
17
17
  import _sfc_main$8 from "../../../../components/Feed/Feed.vue.js";
18
18
  import _sfc_main$a from "../../../../components/Button/Button.vue.js";
@@ -1,5 +1,5 @@
1
1
  import { ref, onMounted, createElementBlock, openBlock, createVNode, TransitionGroup, withCtx, createCommentVNode, createBlock, Fragment, renderList, unref, createElementVNode, toDisplayString, createTextVNode } from "vue";
2
- /* empty css */
2
+ /* empty css */
3
3
  import _sfc_main$2 from "../../../constructor/components/sections/Viewer.vue.js";
4
4
  import _sfc_main$4 from "../../../../components/Countdown/Countdown.vue.js";
5
5
  import HeroEvent from "../sections/HeroEvent.vue.js";
@@ -1,6 +1,6 @@
1
1
  import { computed, ref, watch, createElementBlock, openBlock, createElementVNode, createCommentVNode, unref, createBlock, createVNode, isRef, withCtx, Fragment, renderList } from "vue";
2
2
  import { useRoute, useRouter } from "vue-router";
3
- import _sfc_main$1 from "../../../../components/Tab/Tab.vue2.js";
3
+ import _sfc_main$1 from "../../../../components/Tab/Tab.vue.js";
4
4
  import _sfc_main$2 from "../../../../components/Feed/Feed.vue.js";
5
5
  /* empty css */
6
6
  import _sfc_main$3 from "../blocks/CardEvent.vue.js";
@@ -1,5 +1,5 @@
1
1
  import { ref, onMounted, createElementBlock, openBlock, createVNode, TransitionGroup, withCtx, createBlock, createCommentVNode, Transition, Fragment, renderList } from "vue";
2
- import Loader from "../../../../components/Loader/Loader.vue2.js";
2
+ import Loader from "../../../../components/Loader/Loader.vue.js";
3
3
  import _sfc_main$1 from "../../../../components/EmptyState/EmptyState.vue.js";
4
4
  import _sfc_main$2 from "../blocks/CardEvent.vue.js";
5
5
  import { read } from "../../store/events.js";
@@ -1,5 +1,5 @@
1
1
  import { ref, onMounted, createElementBlock, openBlock, createVNode, TransitionGroup, withCtx, createBlock, Fragment, renderList, normalizeClass } from "vue";
2
- /* empty css */
2
+ /* empty css */
3
3
  import _sfc_main$1 from "../../../../components/EmptyState/EmptyState.vue.js";
4
4
  import _sfc_main$2 from "../blocks/CardEventShort.vue.js";
5
5
  import SkeletonEventShort from "../../../icons/skeletons/SkeletonEventShort.vue.js";
@@ -4,7 +4,7 @@ import { useRoute } from "vue-router";
4
4
  import _sfc_main$8 from "../../../../components/Button/Button.vue.js";
5
5
  /* empty css */
6
6
  import _sfc_main$4 from "../../../../components/Chips/Chips.vue.js";
7
- /* empty css */
7
+ /* empty css */
8
8
  import _sfc_main$5 from "../../../../components/Popup/Popup.vue.js";
9
9
  import _sfc_main$2 from "../../../../components/Feed/Feed.vue.js";
10
10
  import PhotoViewer from "../../../../components/PhotoViewer/PhotoViewer.vue.js";
@@ -1,5 +1,5 @@
1
1
  import { createElementBlock, openBlock, createElementVNode, createCommentVNode, toDisplayString, unref, Fragment, renderList, createBlock, withCtx, createVNode, normalizeClass } from "vue";
2
- import _sfc_main$1 from "../../../../components/Spoiler/Spoiler.vue2.js";
2
+ import _sfc_main$1 from "../../../../components/Spoiler/Spoiler.vue.js";
3
3
  import { useI18n } from "vue-i18n";
4
4
  import IconChevronBottom from "../../../icons/navigation/IconChevronBottom.vue.js";
5
5
  const _hoisted_1 = { class: "" };
@@ -1,5 +1,5 @@
1
1
  import { ref, onMounted, resolveComponent, createElementBlock, openBlock, createElementVNode, createVNode, createTextVNode, Transition, withCtx, Fragment, renderList, createBlock, createCommentVNode, normalizeClass, toDisplayString } from "vue";
2
- import Loader from "../../../../../components/Loader/Loader.vue2.js";
2
+ import Loader from "../../../../../components/Loader/Loader.vue.js";
3
3
  import { useRouter } from "vue-router";
4
4
  import { useI18n } from "vue-i18n";
5
5
  import { actions as actions$1 } from "../../../../products/store/categories.js";
@@ -6,7 +6,7 @@ import _sfc_main$4 from "../../../../components/Button/Button.vue.js";
6
6
  import _sfc_main$3 from "../../../../components/Checkbox/Checkbox.vue.js";
7
7
  import Select from "../../../../components/Select/Select.vue2.js";
8
8
  import UploadImage from "../../../../components/UploadImage/UploadImage.vue.js";
9
- /* empty css */
9
+ /* empty css */
10
10
  import BlockMultiselect from "../../../core/views/components/blocks/BlockMultiselect.vue.js";
11
11
  import _sfc_main$2 from "../../../icons/navigation/IconCross.vue.js";
12
12
  import { actions as actions$1 } from "../../store/artists.js";
@@ -1,6 +1,6 @@
1
1
  import { ref, computed, onMounted, resolveComponent, createElementBlock, openBlock, createCommentVNode, createVNode, createElementVNode, toDisplayString, Fragment, renderList, createBlock, withCtx, createTextVNode } from "vue";
2
2
  import { useRoute, useRouter } from "vue-router";
3
- import Loader from "../../../../components/Loader/Loader.vue2.js";
3
+ import Loader from "../../../../components/Loader/Loader.vue.js";
4
4
  /* empty css */
5
5
  import Media from "../../../../components/Media/Media.vue.js";
6
6
  /* empty css */
@@ -1,7 +1,7 @@
1
1
  import { ref, computed, onMounted, createElementBlock, openBlock, createCommentVNode, createElementVNode, createVNode, unref, withCtx, createTextVNode, normalizeStyle, normalizeClass, toDisplayString, Fragment, renderList, createBlock } from "vue";
2
2
  import { useRouter, useRoute } from "vue-router";
3
3
  import _sfc_main$1 from "../../../../components/Button/Button.vue.js";
4
- /* empty css */
4
+ /* empty css */
5
5
  import _sfc_main$2 from "../cards/TrackListCard.vue.js";
6
6
  import { state, actions } from "../../store/artists.js";
7
7
  import { state as state$1 } from "../../../auth/views/store/auth.js";
@@ -1,7 +1,7 @@
1
1
  import { ref, computed, onMounted, resolveComponent, createElementBlock, openBlock, createCommentVNode, createVNode, createElementVNode, toDisplayString, Fragment, renderList, createBlock, withCtx, createTextVNode } from "vue";
2
2
  import { useRoute, useRouter } from "vue-router";
3
3
  import _sfc_main$9 from "../../../../components/Button/Button.vue.js";
4
- /* empty css */
4
+ /* empty css */
5
5
  import Media from "../../../../components/Media/Media.vue.js";
6
6
  /* empty css */
7
7
  import _sfc_main$7 from "../../../../components/Feed/Feed.vue.js";
@@ -6,7 +6,7 @@ import AlbumCard from "../cards/AlbumCard.vue.js";
6
6
  import PlaylistCard from "../cards/PlaylistCard.vue.js";
7
7
  import ArtistCard from "../cards/ArtistCard.vue.js";
8
8
  import _sfc_main$2 from "../../../../components/Button/Button.vue.js";
9
- import Loader from "../../../../components/Loader/Loader.vue2.js";
9
+ import Loader from "../../../../components/Loader/Loader.vue.js";
10
10
  import { state, actions } from "../../store/search.js";
11
11
  /* empty css */
12
12
  import _export_sfc from "../../../../../../_virtual/_plugin-vue_export-helper.js";
@@ -1,7 +1,7 @@
1
1
  import { computed, ref, onMounted, resolveComponent, createElementBlock, openBlock, createCommentVNode, createBlock, createVNode, createElementVNode, withCtx, toDisplayString, Fragment, renderList } from "vue";
2
2
  import { useRoute, useRouter } from "vue-router";
3
3
  import _sfc_main$5 from "../../../../components/Button/Button.vue.js";
4
- import Loader from "../../../../components/Loader/Loader.vue2.js";
4
+ import Loader from "../../../../components/Loader/Loader.vue.js";
5
5
  import Media from "../../../../components/Media/Media.vue.js";
6
6
  /* empty css */
7
7
  import _sfc_main$c from "../../../../components/Popup/Popup.vue.js";
@@ -1,6 +1,6 @@
1
1
  import { createElementBlock, openBlock, createVNode } from "vue";
2
2
  import { useRouter } from "vue-router";
3
- /* empty css */
3
+ /* empty css */
4
4
  /* empty css */
5
5
  import _sfc_main$1 from "../forms/TrackForm.vue.js";
6
6
  const _hoisted_1 = { class: "track-create-page" };
@@ -1,36 +1,14 @@
1
- import { inject, computed, ref, onMounted, onUnmounted, resolveComponent, createElementBlock, openBlock, createElementVNode, createCommentVNode, createVNode, createTextVNode } from "vue";
1
+ import { inject, computed, resolveComponent, createElementBlock, openBlock, createVNode, createCommentVNode, unref, createElementVNode } from "vue";
2
2
  import { wsManager } from "../../../core/views/classes/ws.manager.js";
3
- const _hoisted_1 = { class: "notifications-layout" };
4
- const _hoisted_2 = { class: "" };
5
- const _hoisted_3 = {
3
+ const _hoisted_1 = {
6
4
  key: 0,
7
- class: "connection-status"
5
+ class: "pos-fixed pos-b-0 pos-l-0 pos-r-0 pd-small bg-warning t-center"
8
6
  };
9
7
  const _sfc_main = {
10
8
  __name: "NotificationsLayout",
11
9
  setup(__props) {
12
10
  const store = inject("store");
13
11
  const notificationManager = computed(() => store.notificationManager || null);
14
- const wsConnected = ref(wsManager.isConnected);
15
- const openListenerId = ref(null);
16
- const closeListenerId = ref(null);
17
- onMounted(() => {
18
- openListenerId.value = wsManager.addEventListener("open", () => {
19
- wsConnected.value = true;
20
- });
21
- closeListenerId.value = wsManager.addEventListener("close", () => {
22
- wsConnected.value = false;
23
- });
24
- wsConnected.value = wsManager.isConnected;
25
- });
26
- onUnmounted(() => {
27
- if (openListenerId.value) {
28
- wsManager.removeEventListener("open", openListenerId.value);
29
- }
30
- if (closeListenerId.value) {
31
- wsManager.removeEventListener("close", closeListenerId.value);
32
- }
33
- });
34
12
  const reconnect = () => {
35
13
  if (notificationManager.value) {
36
14
  notificationManager.value.initialize();
@@ -38,21 +16,14 @@ const _sfc_main = {
38
16
  };
39
17
  return (_ctx, _cache) => {
40
18
  const _component_router_view = resolveComponent("router-view");
41
- return openBlock(), createElementBlock("div", _hoisted_1, [
42
- createElementVNode("div", _hoisted_2, [
43
- createVNode(_component_router_view)
44
- ]),
45
- !wsConnected.value ? (openBlock(), createElementBlock("div", _hoisted_3, [
46
- createElementVNode("div", { class: "connection-warning" }, [
47
- _cache[1] || (_cache[1] = createElementVNode("span", { class: "warning-icon" }, "⚠️", -1)),
48
- createElementVNode("span", { class: "warning-text" }, [
49
- _cache[0] || (_cache[0] = createTextVNode(" Notification service disconnected. ")),
50
- createElementVNode("button", {
51
- onClick: reconnect,
52
- class: "reconnect-btn"
53
- }, "Reconnect")
54
- ])
55
- ])
19
+ return openBlock(), createElementBlock("div", null, [
20
+ createVNode(_component_router_view),
21
+ unref(wsManager).state.wasConnected && !unref(wsManager).state.isConnected ? (openBlock(), createElementBlock("div", _hoisted_1, [
22
+ _cache[0] || (_cache[0] = createElementVNode("span", null, "⚠️ Notification service disconnected.", -1)),
23
+ createElementVNode("button", {
24
+ class: "mn-l-thin bg-none bd-none cursor-pointer t-main",
25
+ onClick: reconnect
26
+ }, "Reconnect")
56
27
  ])) : createCommentVNode("", true)
57
28
  ]);
58
29
  };
@@ -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 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 wsManager from '@martyrs/src/modules/core/views/classes/ws.manager.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(wsManager.isConnected);\n\n// ID слушателей для очистки\nconst openListenerId = ref(null);\nconst closeListenerId = ref(null);\n\nonMounted(() => {\n // Подписываемся на события WebSocket\n openListenerId.value = wsManager.addEventListener('open', () => {\n wsConnected.value = true;\n });\n \n closeListenerId.value = wsManager.addEventListener('close', () => {\n wsConnected.value = false;\n });\n \n // Устанавливаем начальное состояние\n wsConnected.value = wsManager.isConnected;\n});\n\nonUnmounted(() => {\n // Очищаем слушатели\n if (openListenerId.value) {\n wsManager.removeEventListener('open', openListenerId.value);\n }\n if (closeListenerId.value) {\n wsManager.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,UAAU,WAAW;AAG7C,UAAM,iBAAiB,IAAI,IAAI;AAC/B,UAAM,kBAAkB,IAAI,IAAI;AAEhC,cAAU,MAAM;AAEd,qBAAe,QAAQ,UAAU,iBAAiB,QAAQ,MAAM;AAC9D,oBAAY,QAAQ;AAAA,MACtB,CAAC;AAED,sBAAgB,QAAQ,UAAU,iBAAiB,SAAS,MAAM;AAChE,oBAAY,QAAQ;AAAA,MACtB,CAAC;AAGD,kBAAY,QAAQ,UAAU;AAAA,IAChC,CAAC;AAED,gBAAY,MAAM;AAEhB,UAAI,eAAe,OAAO;AACxB,kBAAU,oBAAoB,QAAQ,eAAe,KAAK;AAAA,MAC5D;AACA,UAAI,gBAAgB,OAAO;AACzB,kBAAU,oBAAoB,SAAS,gBAAgB,KAAK;AAAA,MAC9D;AAAA,IACF,CAAC;AAID,UAAM,YAAY,MAAM;AACtB,UAAI,oBAAoB,OAAO;AAC7B,4BAAoB,MAAM,WAAU;AAAA,MACtC;AAAA,IACF;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"NotificationsLayout.vue.js","sources":["../../../../../../../src/modules/notifications/components/layouts/NotificationsLayout.vue"],"sourcesContent":["<template>\n <div>\n <router-view />\n\n <!-- Показываем только если WS был подключен и потом отвалился -->\n <div v-if=\"wsManager.state.wasConnected && !wsManager.state.isConnected\" class=\"pos-fixed pos-b-0 pos-l-0 pos-r-0 pd-small bg-warning t-center\">\n <span>⚠️ Notification service disconnected.</span>\n <button class=\"mn-l-thin bg-none bd-none cursor-pointer t-main\" @click=\"reconnect\">Reconnect</button>\n </div>\n </div>\n</template>\n\n<script setup>\nimport { computed, inject } from 'vue';\nimport wsManager from '@martyrs/src/modules/core/views/classes/ws.manager.js';\n\nconst store = inject('store');\nconst notificationManager = computed(() => store.notificationManager || null);\n\nconst reconnect = () => {\n if (notificationManager.value) {\n notificationManager.value.initialize();\n }\n};\n</script>"],"names":[],"mappings":";;;;;;;;;AAgBA,UAAM,QAAQ,OAAO,OAAO;AAC5B,UAAM,sBAAsB,SAAS,MAAM,MAAM,uBAAuB,IAAI;AAE5E,UAAM,YAAY,MAAM;AACtB,UAAI,oBAAoB,OAAO;AAC7B,4BAAoB,MAAM,WAAU;AAAA,MACtC;AAAA,IACF;;;;;;;;;;;;;;;;"}
@@ -1,31 +1,36 @@
1
- import { inject, ref, createElementBlock, openBlock, createVNode, createElementVNode, unref, createBlock, createCommentVNode } from "vue";
2
- import { useRoute } from "vue-router";
3
- import _sfc_main$1 from "../../../../components/Tab/Tab.vue2.js";
4
- import NotificationsList from "../sections/NotificationsList.vue.js";
5
- import NotificationPreferences from "../sections/NotificationPreferences.vue.js";
6
- const _hoisted_1 = { class: "notifications-page pd-small" };
7
- const _hoisted_2 = { class: "tab-content" };
1
+ import { inject, ref, createElementBlock, openBlock, createBlock, createCommentVNode, createVNode, unref, withCtx } from "vue";
2
+ import _sfc_main$1 from "../../../core/views/components/sections/SectionPageTitle.vue.js";
3
+ import _sfc_main$3 from "../../../../components/Popup/Popup.vue.js";
4
+ import _sfc_main$2 from "../sections/NotificationsList.vue.js";
5
+ import _sfc_main$4 from "../sections/NotificationPreferences.vue.js";
6
+ const _hoisted_1 = { class: "mobile:pd-thin pd-medium" };
8
7
  const _sfc_main = {
9
8
  __name: "Notifications",
10
9
  setup(__props) {
11
- const route = useRoute();
12
10
  const { unreadCount } = inject("useNotifications")();
13
- const activeTab = ref(route.query.tab || "all");
11
+ const isSettingsPopup = ref(false);
14
12
  return (_ctx, _cache) => {
15
13
  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" }
14
+ !_ctx.MOBILE_APP ? (openBlock(), createBlock(_sfc_main$1, {
15
+ key: 0,
16
+ title: `Notifications${unref(unreadCount) > 0 ? ` (${unref(unreadCount)})` : ""}`,
17
+ actions: [
18
+ { method: () => isSettingsPopup.value = true, label: "Settings" }
22
19
  ],
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"]),
26
- createElementVNode("div", _hoisted_2, [
27
- activeTab.value === "all" ? (openBlock(), createBlock(NotificationsList, { key: 0 })) : activeTab.value === "preferences" ? (openBlock(), createBlock(NotificationPreferences, { key: 1 })) : createCommentVNode("", true)
28
- ])
20
+ class: "mn-b-small"
21
+ }, null, 8, ["title", "actions"])) : createCommentVNode("", true),
22
+ createVNode(_sfc_main$2),
23
+ createVNode(_sfc_main$3, {
24
+ isPopupOpen: isSettingsPopup.value,
25
+ onClosePopup: _cache[0] || (_cache[0] = ($event) => isSettingsPopup.value = false),
26
+ title: "Notification Settings",
27
+ class: "bg-white pd-medium w-m-30r radius-big"
28
+ }, {
29
+ default: withCtx(() => [
30
+ createVNode(_sfc_main$4)
31
+ ]),
32
+ _: 1
33
+ }, 8, ["isPopupOpen"])
29
34
  ]);
30
35
  };
31
36
  }
@@ -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 <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,SAAQ;AACtB,UAAM,EAAE,YAAW,IAAK,OAAO,kBAAkB,EAAC;AAGlD,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=\"mobile:pd-thin pd-medium\">\n <SectionPageTitle\n v-if=\"!MOBILE_APP\"\n :title=\"`Notifications${unreadCount > 0 ? ` (${unreadCount})` : ''}`\"\n :actions=\"[\n { method: () => isSettingsPopup = true, label: 'Settings' }\n ]\"\n class=\"mn-b-small\"\n />\n\n <NotificationsList />\n\n <Popup\n :isPopupOpen=\"isSettingsPopup\"\n @close-popup=\"isSettingsPopup = false\"\n title=\"Notification Settings\"\n class=\"bg-white pd-medium w-m-30r radius-big\"\n >\n <NotificationPreferences />\n </Popup>\n </div>\n</template>\n\n<script setup>\nimport { ref, inject } from 'vue';\nimport SectionPageTitle from '@martyrs/src/modules/core/views/components/sections/SectionPageTitle.vue';\nimport Popup from '@martyrs/src/components/Popup/Popup.vue';\nimport NotificationsList from '../sections/NotificationsList.vue';\nimport NotificationPreferences from '../sections/NotificationPreferences.vue';\n\nconst { unreadCount } = inject('useNotifications')();\n\nconst isSettingsPopup = ref(false);\n</script>\n"],"names":[],"mappings":";;;;;;;;;AA+BA,UAAM,EAAE,YAAW,IAAK,OAAO,kBAAkB,EAAC;AAElD,UAAM,kBAAkB,IAAI,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;"}