@ozdao/martyrs 0.2.453 → 0.2.455

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 (142) hide show
  1. package/dist/{Media-BsgJlo-X.js → Media-1oukRVfv.js} +1 -1
  2. package/dist/{Media-CxRfrG2S.mjs → Media-q-XJSM_H.mjs} +3 -3
  3. package/dist/builder.js +5 -0
  4. package/dist/builder.mjs +5 -0
  5. package/dist/{main-Zocv7IVl.js → main-C7jGMDJC.js} +6 -6
  6. package/dist/{main-7FA_ai95.mjs → main-yXkgrjj8.mjs} +120 -133
  7. package/dist/martyrs/src/components/DatePicker/DatePicker.vue.cjs +2 -2
  8. package/dist/martyrs/src/components/DatePicker/DatePicker.vue.cjs.map +1 -1
  9. package/dist/martyrs/src/components/DatePicker/DatePicker.vue.js +2 -2
  10. package/dist/martyrs/src/components/DatePicker/DatePicker.vue.js.map +1 -1
  11. package/dist/martyrs/src/components/EmptyState/EmptyState.vue.cjs +1 -1
  12. package/dist/martyrs/src/components/EmptyState/EmptyState.vue.js +1 -1
  13. package/dist/martyrs/src/components/Media/Media.vue.cjs +2 -2
  14. package/dist/martyrs/src/components/Media/Media.vue.cjs.map +1 -1
  15. package/dist/martyrs/src/components/Media/Media.vue.js +2 -2
  16. package/dist/martyrs/src/components/Media/Media.vue.js.map +1 -1
  17. package/dist/martyrs/src/components/Popup/Popup.vue2.cjs +0 -8
  18. package/dist/martyrs/src/components/Popup/Popup.vue2.cjs.map +1 -1
  19. package/dist/martyrs/src/components/Popup/Popup.vue2.js +0 -8
  20. package/dist/martyrs/src/components/Popup/Popup.vue2.js.map +1 -1
  21. package/dist/martyrs/src/components/Slider/Slider.native.vue.cjs +229 -0
  22. package/dist/martyrs/src/components/Slider/Slider.native.vue.cjs.map +1 -0
  23. package/dist/martyrs/src/components/Slider/Slider.native.vue.js +229 -0
  24. package/dist/martyrs/src/components/Slider/Slider.native.vue.js.map +1 -0
  25. package/dist/martyrs/src/modules/events/components/blocks/CardEvent.vue.cjs +29 -17
  26. package/dist/martyrs/src/modules/events/components/blocks/CardEvent.vue.cjs.map +1 -1
  27. package/dist/martyrs/src/modules/events/components/blocks/CardEvent.vue.js +29 -17
  28. package/dist/martyrs/src/modules/events/components/blocks/CardEvent.vue.js.map +1 -1
  29. package/dist/martyrs/src/modules/events/components/pages/Event.vue.cjs +1 -22
  30. package/dist/martyrs/src/modules/events/components/pages/Event.vue.cjs.map +1 -1
  31. package/dist/martyrs/src/modules/events/components/pages/Event.vue.js +4 -25
  32. package/dist/martyrs/src/modules/events/components/pages/Event.vue.js.map +1 -1
  33. package/dist/martyrs/src/modules/events/components/pages/Events.vue.cjs +50 -132
  34. package/dist/martyrs/src/modules/events/components/pages/Events.vue.cjs.map +1 -1
  35. package/dist/martyrs/src/modules/events/components/pages/Events.vue.js +66 -148
  36. package/dist/martyrs/src/modules/events/components/pages/Events.vue.js.map +1 -1
  37. package/dist/martyrs/src/modules/events/components/pages/EventsBackoffice.vue.cjs +3 -33
  38. package/dist/martyrs/src/modules/events/components/pages/EventsBackoffice.vue.cjs.map +1 -1
  39. package/dist/martyrs/src/modules/events/components/pages/EventsBackoffice.vue.js +3 -33
  40. package/dist/martyrs/src/modules/events/components/pages/EventsBackoffice.vue.js.map +1 -1
  41. package/dist/martyrs/src/modules/events/components/pages/EventsSearch.vue.cjs +98 -0
  42. package/dist/martyrs/src/modules/events/components/pages/EventsSearch.vue.cjs.map +1 -0
  43. package/dist/martyrs/src/modules/events/components/pages/EventsSearch.vue.js +98 -0
  44. package/dist/martyrs/src/modules/events/components/pages/EventsSearch.vue.js.map +1 -0
  45. package/dist/martyrs/src/modules/events/components/sections/EventsHot.vue.cjs +2 -4
  46. package/dist/martyrs/src/modules/events/components/sections/EventsHot.vue.cjs.map +1 -1
  47. package/dist/martyrs/src/modules/events/components/sections/EventsHot.vue.js +2 -4
  48. package/dist/martyrs/src/modules/events/components/sections/EventsHot.vue.js.map +1 -1
  49. package/dist/martyrs/src/modules/events/components/sections/FeaturedEvents.vue.cjs +8 -7
  50. package/dist/martyrs/src/modules/events/components/sections/FeaturedEvents.vue.cjs.map +1 -1
  51. package/dist/martyrs/src/modules/events/components/sections/FeaturedEvents.vue.js +8 -7
  52. package/dist/martyrs/src/modules/events/components/sections/FeaturedEvents.vue.js.map +1 -1
  53. package/dist/martyrs/src/modules/events/components/sections/List.vue.cjs +3 -3
  54. package/dist/martyrs/src/modules/events/components/sections/List.vue.cjs.map +1 -1
  55. package/dist/martyrs/src/modules/events/components/sections/List.vue.js +3 -3
  56. package/dist/martyrs/src/modules/events/components/sections/List.vue.js.map +1 -1
  57. package/dist/martyrs/src/modules/events/components/sections/SelectDate.vue.cjs +190 -0
  58. package/dist/martyrs/src/modules/events/components/sections/SelectDate.vue.cjs.map +1 -0
  59. package/dist/martyrs/src/modules/events/components/sections/SelectDate.vue.js +190 -0
  60. package/dist/martyrs/src/modules/events/components/sections/SelectDate.vue.js.map +1 -0
  61. package/dist/martyrs/src/modules/events/router/events.cjs +15 -0
  62. package/dist/martyrs/src/modules/events/router/events.cjs.map +1 -1
  63. package/dist/martyrs/src/modules/events/router/events.js +15 -0
  64. package/dist/martyrs/src/modules/events/router/events.js.map +1 -1
  65. package/dist/martyrs/src/modules/globals/globals.client.cjs +2 -0
  66. package/dist/martyrs/src/modules/globals/globals.client.cjs.map +1 -1
  67. package/dist/martyrs/src/modules/globals/globals.client.js +2 -0
  68. package/dist/martyrs/src/modules/globals/globals.client.js.map +1 -1
  69. package/dist/martyrs/src/modules/globals/views/components/layouts/App.vue.cjs +4 -1
  70. package/dist/martyrs/src/modules/globals/views/components/layouts/App.vue.cjs.map +1 -1
  71. package/dist/martyrs/src/modules/globals/views/components/layouts/App.vue.js +3 -0
  72. package/dist/martyrs/src/modules/globals/views/components/layouts/App.vue.js.map +1 -1
  73. package/dist/martyrs/src/modules/globals/views/components/layouts/Client.vue.cjs +2 -4
  74. package/dist/martyrs/src/modules/globals/views/components/layouts/Client.vue.cjs.map +1 -1
  75. package/dist/martyrs/src/modules/globals/views/components/layouts/Client.vue.js +0 -2
  76. package/dist/martyrs/src/modules/globals/views/components/layouts/Client.vue.js.map +1 -1
  77. package/dist/martyrs/src/modules/globals/views/plugins/AlertDialog.vue.cjs +43 -0
  78. package/dist/martyrs/src/modules/globals/views/plugins/AlertDialog.vue.cjs.map +1 -0
  79. package/dist/martyrs/src/modules/globals/views/plugins/AlertDialog.vue.js +43 -0
  80. package/dist/martyrs/src/modules/globals/views/plugins/AlertDialog.vue.js.map +1 -0
  81. package/dist/martyrs/src/modules/globals/views/plugins/alert.plugin.cjs +53 -0
  82. package/dist/martyrs/src/modules/globals/views/plugins/alert.plugin.cjs.map +1 -0
  83. package/dist/martyrs/src/modules/globals/views/plugins/alert.plugin.js +53 -0
  84. package/dist/martyrs/src/modules/globals/views/plugins/alert.plugin.js.map +1 -0
  85. package/dist/martyrs/src/modules/organizations/components/sections/Documents.vue.cjs +0 -1
  86. package/dist/martyrs/src/modules/organizations/components/sections/Documents.vue.cjs.map +1 -1
  87. package/dist/martyrs/src/modules/organizations/components/sections/Documents.vue.js +0 -1
  88. package/dist/martyrs/src/modules/organizations/components/sections/Documents.vue.js.map +1 -1
  89. package/dist/martyrs/src/modules/products/components/elements/Price.vue.cjs +5 -6
  90. package/dist/martyrs/src/modules/products/components/elements/Price.vue.cjs.map +1 -1
  91. package/dist/martyrs/src/modules/products/components/elements/Price.vue.js +5 -6
  92. package/dist/martyrs/src/modules/products/components/elements/Price.vue.js.map +1 -1
  93. package/dist/martyrs/src/modules/products/components/pages/Product.vue.cjs +61 -69
  94. package/dist/martyrs/src/modules/products/components/pages/Product.vue.cjs.map +1 -1
  95. package/dist/martyrs/src/modules/products/components/pages/Product.vue.js +62 -70
  96. package/dist/martyrs/src/modules/products/components/pages/Product.vue.js.map +1 -1
  97. package/dist/martyrs/src/modules/products/store/products.cjs +0 -1
  98. package/dist/martyrs/src/modules/products/store/products.cjs.map +1 -1
  99. package/dist/martyrs/src/modules/products/store/products.js +0 -1
  100. package/dist/martyrs/src/modules/products/store/products.js.map +1 -1
  101. package/dist/martyrs/src/modules/spots/components/pages/SpotEdit.vue.cjs +0 -1
  102. package/dist/martyrs/src/modules/spots/components/pages/SpotEdit.vue.cjs.map +1 -1
  103. package/dist/martyrs/src/modules/spots/components/pages/SpotEdit.vue.js +0 -1
  104. package/dist/martyrs/src/modules/spots/components/pages/SpotEdit.vue.js.map +1 -1
  105. package/dist/martyrs.cjs.js +1 -1
  106. package/dist/martyrs.css +1 -1
  107. package/dist/martyrs.es.js +1 -1
  108. package/dist/organizations.server.js +0 -1
  109. package/dist/organizations.server.mjs +0 -1
  110. package/dist/products.server.js +5 -0
  111. package/dist/products.server.mjs +5 -0
  112. package/dist/style.css +93 -6
  113. package/package.json +1 -1
  114. package/src/builder/rspack/rspack.config.client.js +5 -0
  115. package/src/components/DatePicker/DatePicker.vue +1 -1
  116. package/src/components/EmptyState/EmptyState.vue +1 -1
  117. package/src/components/Media/Media.vue +1 -1
  118. package/src/components/Popup/Popup.vue +2 -2
  119. package/src/components/Slider/Slider.native.vue +313 -0
  120. package/src/modules/events/components/blocks/CardEvent.vue +21 -7
  121. package/src/modules/events/components/pages/Event.vue +0 -20
  122. package/src/modules/events/components/pages/Events.vue +91 -141
  123. package/src/modules/events/components/pages/EventsBackoffice.vue +5 -3
  124. package/src/modules/events/components/pages/EventsSearch.vue +122 -0
  125. package/src/modules/events/components/sections/EventsHot.vue +3 -5
  126. package/src/modules/events/components/sections/FeaturedEvents.vue +44 -12
  127. package/src/modules/events/components/sections/List.vue +3 -3
  128. package/src/modules/events/components/sections/SelectDate.vue +217 -0
  129. package/src/modules/events/router/events.js +12 -0
  130. package/src/modules/globals/globals.client.js +5 -2
  131. package/src/modules/globals/views/components/layouts/App.vue +7 -1
  132. package/src/modules/globals/views/components/layouts/Client.vue +0 -3
  133. package/src/modules/globals/views/plugins/AlertDialog.vue +35 -0
  134. package/src/modules/globals/views/plugins/alert.plugin.js +65 -0
  135. package/src/modules/organizations/policies/organizations.policies.js +0 -1
  136. package/src/modules/products/components/elements/Price.vue +3 -4
  137. package/src/modules/products/components/pages/Product.old.vue +201 -0
  138. package/src/modules/products/components/pages/Product.vue +57 -38
  139. package/src/modules/products/controllers/products.controller.js +7 -0
  140. package/src/modules/products/store/products.js +0 -1
  141. package/src/styles/base/all.scss +1 -0
  142. package/src/styles/typography.scss +22 -0
@@ -1,4 +1,4 @@
1
- import { a as o, t, b as d, c as r, u as l, v as i, w as p, d as u, x as n, e as m, y as M, F as S, z as c, f as F, A as g, L as h, g as b, M as k, E as x, n as B, o as C, h as T, i as U, S as f, j as w, B as D, C as E, k as I, D as L, l as P, q, p as y, U as A, r as j, s as v, m as z } from "./main-7FA_ai95.mjs";
1
+ import { a as o, t, b as d, c as r, u as l, v as i, w as p, d as u, x as n, e as m, y as M, F as S, z as c, f as F, A as g, L as h, g as b, M as k, E as x, n as B, o as C, h as T, i as U, S as f, j as w, B as D, C as E, k as I, D as L, l as P, q, p as y, U as A, r as j, s as v, m as z } from "./main-yXkgrjj8.mjs";
2
2
  import "vue";
3
3
  export {
4
4
  o as Address,
@@ -1372,7 +1372,6 @@ function requireOrganizations_policies() {
1372
1372
  const publicAccessVerifier = new Verifier({
1373
1373
  status: {
1374
1374
  allowed: true,
1375
- default: "published",
1376
1375
  validator: Validator.schema({ context: "Status" }).string().required().oneOf(["published", "active", "featured"])
1377
1376
  }
1378
1377
  });
@@ -1371,7 +1371,6 @@ function requireOrganizations_policies() {
1371
1371
  const publicAccessVerifier = new Verifier({
1372
1372
  status: {
1373
1373
  allowed: true,
1374
- default: "published",
1375
1374
  validator: Validator.schema({ context: "Status" }).string().required().oneOf(["published", "active", "featured"])
1376
1375
  }
1377
1376
  });
@@ -224,6 +224,7 @@ function requireProducts_controller() {
224
224
  organization: process.env.OPENAI_ORG_KEY,
225
225
  apiKey: process.env.OPENAI_API_KEY
226
226
  });
227
+ const queryProcessorGlobals = queryProcessor.requireQueryProcessor();
227
228
  const controllerFactory = (db) => {
228
229
  const Product = db.product;
229
230
  db.modification;
@@ -430,6 +431,10 @@ function requireProducts_controller() {
430
431
  }
431
432
  }
432
433
  },
434
+ // For owner
435
+ queryProcessorGlobals.getOwnerUserLookupStage(),
436
+ queryProcessorGlobals.getOwnerOrganizationLookupStage(),
437
+ queryProcessorGlobals.getAddFieldsCreatorOwnerStage(),
433
438
  {
434
439
  $set: {
435
440
  available: {
@@ -223,6 +223,7 @@ function requireProducts_controller() {
223
223
  organization: process.env.OPENAI_ORG_KEY,
224
224
  apiKey: process.env.OPENAI_API_KEY
225
225
  });
226
+ const queryProcessorGlobals = requireQueryProcessor();
226
227
  const controllerFactory = (db) => {
227
228
  const Product = db.product;
228
229
  db.modification;
@@ -429,6 +430,10 @@ function requireProducts_controller() {
429
430
  }
430
431
  }
431
432
  },
433
+ // For owner
434
+ queryProcessorGlobals.getOwnerUserLookupStage(),
435
+ queryProcessorGlobals.getOwnerOrganizationLookupStage(),
436
+ queryProcessorGlobals.getAddFieldsCreatorOwnerStage(),
432
437
  {
433
438
  $set: {
434
439
  available: {
package/dist/style.css CHANGED
@@ -2030,7 +2030,41 @@ to {
2030
2030
  padding: 20px;
2031
2031
  z-index: 10;
2032
2032
  }
2033
- .bg-white-overlay[data-v-0f5877fc] {
2033
+
2034
+ .columns-container {
2035
+ width: 100%;
2036
+ overflow: hidden;
2037
+ }
2038
+ .columns-wrapper {
2039
+ display: flex;
2040
+ width: 100%;
2041
+ }
2042
+ @media (min-width: 768px) {
2043
+ .columns-wrapper {
2044
+ /* Десктоп: 2 колонки рядом */
2045
+ display: grid;
2046
+ grid-template-columns: 1fr 1fr;
2047
+ }
2048
+ }
2049
+ @media (max-width: 767px) {
2050
+ .columns-wrapper {
2051
+ /* Мобильные устройства: горизонтальный скролл */
2052
+ overflow-x: auto;
2053
+ scroll-snap-type: x mandatory;
2054
+ -webkit-overflow-scrolling: touch;
2055
+ }
2056
+ }
2057
+ @media (max-width: 767px) {
2058
+ .column {
2059
+ /* Настройки для мобильных устройств */
2060
+ max-width: 90%;
2061
+ flex: 0 0 auto;
2062
+ scroll-snap-align: start;
2063
+ }
2064
+ .column:last-child {
2065
+ margin-right: 0;
2066
+ }
2067
+ }.bg-white-overlay[data-v-0f5877fc] {
2034
2068
  background: linear-gradient(0deg, rgba(var(--white), 1) 0%, rgba(var(--white), 0) 100%);
2035
2069
  }
2036
2070
  /* Existing styles can stay unchanged */
@@ -2048,17 +2082,70 @@ to {
2048
2082
  }.select-country {
2049
2083
  max-width: 100%;
2050
2084
  }
2051
- .media-container[data-v-94bcf726] {
2085
+ /* Стили остаются неизменными */
2086
+ .carousel[data-v-a766dedc] {
2087
+ position: relative;
2088
+ width: 100%;
2089
+ overflow: hidden;
2090
+ }
2091
+ .carousel__container[data-v-a766dedc] {
2092
+ display: flex;
2093
+ scroll-snap-type: x mandatory;
2094
+ overflow-x: scroll;
2095
+ scrollbar-width: none; /* Firefox */
2096
+ -ms-overflow-style: none; /* IE and Edge */
2097
+ scroll-behavior: smooth;
2098
+ }
2099
+ .carousel__container[data-v-a766dedc]::-webkit-scrollbar {
2100
+ display: none; /* Chrome, Safari, Opera */
2101
+ }
2102
+ .carousel__slide[data-v-a766dedc] {
2103
+ flex: 0 0 100%;
2104
+ width: 100%;
2105
+ scroll-snap-align: start;
2106
+ scroll-snap-stop: always;
2107
+ }
2108
+
2109
+ /* Navigation dots */
2110
+ .carousel__dots[data-v-a766dedc] {
2111
+ display: flex;
2112
+ justify-content: center;
2113
+ gap: 0.5rem;
2114
+ margin-top: 1rem;
2115
+ }
2116
+ .carousel__dot[data-v-a766dedc] {
2117
+ width: 0.625rem;
2118
+ height: 0.625rem;
2119
+ border-radius: 50%;
2120
+ background-color: rgba(0, 0, 0, 0.2);
2121
+ border: none;
2122
+ padding: 0;
2123
+ cursor: pointer;
2124
+ transition: background-color 0.3s ease;
2125
+ }
2126
+ .carousel__dot--active[data-v-a766dedc] {
2127
+ background-color: rgba(0, 0, 0, 0.6);
2128
+ }
2129
+ .fade-enter-active[data-v-a766dedc],
2130
+ .fade-leave-active[data-v-a766dedc] {
2131
+ transition: opacity 0.3s ease;
2132
+ }
2133
+ .fade-enter-from[data-v-a766dedc],
2134
+ .fade-leave-to[data-v-a766dedc] {
2135
+ opacity: 0;
2136
+ }
2137
+
2138
+ .media-container[data-v-1f94a0e9] {
2052
2139
  }
2053
- .media-item[data-v-94bcf726] {
2140
+ .media-item[data-v-1f94a0e9] {
2054
2141
  all: inherit;
2055
2142
  opacity: 1;
2056
2143
  transition: opacity 0.3s ease;
2057
2144
  }
2058
- .media-item.loading[data-v-94bcf726] {
2145
+ .media-item.loading[data-v-1f94a0e9] {
2059
2146
  opacity: 0;
2060
2147
  }
2061
- .media-placeholder[data-v-94bcf726] {
2148
+ .media-placeholder[data-v-1f94a0e9] {
2062
2149
  position: absolute;
2063
2150
  top: 0;
2064
2151
  left: 0;
@@ -2069,7 +2156,7 @@ to {
2069
2156
  justify-content: center;
2070
2157
  background-color: #f5f5f5;
2071
2158
  }
2072
- .media-error[data-v-94bcf726] {
2159
+ .media-error[data-v-1f94a0e9] {
2073
2160
  color: #ff4444;
2074
2161
  padding: 1rem;
2075
2162
  text-align: center;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ozdao/martyrs",
3
- "version": "0.2.453",
3
+ "version": "0.2.455",
4
4
  "description": "Fullstack framework focused on user experience and ease of development.",
5
5
  "author": "OZ DAO <hello@ozdao.dev>",
6
6
  "license": "GPL-3.0-or-later",
@@ -34,8 +34,13 @@ module.exports = (projectRoot) => {
34
34
  new PurgeCSSPlugin({
35
35
  paths: glob.sync([
36
36
  path.join(projectRoot, 'src/**/*.vue'),
37
+ path.join(projectRoot, 'src/**/*.js'),
37
38
  path.join(projectRoot, 'martyrs/src/**/*.vue'),
39
+ path.join(projectRoot, 'martyrs/src/**/*.js'),
40
+ path.join(projectRoot, '/node_modules/@ozdao/martyrs/**/*.css'),
41
+ path.join(projectRoot, '/node_modules/@ozdao/martyrs/**/*.scss'),
38
42
  path.join(projectRoot, '/node_modules/@ozdao/martyrs/src/**/*.vue'),
43
+ path.join(projectRoot, '/node_modules/@ozdao/martyrs/src/**/*.js'),
39
44
  path.join(projectRoot, '/node_modules/@vuepic/vue-datepicker/**/*.js')
40
45
  ]),
41
46
 
@@ -78,7 +78,7 @@ function selectDate(date) {
78
78
  // Select new date
79
79
  selectedDate.value = date;
80
80
  const formattedDate = formatDateForRouter(date);
81
- emit('update:date', formattedDate);
81
+ emit('update:date', date);
82
82
  }
83
83
  }
84
84
 
@@ -1,6 +1,6 @@
1
1
  <template>
2
2
  <section>
3
- <h4 class="mn-b-thin">{{ title }}</h4>
3
+ <h5 class="mn-b-thin">{{ title }}</h5>
4
4
  <p class="mn-b-small t-transp p-medium">{{ description }}</p>
5
5
 
6
6
  <button v-if="action" @click="callback" class="t-white bg-second w-100 button">
@@ -34,7 +34,7 @@
34
34
 
35
35
  <!-- Плейсхолдер во время загрузки -->
36
36
  <div v-if="!isLoaded" class="media-placeholder">
37
- Загрузка...
37
+ Loading...
38
38
  </div>
39
39
 
40
40
  <!-- Сообщение об ошибке -->
@@ -30,7 +30,7 @@
30
30
  import { computed, watch, onMounted, ref, nextTick } from 'vue';
31
31
  // Import libs
32
32
  import { useRoute, useRouter } from 'vue-router'
33
- import { useI18n } from 'vue-i18n'
33
+ // import { useI18n } from 'vue-i18n'
34
34
  // Icons
35
35
  import IconCross from '@martyrs/src/modules/icons/navigation/IconCross.vue';
36
36
  // Define props
@@ -66,7 +66,7 @@ const text = {
66
66
  ru: {}
67
67
  }
68
68
  }
69
- const { t } = useI18n(text)
69
+ // const { t } = useI18n(text)
70
70
  </script>
71
71
 
72
72
  <style lang="scss">
@@ -0,0 +1,313 @@
1
+ <template>
2
+ <div class="pos-relative">
3
+ <!-- Loading State -->
4
+ <div v-if="isLoading" class="h-20r radius-semi pos-relative w-100 bg-light">
5
+ <Loader />
6
+ </div>
7
+ <!-- Empty State -->
8
+ <div v-else-if="!entitiesState.length" class="bg-light radius-semi flex flex-center w-100 h-20r">
9
+ <p class="text-gray-500">{{t('title')}}</p>
10
+ </div>
11
+ <!-- Native Carousel -->
12
+ <div v-else class="carousel" ref="carouselRef">
13
+ <div class="carousel__container" @scroll="handleScroll">
14
+ <div
15
+ class="carousel__slide pd-nano"
16
+ v-for="(entity, key, index) in entitiesState"
17
+ :key="key"
18
+ >
19
+ <transition name="fade" mode="out-in" appear>
20
+ <slot
21
+ :item="entity"
22
+ :user="user"
23
+ ></slot>
24
+ </transition>
25
+ </div>
26
+ </div>
27
+
28
+ <!-- Navigation Dots (optional) -->
29
+ <div class="carousel__dots" v-if="showDots && entitiesState.length > 1">
30
+ <button
31
+ v-for="(_, index) in entitiesState"
32
+ :key="index"
33
+ class="carousel__dot"
34
+ :class="{ 'carousel__dot--active': selectedIndex === index }"
35
+ @click="scrollTo(index)"
36
+ ></button>
37
+ </div>
38
+ </div>
39
+ </div>
40
+ </template>
41
+
42
+ <script setup>
43
+ import { ref, onMounted, onBeforeUnmount, watch } from 'vue'
44
+ import { useRouter } from 'vue-router'
45
+ import { useI18n } from 'vue-i18n'
46
+ import Loader from '@martyrs/src/components/Loader/Loader.vue'
47
+
48
+ // Props for customization
49
+ const props = defineProps({
50
+ showDots: Boolean,
51
+ store: Object,
52
+ options: Object,
53
+ text: Object,
54
+ user: Object
55
+ });
56
+
57
+ const router = useRouter()
58
+ const carouselRef = ref(null)
59
+ const entitiesState = ref([])
60
+ const isLoading = ref(true)
61
+ const selectedIndex = ref(0)
62
+ const autoplayInterval = ref(null)
63
+ const scrollTimeout = ref(null)
64
+
65
+ const { t } = useI18n({
66
+ messages: props.text
67
+ })
68
+
69
+ // Scroll to specific slide
70
+ const scrollTo = (index) => {
71
+ if (!carouselRef.value) return
72
+
73
+ const container = carouselRef.value.querySelector('.carousel__container')
74
+ const slides = container.querySelectorAll('.carousel__slide')
75
+
76
+ if (slides[index]) {
77
+ container.scrollTo({
78
+ left: slides[index].offsetLeft,
79
+ behavior: 'smooth'
80
+ })
81
+
82
+ selectedIndex.value = index
83
+ }
84
+ }
85
+
86
+ // Handle scroll event with debounce
87
+ const handleScroll = () => {
88
+ // Clear previous timeout
89
+ if (scrollTimeout.value) {
90
+ clearTimeout(scrollTimeout.value)
91
+ }
92
+
93
+ // Set a timeout to update the index when scrolling stops
94
+ scrollTimeout.value = setTimeout(() => {
95
+ updateSelectedIndex()
96
+ }, 50) // Small delay to ensure scroll has completed
97
+ }
98
+
99
+ // Update selected index when scrolling
100
+ const updateSelectedIndex = () => {
101
+ if (!carouselRef.value) return
102
+
103
+ const container = carouselRef.value.querySelector('.carousel__container')
104
+ const slides = container.querySelectorAll('.carousel__slide')
105
+
106
+ if (!slides.length) return
107
+
108
+ const scrollPosition = container.scrollLeft
109
+ const slideWidth = slides[0].offsetWidth
110
+
111
+ // Find current slide index based on scroll position
112
+ const index = Math.round(scrollPosition / slideWidth)
113
+
114
+ // Ensure index is within bounds
115
+ const boundedIndex = Math.max(0, Math.min(index, entitiesState.value.length - 1))
116
+
117
+ // Update selected index
118
+ selectedIndex.value = boundedIndex
119
+ }
120
+
121
+ // Setup autoplay functionality
122
+ const setupAutoplay = () => {
123
+ if (autoplayInterval.value) {
124
+ clearInterval(autoplayInterval.value)
125
+ }
126
+
127
+ autoplayInterval.value = setInterval(() => {
128
+ const nextIndex = (selectedIndex.value + 1) % entitiesState.value.length
129
+ scrollTo(nextIndex)
130
+ }, 2000) // 2 seconds interval like in original
131
+ }
132
+
133
+ onMounted(async() => {
134
+ try {
135
+ entitiesState.value = await props.store.read(props.options)
136
+ } catch (error) {
137
+ console.error('Error loading entities:', error)
138
+ entitiesState.value = []
139
+ } finally {
140
+ isLoading.value = false
141
+ }
142
+
143
+ // Initialize native carousel after entities are loaded
144
+ if (entitiesState.value.length && carouselRef.value) {
145
+ // Listen for scroll end using intersection observer for better performance
146
+ const container = carouselRef.value.querySelector('.carousel__container')
147
+ const slides = container.querySelectorAll('.carousel__slide')
148
+
149
+ // Create intersection observer to detect when slides are visible
150
+ const observer = new IntersectionObserver((entries) => {
151
+ entries.forEach(entry => {
152
+ if (entry.isIntersecting) {
153
+ // Find the index of the visible slide
154
+ const slideIndex = Array.from(slides).indexOf(entry.target)
155
+ if (slideIndex !== -1) {
156
+ selectedIndex.value = slideIndex
157
+ }
158
+ }
159
+ })
160
+ }, {
161
+ root: container,
162
+ threshold: 0.7 // Consider slide visible when 70% is in view
163
+ })
164
+
165
+ // Observe all slides
166
+ slides.forEach(slide => {
167
+ observer.observe(slide)
168
+ })
169
+
170
+ // Add focus/blur events to pause autoplay on focus
171
+ container.addEventListener('focusin', () => {
172
+ if (autoplayInterval.value) {
173
+ clearInterval(autoplayInterval.value)
174
+ }
175
+ })
176
+
177
+ container.addEventListener('focusout', () => {
178
+ setupAutoplay()
179
+ })
180
+
181
+ // Stop autoplay on touch/mouse interaction
182
+ container.addEventListener('mousedown', () => {
183
+ if (autoplayInterval.value) {
184
+ clearInterval(autoplayInterval.value)
185
+ }
186
+ })
187
+
188
+ container.addEventListener('touchstart', () => {
189
+ if (autoplayInterval.value) {
190
+ clearInterval(autoplayInterval.value)
191
+ }
192
+ })
193
+
194
+ // Resume autoplay after interaction ends
195
+ container.addEventListener('mouseup', () => {
196
+ setupAutoplay()
197
+ })
198
+
199
+ container.addEventListener('touchend', () => {
200
+ setupAutoplay()
201
+ })
202
+
203
+ // Initialize autoplay
204
+ setupAutoplay()
205
+
206
+ // Store observer for cleanup
207
+ carouselRef.value._observer = observer
208
+ }
209
+ })
210
+
211
+ onBeforeUnmount(() => {
212
+ // Clean up all resources
213
+ if (carouselRef.value) {
214
+ // Clean up intersection observer
215
+ if (carouselRef.value._observer) {
216
+ carouselRef.value._observer.disconnect()
217
+ }
218
+
219
+ // Clean up event listeners
220
+ const container = carouselRef.value.querySelector('.carousel__container')
221
+ if (container) {
222
+ container.removeEventListener('focusin', () => {})
223
+ container.removeEventListener('focusout', () => {})
224
+ container.removeEventListener('mousedown', () => {})
225
+ container.removeEventListener('touchstart', () => {})
226
+ container.removeEventListener('mouseup', () => {})
227
+ container.removeEventListener('touchend', () => {})
228
+ }
229
+ }
230
+
231
+ // Clear all timeouts and intervals
232
+ if (autoplayInterval.value) {
233
+ clearInterval(autoplayInterval.value)
234
+ }
235
+
236
+ if (scrollTimeout.value) {
237
+ clearTimeout(scrollTimeout.value)
238
+ }
239
+ })
240
+
241
+ // Watch for changes in entities to reinitialize if needed
242
+ watch(entitiesState, (newValue) => {
243
+ if (newValue.length && carouselRef.value) {
244
+ // Reset to first slide
245
+ selectedIndex.value = 0
246
+ scrollTo(0)
247
+
248
+ // Reset autoplay
249
+ setupAutoplay()
250
+ }
251
+ })
252
+ </script>
253
+
254
+ <style scoped>
255
+ .carousel {
256
+ position: relative;
257
+ width: 100%;
258
+ overflow: hidden;
259
+ }
260
+
261
+ .carousel__container {
262
+ display: flex;
263
+ scroll-snap-type: x mandatory;
264
+ overflow-x: scroll;
265
+ scrollbar-width: none; /* Firefox */
266
+ -ms-overflow-style: none; /* IE and Edge */
267
+ scroll-behavior: smooth;
268
+ }
269
+
270
+ .carousel__container::-webkit-scrollbar {
271
+ display: none; /* Chrome, Safari, Opera */
272
+ }
273
+
274
+ .carousel__slide {
275
+ flex: 0 0 100%;
276
+ width: 100%;
277
+ scroll-snap-align: start;
278
+ scroll-snap-stop: always;
279
+ }
280
+
281
+ /* Navigation dots */
282
+ .carousel__dots {
283
+ display: flex;
284
+ justify-content: center;
285
+ gap: 0.5rem;
286
+ margin-top: 1rem;
287
+ }
288
+
289
+ .carousel__dot {
290
+ width: 0.625rem;
291
+ height: 0.625rem;
292
+ border-radius: 50%;
293
+ background-color: rgba(0, 0, 0, 0.2);
294
+ border: none;
295
+ padding: 0;
296
+ cursor: pointer;
297
+ transition: background-color 0.3s ease;
298
+ }
299
+
300
+ .carousel__dot--active {
301
+ background-color: rgba(0, 0, 0, 0.6);
302
+ }
303
+
304
+ .fade-enter-active,
305
+ .fade-leave-active {
306
+ transition: opacity 0.3s ease;
307
+ }
308
+
309
+ .fade-enter-from,
310
+ .fade-leave-to {
311
+ opacity: 0;
312
+ }
313
+ </style>
@@ -45,7 +45,10 @@
45
45
 
46
46
  <section
47
47
  class="pos-relative w-100"
48
- :class="{'pd-t-zero pd-medium': type !== 'short'}"
48
+ :class="{
49
+ 'pd-t-zero pd-medium': type !== 'short',
50
+ 'flex-nowrap flex flex-v-center': type === 'short'
51
+ }"
49
52
  >
50
53
 
51
54
  <IconEdit
@@ -60,14 +63,17 @@
60
63
  />
61
64
 
62
65
  <div
63
- :class="{'mn-b-small': type !== 'short'}"
66
+ :class="{
67
+ 'mn-b-small': type !== 'short',
68
+ 'order-2 mn-l-thin': type === 'short'
69
+ }"
64
70
  class="flex-v-center flex-nowrap flex"
65
71
  >
66
72
  <span
67
73
  v-if="type === 'short'"
68
- class="t-semi uppercase"
74
+ class="t-semi t-truncate uppercase"
69
75
  >
70
- {{ truncatedEventName }}
76
+ {{ event.name }}
71
77
  </span>
72
78
  </div>
73
79
 
@@ -88,20 +94,27 @@
88
94
 
89
95
  <p
90
96
  v-if="type !== 'short'"
91
- class="mn-b-small p-big"
97
+ class="mn-b-small p-big t-trim-3"
92
98
  >
93
99
  {{ event.description }}
94
100
  </p>
95
101
 
96
102
  <slot></slot>
97
103
 
98
- <div class="flex flex-wrap gap-micro t-medium p-big justify-start align-center">
104
+ <div
105
+ class="flex-wrap flex-child-default gap-micro t-medium p-big justify-start align-center t-trim-2"
106
+ :class="{
107
+ 'order-1': type === 'short'
108
+ }"
109
+ >
99
110
  <span v-if="event.date?.start" class="mn-r-nano d-inline-block w-max pd-b-micro pd-t-micro pd-r-thin pd-l-thin radius-small t-medium bg-white">
100
111
  <!-- <IconDate :fill="'rgb(var(--black))'" class="w-1r h-auto"/> -->
101
112
  <!-- {{formatDate(event.date.start)}} -->
102
113
 
103
114
  <span
104
-
115
+ :class="{
116
+ 'p-medium': type === 'short'
117
+ }"
105
118
  class="t-semi"
106
119
  >
107
120
  {{ formattedDate }}
@@ -115,6 +128,7 @@
115
128
 
116
129
 
117
130
  <span
131
+ v-if="type !== 'short'"
118
132
  v-for="(chip, index) in event.tags"
119
133
  :key="index"
120
134
  class="d-inline-flex pd-b-micro pd-t-micro pd-r-thin pd-l-thin radius-small bg-main"
@@ -97,26 +97,6 @@
97
97
  />
98
98
  </div>
99
99
 
100
- <div class="radius-semi pd-medium bg-light">
101
- <h4 class="mn-b-small">Organizer</h4>
102
- <User
103
- class="h-5r cursor-pointer pd-medium radius-medium bg-white"
104
- :user="event.owner.target._id"
105
- :photo="event.owner.target.profile.photo"
106
- :name="event.owner.target.profile.name"
107
- :position="event.owner"
108
- @click.stop="$router.push({
109
- name: event.owner.type === 'user' ? 'User Profile' : 'Organization',
110
- params: {
111
- _id: event.owner.target._id,
112
-
113
- },
114
- query: {
115
- tab: 'events'
116
- }
117
- })"
118
- />
119
- </div>
120
100
 
121
101
  </div>
122
102