@ozdao/martyrs 0.2.562 → 0.2.564

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 (42) hide show
  1. package/dist/{abac-DC2x92Pa.js → abac-DYoheWuc.js} +2 -1
  2. package/dist/{core.logger-VRHh-WUW.js → core.cache-DALYFDdy.js} +10 -59
  3. package/dist/core.logger-C3q8A9dl.js +51 -0
  4. package/dist/core.server.js +1 -1
  5. package/dist/{crud-DFFgLl09.js → crud-C7FSTUes.js} +2 -1
  6. package/dist/inventory.server.js +4 -3
  7. package/dist/{main-TV4u6Jux.js → main-CmjWiDVF.js} +402 -402
  8. package/dist/marketplace.server.js +389 -0
  9. package/dist/martyrs/src/modules/core/views/components/sections/filters/FiltersGroup.vue.js +1 -3
  10. package/dist/martyrs/src/modules/core/views/components/sections/filters/FiltersGroup.vue.js.map +1 -1
  11. package/dist/martyrs/src/modules/landing/components/sections/SectionFeatures.vue.js +1 -1
  12. package/dist/martyrs/src/modules/landing/components/sections/SectionFeatures.vue.js.map +1 -1
  13. package/dist/martyrs/src/modules/marketplace/marketplace.client.js +5 -9
  14. package/dist/martyrs/src/modules/marketplace/marketplace.client.js.map +1 -1
  15. package/dist/martyrs/src/modules/marketplace/views/components/{layouts → pages}/Marketplace.vue.js +14 -18
  16. package/dist/martyrs/src/modules/marketplace/views/components/pages/Marketplace.vue.js.map +1 -0
  17. package/dist/martyrs/src/modules/marketplace/views/router/marketplace.router.js +39 -0
  18. package/dist/martyrs/src/modules/marketplace/views/router/marketplace.router.js.map +1 -0
  19. package/dist/martyrs/src/modules/marketplace/views/store/marketplace.js +0 -16
  20. package/dist/martyrs/src/modules/marketplace/views/store/marketplace.js.map +1 -1
  21. package/dist/martyrs.es.js +1 -1
  22. package/dist/music.server.js +4 -3
  23. package/dist/orders.server.js +2 -2
  24. package/dist/organizations.server.js +9 -219
  25. package/dist/products.server.js +4 -3
  26. package/dist/queryProcessorOrganizations-BB11WFpc.js +221 -0
  27. package/dist/rents.server.js +2 -1
  28. package/dist/{web-Cq5tyhkl.js → web-cNKIl_cL.js} +1 -1
  29. package/package.json +1 -1
  30. package/src/modules/core/views/components/sections/filters/FiltersGroup.vue +3 -4
  31. package/src/modules/landing/components/sections/SectionFeatures.vue +1 -1
  32. package/src/modules/marketplace/marketplace.client.js +3 -10
  33. package/src/modules/marketplace/views/components/{layouts → pages}/Marketplace.vue +7 -16
  34. package/src/modules/marketplace/views/router/marketplace.router.js +37 -45
  35. package/src/modules/marketplace/views/store/marketplace.js +0 -16
  36. package/dist/martyrs/src/modules/marketplace/marketplace.router.js +0 -63
  37. package/dist/martyrs/src/modules/marketplace/marketplace.router.js.map +0 -1
  38. package/dist/martyrs/src/modules/marketplace/views/components/layouts/Marketplace.vue.js.map +0 -1
  39. package/dist/martyrs/src/modules/marketplace/views/components/pages/Catalog.vue.js +0 -73
  40. package/dist/martyrs/src/modules/marketplace/views/components/pages/Catalog.vue.js.map +0 -1
  41. package/src/modules/marketplace/marketplace.router.js +0 -66
  42. package/src/modules/marketplace/views/components/pages/Catalog.vue +0 -74
@@ -0,0 +1,389 @@
1
+ import { m as middlewareIndexFactory } from "./index-_Edcmck_.js";
2
+ import { C as CacheNamespaced } from "./core.cache-DALYFDdy.js";
3
+ import { q as queryProcessorCore } from "./queryProcessor-CBQgZycY.js";
4
+ import { b as getLookupStages } from "./queryProcessorOrganizations-BB11WFpc.js";
5
+ import { Types } from "mongoose";
6
+ import * as googleMapsServicesJs from "@googlemaps/google-maps-services-js";
7
+ const lookupConfigs = {
8
+ availability: {
9
+ lookup: {
10
+ from: "stockavailabilities",
11
+ localField: "_id",
12
+ foreignField: "storage",
13
+ pipeline: [
14
+ {
15
+ $match: {
16
+ $expr: { $gt: ["$available", 0] }
17
+ }
18
+ },
19
+ {
20
+ $project: {
21
+ _id: 1,
22
+ product: 1,
23
+ variant: 1,
24
+ available: 1,
25
+ quantity: 1
26
+ }
27
+ }
28
+ ],
29
+ as: "availability"
30
+ }
31
+ },
32
+ variants: {
33
+ lookup: {
34
+ from: "variants",
35
+ let: { variantIds: "$availability.variant" },
36
+ pipeline: [
37
+ {
38
+ $match: {
39
+ $expr: {
40
+ $in: ["$_id", "$$variantIds"]
41
+ },
42
+ status: "published"
43
+ }
44
+ },
45
+ {
46
+ $project: {
47
+ _id: 1,
48
+ product: 1,
49
+ name: 1,
50
+ price: 1,
51
+ unit: 1,
52
+ images: 1,
53
+ sku: 1
54
+ }
55
+ }
56
+ ],
57
+ as: "variants"
58
+ }
59
+ },
60
+ products: {
61
+ lookup: {
62
+ from: "products",
63
+ localField: "organization",
64
+ foreignField: "owner.target",
65
+ pipeline: [
66
+ {
67
+ $match: {
68
+ status: "published"
69
+ }
70
+ },
71
+ {
72
+ $lookup: {
73
+ from: "variants",
74
+ localField: "_id",
75
+ foreignField: "product",
76
+ pipeline: [
77
+ {
78
+ $project: {
79
+ _id: 1,
80
+ name: 1,
81
+ price: 1,
82
+ unit: 1,
83
+ images: 1,
84
+ sku: 1
85
+ }
86
+ }
87
+ ],
88
+ as: "variants"
89
+ }
90
+ },
91
+ {
92
+ $project: {
93
+ _id: 1,
94
+ name: 1,
95
+ description: 1,
96
+ images: 1,
97
+ category: 1,
98
+ "owner.target": 1,
99
+ "owner.type": 1,
100
+ variants: 1
101
+ }
102
+ }
103
+ ],
104
+ as: "products"
105
+ }
106
+ },
107
+ organizations: {
108
+ lookup: {
109
+ from: "organizations",
110
+ let: { orgIds: "$products.owner.target" },
111
+ pipeline: [
112
+ {
113
+ $match: {
114
+ $expr: {
115
+ $in: ["$_id", "$$orgIds"]
116
+ }
117
+ }
118
+ },
119
+ {
120
+ $project: {
121
+ _id: 1,
122
+ "profile.name": 1,
123
+ "profile.photo": 1,
124
+ "profile.description": 1,
125
+ "profile.tags": 1,
126
+ rating: 1,
127
+ official: 1
128
+ }
129
+ }
130
+ ],
131
+ as: "organizations"
132
+ }
133
+ }
134
+ };
135
+ const ObjectId = Types.ObjectId;
136
+ const { Client } = googleMapsServicesJs;
137
+ const client = new Client({});
138
+ const getBasicMatchConditions = (query) => {
139
+ const conditions = [];
140
+ if (query.delivery) {
141
+ let deliveryMethods = Array.isArray(query.delivery) ? query.delivery : typeof query.delivery === "string" ? query.delivery.split(",") : [];
142
+ deliveryMethods = deliveryMethods.filter(Boolean).map((m) => m.trim());
143
+ if (deliveryMethods.length > 0) {
144
+ conditions.push({ delivery: { $in: deliveryMethods } });
145
+ }
146
+ }
147
+ if (query.payment) {
148
+ let paymentMethods = Array.isArray(query.payment) ? query.payment : typeof query.payment === "string" ? query.payment.split(",") : [];
149
+ paymentMethods = paymentMethods.filter(Boolean).map((m) => m.trim());
150
+ if (paymentMethods.length > 0) {
151
+ conditions.push({ payment: { $in: paymentMethods } });
152
+ }
153
+ }
154
+ return conditions;
155
+ };
156
+ const getPriceConditions = (priceMin, priceMax) => {
157
+ if (!priceMin && !priceMax) return [];
158
+ const conditions = {};
159
+ if (priceMin !== void 0 && priceMin !== null && priceMin !== "") {
160
+ conditions["products.variants.price"] = { $gte: parseFloat(priceMin) };
161
+ }
162
+ if (priceMax !== void 0 && priceMax !== null && priceMax !== "") {
163
+ if (conditions["products.variants.price"]) {
164
+ conditions["products.variants.price"].$lte = parseFloat(priceMax);
165
+ } else {
166
+ conditions["products.variants.price"] = { $lte: parseFloat(priceMax) };
167
+ }
168
+ }
169
+ return Object.keys(conditions).length > 0 ? [{ $match: conditions }] : [];
170
+ };
171
+ const getCategoryConditions = (categories) => {
172
+ if (!categories || categories.length === 0) return [];
173
+ const categoriesArray = Array.isArray(categories) ? categories : categories.split(",");
174
+ return [
175
+ {
176
+ $match: {
177
+ "products.category": { $in: categoriesArray.map((id) => new ObjectId(id)) }
178
+ }
179
+ }
180
+ ];
181
+ };
182
+ const getContainConditions = (contain) => {
183
+ if (!contain) return [];
184
+ const conditions = contain.map((property) => ({
185
+ [property]: { $exists: true, $not: { $size: 0 } }
186
+ }));
187
+ return conditions.length > 0 ? [{ $match: { $and: conditions } }] : [];
188
+ };
189
+ const hasLocationParams = (query) => query.location || query.address || query.city || query.state || query.country;
190
+ const resolveLocation = async (query) => {
191
+ if (query.location) {
192
+ const parsedLocation = typeof query.location === "string" ? JSON.parse(query.location) : query.location;
193
+ const coordinates = parsedLocation.lng ? [parsedLocation.lng, parsedLocation.lat] : parsedLocation.coordinates;
194
+ return { coordinates: coordinates.map((coord) => parseFloat(coord)) };
195
+ }
196
+ const searchString = [query.address, query.city, query.state, query.country].filter(Boolean).join(", ");
197
+ try {
198
+ const geoResponse = await client.geocode({
199
+ params: {
200
+ address: searchString,
201
+ key: process.env.GOOGLE_MAPS_API_KEY
202
+ }
203
+ });
204
+ if (!geoResponse.data.results?.length) {
205
+ throw new Error("Unable to geocode the provided location.");
206
+ }
207
+ const { lng, lat } = geoResponse.data.results[0].geometry.location;
208
+ return { coordinates: [lng, lat] };
209
+ } catch (err) {
210
+ throw new Error("Error occurred while geocoding.");
211
+ }
212
+ };
213
+ const getRadius = (query) => {
214
+ if (query.locationRadius) return parseFloat(query.locationRadius) / 6378.1;
215
+ if (query.city) return 25 / 6378.1;
216
+ if (query.state) return 50 / 6378.1;
217
+ return null;
218
+ };
219
+ const getDistanceStages = (location) => [
220
+ {
221
+ $addFields: {
222
+ distance: {
223
+ $function: {
224
+ body: `function(spotCoords, userCoords, isMiles) {
225
+ function toRad(x) {
226
+ return x * Math.PI / 180;
227
+ }
228
+ var lon1 = spotCoords[0];
229
+ var lat1 = spotCoords[1];
230
+ var lon2 = userCoords[0];
231
+ var lat2 = userCoords[1];
232
+ var R = 6371;
233
+ if (isMiles) R = 3959;
234
+ var x1 = lat2 - lat1;
235
+ var dLat = toRad(x1);
236
+ var x2 = lon2 - lon1;
237
+ var dLon = toRad(x2);
238
+ var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
239
+ Math.cos(toRad(lat1)) * Math.cos(toRad(lat2)) *
240
+ Math.sin(dLon / 2) * Math.sin(dLon / 2);
241
+ var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
242
+ var d = R * c;
243
+ return d;
244
+ }`,
245
+ args: ["$location.coordinates", location.coordinates, false],
246
+ lang: "js"
247
+ }
248
+ }
249
+ }
250
+ }
251
+ ];
252
+ const getSpotsLocationStages = async (query) => {
253
+ if (!hasLocationParams(query)) {
254
+ return { stages: [], userLocation: null };
255
+ }
256
+ const location = await resolveLocation(query);
257
+ const radius = getRadius(query);
258
+ const geoStages = radius ? [
259
+ {
260
+ $match: {
261
+ "location.coordinates": {
262
+ $geoWithin: {
263
+ $centerSphere: [[location.coordinates[0], location.coordinates[1]], radius]
264
+ }
265
+ }
266
+ }
267
+ }
268
+ ] : [];
269
+ return {
270
+ stages: [...geoStages, ...getDistanceStages(location)],
271
+ userLocation: location
272
+ };
273
+ };
274
+ const controllerFactory = (db) => {
275
+ const Spot = db.spot;
276
+ const cache = new CacheNamespaced({ ttlSeconds: 60 * 5 });
277
+ const readCatalog = async (req, res) => {
278
+ console.log("marketplace catalog query", req.query);
279
+ try {
280
+ const cacheKey = JSON.stringify(req.query);
281
+ let cachedResult = await cache.get(cacheKey);
282
+ if (cachedResult) {
283
+ return res.status(200).send(cachedResult);
284
+ }
285
+ const matchConditions = getBasicMatchConditions(req.query);
286
+ const stages = [
287
+ // Базовые фильтры spots (delivery, payment)
288
+ ...matchConditions.length > 0 ? [{ $match: { $and: matchConditions } }] : [],
289
+ // Геопоиск ПЕРВЫМ (если есть location)
290
+ ...req.query.location || req.query.city || req.query.state || req.query.country ? (await getSpotsLocationStages(req.query)).stages : [{ $addFields: { distance: null } }],
291
+ // Lookups (без availability пока)
292
+ ...getLookupStages(["products", "organizations"], lookupConfigs),
293
+ // Фильтр по наличию products
294
+ ...getContainConditions(["products", "organizations"]),
295
+ // Фильтр по ценам
296
+ ...getPriceConditions(req.query.priceMin, req.query.priceMax),
297
+ // Фильтр по категориям
298
+ ...getCategoryConditions(req.query.categories),
299
+ // Group по organization
300
+ {
301
+ $group: {
302
+ _id: { $arrayElemAt: ["$organizations._id", 0] },
303
+ profile: { $first: { $arrayElemAt: ["$organizations.profile", 0] } },
304
+ rating: { $first: { $arrayElemAt: ["$organizations.rating", 0] } },
305
+ official: { $first: { $arrayElemAt: ["$organizations.official", 0] } },
306
+ views: { $first: { $arrayElemAt: ["$organizations.views", 0] } },
307
+ spots: {
308
+ $push: {
309
+ _id: "$_id",
310
+ name: "$profile.name",
311
+ address: "$address",
312
+ location: "$location",
313
+ distance: "$distance",
314
+ delivery: "$delivery",
315
+ payment: "$payment"
316
+ }
317
+ },
318
+ products: { $first: "$products" },
319
+ distance: { $min: "$distance" }
320
+ }
321
+ },
322
+ // Добавляем numberOfProducts
323
+ {
324
+ $addFields: {
325
+ numberOfProducts: { $size: { $ifNull: ["$products", []] } }
326
+ }
327
+ },
328
+ // Финальная структура
329
+ {
330
+ $project: {
331
+ _id: 1,
332
+ profile: 1,
333
+ rating: 1,
334
+ official: 1,
335
+ views: 1,
336
+ spots: 1,
337
+ products: 1,
338
+ distance: 1,
339
+ numberOfProducts: 1
340
+ }
341
+ },
342
+ // Сортировка
343
+ ...queryProcessorCore.getSortingOptions(req.query.sortParam || "distance", req.query.sortOrder),
344
+ // Пагинация
345
+ ...queryProcessorCore.getPaginationOptions(req.query.skip, req.query.limit)
346
+ ].filter(Boolean);
347
+ console.log("Marketplace pipeline:", JSON.stringify(stages, null, 2));
348
+ const catalog = await Spot.aggregate(stages);
349
+ await cache.setWithTags(cacheKey, catalog, ["marketplace_catalog"]);
350
+ res.status(200).send(catalog);
351
+ } catch (err) {
352
+ console.error("Marketplace catalog error:", err);
353
+ res.status(500).send({ message: err.message });
354
+ }
355
+ };
356
+ return {
357
+ readCatalog
358
+ };
359
+ };
360
+ const marketplaceRoutes = (function(app, db) {
361
+ const controller = controllerFactory(db);
362
+ const { authJwt } = middlewareIndexFactory(db);
363
+ app.get(
364
+ "/api/marketplace/catalog",
365
+ [
366
+ authJwt.verifyToken(true)
367
+ // Optional authentication
368
+ ],
369
+ controller.readCatalog
370
+ );
371
+ });
372
+ function initializeMarketplace(app, db, origins, publicPath) {
373
+ if (app) {
374
+ marketplaceRoutes(app, db);
375
+ }
376
+ }
377
+ const routes = {
378
+ marketplaceRoutes
379
+ };
380
+ const initialize = initializeMarketplace;
381
+ const marketplace_server = {
382
+ initialize: initializeMarketplace,
383
+ routes
384
+ };
385
+ export {
386
+ marketplace_server as default,
387
+ initialize,
388
+ routes
389
+ };
@@ -101,10 +101,8 @@ const _sfc_main = {
101
101
  } else {
102
102
  workingValues[filter.value] = null;
103
103
  }
104
+ delete selected.value[filter.value];
104
105
  });
105
- if (props.immediate) {
106
- applyFilters();
107
- }
108
106
  };
109
107
  return (_ctx, _cache) => {
110
108
  return openBlock(), createElementBlock("div", null, [
@@ -1 +1 @@
1
- {"version":3,"file":"FiltersGroup.vue.js","sources":["../../../../../../../../../src/modules/core/views/components/sections/filters/FiltersGroup.vue"],"sourcesContent":["<template>\n <div>\n <div v-if=\"showHeader\" class=\"flex-v-center flex-nowrap flex mn-b-medium\">\n <h3 class=\"flex-child-full\">Filters</h3>\n </div>\n\n <div class=\"filters-content\">\n <div\n v-for=\"filter in filters\"\n :key=\"filter.value\"\n class=\"mn-b-medium\"\n >\n <h4 class=\"mn-b-small\">{{ filter.title }}</h4>\n\n <!-- Checkbox Filter -->\n <FilterCheckbox\n v-if=\"filter.type === 'checkbox'\"\n v-model=\"workingValues[filter.value]\"\n :options=\"filter.options\"\n @apply=\"handleApply(filter.value)\"\n />\n\n <!-- Range Filter -->\n <FilterRange\n v-else-if=\"filter.type === 'range'\"\n v-model=\"workingValues[filter.value]\"\n :minPlaceholder=\"filter.minPlaceholder || 'Min'\"\n :maxPlaceholder=\"filter.maxPlaceholder || 'Max'\"\n :label=\"filter.label\"\n @apply=\"handleApply(filter.value)\"\n />\n\n <!-- Date Filter -->\n <FilterDateRange\n v-else-if=\"filter.type === 'date'\"\n v-model=\"workingValues[filter.value]\"\n @apply=\"handleApply(filter.value)\"\n />\n\n <!-- Radio/Options Filter -->\n <FilterOptions\n v-else-if=\"filter.type === 'radio'\"\n v-model=\"workingValues[filter.value]\"\n :options=\"filter.options\"\n />\n </div>\n </div>\n\n <div class=\"flex gap-thin mn-t-medium\">\n <button\n v-if=\"showApplyButton\"\n @click=\"applyFilters\"\n class=\"button bg-main flex-child-full\"\n >\n Apply\n </button>\n <button\n v-if=\"showResetButton\"\n @click=\"resetFilters\"\n class=\"button bg-light\"\n :class=\"{ 'flex-child-full': !showApplyButton }\"\n >\n Reset Filters\n </button>\n </div>\n </div>\n</template>\n\n<script setup>\nimport { ref, reactive, watch } from 'vue'\nimport { useGlobalMixins } from '@martyrs/src/modules/core/views/mixins/mixins.js'\nimport FilterCheckbox from './FilterCheckbox.vue'\nimport FilterRange from './FilterRange.vue'\nimport FilterDateRange from './FilterDateRange.vue'\nimport FilterOptions from './FilterOptions.vue'\n\nconst props = defineProps({\n filters: {\n type: Array,\n required: true\n },\n immediate: {\n type: Boolean,\n default: false\n },\n showHeader: {\n type: Boolean,\n default: true\n },\n showApplyButton: {\n type: Boolean,\n default: false\n },\n showResetButton: {\n type: Boolean,\n default: true\n }\n})\n\nconst selected = defineModel('selected', {\n type: Object,\n default: () => ({})\n})\n\nconst { returnCurrency } = useGlobalMixins()\n\nconst workingValues = reactive({})\n\n// Initialize working values\nwatch(() => props.filters, (newFilters) => {\n newFilters.forEach(filter => {\n if (!workingValues[filter.value]) {\n if (filter.type === 'checkbox') {\n workingValues[filter.value] = [...(selected.value[filter.value] || [])]\n } else if (filter.type === 'range') {\n workingValues[filter.value] = { ...(selected.value[filter.value] || { min: '', max: '' }) }\n } else if (filter.type === 'date') {\n workingValues[filter.value] = selected.value[filter.value] || null\n } else {\n workingValues[filter.value] = selected.value[filter.value] || null\n }\n }\n })\n}, { immediate: true, deep: true })\n\n// Sync selected to workingValues\nwatch(selected, (newValue) => {\n Object.keys(newValue).forEach(key => {\n const filter = props.filters.find(f => f.value === key)\n if (filter) {\n if (filter.type === 'checkbox') {\n workingValues[key] = [...(newValue[key] || [])]\n } else if (filter.type === 'range') {\n workingValues[key] = { ...(newValue[key] || { min: '', max: '' }) }\n } else {\n workingValues[key] = newValue[key]\n }\n }\n })\n}, { deep: true })\n\nconst handleApply = (filterValue) => {\n if (props.immediate) {\n const updated = { ...selected.value }\n updated[filterValue] = workingValues[filterValue]\n selected.value = updated\n }\n}\n\nconst applyFilters = () => {\n const updated = {}\n Object.keys(workingValues).forEach(key => {\n updated[key] = workingValues[key]\n })\n selected.value = updated\n}\n\nconst resetFilters = () => {\n props.filters.forEach(filter => {\n if (filter.type === 'checkbox') {\n workingValues[filter.value] = []\n } else if (filter.type === 'range') {\n workingValues[filter.value] = { min: '', max: '' }\n } else if (filter.type === 'date') {\n workingValues[filter.value] = null\n } else {\n workingValues[filter.value] = null\n }\n })\n\n if (props.immediate) {\n applyFilters()\n }\n}\n</script>\n\n<style scoped>\n</style>\n"],"names":["_useModel"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4EA,UAAM,QAAQ;AAuBd,UAAM,WAAWA,SAAW,SAAC,UAG5B;AAED,UAAM,EAAE,eAAc,IAAK,gBAAe;AAE1C,UAAM,gBAAgB,SAAS,CAAA,CAAE;AAGjC,UAAM,MAAM,MAAM,SAAS,CAAC,eAAe;AACzC,iBAAW,QAAQ,YAAU;AAC3B,YAAI,CAAC,cAAc,OAAO,KAAK,GAAG;AAChC,cAAI,OAAO,SAAS,YAAY;AAC9B,0BAAc,OAAO,KAAK,IAAI,CAAC,GAAI,SAAS,MAAM,OAAO,KAAK,KAAK,EAAG;AAAA,UACxE,WAAW,OAAO,SAAS,SAAS;AAClC,0BAAc,OAAO,KAAK,IAAI,EAAE,GAAI,SAAS,MAAM,OAAO,KAAK,KAAK,EAAE,KAAK,IAAI,KAAK,GAAE,EAAG;AAAA,UAC3F,WAAW,OAAO,SAAS,QAAQ;AACjC,0BAAc,OAAO,KAAK,IAAI,SAAS,MAAM,OAAO,KAAK,KAAK;AAAA,UAChE,OAAO;AACL,0BAAc,OAAO,KAAK,IAAI,SAAS,MAAM,OAAO,KAAK,KAAK;AAAA,UAChE;AAAA,QACF;AAAA,MACF,CAAC;AAAA,IACH,GAAG,EAAE,WAAW,MAAM,MAAM,KAAI,CAAE;AAGlC,UAAM,UAAU,CAAC,aAAa;AAC5B,aAAO,KAAK,QAAQ,EAAE,QAAQ,SAAO;AACnC,cAAM,SAAS,MAAM,QAAQ,KAAK,OAAK,EAAE,UAAU,GAAG;AACtD,YAAI,QAAQ;AACV,cAAI,OAAO,SAAS,YAAY;AAC9B,0BAAc,GAAG,IAAI,CAAC,GAAI,SAAS,GAAG,KAAK,EAAG;AAAA,UAChD,WAAW,OAAO,SAAS,SAAS;AAClC,0BAAc,GAAG,IAAI,EAAE,GAAI,SAAS,GAAG,KAAK,EAAE,KAAK,IAAI,KAAK,GAAE,EAAG;AAAA,UACnE,OAAO;AACL,0BAAc,GAAG,IAAI,SAAS,GAAG;AAAA,UACnC;AAAA,QACF;AAAA,MACF,CAAC;AAAA,IACH,GAAG,EAAE,MAAM,KAAI,CAAE;AAEjB,UAAM,cAAc,CAAC,gBAAgB;AACnC,UAAI,MAAM,WAAW;AACnB,cAAM,UAAU,EAAE,GAAG,SAAS,MAAK;AACnC,gBAAQ,WAAW,IAAI,cAAc,WAAW;AAChD,iBAAS,QAAQ;AAAA,MACnB;AAAA,IACF;AAEA,UAAM,eAAe,MAAM;AACzB,YAAM,UAAU,CAAA;AAChB,aAAO,KAAK,aAAa,EAAE,QAAQ,SAAO;AACxC,gBAAQ,GAAG,IAAI,cAAc,GAAG;AAAA,MAClC,CAAC;AACD,eAAS,QAAQ;AAAA,IACnB;AAEA,UAAM,eAAe,MAAM;AACzB,YAAM,QAAQ,QAAQ,YAAU;AAC9B,YAAI,OAAO,SAAS,YAAY;AAC9B,wBAAc,OAAO,KAAK,IAAI,CAAA;AAAA,QAChC,WAAW,OAAO,SAAS,SAAS;AAClC,wBAAc,OAAO,KAAK,IAAI,EAAE,KAAK,IAAI,KAAK,GAAE;AAAA,QAClD,WAAW,OAAO,SAAS,QAAQ;AACjC,wBAAc,OAAO,KAAK,IAAI;AAAA,QAChC,OAAO;AACL,wBAAc,OAAO,KAAK,IAAI;AAAA,QAChC;AAAA,MACF,CAAC;AAED,UAAI,MAAM,WAAW;AACnB,qBAAY;AAAA,MACd;AAAA,IACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"FiltersGroup.vue.js","sources":["../../../../../../../../../src/modules/core/views/components/sections/filters/FiltersGroup.vue"],"sourcesContent":["<template>\n <div>\n <div v-if=\"showHeader\" class=\"flex-v-center flex-nowrap flex mn-b-medium\">\n <h3 class=\"flex-child-full\">Filters</h3>\n </div>\n\n <div class=\"filters-content\">\n <div\n v-for=\"filter in filters\"\n :key=\"filter.value\"\n class=\"mn-b-medium\"\n >\n <h4 class=\"mn-b-small\">{{ filter.title }}</h4>\n\n <!-- Checkbox Filter -->\n <FilterCheckbox\n v-if=\"filter.type === 'checkbox'\"\n v-model=\"workingValues[filter.value]\"\n :options=\"filter.options\"\n @apply=\"handleApply(filter.value)\"\n />\n\n <!-- Range Filter -->\n <FilterRange\n v-else-if=\"filter.type === 'range'\"\n v-model=\"workingValues[filter.value]\"\n :minPlaceholder=\"filter.minPlaceholder || 'Min'\"\n :maxPlaceholder=\"filter.maxPlaceholder || 'Max'\"\n :label=\"filter.label\"\n @apply=\"handleApply(filter.value)\"\n />\n\n <!-- Date Filter -->\n <FilterDateRange\n v-else-if=\"filter.type === 'date'\"\n v-model=\"workingValues[filter.value]\"\n @apply=\"handleApply(filter.value)\"\n />\n\n <!-- Radio/Options Filter -->\n <FilterOptions\n v-else-if=\"filter.type === 'radio'\"\n v-model=\"workingValues[filter.value]\"\n :options=\"filter.options\"\n />\n </div>\n </div>\n\n <div class=\"flex gap-thin mn-t-medium\">\n <button\n v-if=\"showApplyButton\"\n @click=\"applyFilters\"\n class=\"button bg-main flex-child-full\"\n >\n Apply\n </button>\n <button\n v-if=\"showResetButton\"\n @click=\"resetFilters\"\n class=\"button bg-light\"\n :class=\"{ 'flex-child-full': !showApplyButton }\"\n >\n Reset Filters\n </button>\n </div>\n </div>\n</template>\n\n<script setup>\nimport { ref, reactive, watch } from 'vue'\nimport { useGlobalMixins } from '@martyrs/src/modules/core/views/mixins/mixins.js'\nimport FilterCheckbox from './FilterCheckbox.vue'\nimport FilterRange from './FilterRange.vue'\nimport FilterDateRange from './FilterDateRange.vue'\nimport FilterOptions from './FilterOptions.vue'\n\nconst props = defineProps({\n filters: {\n type: Array,\n required: true\n },\n immediate: {\n type: Boolean,\n default: false\n },\n showHeader: {\n type: Boolean,\n default: true\n },\n showApplyButton: {\n type: Boolean,\n default: false\n },\n showResetButton: {\n type: Boolean,\n default: true\n }\n})\n\nconst selected = defineModel('selected', {\n type: Object,\n default: () => ({})\n})\n\nconst { returnCurrency } = useGlobalMixins()\n\nconst workingValues = reactive({})\n\n// Initialize working values\nwatch(() => props.filters, (newFilters) => {\n newFilters.forEach(filter => {\n if (!workingValues[filter.value]) {\n if (filter.type === 'checkbox') {\n workingValues[filter.value] = [...(selected.value[filter.value] || [])]\n } else if (filter.type === 'range') {\n workingValues[filter.value] = { ...(selected.value[filter.value] || { min: '', max: '' }) }\n } else if (filter.type === 'date') {\n workingValues[filter.value] = selected.value[filter.value] || null\n } else {\n workingValues[filter.value] = selected.value[filter.value] || null\n }\n }\n })\n}, { immediate: true, deep: true })\n\n// Sync selected to workingValues\nwatch(selected, (newValue) => {\n Object.keys(newValue).forEach(key => {\n const filter = props.filters.find(f => f.value === key)\n if (filter) {\n if (filter.type === 'checkbox') {\n workingValues[key] = [...(newValue[key] || [])]\n } else if (filter.type === 'range') {\n workingValues[key] = { ...(newValue[key] || { min: '', max: '' }) }\n } else {\n workingValues[key] = newValue[key]\n }\n }\n })\n}, { deep: true })\n\nconst handleApply = (filterValue) => {\n if (props.immediate) {\n const updated = { ...selected.value }\n updated[filterValue] = workingValues[filterValue]\n selected.value = updated\n }\n}\n\nconst applyFilters = () => {\n const updated = {}\n Object.keys(workingValues).forEach(key => {\n updated[key] = workingValues[key]\n })\n selected.value = updated\n}\n\nconst resetFilters = () => {\n props.filters.forEach(filter => {\n if (filter.type === 'checkbox') {\n workingValues[filter.value] = []\n } else if (filter.type === 'range') {\n workingValues[filter.value] = { min: '', max: '' }\n } else if (filter.type === 'date') {\n workingValues[filter.value] = null\n } else {\n workingValues[filter.value] = null\n }\n\n // Удаляем ключ из selected\n delete selected.value[filter.value]\n })\n}\n</script>\n\n<style scoped>\n</style>\n"],"names":["_useModel"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4EA,UAAM,QAAQ;AAuBd,UAAM,WAAWA,SAAW,SAAC,UAG5B;AAED,UAAM,EAAE,eAAc,IAAK,gBAAe;AAE1C,UAAM,gBAAgB,SAAS,CAAA,CAAE;AAGjC,UAAM,MAAM,MAAM,SAAS,CAAC,eAAe;AACzC,iBAAW,QAAQ,YAAU;AAC3B,YAAI,CAAC,cAAc,OAAO,KAAK,GAAG;AAChC,cAAI,OAAO,SAAS,YAAY;AAC9B,0BAAc,OAAO,KAAK,IAAI,CAAC,GAAI,SAAS,MAAM,OAAO,KAAK,KAAK,EAAG;AAAA,UACxE,WAAW,OAAO,SAAS,SAAS;AAClC,0BAAc,OAAO,KAAK,IAAI,EAAE,GAAI,SAAS,MAAM,OAAO,KAAK,KAAK,EAAE,KAAK,IAAI,KAAK,GAAE,EAAG;AAAA,UAC3F,WAAW,OAAO,SAAS,QAAQ;AACjC,0BAAc,OAAO,KAAK,IAAI,SAAS,MAAM,OAAO,KAAK,KAAK;AAAA,UAChE,OAAO;AACL,0BAAc,OAAO,KAAK,IAAI,SAAS,MAAM,OAAO,KAAK,KAAK;AAAA,UAChE;AAAA,QACF;AAAA,MACF,CAAC;AAAA,IACH,GAAG,EAAE,WAAW,MAAM,MAAM,KAAI,CAAE;AAGlC,UAAM,UAAU,CAAC,aAAa;AAC5B,aAAO,KAAK,QAAQ,EAAE,QAAQ,SAAO;AACnC,cAAM,SAAS,MAAM,QAAQ,KAAK,OAAK,EAAE,UAAU,GAAG;AACtD,YAAI,QAAQ;AACV,cAAI,OAAO,SAAS,YAAY;AAC9B,0BAAc,GAAG,IAAI,CAAC,GAAI,SAAS,GAAG,KAAK,EAAG;AAAA,UAChD,WAAW,OAAO,SAAS,SAAS;AAClC,0BAAc,GAAG,IAAI,EAAE,GAAI,SAAS,GAAG,KAAK,EAAE,KAAK,IAAI,KAAK,GAAE,EAAG;AAAA,UACnE,OAAO;AACL,0BAAc,GAAG,IAAI,SAAS,GAAG;AAAA,UACnC;AAAA,QACF;AAAA,MACF,CAAC;AAAA,IACH,GAAG,EAAE,MAAM,KAAI,CAAE;AAEjB,UAAM,cAAc,CAAC,gBAAgB;AACnC,UAAI,MAAM,WAAW;AACnB,cAAM,UAAU,EAAE,GAAG,SAAS,MAAK;AACnC,gBAAQ,WAAW,IAAI,cAAc,WAAW;AAChD,iBAAS,QAAQ;AAAA,MACnB;AAAA,IACF;AAEA,UAAM,eAAe,MAAM;AACzB,YAAM,UAAU,CAAA;AAChB,aAAO,KAAK,aAAa,EAAE,QAAQ,SAAO;AACxC,gBAAQ,GAAG,IAAI,cAAc,GAAG;AAAA,MAClC,CAAC;AACD,eAAS,QAAQ;AAAA,IACnB;AAEA,UAAM,eAAe,MAAM;AACzB,YAAM,QAAQ,QAAQ,YAAU;AAC9B,YAAI,OAAO,SAAS,YAAY;AAC9B,wBAAc,OAAO,KAAK,IAAI,CAAA;AAAA,QAChC,WAAW,OAAO,SAAS,SAAS;AAClC,wBAAc,OAAO,KAAK,IAAI,EAAE,KAAK,IAAI,KAAK,GAAE;AAAA,QAClD,WAAW,OAAO,SAAS,QAAQ;AACjC,wBAAc,OAAO,KAAK,IAAI;AAAA,QAChC,OAAO;AACL,wBAAc,OAAO,KAAK,IAAI;AAAA,QAChC;AAGA,eAAO,SAAS,MAAM,OAAO,KAAK;AAAA,MACpC,CAAC;AAAA,IACH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -22,7 +22,7 @@ const _sfc_main = {
22
22
  return (_ctx, _cache) => {
23
23
  return openBlock(), createElementBlock("section", _hoisted_1, [
24
24
  createElementVNode("h2", {
25
- class: "w-100 w-max-50r mn-b-small",
25
+ class: "w-100 w-max-50r mn-l-auto mn-r-auto mn-b-small",
26
26
  innerHTML: unref(t)("title")
27
27
  }, null, 8, _hoisted_2),
28
28
  createElementVNode("div", _hoisted_3, [
@@ -1 +1 @@
1
- {"version":3,"file":"SectionFeatures.vue.js","sources":["../../../../../../../src/modules/landing/components/sections/SectionFeatures.vue"],"sourcesContent":["<template>\n <section id=\"howtobuy\">\n <h2 class=\"w-100 w-max-50r mn-b-small\" v-html=\"t('title')\"/>\n \n <div class=\"cols-3 mobile:cols-1 gap-thin\">\n <div \n v-for=\"feature in tm('features')\" \n :key=\"feature.title\" \n class=\"pd-medium radius-medium\"\n >\n <p class=\"h2 i-extra radius-extra bg-main flex-center d-inline-flex mn-b-medium\">\n {{ feature.icon }}\n </p>\n <h3 class=\"mn-b-medium\">\n {{ feature.title }}\n </h3>\n <p class=\"t-transp\">\n {{ feature.description }}\n </p>\n </div>\n </div>\n </section>\n</template>\n\n\n<script setup>\n import { useI18n } from 'vue-i18n'\n\n const props = defineProps({\n content: {\n type: Object,\n required: true\n }\n })\n\n const { t, tm } = useI18n({\n messages: props.content\n })\n</script>\n\n<style lang=\"scss\">\n</style>\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AA4BE,UAAM,QAAQ;AAOd,UAAM,EAAE,GAAG,GAAE,IAAK,QAAQ;AAAA,MACxB,UAAU,MAAM;AAAA,IACpB,CAAG;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"SectionFeatures.vue.js","sources":["../../../../../../../src/modules/landing/components/sections/SectionFeatures.vue"],"sourcesContent":["<template>\n <section id=\"howtobuy\">\n <h2 class=\"w-100 w-max-50r mn-l-auto mn-r-auto mn-b-small\" v-html=\"t('title')\"/>\n \n <div class=\"cols-3 mobile:cols-1 gap-thin\">\n <div \n v-for=\"feature in tm('features')\" \n :key=\"feature.title\" \n class=\"pd-medium radius-medium\"\n >\n <p class=\"h2 i-extra radius-extra bg-main flex-center d-inline-flex mn-b-medium\">\n {{ feature.icon }}\n </p>\n <h3 class=\"mn-b-medium\">\n {{ feature.title }}\n </h3>\n <p class=\"t-transp\">\n {{ feature.description }}\n </p>\n </div>\n </div>\n </section>\n</template>\n\n\n<script setup>\n import { useI18n } from 'vue-i18n'\n\n const props = defineProps({\n content: {\n type: Object,\n required: true\n }\n })\n\n const { t, tm } = useI18n({\n messages: props.content\n })\n</script>\n\n<style lang=\"scss\">\n</style>\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AA4BE,UAAM,QAAQ;AAOd,UAAM,EAAE,GAAG,GAAE,IAAK,QAAQ;AAAA,MACxB,UAAU,MAAM;AAAA,IACpB,CAAG;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1,9 +1,8 @@
1
1
  import addRoutes from "../core/views/router/addRoutes.js";
2
- import { getRoutes } from "./marketplace.router.js";
2
+ import { getRoutes } from "./views/router/marketplace.router.js";
3
3
  import * as marketplace from "./views/store/marketplace.js";
4
- import _sfc_main from "./views/components/layouts/Marketplace.vue.js";
5
- import _sfc_main$2 from "./views/components/sections/SectionMenu.vue.js";
6
- import _sfc_main$1 from "./views/components/pages/Catalog.vue.js";
4
+ import _sfc_main from "./views/components/pages/Marketplace.vue.js";
5
+ import _sfc_main$1 from "./views/components/sections/SectionMenu.vue.js";
7
6
  function initializeMarketplace(app, store, router, options = {}) {
8
7
  const routes = getRoutes(options);
9
8
  routes.forEach(({ parentName, config }) => {
@@ -24,18 +23,15 @@ const ModuleMarketplace = {
24
23
  // Elements
25
24
  // Blocks
26
25
  // Sections
27
- SectionMenu: _sfc_main$2,
26
+ SectionMenu: _sfc_main$1,
28
27
  // Pages
29
- Catalog: _sfc_main$1,
30
- // Layouts
31
28
  Marketplace: _sfc_main
32
29
  }
33
30
  }
34
31
  };
35
32
  export {
36
- _sfc_main$1 as Catalog,
37
33
  _sfc_main as Marketplace,
38
- _sfc_main$2 as SectionMenu,
34
+ _sfc_main$1 as SectionMenu,
39
35
  ModuleMarketplace as default
40
36
  };
41
37
  //# sourceMappingURL=marketplace.client.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"marketplace.client.js","sources":["../../../../../src/modules/marketplace/marketplace.client.js"],"sourcesContent":["// Router\nimport addRoutes from '@martyrs/src/modules/core/views/router/addRoutes.js';\nimport { getRoutes } from './marketplace.router.js';\n\n//Store\nimport * as storeMarketplace from './views/store/marketplace.js';\n\n// Layouts\nimport Marketplace from './views/components/layouts/Marketplace.vue';\n\n// Sections\nimport SectionMenu from './views/components/sections/SectionMenu.vue';\n\n// Pages\nimport Catalog from './views/components/pages/Catalog.vue';\n\n// Пример функции инициализации для модуля маркетплейса\nfunction initializeMarketplace(app, store, router, options = {}) {\n const routes = getRoutes(options);\n routes.forEach(({ parentName, config }) => {\n addRoutes(router, { ...config, parentName });\n });\n\n store.addStore('marketplace', storeMarketplace);\n}\n\nconst ModuleMarketplace = {\n initialize: initializeMarketplace,\n views: {\n store: {\n storeMarketplace,\n },\n router: {\n getRoutes,\n },\n components: {\n // Elements\n // Blocks\n // Sections\n SectionMenu,\n // Pages\n Catalog,\n // Layouts\n Marketplace,\n },\n },\n};\n\nexport {\n // Elements\n // Pages\n Catalog,\n // Layouts\n Marketplace,\n // Blocks\n // Sections\n SectionMenu,\n};\n\nexport default ModuleMarketplace;\n"],"names":["storeMarketplace","SectionMenu","Catalog","Marketplace"],"mappings":";;;;;;AAiBA,SAAS,sBAAsB,KAAK,OAAO,QAAQ,UAAU,CAAA,GAAI;AAC/D,QAAM,SAAS,UAAU,OAAO;AAChC,SAAO,QAAQ,CAAC,EAAE,YAAY,OAAM,MAAO;AACzC,cAAU,QAAQ,EAAE,GAAG,QAAQ,WAAU,CAAE;AAAA,EAC7C,CAAC;AAED,QAAM,SAAS,eAAeA,WAAgB;AAChD;AAEK,MAAC,oBAAoB;AAAA,EACxB,YAAY;AAAA,EACZ,OAAO;AAAA,IACL,OAAO;AAAA,MACX,kBAAMA;AAAAA,IACN;AAAA,IACI,QAAQ;AAAA,MACN;AAAA,IACN;AAAA,IACI,YAAY;AAAA;AAAA;AAAA;AAAA,MAIhB,aAAMC;AAAAA;AAAAA,MAEN,SAAMC;AAAAA;AAAAA,MAEN,aAAMC;AAAAA,IACN;AAAA,EACA;AACA;"}
1
+ {"version":3,"file":"marketplace.client.js","sources":["../../../../../src/modules/marketplace/marketplace.client.js"],"sourcesContent":["// Router\nimport addRoutes from '@martyrs/src/modules/core/views/router/addRoutes.js';\nimport { getRoutes } from './views/router/marketplace.router.js';\n\n//Store\nimport * as storeMarketplace from './views/store/marketplace.js';\n\n// Pages\nimport Marketplace from './views/components/pages/Marketplace.vue';\n\n// Sections\nimport SectionMenu from './views/components/sections/SectionMenu.vue';\n\n// Пример функции инициализации для модуля маркетплейса\nfunction initializeMarketplace(app, store, router, options = {}) {\n const routes = getRoutes(options);\n routes.forEach(({ parentName, config }) => {\n addRoutes(router, { ...config, parentName });\n });\n\n store.addStore('marketplace', storeMarketplace);\n}\n\nconst ModuleMarketplace = {\n initialize: initializeMarketplace,\n views: {\n store: {\n storeMarketplace,\n },\n router: {\n getRoutes,\n },\n components: {\n // Elements\n // Blocks\n // Sections\n SectionMenu,\n // Pages\n Marketplace,\n },\n },\n};\n\nexport {\n // Elements\n // Pages\n Marketplace,\n // Blocks\n // Sections\n SectionMenu,\n};\n\nexport default ModuleMarketplace;\n"],"names":["storeMarketplace","SectionMenu","Marketplace"],"mappings":";;;;;AAcA,SAAS,sBAAsB,KAAK,OAAO,QAAQ,UAAU,CAAA,GAAI;AAC/D,QAAM,SAAS,UAAU,OAAO;AAChC,SAAO,QAAQ,CAAC,EAAE,YAAY,OAAM,MAAO;AACzC,cAAU,QAAQ,EAAE,GAAG,QAAQ,WAAU,CAAE;AAAA,EAC7C,CAAC;AAED,QAAM,SAAS,eAAeA,WAAgB;AAChD;AAEK,MAAC,oBAAoB;AAAA,EACxB,YAAY;AAAA,EACZ,OAAO;AAAA,IACL,OAAO;AAAA,MACX,kBAAMA;AAAAA,IACN;AAAA,IACI,QAAQ;AAAA,MACN;AAAA,IACN;AAAA,IACI,YAAY;AAAA;AAAA;AAAA;AAAA,MAIhB,aAAMC;AAAAA;AAAAA,MAEN,aAAMC;AAAAA,IACN;AAAA,EACA;AACA;"}
@@ -15,7 +15,10 @@ const _hoisted_3 = { class: "" };
15
15
  const _hoisted_4 = { class: "cols-2-1_3 br-1px br-solid br-light z-index-3 pos-relative" };
16
16
  const _hoisted_5 = { class: "o-y-scroll br-r br-solid br-light pd-medium z-index-2 desktop-only h-100 pos-relative" };
17
17
  const _hoisted_6 = { class: "w-100 o-y-scroll h-100" };
18
- const _hoisted_7 = { class: "mn-b-medium" };
18
+ const _hoisted_7 = {
19
+ key: 0,
20
+ class: "mn-b-medium"
21
+ };
19
22
  const _hoisted_8 = { class: "gap-micro" };
20
23
  const _hoisted_9 = ["onClick"];
21
24
  const _hoisted_10 = { class: "w-100 rows-1 pd-thin pos-relative o-hidden" };
@@ -34,13 +37,6 @@ const _sfc_main = {
34
37
  });
35
38
  const localLocation = ref(null);
36
39
  const searchLocation = ref("");
37
- const selectedFilters = ref({
38
- price: { min: null, max: null },
39
- delivery: [],
40
- payment: [],
41
- availabilityDate: null,
42
- rating: null
43
- });
44
40
  if (route.params) {
45
41
  let newState = {
46
42
  country: denormalizeUrlParam(route.params.country),
@@ -150,7 +146,7 @@ const _sfc_main = {
150
146
  createElementVNode("div", _hoisted_4, [
151
147
  createElementVNode("div", _hoisted_5, [
152
148
  createElementVNode("div", _hoisted_6, [
153
- createElementVNode("div", _hoisted_7, [
149
+ !unref(route).params.country && !unref(route).params.state && !unref(route).params.city ? (openBlock(), createElementBlock("div", _hoisted_7, [
154
150
  _cache[8] || (_cache[8] = createElementVNode("h4", { class: "mn-b-small" }, "Location", -1)),
155
151
  createVNode(Field, {
156
152
  modelValue: searchLocation.value,
@@ -168,11 +164,11 @@ const _sfc_main = {
168
164
  }, toDisplayString(location.label), 9, _hoisted_9);
169
165
  }), 128))
170
166
  ])
171
- ]),
167
+ ])) : createCommentVNode("", true),
172
168
  createVNode(_sfc_main$1, {
173
169
  filters: state.filter.options,
174
- selected: selectedFilters.value,
175
- "onUpdate:selected": _cache[3] || (_cache[3] = ($event) => selectedFilters.value = $event),
170
+ selected: state.filter.selected,
171
+ "onUpdate:selected": _cache[3] || (_cache[3] = ($event) => state.filter.selected = $event),
176
172
  immediate: true,
177
173
  showHeader: false,
178
174
  showApplyButton: false,
@@ -202,10 +198,10 @@ const _sfc_main = {
202
198
  location: localLocation.value?.location,
203
199
  lookup: ["products", "spots"],
204
200
  contain: ["products"],
205
- priceMin: selectedFilters.value.price?.min,
206
- priceMax: selectedFilters.value.price?.max,
207
- delivery: selectedFilters.value.delivery?.length > 0 ? selectedFilters.value.delivery.join(",") : void 0,
208
- payment: selectedFilters.value.payment?.length > 0 ? selectedFilters.value.payment.join(",") : void 0
201
+ priceMin: state.filter.selected.price?.min,
202
+ priceMax: state.filter.selected.price?.max,
203
+ delivery: state.filter.selected.delivery?.length > 0 ? state.filter.selected.delivery.join(",") : void 0,
204
+ payment: state.filter.selected.payment?.length > 0 ? state.filter.selected.payment.join(",") : void 0
209
205
  },
210
206
  class: "rows-1 gap-thin"
211
207
  }, {
@@ -216,8 +212,8 @@ const _sfc_main = {
216
212
  createVNode(Filters, {
217
213
  filters: state.filter.options,
218
214
  "onUpdate:filters": _cache[4] || (_cache[4] = ($event) => state.filter.options = $event),
219
- selected: selectedFilters.value,
220
- "onUpdate:selected": _cache[5] || (_cache[5] = ($event) => selectedFilters.value = $event),
215
+ selected: state.filter.selected,
216
+ "onUpdate:selected": _cache[5] || (_cache[5] = ($event) => state.filter.selected = $event),
221
217
  class: ""
222
218
  }, null, 8, ["filters", "selected"])
223
219
  ]),
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Marketplace.vue.js","sources":["../../../../../../../../src/modules/marketplace/views/components/pages/Marketplace.vue"],"sourcesContent":["<template>\n <div class=\"pos-relative\">\n <header class=\"pd-medium mn-b-thin\">\n <h2 class=\"\">\n <span class=\"\">Weed Deliveries in </span>\n\n <span\n v-if=\"localPosition.city || localPosition.state || localPosition.country\"\n @click=\"a => { store.core.state.isOpenLocationPopup = true }\"\n class=\"t-main t-semi cursor-pointer \"\n >\n <template v-if=\"localPosition.city\">{{localPosition.city}}, </template>\n <template v-if=\"localPosition.state\">{{localPosition.state}}, </template>\n <template v-if=\"localPosition.country\">{{localPosition.country}}</template>\n </span>\n\n <span v-else @click=\"a => { store.core.state.isOpenLocationPopup = true }\" class=\"t-main t-semi cursor-pointer\">The World</span>\n </h2>\n </header>\n\n <div class=\"cols-2-1_3 br-1px br-solid br-light z-index-3 pos-relative\">\n\n <div class=\"o-y-scroll br-r br-solid br-light pd-medium z-index-2 desktop-only h-100 pos-relative\">\n <div class=\"w-100 o-y-scroll h-100\">\n <!-- Location Filter -->\n <div v-if=\"!route.params.country && !route.params.state && !route.params.city\" class=\"mn-b-medium\">\n <h4 class=\"mn-b-small\">Location</h4>\n <Field\n v-model=\"searchLocation\"\n placeholder=\"Search location...\"\n type=\"text\"\n class=\"w-100 bg-light pd-small radius-small mn-b-small\"\n />\n <div class=\"gap-micro\">\n <div\n v-for=\"location in marketplace.state.locationOptions\"\n :key=\"location.label\"\n @click=\"router.push(location.path)\"\n class=\"cursor-pointer hover-t-underline mn-b-regular transition-all\"\n >\n {{ location.label }}\n </div>\n </div>\n </div>\n\n <!-- Filters Group -->\n <FiltersGroup\n :filters=\"marketplace.state.filter.options\"\n v-model:selected=\"marketplace.state.filter.selected\"\n :immediate=\"true\"\n :showHeader=\"false\"\n :showApplyButton=\"false\"\n :showResetButton=\"true\"\n />\n </div>\n </div>\n\n <div class=\"w-100 rows-1 pd-thin pos-relative o-hidden\">\n <Feed\n :search=\"true\"\n v-model:sort=\"marketplace.state.sort\"\n :showLoadMore=\"false\"\n :states=\"{\n empty: {\n title: 'No Shops Found',\n description: 'Currently, there are no shops.'\n }\n }\"\n :store=\"{\n read: (options) => marketplaceStore.readCatalog(options)\n }\"\n :options=\"{\n country: localPosition.country,\n state: localPosition.state,\n city: localPosition.city,\n location: localLocation?.location,\n lookup: ['products','spots'],\n contain: ['products'],\n priceMin: marketplace.state.filter.selected.price?.min,\n priceMax: marketplace.state.filter.selected.price?.max,\n delivery: marketplace.state.filter.selected.delivery?.length > 0 ? marketplace.state.filter.selected.delivery.join(',') : undefined,\n payment: marketplace.state.filter.selected.payment?.length > 0 ? marketplace.state.filter.selected.payment.join(',') : undefined\n }\"\n v-slot=\"{\n items\n }\"\n class=\"rows-1 gap-thin\"\n >\n <div class=\"mn-b-thin mobile-only\">\n <Filters\n v-model:filters=\"marketplace.state.filter.options\"\n v-model:selected=\"marketplace.state.filter.selected\"\n class=\"\"\n />\n </div>\n\n <CardOrganization\n v-for=\"organization in items\"\n :key=\"organization._id\"\n :organization=\"organization\"\n :showRating=\"true\"\n :showFollowers=\"false\"\n :showProducts=\"true\"\n class=\"bg-light w-100 o-hidden radius-medium pd-small \"\n />\n </Feed>\n\n </div>\n </div>\n </div>\n\n</template>\n\n\n<script setup=\"props\">\n // Import libs\n import { onMounted, watch, ref } from 'vue'\n import { useRoute, useRouter } from 'vue-router'\n import { useI18n } from 'vue-i18n'\n\n import Feed from '@martyrs/src/components/Feed/Feed.vue'\n import Filters from '@martyrs/src/modules/core/views/components/sections/Filters.vue'\n import FiltersGroup from '@martyrs/src/modules/core/views/components/sections/filters/FiltersGroup.vue'\n import Field from \"@martyrs/src/components/Field/Field.vue\"\n\n import CardOrganization from '@martyrs/src/modules/organizations/components/blocks/CardOrganization.vue'\n\n import { useStore } from '@martyrs/src/modules/core/views/store/core.store.js'\n import * as organization from '@martyrs/src/modules/organizations/store/organizations.js'\n import * as marketplace from '../../store/marketplace'\n import marketplaceStore from '../../store/marketplace'\n import { useGlobalMixins } from '@martyrs/src/modules/core/views/mixins/mixins.js'\n\n const route = useRoute()\n const router = useRouter()\n const store = useStore()\n const { returnCurrency } = useGlobalMixins()\n\n const localPosition = ref({\n city: null,\n state: null,\n country: null\n });\n\n const localLocation = ref(null);\n // Location filter\n const searchLocation = ref('');\n\n if (route.params) {\n // Загружаем новые значения из параметров маршрута в состояние\n let newState = {\n country: denormalizeUrlParam(route.params.country),\n state: denormalizeUrlParam(route.params.state),\n city: denormalizeUrlParam(route.params.city),\n };\n\n\t // Обновляем глобальное состояние\n\t localPosition.value = newState;\n\t}\n\n\tif (route.query) {\n\t \tconst query = route.query;\n\n\t\tmarketplace.state.filter.selected.categories = query.categories ? query.categories.split(',') : [];\n\t\tmarketplace.state.filter.selected.prices = query.prices ? query.prices.split(',') : [];\n\t\tmarketplace.state.filter.selected.delivery = query.delivery ? query.delivery.split(',') : [];\n\t}\n\n\tif (route.query.sortParam) marketplace.state.sort.param = route.query.sortParam\n\tif (route.query.sortOrder) marketplace.state.sort.order = route.query.sortOrder\n\n function denormalizeUrlParam(param) {\n return param\n .replace(/-/g, ' ')\n .replace(/\\b\\w/g, l => l.toUpperCase());\n }\n\n function normalizeUrlParam(param) {\n return param\n .toLowerCase()\n .replace(/ /g, '-')\n .replace(/[^a-z0-9-]/g, '');\n }\n\n\twatch(() => marketplace.state.sort, (newSortValue, oldSortValue) => {\n\t\tlet query = { ...route.query}\n\t\t\n\t\tquery.sortParam = newSortValue.param\n\t\tquery.sortOrder = newSortValue.order\n\t \n\t // replace the current route\n\t router.replace({ query });\n\t}, { deep: true });\n\n\n\twatch(() => marketplace.state.filter.selectedFilters, (newFilterValue, oldFilterValue) => {\n\t // Переводим фильтр в формат query\n\t const query = { ...route.query };\n\n\t // Удаляем старые значения фильтра из query\n\t Object.keys(oldFilterValue).forEach(key => {\n\t if (query[key]) {\n\t delete query[key];\n\t }\n\t });\n\n\t // Добавляем новые значения фильтра в query\n\t const newQueryValues = Object.fromEntries(\n\t Object.entries(newFilterValue)\n\t .filter(([key, value]) => Array.isArray(value) && value.length > 0)\n\t .map(([key, value]) => [key, value.join(',')])\n\t );\n\n\t delete query.options;\n\t Object.assign(query, newQueryValues);\n\n\t // Обновляем маршрут с новым query\n\t router.replace({ query });\n\t}, { deep: true })\n\n\twatch(() => store.core.state.position, (newPosition) => {\n // get the current route\n const currentRoute = { ...router.currentRoute.value };\n\t \n // create new parameters based on globals state position\n let newParams = {\n country: normalizeUrlParam(newPosition.country),\n state: normalizeUrlParam(newPosition.state),\n city: normalizeUrlParam(newPosition.city),\n };\n\n let newState = {\n country: denormalizeUrlParam(newPosition.country),\n state: denormalizeUrlParam(newPosition.state),\n city: denormalizeUrlParam(newPosition.city),\n };\n \n // update route params\n localPosition.value = newState;\n currentRoute.params = newParams;\n\n \n // replace the current route\n router.replace(currentRoute);\n\t}, { deep: true });\n\n const text = {\n locale: 'en',\n messages: {\n en: {\n meta: {\n title: \"Marketplace – Shop Our Wide Selection of Quality Weed for Delivery\",\n description: \"Browse our marketplace of top-grade weed strains and choose from a variety of delivery options. Order now and have your favorite strains delivered straight to your door. Safe, fast, and reliable.\",\n }\n },\n ru: {\n meta: {\n title: \"Маркетплейс – Выбирайте из нашего ассортимента качественной травки для доставки\",\n description: \"Маркетплейс – Изучите наши продукты высокого качества и выбирайте из различных вариантов доставки. Закажите сейчас и получите свои любимые сорта на дом. Безопасно, быстро и надежно.\",\n }\n }\n }\n }\n\n const { t } = useI18n(text)\n</script>\n\n<style lang=\"scss\">\n\n\n</style>\n\n\n"],"names":["marketplace.state"],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ function buildMarketplaceTree(options = {}) {
2
+ const marketplaceComponent = options.marketplaceComponent || (() => import(
3
+ /* webpackChunkName: 'marketplace-page' */
4
+ "../components/pages/Marketplace.vue.js"
5
+ ));
6
+ const buildName = (suffix) => {
7
+ const prefix = options.routeNamePrefix || "";
8
+ return suffix ? `${prefix}${suffix}` : prefix || void 0;
9
+ };
10
+ return [
11
+ {
12
+ path: ":country?/:state?/:city?",
13
+ name: buildName("Marketplace") || "Marketplace",
14
+ component: marketplaceComponent,
15
+ meta: {
16
+ title: {
17
+ en: "Marketplace",
18
+ ru: "Маркетплейс"
19
+ }
20
+ }
21
+ }
22
+ ];
23
+ }
24
+ function getRoutes(options = {}) {
25
+ const route = options.route || "Home";
26
+ const routes = [];
27
+ routes.push({
28
+ parentName: route,
29
+ config: {
30
+ basePath: options.basePath || "marketplace",
31
+ routes: buildMarketplaceTree(options)
32
+ }
33
+ });
34
+ return routes;
35
+ }
36
+ export {
37
+ getRoutes
38
+ };
39
+ //# sourceMappingURL=marketplace.router.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"marketplace.router.js","sources":["../../../../../../../src/modules/marketplace/views/router/marketplace.router.js"],"sourcesContent":["function buildMarketplaceTree(options = {}) {\n const marketplaceComponent = options.marketplaceComponent || (() => import(\n /* webpackChunkName: 'marketplace-page' */\n '../components/pages/Marketplace.vue'\n ));\n\n const buildName = (suffix) => {\n const prefix = options.routeNamePrefix || '';\n return suffix ? `${prefix}${suffix}` : prefix || undefined;\n };\n\n return [\n {\n path: ':country?/:state?/:city?',\n name: buildName('Marketplace') || 'Marketplace',\n component: marketplaceComponent,\n meta: {\n title: {\n en: 'Marketplace',\n ru: 'Маркетплейс',\n },\n },\n },\n ];\n}\n\nexport function getRoutes(options = {}) {\n const route = options.route || 'Home';\n const routes = [];\n\n routes.push({\n parentName: route,\n config: {\n basePath: options.basePath || 'marketplace',\n routes: buildMarketplaceTree(options),\n },\n });\n\n return routes;\n}\n\nexport default { getRoutes };\n"],"names":[],"mappings":"AAAA,SAAS,qBAAqB,UAAU,IAAI;AAC1C,QAAM,uBAAuB,QAAQ,yBAAyB,MAAM;AAAA;AAAA,IAElE;AAAA,EACJ;AAEE,QAAM,YAAY,CAAC,WAAW;AAC5B,UAAM,SAAS,QAAQ,mBAAmB;AAC1C,WAAO,SAAS,GAAG,MAAM,GAAG,MAAM,KAAK,UAAU;AAAA,EACnD;AAEA,SAAO;AAAA,IACL;AAAA,MACE,MAAM;AAAA,MACN,MAAM,UAAU,aAAa,KAAK;AAAA,MAClC,WAAW;AAAA,MACX,MAAM;AAAA,QACJ,OAAO;AAAA,UACL,IAAI;AAAA,UACJ,IAAI;AAAA,QACd;AAAA,MACA;AAAA,IACA;AAAA,EACA;AACA;AAEO,SAAS,UAAU,UAAU,IAAI;AACtC,QAAM,QAAQ,QAAQ,SAAS;AAC/B,QAAM,SAAS,CAAA;AAEf,SAAO,KAAK;AAAA,IACV,YAAY;AAAA,IACZ,QAAQ;AAAA,MACN,UAAU,QAAQ,YAAY;AAAA,MAC9B,QAAQ,qBAAqB,OAAO;AAAA,IAC1C;AAAA,EACA,CAAG;AAED,SAAO;AACT;"}