@ozdao/martyrs 0.2.581 → 0.2.583

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 (86) hide show
  1. package/dist/martyrs/src/components/Feed/Feed.vue.js +1 -1
  2. package/dist/martyrs/src/modules/auth/views/components/pages/Profile.vue.js +6 -12
  3. package/dist/martyrs/src/modules/auth/views/components/pages/Profile.vue.js.map +1 -1
  4. package/dist/martyrs/src/modules/auth/views/components/pages/ProfileEdit.vue.js +1 -1
  5. package/dist/martyrs/src/modules/auth/views/components/pages/ProfileEdit.vue.js.map +1 -1
  6. package/dist/martyrs/src/modules/auth/views/components/pages/UserDashboard.vue.js +182 -89
  7. package/dist/martyrs/src/modules/auth/views/components/pages/UserDashboard.vue.js.map +1 -1
  8. package/dist/martyrs/src/modules/auth/views/configs/navigation.user.config.js +11 -5
  9. package/dist/martyrs/src/modules/auth/views/configs/navigation.user.config.js.map +1 -1
  10. package/dist/martyrs/src/modules/auth/views/router/users.router.js +1 -2
  11. package/dist/martyrs/src/modules/auth/views/router/users.router.js.map +1 -1
  12. package/dist/martyrs/src/modules/backoffice/components/partials/Sidebar.vue.js +1 -1
  13. package/dist/martyrs/src/modules/core/views/classes/ws.manager.js +16 -1
  14. package/dist/martyrs/src/modules/core/views/classes/ws.manager.js.map +1 -1
  15. package/dist/martyrs/src/modules/core/views/components/sections/{Filters.vue.js → Filters.vue2.js} +2 -2
  16. package/dist/martyrs/src/modules/core/views/components/sections/Filters.vue2.js.map +1 -0
  17. package/dist/martyrs/src/modules/core/views/utils/vue-app-renderer.js +7 -0
  18. package/dist/martyrs/src/modules/core/views/utils/vue-app-renderer.js.map +1 -1
  19. package/dist/martyrs/src/modules/events/components/pages/EditEvent.vue.js +1 -1
  20. package/dist/martyrs/src/modules/events/components/pages/Event.vue.js +1 -1
  21. package/dist/martyrs/src/modules/gallery/components/sections/BackofficeGallery.vue.js +1 -1
  22. package/dist/martyrs/src/modules/marketplace/views/components/pages/Marketplace.vue.js +1 -1
  23. package/dist/martyrs/src/modules/notifications/components/elements/NotificationBadge.vue.js +3 -3
  24. package/dist/martyrs/src/modules/notifications/components/elements/NotificationBadge.vue.js.map +1 -1
  25. package/dist/martyrs/src/modules/notifications/components/layouts/NotificationsLayout.vue.js +11 -40
  26. package/dist/martyrs/src/modules/notifications/components/layouts/NotificationsLayout.vue.js.map +1 -1
  27. package/dist/martyrs/src/modules/notifications/components/pages/Notifications.vue.js +26 -21
  28. package/dist/martyrs/src/modules/notifications/components/pages/Notifications.vue.js.map +1 -1
  29. package/dist/martyrs/src/modules/notifications/components/sections/NotificationPreferences.vue.js +54 -48
  30. package/dist/martyrs/src/modules/notifications/components/sections/NotificationPreferences.vue.js.map +1 -1
  31. package/dist/martyrs/src/modules/notifications/components/sections/NotificationsList.vue.js +37 -117
  32. package/dist/martyrs/src/modules/notifications/components/sections/NotificationsList.vue.js.map +1 -1
  33. package/dist/martyrs/src/modules/notifications/notifications.client.js +18 -15
  34. package/dist/martyrs/src/modules/notifications/notifications.client.js.map +1 -1
  35. package/dist/martyrs/src/modules/orders/components/blocks/CardOrderUser.vue.js +90 -175
  36. package/dist/martyrs/src/modules/orders/components/blocks/CardOrderUser.vue.js.map +1 -1
  37. package/dist/martyrs/src/modules/orders/components/pages/OrderBackoffice.vue.js +6 -6
  38. package/dist/martyrs/src/modules/orders/components/pages/OrderBackoffice.vue.js.map +1 -1
  39. package/dist/martyrs/src/modules/orders/components/pages/Orders.vue.js +41 -28
  40. package/dist/martyrs/src/modules/orders/components/pages/Orders.vue.js.map +1 -1
  41. package/dist/martyrs/src/modules/orders/components/sections/FormDelivery.vue.js +1 -1
  42. package/dist/martyrs/src/modules/orders/orders.client.js +14 -14
  43. package/dist/martyrs/src/modules/orders/orders.client.js.map +1 -1
  44. package/dist/martyrs/src/modules/organizations/components/pages/OrganizationBackoffice.vue.js +1 -1
  45. package/dist/martyrs/src/modules/organizations/components/pages/OrganizationEdit.vue.js +88 -39
  46. package/dist/martyrs/src/modules/organizations/components/pages/OrganizationEdit.vue.js.map +1 -1
  47. package/dist/martyrs/src/modules/products/components/pages/CategoryEdit.vue.js +1 -1
  48. package/dist/martyrs/src/modules/products/components/pages/ProductEdit.vue.js +1 -1
  49. package/dist/martyrs/src/modules/products/components/pages/Products.vue.js +1 -1
  50. package/dist/style.css +73 -265
  51. package/package.json +1 -1
  52. package/src/modules/TASKS.MD +26 -1
  53. package/src/modules/auth/views/components/pages/Profile.vue +9 -15
  54. package/src/modules/auth/views/components/pages/ProfileEdit.vue +1 -1
  55. package/src/modules/auth/views/components/pages/UserDashboard.vue +214 -125
  56. package/src/modules/auth/views/configs/navigation.user.config.js +17 -11
  57. package/src/modules/auth/views/router/users.router.js +0 -1
  58. package/src/modules/core/views/classes/ws.manager.js +20 -1
  59. package/src/modules/core/views/utils/vue-app-renderer.js +9 -3
  60. package/src/modules/notifications/components/elements/NotificationBadge.vue +1 -1
  61. package/src/modules/notifications/components/layouts/NotificationsLayout.vue +9 -53
  62. package/src/modules/notifications/components/pages/Notifications.vue +21 -22
  63. package/src/modules/notifications/components/sections/NotificationPreferences.vue +41 -180
  64. package/src/modules/notifications/components/sections/NotificationsList.vue +39 -219
  65. package/src/modules/notifications/notifications.client.js +17 -16
  66. package/src/modules/orders/components/blocks/CardOrderUser.vue +88 -190
  67. package/src/modules/orders/components/pages/OrderBackoffice.vue +5 -5
  68. package/src/modules/orders/components/pages/Orders.vue +56 -50
  69. package/src/modules/organizations/components/pages/OrganizationEdit.vue +42 -11
  70. package/dist/martyrs/src/components/SelectMulti/SelectMulti.vue.js +0 -625
  71. package/dist/martyrs/src/components/SelectMulti/SelectMulti.vue.js.map +0 -1
  72. package/dist/martyrs/src/modules/auth/views/components/blocks/ProfileCard.vue.js +0 -44
  73. package/dist/martyrs/src/modules/auth/views/components/blocks/ProfileCard.vue.js.map +0 -1
  74. package/dist/martyrs/src/modules/core/views/components/sections/Filters.vue.js.map +0 -1
  75. package/dist/martyrs/src/modules/orders/components/icons/IconStatusCanceled.vue.js +0 -32
  76. package/dist/martyrs/src/modules/orders/components/icons/IconStatusCanceled.vue.js.map +0 -1
  77. package/dist/martyrs/src/modules/orders/components/icons/IconStatusConfirmed.vue.js +0 -32
  78. package/dist/martyrs/src/modules/orders/components/icons/IconStatusConfirmed.vue.js.map +0 -1
  79. package/dist/martyrs/src/modules/orders/components/icons/IconStatusCreated.vue.js +0 -32
  80. package/dist/martyrs/src/modules/orders/components/icons/IconStatusCreated.vue.js.map +0 -1
  81. package/dist/martyrs/src/modules/orders/components/icons/IconStatusDelay.vue.js +0 -32
  82. package/dist/martyrs/src/modules/orders/components/icons/IconStatusDelay.vue.js.map +0 -1
  83. package/dist/martyrs/src/modules/orders/components/icons/IconStatusFinished.vue.js +0 -32
  84. package/dist/martyrs/src/modules/orders/components/icons/IconStatusFinished.vue.js.map +0 -1
  85. package/dist/martyrs/src/modules/orders/components/icons/IconStatusInUse.vue.js +0 -32
  86. package/dist/martyrs/src/modules/orders/components/icons/IconStatusInUse.vue.js.map +0 -1
@@ -1,51 +1,49 @@
1
1
  <template>
2
- <div class="notification-preferences">
3
- <h2 class="mn-b-small">Notification Preferences</h2>
4
- <p class="description">Choose how you want to receive notifications</p>
5
-
6
- <div v-if="loading" class="preferences-loading">
7
- <div class="loading-spinner">🔄</div>
8
- <p>Loading preferences...</p>
2
+ <div>
3
+ <p class="t-transp mn-b-small">Choose how you want to receive notifications</p>
4
+
5
+ <div v-if="loading" class="pd-large t-center t-transp">
6
+ <Loader />
9
7
  </div>
10
-
11
- <div v-else class="preferences-form">
12
- <div
13
- v-for="(enabled, channelType) in preferences"
14
- :key="channelType"
15
- class="preference-item"
8
+
9
+ <div v-else class="gap-thin flex-column flex">
10
+ <div
11
+ v-for="(enabled, channelType) in preferences"
12
+ :key="channelType"
13
+ class="flex flex-v-center flex-between bg-light radius-small pd-small"
16
14
  >
17
- <div class="preference-info">
18
- <div class="preference-icon">{{ getChannelIcon(channelType) }}</div>
19
- <div class="preference-details">
20
- <h3>{{ getChannelName(channelType) }}</h3>
21
- <p>{{ getChannelDescription(channelType) }}</p>
15
+ <div class="flex w-100 flex-v-center gap-small mn-r-small">
16
+ <div class="h4">{{ getChannelIcon(channelType) }}</div>
17
+ <div class="flex-column flex gap-micro">
18
+ <p class="fw-medium lh-1">{{ getChannelName(channelType) }}</p>
19
+ <p class="p-small t-transp lh-1">{{ getChannelDescription(channelType) }}</p>
22
20
  </div>
23
21
  </div>
24
- <label class="toggle-switch">
25
- <input
26
- type="checkbox"
27
- :checked="enabled"
28
- @change="updatePreference(channelType, $event.target.checked)"
29
- >
30
- <span class="toggle-slider"></span>
31
- </label>
22
+ <Checkbox
23
+ mode="switch"
24
+ :radio="enabled"
25
+ @update:radio="updatePreference(channelType, $event)"
26
+ class="flex-shrink-0"
27
+ />
32
28
  </div>
33
-
34
- <div class="form-actions">
35
- <button
36
- class="save-btn"
37
- :disabled="!hasChanges || saving"
38
- @click="savePreferences"
39
- >
40
- {{ saving ? 'Saving...' : 'Save Changes' }}
41
- </button>
42
- <button
43
- v-if="hasChanges"
44
- class="cancel-btn"
45
- @click="resetChanges"
29
+
30
+ <div class="flex flex-end gap-small mn-t-thin">
31
+ <Button
32
+ v-if="hasChanges"
33
+ :submit="resetChanges"
34
+ :showLoader="false"
35
+ :showSucces="false"
36
+ class="bg-white t-dark"
46
37
  >
47
38
  Cancel
48
- </button>
39
+ </Button>
40
+ <Button
41
+ :submit="savePreferences"
42
+ :validation="!hasChanges || saving"
43
+ class="bg-main t-white"
44
+ >
45
+ {{ saving ? 'Saving...' : 'Save Changes' }}
46
+ </Button>
49
47
  </div>
50
48
  </div>
51
49
  </div>
@@ -53,6 +51,9 @@
53
51
 
54
52
  <script setup>
55
53
  import { ref, reactive, computed, onMounted, inject } from 'vue';
54
+ import Checkbox from '@martyrs/src/components/Checkbox/Checkbox.vue';
55
+ import Button from '@martyrs/src/components/Button/Button.vue';
56
+ import Loader from '@martyrs/src/components/Loader/Loader.vue';
56
57
 
57
58
  // Get notification preferences functionality
58
59
  const {
@@ -154,143 +155,3 @@ onMounted(async () => {
154
155
  });
155
156
  </script>
156
157
 
157
- <style scoped>
158
-
159
- .description {
160
- color: #666;
161
- margin-bottom: 24px;
162
- }
163
-
164
- .preferences-loading {
165
- display: flex;
166
- flex-direction: column;
167
- align-items: center;
168
- justify-content: center;
169
- padding: 48px 0;
170
- }
171
-
172
- .loading-spinner {
173
- font-size: 2rem;
174
- margin-bottom: 16px;
175
- animation: spin 2s linear infinite;
176
- }
177
-
178
- @keyframes spin {
179
- 0% { transform: rotate(0deg); }
180
- 100% { transform: rotate(360deg); }
181
- }
182
-
183
- .preference-item {
184
- display: flex;
185
- align-items: center;
186
- justify-content: space-between;
187
- padding: 16px;
188
- border-bottom: 1px solid #eee;
189
- }
190
-
191
- .preference-item:last-child {
192
- border-bottom: none;
193
- }
194
-
195
- .preference-info {
196
- display: flex;
197
- align-items: center;
198
- flex: 1;
199
- }
200
-
201
- .preference-icon {
202
- font-size: 1.5rem;
203
- margin-right: 16px;
204
- width: 40px;
205
- height: 40px;
206
- display: flex;
207
- align-items: center;
208
- justify-content: center;
209
- }
210
-
211
- .preference-details h3 {
212
- margin: 0 0 4px 0;
213
- font-size: 1rem;
214
- }
215
-
216
- .preference-details p {
217
- margin: 0;
218
- color: #666;
219
- font-size: 0.875rem;
220
- }
221
-
222
- /* Toggle switch styles */
223
- .toggle-switch {
224
- position: relative;
225
- display: inline-block;
226
- width: 50px;
227
- height: 24px;
228
- }
229
-
230
- .toggle-switch input {
231
- opacity: 0;
232
- width: 0;
233
- height: 0;
234
- }
235
-
236
- .toggle-slider {
237
- position: absolute;
238
- cursor: pointer;
239
- top: 0;
240
- left: 0;
241
- right: 0;
242
- bottom: 0;
243
- background-color: #ccc;
244
- transition: .4s;
245
- border-radius: 24px;
246
- }
247
-
248
- .toggle-slider:before {
249
- position: absolute;
250
- content: "";
251
- height: 16px;
252
- width: 16px;
253
- left: 4px;
254
- bottom: 4px;
255
- background-color: white;
256
- transition: .4s;
257
- border-radius: 50%;
258
- }
259
-
260
- input:checked + .toggle-slider {
261
- background-color: #2196F3;
262
- }
263
-
264
- input:checked + .toggle-slider:before {
265
- transform: translateX(26px);
266
- }
267
-
268
- .form-actions {
269
- margin-top: 24px;
270
- display: flex;
271
- justify-content: flex-end;
272
- gap: 16px;
273
- }
274
-
275
- .save-btn, .cancel-btn {
276
- padding: 8px 16px;
277
- border-radius: 4px;
278
- cursor: pointer;
279
- }
280
-
281
- .save-btn {
282
- background-color: #2196F3;
283
- border: none;
284
- color: white;
285
- }
286
-
287
- .save-btn:disabled {
288
- background-color: #ccc;
289
- cursor: not-allowed;
290
- }
291
-
292
- .cancel-btn {
293
- background-color: white;
294
- border: 1px solid #ccc;
295
- }
296
- </style>
@@ -1,111 +1,52 @@
1
1
  <template>
2
- <div class="notifications-list-container">
3
- <div v-if="!MOBILE_APP" class="notifications-header">
4
- <h2>Notifications</h2>
5
- <!-- <div class="notifications-controls">
6
- <div class="notifications-filter">
7
- <label for="filter-type">Filter: </label>
8
- <select id="filter-type" v-model="filterType">
9
- <option value="all">All</option>
10
- <option value="unread">Unread</option>
11
- <option value="read">Read</option>
12
- <option value="info">Info</option>
13
- <option value="success">Success</option>
14
- <option value="warning">Warning</option>
15
- <option value="error">Error</option>
16
- </select>
17
- </div>
18
- <button
19
- v-if="unreadCount > 0"
20
- class="mark-all-read-btn"
21
- @click="markAllAsRead"
22
- >
23
- Mark all as read
24
- </button>
25
- </div> -->
26
- </div>
27
-
28
- <div v-if="loading" class="notifications-loading">
29
- <div class="loading-spinner">🔄</div>
30
- <p>Loading notifications...</p>
31
- </div>
32
-
33
- <div v-else-if="filteredNotifications.length === 0" class="notifications-empty">
34
- <p>{{ emptyMessage }}</p>
35
- </div>
36
-
37
- <div v-else class="notifications-items">
38
- <notification-item
39
- v-for="notification in filteredNotifications"
40
- :key="notification._id"
41
- :notification="notification"
42
- @click="handleNotificationClick(notification)"
43
- />
44
- </div>
45
-
46
- <div v-if="!loading && notifications.length > 0" class="notifications-footer">
47
- <button v-if="lastSync" class="refresh-btn" @click="refreshNotifications">
48
- 🔄 Last updated: {{ formatTime(lastSync) }}
49
- </button>
50
- </div>
51
- </div>
2
+ <Feed
3
+ :states="{
4
+ empty: {
5
+ title: 'No Notifications',
6
+ description: 'You have no notifications yet'
7
+ }
8
+ }"
9
+ :store="{
10
+ read: fetchNotifications
11
+ }"
12
+ :options="{
13
+ limit: 20
14
+ }"
15
+ :skeleton="{
16
+ structure: [
17
+ { block: 'text', size: 'small' },
18
+ { block: 'text', size: 'large' }
19
+ ]
20
+ }"
21
+ v-slot="{ items }"
22
+ class="gap-thin cols-1"
23
+ >
24
+ <NotificationItem
25
+ v-for="notification in items"
26
+ :key="notification._id"
27
+ :notification="notification"
28
+ @click="handleNotificationClick(notification)"
29
+ />
30
+ </Feed>
52
31
  </template>
53
32
 
54
33
  <script setup>
55
- import { ref, computed, onMounted, inject } from 'vue';
56
- import { useRouter } from 'vue-router';
34
+ import { inject } from 'vue';
35
+ import Feed from '@martyrs/src/components/Feed/Feed.vue';
57
36
  import NotificationItem from '../blocks/NotificationItem.vue';
58
37
  import * as auth from '@martyrs/src/modules/auth/views/store/auth.js';
38
+ import { actions } from '@martyrs/src/modules/notifications/store/notifications.store.js';
59
39
 
60
- // Get router and notification functionality
61
- const router = useRouter();
62
- const {
63
- notifications,
64
- unreadCount,
65
- loading,
66
- lastSync,
67
- markAllAsRead,
68
- getNotifications,
69
- handleNotificationAction
70
- } = inject('useNotifications')();
40
+ const { handleNotificationAction } = inject('useNotifications')();
71
41
 
72
- // Local state
73
- const filterType = ref('all');
74
-
75
- // Computed properties
76
- const filteredNotifications = computed(() => {
77
- let filtered = [...notifications.value];
78
-
79
- // Apply filters
80
- if (filterType.value === 'unread') {
81
- filtered = filtered.filter(n => n.status !== 'read');
82
- } else if (filterType.value === 'read') {
83
- filtered = filtered.filter(n => n.status === 'read');
84
- } else if (filterType.value !== 'all') {
85
- // Filter by notification type
86
- filtered = filtered.filter(n => n.type === filterType.value);
87
- }
88
-
89
- // Sort by creation date (newest first)
90
- return filtered.sort((a, b) => new Date(b.createdAt) - new Date(a.createdAt));
91
- });
42
+ const fetchNotifications = async (options) => {
43
+ const userId = auth.state.user._id;
44
+ if (!userId) return [];
92
45
 
93
- const emptyMessage = computed(() => {
94
- if (notifications.value.length === 0) {
95
- return 'You have no notifications';
96
- }
97
-
98
- switch (filterType.value) {
99
- case 'unread':
100
- return 'You have no unread notifications';
101
- case 'read':
102
- return 'You have no read notifications';
103
- default:
104
- return `You have no ${filterType.value} notifications`;
105
- }
106
- });
46
+ const data = await actions.getNotifications(userId);
47
+ return data || [];
48
+ };
107
49
 
108
- // Methods
109
50
  const handleNotificationClick = (notification) => {
110
51
  if (notification._id) {
111
52
  handleNotificationAction({
@@ -114,125 +55,4 @@ const handleNotificationClick = (notification) => {
114
55
  });
115
56
  }
116
57
  };
117
-
118
- const refreshNotifications = () => {
119
- const userId = auth.state.user._id;
120
- if (userId) {
121
- getNotifications(userId);
122
- }
123
- };
124
-
125
- // Format relative time without external libraries
126
- const formatTime = (timestamp) => {
127
- if (!timestamp) return '';
128
-
129
- const now = new Date();
130
- const date = new Date(timestamp);
131
- const diffSeconds = Math.floor((now - date) / 1000);
132
-
133
- // Format based on how long ago
134
- if (diffSeconds < 60) {
135
- return 'Just now';
136
- } else if (diffSeconds < 3600) {
137
- const minutes = Math.floor(diffSeconds / 60);
138
- return `${minutes} ${minutes === 1 ? 'minute' : 'minutes'} ago`;
139
- } else if (diffSeconds < 86400) {
140
- const hours = Math.floor(diffSeconds / 3600);
141
- return `${hours} ${hours === 1 ? 'hour' : 'hours'} ago`;
142
- } else {
143
- // Format date string
144
- return date.toLocaleDateString(undefined, {
145
- year: 'numeric',
146
- month: 'short',
147
- day: 'numeric',
148
- hour: '2-digit',
149
- minute: '2-digit'
150
- });
151
- }
152
- };
153
-
154
- // Lifecycle
155
- onMounted(() => {
156
- const userId = auth.state.user._id;
157
- if (userId && notifications.value.length === 0 && !loading.value) {
158
- getNotifications(userId);
159
- }
160
- });
161
58
  </script>
162
-
163
- <style scoped>
164
- .notifications-list-container {
165
- width: 100%;
166
- max-width: 800px;
167
- margin: 0 auto;
168
- }
169
-
170
- .notifications-header {
171
- display: flex;
172
- justify-content: space-between;
173
- align-items: center;
174
- margin-bottom: 20px;
175
- }
176
-
177
- .notifications-controls {
178
- display: flex;
179
- align-items: center;
180
- gap: 16px;
181
- }
182
-
183
- .notifications-filter select {
184
- padding: 6px 12px;
185
- border-radius: 4px;
186
- border: 1px solid #ddd;
187
- }
188
-
189
- .mark-all-read-btn {
190
- background-color: #2196f3;
191
- color: white;
192
- border: none;
193
- padding: 6px 12px;
194
- border-radius: 4px;
195
- cursor: pointer;
196
- }
197
-
198
- .notifications-loading,
199
- .notifications-empty {
200
- padding: 40px 0;
201
- text-align: center;
202
- color: #666;
203
- }
204
-
205
- .loading-spinner {
206
- font-size: 2rem;
207
- margin-bottom: 10px;
208
- animation: spin 1s linear infinite;
209
- }
210
-
211
- @keyframes spin {
212
- from { transform: rotate(0deg); }
213
- to { transform: rotate(360deg); }
214
- }
215
-
216
- .notifications-items {
217
- display: flex;
218
- flex-direction: column;
219
- gap: 10px;
220
- }
221
-
222
- .notifications-footer {
223
- margin-top: 20px;
224
- text-align: center;
225
- }
226
-
227
- .refresh-btn {
228
- background: none;
229
- border: none;
230
- color: #666;
231
- cursor: pointer;
232
- padding: 6px 12px;
233
- }
234
-
235
- .refresh-btn:hover {
236
- color: #2196f3;
237
- }
238
- </style>
@@ -439,29 +439,30 @@ function initializeNotifications(app, store, router, options = {}) {
439
439
  const autoInit = !isServer && options.autoInit !== false;
440
440
 
441
441
  if (autoInit) {
442
- // Initialize immediately (supports both authenticated and anonymous users)
443
- notificationManager.initialize();
444
-
445
- // Watch for user login/logout using store.core.state.session
442
+ // Watch for user login/logout using store.core.state.session.userId
443
+ // immediate: true — сработает сразу после применения initialState (гидратация)
446
444
  watch(
447
- () => store.core.state.session.token,
448
- async (token, oldToken) => {
449
- const isAuthenticated = !!token;
450
- const wasAuthenticated = !!oldToken;
451
-
452
- if (isAuthenticated && !wasAuthenticated) {
453
- // Re-register device for authenticated user
454
- console.log('[Notifications] User logged in, re-registering device...');
445
+ () => store.core.state.session.userId,
446
+ async (userId, oldUserId) => {
447
+ console.log('[Notifications] Watch triggered, userId:', userId, 'oldUserId:', oldUserId);
448
+ if (userId && !oldUserId) {
449
+ // Пользователь залогинен (либо при гидратации, либо при логине)
450
+ console.log('[Notifications] User authenticated, initializing WebSocket...', userId);
455
451
  await store.notifications.actions.reregisterDeviceAfterLogin();
456
- // Reinitialize notifications for authenticated user
457
452
  notificationManager.disconnect();
458
453
  await notificationManager.initialize();
459
- } else if (!isAuthenticated && wasAuthenticated) {
460
- // Keep notifications active for anonymous users, just reset user-specific data
454
+ } else if (!userId && oldUserId) {
455
+ // Пользователь разлогинился
461
456
  console.log('[Notifications] User logged out, resetting notifications...');
457
+ notificationManager.disconnect();
462
458
  store.notifications.mutations.resetNotifications();
459
+ } else if (!userId && !oldUserId) {
460
+ // Анонимный пользователь — инициализируем без WebSocket
461
+ console.log('[Notifications] Anonymous user, initializing without WebSocket...');
462
+ await notificationManager.initialize();
463
463
  }
464
- }
464
+ },
465
+ { immediate: true }
465
466
  );
466
467
  }
467
468