@ozdao/martyrs 0.2.511 → 0.2.513

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 (156) hide show
  1. package/dist/{main-B1XN9Zjg.cjs → main-CVOBCkmD.cjs} +5 -5
  2. package/dist/{main-u7zgfMGL.js → main-CVRRj-vK.js} +259 -262
  3. package/dist/martyrs/src/components/Button/Button.vue2.cjs.map +1 -1
  4. package/dist/martyrs/src/components/Button/Button.vue2.js.map +1 -1
  5. package/dist/martyrs/src/components/Menu/{Menu.vue.cjs → Menu.vue2.cjs} +2 -2
  6. package/dist/martyrs/src/components/Menu/Menu.vue2.cjs.map +1 -0
  7. package/dist/martyrs/src/components/Menu/{Menu.vue.js → Menu.vue2.js} +2 -2
  8. package/dist/martyrs/src/components/Menu/Menu.vue2.js.map +1 -0
  9. package/dist/martyrs/src/components/Menu/MenuItem.vue.cjs +2 -2
  10. package/dist/martyrs/src/components/Menu/MenuItem.vue.cjs.map +1 -1
  11. package/dist/martyrs/src/components/Menu/MenuItem.vue.js +2 -2
  12. package/dist/martyrs/src/components/Menu/MenuItem.vue.js.map +1 -1
  13. package/dist/martyrs/src/modules/auth/views/components/pages/Profile.vue.cjs +2 -2
  14. package/dist/martyrs/src/modules/auth/views/components/pages/Profile.vue.cjs.map +1 -1
  15. package/dist/martyrs/src/modules/auth/views/components/pages/Profile.vue.js +2 -2
  16. package/dist/martyrs/src/modules/auth/views/components/pages/Profile.vue.js.map +1 -1
  17. package/dist/martyrs/src/modules/chats/components/sections/ChatWindow.vue.cjs +0 -2
  18. package/dist/martyrs/src/modules/chats/components/sections/ChatWindow.vue.cjs.map +1 -1
  19. package/dist/martyrs/src/modules/chats/components/sections/ChatWindow.vue.js +0 -2
  20. package/dist/martyrs/src/modules/chats/components/sections/ChatWindow.vue.js.map +1 -1
  21. package/dist/martyrs/src/modules/events/components/pages/EventsBackoffice.vue.cjs +3 -5
  22. package/dist/martyrs/src/modules/events/components/pages/EventsBackoffice.vue.cjs.map +1 -1
  23. package/dist/martyrs/src/modules/events/components/pages/EventsBackoffice.vue.js +3 -5
  24. package/dist/martyrs/src/modules/events/components/pages/EventsBackoffice.vue.js.map +1 -1
  25. package/dist/martyrs/src/modules/globals/globals.client.cjs +10 -1
  26. package/dist/martyrs/src/modules/globals/globals.client.cjs.map +1 -1
  27. package/dist/martyrs/src/modules/globals/globals.client.js +31 -22
  28. package/dist/martyrs/src/modules/globals/globals.client.js.map +1 -1
  29. package/dist/martyrs/src/modules/globals/views/components/layouts/Client.vue.cjs.map +1 -1
  30. package/dist/martyrs/src/modules/globals/views/components/layouts/Client.vue.js.map +1 -1
  31. package/dist/martyrs/src/modules/globals/views/components/sections/Filters.vue2.cjs +42 -46
  32. package/dist/martyrs/src/modules/globals/views/components/sections/Filters.vue2.cjs.map +1 -1
  33. package/dist/martyrs/src/modules/globals/views/components/sections/Filters.vue2.js +45 -49
  34. package/dist/martyrs/src/modules/globals/views/components/sections/Filters.vue2.js.map +1 -1
  35. package/dist/martyrs/src/modules/globals/views/components/sections/Walkthrough.vue.cjs +308 -0
  36. package/dist/martyrs/src/modules/globals/views/components/sections/Walkthrough.vue.cjs.map +1 -0
  37. package/dist/martyrs/src/modules/globals/views/components/sections/Walkthrough.vue.js +308 -0
  38. package/dist/martyrs/src/modules/globals/views/components/sections/Walkthrough.vue.js.map +1 -0
  39. package/dist/martyrs/src/modules/inventory/components/pages/Inventory.vue.cjs +14 -16
  40. package/dist/martyrs/src/modules/inventory/components/pages/Inventory.vue.cjs.map +1 -1
  41. package/dist/martyrs/src/modules/inventory/components/pages/Inventory.vue.js +13 -15
  42. package/dist/martyrs/src/modules/inventory/components/pages/Inventory.vue.js.map +1 -1
  43. package/dist/martyrs/src/modules/notifications/notifications.client.cjs +101 -32
  44. package/dist/martyrs/src/modules/notifications/notifications.client.cjs.map +1 -1
  45. package/dist/martyrs/src/modules/notifications/notifications.client.js +101 -32
  46. package/dist/martyrs/src/modules/notifications/notifications.client.js.map +1 -1
  47. package/dist/martyrs/src/modules/notifications/store/notifications.store.cjs +45 -12
  48. package/dist/martyrs/src/modules/notifications/store/notifications.store.cjs.map +1 -1
  49. package/dist/martyrs/src/modules/notifications/store/notifications.store.js +38 -5
  50. package/dist/martyrs/src/modules/notifications/store/notifications.store.js.map +1 -1
  51. package/dist/martyrs/src/modules/orders/components/blocks/CardOrderItem.vue.cjs +19 -18
  52. package/dist/martyrs/src/modules/orders/components/blocks/CardOrderItem.vue.cjs.map +1 -1
  53. package/dist/martyrs/src/modules/orders/components/blocks/CardOrderItem.vue.js +19 -18
  54. package/dist/martyrs/src/modules/orders/components/blocks/CardOrderItem.vue.js.map +1 -1
  55. package/dist/martyrs/src/modules/orders/components/forms/FormCustomerDetails.vue.cjs +82 -61
  56. package/dist/martyrs/src/modules/orders/components/forms/FormCustomerDetails.vue.cjs.map +1 -1
  57. package/dist/martyrs/src/modules/orders/components/forms/FormCustomerDetails.vue.js +83 -62
  58. package/dist/martyrs/src/modules/orders/components/forms/FormCustomerDetails.vue.js.map +1 -1
  59. package/dist/martyrs/src/modules/orders/components/pages/OrderBackoffice.vue.cjs +3 -3
  60. package/dist/martyrs/src/modules/orders/components/pages/OrderBackoffice.vue.cjs.map +1 -1
  61. package/dist/martyrs/src/modules/orders/components/pages/OrderBackoffice.vue.js +3 -3
  62. package/dist/martyrs/src/modules/orders/components/pages/OrderBackoffice.vue.js.map +1 -1
  63. package/dist/martyrs/src/modules/orders/components/pages/OrderCreate.vue.cjs +4 -2
  64. package/dist/martyrs/src/modules/orders/components/pages/OrderCreate.vue.cjs.map +1 -1
  65. package/dist/martyrs/src/modules/orders/components/pages/OrderCreate.vue.js +4 -2
  66. package/dist/martyrs/src/modules/orders/components/pages/OrderCreate.vue.js.map +1 -1
  67. package/dist/martyrs/src/modules/orders/components/sections/FormDelivery.vue.cjs +2 -2
  68. package/dist/martyrs/src/modules/orders/components/sections/FormDelivery.vue.cjs.map +1 -1
  69. package/dist/martyrs/src/modules/orders/components/sections/FormDelivery.vue.js +2 -2
  70. package/dist/martyrs/src/modules/orders/components/sections/FormDelivery.vue.js.map +1 -1
  71. package/dist/martyrs/src/modules/orders/orders.client.cjs +1 -0
  72. package/dist/martyrs/src/modules/orders/orders.client.cjs.map +1 -1
  73. package/dist/martyrs/src/modules/orders/orders.client.js +2 -0
  74. package/dist/martyrs/src/modules/orders/orders.client.js.map +1 -1
  75. package/dist/martyrs/src/modules/orders/store/shopcart.cjs +33 -23
  76. package/dist/martyrs/src/modules/orders/store/shopcart.cjs.map +1 -1
  77. package/dist/martyrs/src/modules/orders/store/shopcart.js +31 -21
  78. package/dist/martyrs/src/modules/orders/store/shopcart.js.map +1 -1
  79. package/dist/martyrs/src/modules/organizations/components/pages/Members.vue.cjs +1 -1
  80. package/dist/martyrs/src/modules/organizations/components/pages/Members.vue.js +1 -1
  81. package/dist/martyrs/src/modules/organizations/components/pages/Organization.vue.cjs +3 -18
  82. package/dist/martyrs/src/modules/organizations/components/pages/Organization.vue.cjs.map +1 -1
  83. package/dist/martyrs/src/modules/organizations/components/pages/Organization.vue.js +4 -19
  84. package/dist/martyrs/src/modules/organizations/components/pages/Organization.vue.js.map +1 -1
  85. package/dist/martyrs/src/modules/organizations/components/pages/OrganizationBackoffice.vue.cjs +1 -1
  86. package/dist/martyrs/src/modules/organizations/components/pages/OrganizationBackoffice.vue.js +1 -1
  87. package/dist/martyrs/src/modules/organizations/configs/navigation.organization.config.cjs +37 -43
  88. package/dist/martyrs/src/modules/organizations/configs/navigation.organization.config.cjs.map +1 -1
  89. package/dist/martyrs/src/modules/organizations/configs/navigation.organization.config.js +48 -54
  90. package/dist/martyrs/src/modules/organizations/configs/navigation.organization.config.js.map +1 -1
  91. package/dist/martyrs/src/modules/organizations/router/organizations.cjs +1 -1
  92. package/dist/martyrs/src/modules/organizations/router/organizations.js +1 -1
  93. package/dist/martyrs/src/modules/products/components/pages/Products.vue.cjs +11 -8
  94. package/dist/martyrs/src/modules/products/components/pages/Products.vue.cjs.map +1 -1
  95. package/dist/martyrs/src/modules/products/components/pages/Products.vue.js +11 -8
  96. package/dist/martyrs/src/modules/products/components/pages/Products.vue.js.map +1 -1
  97. package/dist/martyrs.cjs.js +1 -1
  98. package/dist/martyrs.css +1 -1
  99. package/dist/martyrs.es.js +1 -1
  100. package/dist/node_modules/.pnpm/capacitor-plugin-app-tracking-transparency@2.0.5_@capacitor_core@7.2.0/node_modules/capacitor-plugin-app-tracking-transparency/dist/esm/index.cjs +8 -0
  101. package/dist/node_modules/.pnpm/capacitor-plugin-app-tracking-transparency@2.0.5_@capacitor_core@7.2.0/node_modules/capacitor-plugin-app-tracking-transparency/dist/esm/index.cjs.map +1 -0
  102. package/dist/node_modules/.pnpm/capacitor-plugin-app-tracking-transparency@2.0.5_@capacitor_core@7.2.0/node_modules/capacitor-plugin-app-tracking-transparency/dist/esm/index.js +8 -0
  103. package/dist/node_modules/.pnpm/capacitor-plugin-app-tracking-transparency@2.0.5_@capacitor_core@7.2.0/node_modules/capacitor-plugin-app-tracking-transparency/dist/esm/index.js.map +1 -0
  104. package/dist/node_modules/.pnpm/capacitor-plugin-app-tracking-transparency@2.0.5_@capacitor_core@7.2.0/node_modules/capacitor-plugin-app-tracking-transparency/dist/esm/web.cjs +13 -0
  105. package/dist/node_modules/.pnpm/capacitor-plugin-app-tracking-transparency@2.0.5_@capacitor_core@7.2.0/node_modules/capacitor-plugin-app-tracking-transparency/dist/esm/web.cjs.map +1 -0
  106. package/dist/node_modules/.pnpm/capacitor-plugin-app-tracking-transparency@2.0.5_@capacitor_core@7.2.0/node_modules/capacitor-plugin-app-tracking-transparency/dist/esm/web.js +13 -0
  107. package/dist/node_modules/.pnpm/capacitor-plugin-app-tracking-transparency@2.0.5_@capacitor_core@7.2.0/node_modules/capacitor-plugin-app-tracking-transparency/dist/esm/web.js.map +1 -0
  108. package/dist/node_modules/.pnpm/embla-carousel-reactive-utils@8.6.0_embla-carousel@8.6.0/node_modules/embla-carousel-reactive-utils/esm/embla-carousel-reactive-utils.esm.cjs +43 -0
  109. package/dist/node_modules/.pnpm/embla-carousel-reactive-utils@8.6.0_embla-carousel@8.6.0/node_modules/embla-carousel-reactive-utils/esm/embla-carousel-reactive-utils.esm.cjs.map +1 -0
  110. package/dist/node_modules/.pnpm/embla-carousel-reactive-utils@8.6.0_embla-carousel@8.6.0/node_modules/embla-carousel-reactive-utils/esm/embla-carousel-reactive-utils.esm.js +43 -0
  111. package/dist/node_modules/.pnpm/embla-carousel-reactive-utils@8.6.0_embla-carousel@8.6.0/node_modules/embla-carousel-reactive-utils/esm/embla-carousel-reactive-utils.esm.js.map +1 -0
  112. package/dist/node_modules/.pnpm/embla-carousel-vue@8.6.0_vue@3.5.13_typescript@5.8.3_/node_modules/embla-carousel-vue/esm/embla-carousel-vue.esm.cjs +43 -0
  113. package/dist/node_modules/.pnpm/embla-carousel-vue@8.6.0_vue@3.5.13_typescript@5.8.3_/node_modules/embla-carousel-vue/esm/embla-carousel-vue.esm.cjs.map +1 -0
  114. package/dist/node_modules/.pnpm/embla-carousel-vue@8.6.0_vue@3.5.13_typescript@5.8.3_/node_modules/embla-carousel-vue/esm/embla-carousel-vue.esm.js +43 -0
  115. package/dist/node_modules/.pnpm/embla-carousel-vue@8.6.0_vue@3.5.13_typescript@5.8.3_/node_modules/embla-carousel-vue/esm/embla-carousel-vue.esm.js.map +1 -0
  116. package/dist/node_modules/.pnpm/embla-carousel@8.6.0/node_modules/embla-carousel/esm/embla-carousel.esm.cjs +1630 -0
  117. package/dist/node_modules/.pnpm/embla-carousel@8.6.0/node_modules/embla-carousel/esm/embla-carousel.esm.cjs.map +1 -0
  118. package/dist/node_modules/.pnpm/embla-carousel@8.6.0/node_modules/embla-carousel/esm/embla-carousel.esm.js +1630 -0
  119. package/dist/node_modules/.pnpm/embla-carousel@8.6.0/node_modules/embla-carousel/esm/embla-carousel.esm.js.map +1 -0
  120. package/dist/notifications.server.cjs +205 -11
  121. package/dist/notifications.server.js +205 -11
  122. package/dist/style.css +258 -242
  123. package/dist/{web--8-wgr6b.js → web-BW449LVt.js} +1 -1
  124. package/dist/{web-BS6utuAZ.cjs → web-CO3tWG6J.cjs} +1 -1
  125. package/package.json +1 -1
  126. package/src/components/Button/Button.vue +2 -2
  127. package/src/components/Menu/MenuItem.vue +11 -6
  128. package/src/modules/auth/views/components/pages/Profile.vue +1 -1
  129. package/src/modules/chats/components/sections/ChatWindow.vue +1 -1
  130. package/src/modules/events/components/pages/EventsBackoffice.vue +0 -1
  131. package/src/modules/globals/globals.client.js +17 -0
  132. package/src/modules/globals/views/components/layouts/Client.vue +1 -0
  133. package/src/modules/globals/views/components/sections/Filters.vue +2 -4
  134. package/src/modules/globals/views/components/sections/Walkthrough.vue +245 -57
  135. package/src/modules/inventory/components/pages/Inventory.vue +0 -1
  136. package/src/modules/notifications/FIXES.md +1 -0
  137. package/src/modules/notifications/controllers/notifications.controller.js +147 -7
  138. package/src/modules/notifications/models/user-device.model.js +10 -2
  139. package/src/modules/notifications/notifications.client.js +127 -41
  140. package/src/modules/notifications/routes/notifications.routes.js +4 -0
  141. package/src/modules/notifications/services/notification.service.js +93 -0
  142. package/src/modules/notifications/store/notifications.store.js +47 -7
  143. package/src/modules/orders/components/blocks/CardOrderItem.vue +1 -1
  144. package/src/modules/orders/components/forms/FormCustomerDetails.vue +52 -35
  145. package/src/modules/orders/components/pages/OrderBackoffice.vue +2 -2
  146. package/src/modules/orders/components/pages/OrderCreate.vue +3 -1
  147. package/src/modules/orders/components/sections/FormDelivery.vue +2 -2
  148. package/src/modules/orders/orders.client.js +2 -0
  149. package/src/modules/orders/store/shopcart.js +34 -23
  150. package/src/modules/organizations/components/pages/Organization.vue +6 -2
  151. package/src/modules/organizations/configs/navigation.organization.config.js +36 -36
  152. package/src/modules/products/components/pages/Products.vue +11 -9
  153. package/src/modules/products/migrations/categories-to-materialized-path.js +0 -3
  154. package/src/styles/base/backgrounds.scss +1 -0
  155. package/dist/martyrs/src/components/Menu/Menu.vue.cjs.map +0 -1
  156. package/dist/martyrs/src/components/Menu/Menu.vue.js.map +0 -1
@@ -17,6 +17,7 @@
17
17
  name="moveFromTop"
18
18
  mode="out-in"
19
19
  >
20
+
20
21
  <section
21
22
  v-if="FirstUse && route.meta.walkthrough"
22
23
  class="w-100 h-100"
@@ -35,10 +35,6 @@
35
35
  >
36
36
  <div class="flex-v-center flex-nowrap flex mn-b-medium">
37
37
  <h3 class="flex-child-full">Filters</h3>
38
- <IconCross
39
- @click="showAllFilters = false"
40
- class="i-regular cursor-pointer"
41
- />
42
38
  </div>
43
39
 
44
40
  <div class="filters-content">
@@ -168,12 +164,14 @@
168
164
  v-model:field="tempSelected[filter.value].min"
169
165
  :placeholder="filter.minPlaceholder || 'Min'"
170
166
  type="number"
167
+ :label="returnCurrency()"
171
168
  class="w-50 bg-light pd-small radius-small"
172
169
  />
173
170
  <Field
174
171
  v-model:field="tempSelected[filter.value].max"
175
172
  :placeholder="filter.maxPlaceholder || 'Max'"
176
173
  type="number"
174
+ :label="returnCurrency()"
177
175
  class="w-50 bg-light pd-small radius-small"
178
176
  />
179
177
  </div>
@@ -1,82 +1,210 @@
1
1
  <template>
2
- <div class="pos-fixed pos-t-0 pos-l-0 w-100 h-100vh z-index-6 bg-light flex embla" ref="emblaNode">
3
- <div class="w-100 embla__container z-index-1">
4
- <div
5
- v-for="(slide, index) in walkthrough"
6
- :key="index"
7
- class="flex-center pd-thin t-center flex-column flex embla__slide"
8
- :style="{ opacity: tweenSlides.length ? tweenSlides[index] : undefined, transform: tweenSlides[index] ? `scale(${tweenSlides[index]})` : '' }"
9
- >
10
- <img loading="lazy" class="w-100" :src="require(`@/assets/images/walkthrough/walkthrough_${index}.png`).default">
11
- <h2 class="mn-b-small">{{slide.title}}</h2>
12
- <p class="p-semi t-transp">{{slide.subtitle}}</p>
2
+ <div class="pos-fixed pos-t-0 pos-l-0 w-100 h-100vh z-index-6 bg-white flex embla" ref="emblaNode">
3
+
4
+
5
+ <div class="embla__container w-100 z-index-1">
6
+
7
+
8
+ <!-- SLIDE 1 -->
9
+ <!-- ------------------------------- -->
10
+ <div class="pos-relative flex-justify-center pd-thin t-center flex-column flex embla__slide">
11
+ <!-- <div class="pos-absolute w-100 h-100 z-index-0 pos-t-0 pos-r-0">
12
+ <div class="pos-absolute z-index-1 pos-t-0 pos-r-0 w-100 h-100 bg-black-grad"></div>
13
+ <img class="pos-absolute z-index-0 pos-t-0 pos-r-0 object-fit-cover h-100 w-100" src="/assets/walkthrough/1.png">
14
+ </div> -->
15
+ <div
16
+ class="flex flex-column flex-center pd-semi o-hidden pos-relative pos-b-0 z-index-1"
17
+ :style="{ opacity: tweenSlides.length ? tweenSlides[0] : undefined, transform: tweenSlides[0] ? `scale(${tweenSlides[0]})` : '' }"
18
+ >
19
+ <img
20
+ :src="'/logo/logo_square.svg'"
21
+ class="i-extra radius-medium mn-b-small"
22
+ >
23
+
24
+ <h3 class="h3 mn-b-medium">Welcome to 3SR</h3>
25
+
26
+ <p class="p-regular t-transp mn-b-big">
27
+ Access premium cameras, lenses, lighting, and audio gear through our app designed for filmmakers and content creators.
28
+ </p>
29
+
30
+
31
+ <button @click="nextSlide" class="bg-main p-big w-max button">
32
+ Get Started
33
+ </button>
34
+ </div>
35
+ </div>
36
+
37
+ <!-- SLIDE 2 -->
38
+ <!-- ------------------------------- -->
39
+ <div class="pos-relative flex-justify-center pd-thin t-center flex-column flex embla__slide">
40
+ <div class="flex flex-column flex-center pd-semi o-hidden pos-relative pos-b-0 z-index-1">
41
+
42
+ <div class="mn-b-small w-4r h-4r mn-auto pd-regular bg-main radius-regular t-white flex flex-center">
43
+ <IconBell/>
44
+ </div>
45
+
46
+ <h3 class="h3 mn-b-medium">Stay in the Loop</h3>
47
+ <p class="p-regular t-transp mn-b-big">
48
+ Get instant notifications about equipment availability, booking confirmations, and exclusive deals from our rental platform.
49
+ </p>
50
+
51
+ <div class="flex flex-column flex-center gap-small">
52
+ <button @click="requestNotificationPermission" class="bg-main p-big w-max button">
53
+ Enable Notifications
54
+ </button>
55
+ <button @click="nextSlide" class="bg-light p-big w-max button">
56
+ Maybe Later
57
+ </button>
58
+ </div>
59
+ </div>
60
+ </div>
61
+
62
+ <!-- SLIDE 3 -->
63
+ <!-- ------------------------------- -->
64
+ <div class="pos-relative flex-justify-center pd-thin t-center flex-column flex embla__slide">
65
+ <div class="flex flex-column flex-center pd-semi o-hidden pos-relative pos-b-0 z-index-1">
66
+
67
+ <div class="mn-b-small w-4r h-4r mn-auto pd-regular bg-main radius-regular t-white flex flex-center">
68
+ <IconAddress/>
69
+ </div>
70
+
71
+ <h3 class="h3 mn-b-medium">Find Nearby Equipment</h3>
72
+ <p class="p-regular t-transp mn-b-big">
73
+ Discover rental locations and equipment availability near you. We'll show you the closest pickup points and delivery options.
74
+ </p>
75
+
76
+ <div class="flex flex-column flex-center gap-small">
77
+ <button @click="requestLocationPermission" class="bg-main p-big w-max button">
78
+ Enable Location
79
+ </button>
80
+ <button @click="nextSlide" class="bg-light p-big w-max button">
81
+ Skip for Now
82
+ </button>
83
+ </div>
84
+ </div>
13
85
  </div>
14
86
 
15
- <div
16
- class="flex-center flex-column flex pd-big embla__slide"
17
- >
18
- <img loading="lazy"
19
- :src="'/logo/logo_square.svg'"
20
- class="i-extra radius-medium mn-b-small"
21
- >
22
- <h2 class="t-center mn-b-small">Welcome to The&nbsp;Commune</h2>
23
- <p class="p-medium t-transp mn-b-semi mn-r-auto mn-l-auto t-center">Join our community to connect, share, and learn from the best. Discover new opportunities and grow with us!</p>
24
-
25
- <button @click="openFirstRoute('Sign Up')" class="w-100 bg-main button mn-b-thin">Sign Up</button>
26
- <button @click="openFirstRoute('Sign In')" class="w-100 bg-white button mn-b-semi">Sign In</button>
87
+ <!-- SLIDE 4 - App Tracking Transparency -->
88
+ <!-- ------------------------------- -->
89
+ <div class="pos-relative flex-justify-center pd-thin t-center flex-column flex embla__slide">
90
+ <div class="flex flex-column flex-center pd-semi o-hidden pos-relative pos-b-0 z-index-1">
91
+ <div class="mn-b-small w-4r h-4r mn-auto pd-regular bg-main radius-regular t-white flex flex-center">
92
+ <IconShield/>
93
+ </div>
94
+
95
+ <h3 class="h3 mn-b-medium">Personalized Experience</h3>
96
+ <p class="p-regular t-transp mn-b-big">
97
+ Allow us to provide you with personalized recommendations and improve your app experience based on your preferences.
98
+ </p>
27
99
 
28
- <p class="p-medium text-center">Or explore as a guest:</p>
29
- <button @click="setFirstUseFalse()" class="button bg-white w-100">Continue without registration</button>
100
+ <div class="flex flex-column flex-center gap-small">
101
+ <button @click="requestTrackingPermission" class="bg-main p-big w-max button">
102
+ Allow Tracking
103
+ </button>
104
+ <button @click="nextSlide" class="bg-light p-big w-max button">
105
+ Ask App Not to Track
106
+ </button>
107
+ </div>
108
+ </div>
109
+ </div>
110
+
111
+ <!-- SLIDE 5 - Final -->
112
+ <!-- ------------------------------- -->
113
+ <div class="pos-relative flex-justify-center pd-thin t-center flex-column flex embla__slide">
114
+ <div class="flex flex-column flex-center pd-semi o-hidden pos-relative pos-b-0 z-index-1">
115
+ <img loading="lazy"
116
+ :src="'/logo/logo_square.svg'"
117
+ class="i-extra radius-medium mn-b-small"
118
+ >
119
+ <h3 class="h3 mn-b-medium">Ready to Rent?</h3>
120
+ <p class="p-regular t-transp mn-b-big">Join thousands of creators who trust 3SR for their professional video equipment needs. Choose how you'd like to get started.</p>
121
+
122
+ <button @click="openFirstRoute('Sign Up')" class="bg-main p-big w-100 button mn-b-thin">Create Account</button>
123
+ <button @click="openFirstRoute('Sign In')" class="bg-light t-black p-big w-100 button mn-b-semi">Sign In</button>
124
+
125
+ <p class="p-small mn-b-medium t-transp">Or explore as a guest:</p>
126
+ <button @click="setFirstUseFalse()" class="bg-light p-big w-max button">Continue as Guest</button>
127
+ </div>
30
128
  </div>
31
129
 
32
130
  </div>
33
-
34
- <!-- <WavesBackground
35
- :style="{ transform: tweenValues[0] ? `translateX(${tweenValues[0]}%)` : '' }"
36
- class="pos-fixed pos-t-0 pos-l-0 z-index-0"
37
- /> -->
38
- <!-- <ColorsBackground
39
- :style="{ transform: tweenValues[0] ? `translateX(${tweenValues[0]}%)` : '' }"
40
- class="pos-fixed pos-t-0 pos-l-0 z-index-0"
41
- /> -->
42
-
43
- <div class="z-index-5 h-4r pos-absolute pos-b-1r pd-small flex-nowrap flex flex-center gap-small w-100 embla__dots">
44
- <div
131
+
132
+ <div class="
133
+ embla__dots
134
+ z-index-5
135
+ h-4r
136
+ pos-absolute
137
+ pos-t-1r
138
+ flex-nowrap
139
+ flex
140
+ flex-center
141
+ gap-thin
142
+ w-100"
143
+ >
144
+ <button
45
145
  v-for="(snap, index) in scrollSnaps"
46
146
  :key="index"
47
147
  @click="scrollTo(index)"
48
148
  :class="[
49
- 'embla__dot i-small radius-extra br-solid br-main br-2px',
149
+ 'embla__dot bg- i-small radius-extra',
50
150
  { 'bg-light': index !== selectedIndex },
51
151
  { 'bg-main': index === selectedIndex }
52
152
  ]"
53
153
  >
54
- </div>
154
+ </button>
55
155
 
56
- <div @click.native="setFirstUseFalse()" class="h-100 w-6r pos-b-0r flex-nowrap flex flex-center pos-r-1r pos-relative radius-small br-solid br-main br-2px uppercase t-semi p-semi t-main pos-absolute">
57
- skip
58
- </div>
156
+ <button
157
+ @click.native="setFirstUseFalse()"
158
+ class="
159
+ pd-small
160
+ bg-white
161
+ t-black
162
+ w-6r
163
+ pos-b-0r
164
+ flex-nowrap
165
+ flex
166
+ flex-center
167
+ pos-r-1r
168
+ pos-relative
169
+ radius-small
170
+ uppercase
171
+ pos-absolute
172
+ ">
173
+ <span>Skip</span>
174
+ </button>
59
175
  </div>
60
176
  </div>
61
177
 
62
178
  </template>
63
179
 
64
180
  <script setup>
65
- import { ref, onMounted } from 'vue';
181
+ import { ref, onMounted, reactive, inject } from 'vue';
66
182
  import { useRoute, useRouter } from 'vue-router'
67
183
 
68
- import emblaCarouselVue from 'embla-carousel-vue'; // Assuming a Vue version exists
184
+ import emblaCarouselVue from 'embla-carousel-vue';
185
+
186
+ import IconBell from '@martyrs/src/modules/icons/entities/IconBell.vue';
187
+ import IconAddress from '@martyrs/src/modules/icons/entities/IconAddress.vue';
188
+ import IconShield from '@martyrs/src/modules/icons/entities/IconAddress.vue';
69
189
 
70
- // import WavesBackground from '@/components/icons/backgrounds/WavesBackground.vue'
71
- // import ColorsBackground from '@/components/icons/backgrounds/ColorsBackground.vue'
190
+ import { AppTrackingTransparency } from 'capacitor-plugin-app-tracking-transparency';
72
191
 
73
192
  const props = defineProps(['slides', 'options']);
74
193
  const emits = defineEmits(['updateFirstUse'])
75
194
  const router = useRouter()
195
+
196
+ // Get notification manager directly
197
+ import ModuleNotifications from '@martyrs/src/modules/notifications/notifications.client.js'
76
198
 
77
199
  // Set firstUse
78
200
  import { Preferences } from '@capacitor/preferences';
79
201
 
202
+ const permissions = reactive({
203
+ notifications: false,
204
+ location: false,
205
+ tracking: false
206
+ })
207
+
80
208
  async function setFirstUseFalse() {
81
209
  await Preferences.set({
82
210
  key: 'first-use',
@@ -96,17 +224,6 @@
96
224
 
97
225
  emits('updateFirstUse', false);
98
226
  }
99
- // Set Slider
100
- let walkthrough = [{
101
- title: 'Communicate',
102
- subtitle: 'Write posts, comments and put likes.'
103
- },{
104
- title: 'Party & Fun',
105
- subtitle: 'Check the calendar for new events.'
106
- },{
107
- title: 'Discover',
108
- subtitle: 'Browse the gallery of photos.'
109
- }]
110
227
 
111
228
  const [emblaNode, emblaApi] = emblaCarouselVue({ loop: false })
112
229
 
@@ -118,6 +235,12 @@
118
235
 
119
236
  const scrollTo = (index) => emblaApi.value && emblaApi.value.scrollTo(index);
120
237
 
238
+ const nextSlide = () => {
239
+ if (emblaApi.value) {
240
+ emblaApi.value.scrollNext();
241
+ }
242
+ };
243
+
121
244
  const onInit = (embla) => {
122
245
  scrollSnaps.value = emblaApi.value.scrollSnapList();
123
246
  };
@@ -179,6 +302,71 @@
179
302
  emblaApi.value.on('select', onSelect);
180
303
  emblaApi.value.on('scroll', onScroll)
181
304
  });
305
+
306
+ const requestNotificationPermission = async () => {
307
+ try {
308
+ // Use notification manager from global store if available
309
+ const notificationManager = window.$store?.notificationManager;
310
+
311
+ if (notificationManager) {
312
+ await notificationManager.pushHandler.requestPermissions();
313
+ await notificationManager.registerWebPush(window.$store);
314
+ permissions.notifications = true;
315
+ }
316
+
317
+ setTimeout(() => {
318
+ nextSlide()
319
+ }, 1000)
320
+ } catch (error) {
321
+ console.error('Notification permission error:', error)
322
+ nextSlide()
323
+ }
324
+ }
325
+
326
+ const requestLocationPermission = async () => {
327
+ try {
328
+ if (!('geolocation' in navigator)) {
329
+ nextSlide()
330
+ return
331
+ }
332
+
333
+ navigator.geolocation.getCurrentPosition(
334
+ () => {
335
+ permissions.location = true
336
+ setTimeout(() => {
337
+ nextSlide()
338
+ }, 1000)
339
+ },
340
+ () => {
341
+ setTimeout(() => {
342
+ nextSlide()
343
+ }, 1000)
344
+ },
345
+ { timeout: 8000 }
346
+ )
347
+ } catch (error) {
348
+ console.error('Location permission error:', error)
349
+ nextSlide()
350
+ }
351
+ }
352
+
353
+ const requestTrackingPermission = async () => {
354
+ try {
355
+ const { status } = await AppTrackingTransparency.requestPermission();
356
+
357
+ if (status === 'authorized') {
358
+ permissions.tracking = true;
359
+ }
360
+
361
+ setTimeout(() => {
362
+ nextSlide();
363
+ }, 1000);
364
+ } catch (error) {
365
+ console.error('Tracking permission error:', error);
366
+ nextSlide();
367
+ }
368
+ };
369
+
182
370
  </script>
183
371
 
184
372
  <style lang="scss">
@@ -21,7 +21,6 @@
21
21
  <div class="rows-1">
22
22
  <Feed
23
23
  :search="true"
24
- v-model:filter="filter"
25
24
  v-model:sort="sort"
26
25
  :store="{
27
26
  read: (options) => products.actions.read(options),
@@ -1,3 +1,4 @@
1
+ 0. Нужно перерегистрировать девайс после аутентификации для связи с пользователем
1
2
  1. У globals.ws нотификаций нет реактиновного состояния или инструментов крове listeners для получения текущего состояния сокетов. Если это синглтон в него надо добавить методы для получения такой информации.
2
3
  2. Тоже самое касается NotificationManager - у него нет реактивного состояния и вообще хуй знает что он делает
3
4
  3. Нету ABAC для нотификаций и мидлваров вообще никаких. Методы для отправки нотификаций вообще не нужно делать доступными по апи без сервисного ключа.
@@ -126,20 +126,56 @@ const NotificationsController = (db, wss, notificationService) => {
126
126
  // Register device for push notifications
127
127
  const registerDevice = async (req, res) => {
128
128
  try {
129
- const { userId, deviceId, deviceType, deviceToken } = req.body;
130
- // Upsert device registration
131
- const device = await db.userDevice.findOneAndUpdate(
132
- { userId, deviceId },
133
- {
129
+ const { userId, anonymousId, deviceId, deviceType, deviceToken } = req.body;
130
+
131
+ // Validate that either userId or anonymousId is provided
132
+ if (!userId && !anonymousId) {
133
+ return res.status(400).json({ message: 'Either userId or anonymousId is required' });
134
+ }
135
+
136
+ const isAnonymous = !userId;
137
+ let query, updateData;
138
+
139
+ if (isAnonymous) {
140
+ // For anonymous users
141
+ query = { anonymousId, deviceId };
142
+ updateData = {
143
+ anonymousId,
144
+ deviceId,
145
+ deviceType,
146
+ deviceToken,
147
+ isActive: true,
148
+ isAnonymous: true,
149
+ lastActive: Date.now(),
150
+ };
151
+ } else {
152
+ // For registered users - first delete any anonymous device with same deviceId/token
153
+ await db.userDevice.deleteMany({
154
+ $or: [
155
+ { deviceId, isAnonymous: true },
156
+ { deviceToken, isAnonymous: true }
157
+ ]
158
+ });
159
+
160
+ query = { userId, deviceId };
161
+ updateData = {
134
162
  userId,
135
163
  deviceId,
136
164
  deviceType,
137
165
  deviceToken,
138
166
  isActive: true,
167
+ isAnonymous: false,
139
168
  lastActive: Date.now(),
140
- },
141
- { upsert: true, new: true }
169
+ };
170
+ }
171
+
172
+ // Upsert device registration
173
+ const device = await db.userDevice.findOneAndUpdate(
174
+ query,
175
+ { $set: updateData },
176
+ { upsert: true, new: true, setDefaultsOnInsert: true }
142
177
  );
178
+
143
179
  return res.status(201).json(device);
144
180
  } catch (err) {
145
181
  return res.status(500).json({ message: err.message });
@@ -184,6 +220,108 @@ const NotificationsController = (db, wss, notificationService) => {
184
220
  }
185
221
  };
186
222
 
223
+ // Send notification to specific device tokens
224
+ const sendToTokens = async (req, res) => {
225
+ try {
226
+ const { tokens, title, body, data = {} } = req.body;
227
+
228
+ if (!tokens || !Array.isArray(tokens) || tokens.length === 0) {
229
+ return res.status(400).json({ message: 'tokens array is required' });
230
+ }
231
+
232
+ if (!title || !body) {
233
+ return res.status(400).json({ message: 'title and body are required' });
234
+ }
235
+
236
+ // Find devices by tokens
237
+ const devices = await db.userDevice.find({
238
+ deviceToken: { $in: tokens },
239
+ isActive: true
240
+ });
241
+
242
+ const results = [];
243
+
244
+ // Send to each device
245
+ for (const device of devices) {
246
+ try {
247
+ await notificationService.sendToDeviceToken({
248
+ deviceToken: device.deviceToken,
249
+ deviceType: device.deviceType,
250
+ title,
251
+ body,
252
+ data
253
+ });
254
+ results.push({ token: device.deviceToken, success: true });
255
+ } catch (error) {
256
+ results.push({ token: device.deviceToken, success: false, error: error.message });
257
+ }
258
+ }
259
+
260
+ return res.json({
261
+ message: 'Notifications sent',
262
+ results,
263
+ total: tokens.length,
264
+ found: devices.length
265
+ });
266
+ } catch (err) {
267
+ return res.status(500).json({ message: err.message });
268
+ }
269
+ };
270
+
271
+ // Send notification to anonymous devices
272
+ const sendToAnonymous = async (req, res) => {
273
+ try {
274
+ const { anonymousIds, title, body, data = {} } = req.body;
275
+
276
+ if (!title || !body) {
277
+ return res.status(400).json({ message: 'title and body are required' });
278
+ }
279
+
280
+ let devices;
281
+
282
+ if (anonymousIds && Array.isArray(anonymousIds)) {
283
+ // Send to specific anonymous IDs
284
+ devices = await db.userDevice.find({
285
+ anonymousId: { $in: anonymousIds },
286
+ isAnonymous: true,
287
+ isActive: true
288
+ });
289
+ } else {
290
+ // Send to all anonymous devices
291
+ devices = await db.userDevice.find({
292
+ isAnonymous: true,
293
+ isActive: true
294
+ });
295
+ }
296
+
297
+ const results = [];
298
+
299
+ // Send to each device
300
+ for (const device of devices) {
301
+ try {
302
+ await notificationService.sendToDeviceToken({
303
+ deviceToken: device.deviceToken,
304
+ deviceType: device.deviceType,
305
+ title,
306
+ body,
307
+ data
308
+ });
309
+ results.push({ anonymousId: device.anonymousId, deviceToken: device.deviceToken, success: true });
310
+ } catch (error) {
311
+ results.push({ anonymousId: device.anonymousId, deviceToken: device.deviceToken, success: false, error: error.message });
312
+ }
313
+ }
314
+
315
+ return res.json({
316
+ message: 'Notifications sent to anonymous devices',
317
+ results,
318
+ devicesFound: devices.length
319
+ });
320
+ } catch (err) {
321
+ return res.status(500).json({ message: err.message });
322
+ }
323
+ };
324
+
187
325
  return {
188
326
  create,
189
327
  createBatch,
@@ -193,6 +331,8 @@ const NotificationsController = (db, wss, notificationService) => {
193
331
  updatePreferences,
194
332
  getUserPreferences,
195
333
  markAllAsRead,
334
+ sendToTokens,
335
+ sendToAnonymous,
196
336
  };
197
337
  };
198
338
  export default NotificationsController;
@@ -1,12 +1,20 @@
1
1
  export default (db, additionalFields = {}) => {
2
2
  const schema = new db.mongoose.Schema({
3
- userId: { type: db.mongoose.Schema.Types.ObjectId, ref: 'User', required: true },
3
+ userId: { type: db.mongoose.Schema.Types.ObjectId, ref: 'User', required: false },
4
+ anonymousId: { type: String, required: false }, // For anonymous users
4
5
  deviceId: { type: String, required: true },
5
6
  deviceType: { type: String, enum: ['ios', 'android', 'web'], required: true },
6
7
  deviceToken: { type: String, required: true }, // Push token for mobile, or web token
7
8
  isActive: { type: Boolean, default: true },
8
9
  lastActive: { type: Date, default: Date.now },
10
+ isAnonymous: { type: Boolean, default: false }, // Flag to identify anonymous devices
9
11
  });
10
- schema.index({ userId: 1, deviceId: 1 }, { unique: true });
12
+
13
+ // Compound indexes for both registered and anonymous users
14
+ schema.index({ userId: 1, deviceId: 1 }, { unique: true, sparse: true });
15
+ schema.index({ anonymousId: 1, deviceId: 1 }, { unique: true, sparse: true });
16
+ schema.index({ deviceToken: 1 }, { unique: true });
17
+ schema.index({ isAnonymous: 1, isActive: 1 });
18
+
11
19
  return db.mongoose.model('UserDevice', schema);
12
20
  };