@ozdao/martyrs 0.2.561 → 0.2.562
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.
- package/dist/{main-DQtUY5ma.js → main-TV4u6Jux.js} +2915 -2626
- package/dist/martyrs/src/components/Button/Button.vue.js +2 -2
- package/dist/martyrs/src/components/Button/Button.vue.js.map +1 -1
- package/dist/martyrs/src/components/Checkbox/Checkbox.vue.js +1 -1
- package/dist/martyrs/src/components/Checkbox/Checkbox.vue.js.map +1 -1
- package/dist/martyrs/src/components/EditImages/{EditImages.vue.js → EditImages.vue2.js} +2 -2
- package/dist/martyrs/src/components/EditImages/EditImages.vue2.js.map +1 -0
- package/dist/martyrs/src/components/Feed/Carousel.vue.js +1 -1
- package/dist/martyrs/src/components/Feed/Feed.vue.js +2 -2
- package/dist/martyrs/src/components/Field/{Field.vue.js → Field.vue2.js} +2 -2
- package/dist/martyrs/src/components/Field/Field.vue2.js.map +1 -0
- package/dist/martyrs/src/components/FieldBig/FieldBig.vue.js +1 -1
- package/dist/martyrs/src/components/Loader/{Loader.vue.js → Loader.vue2.js} +2 -2
- package/dist/martyrs/src/components/Loader/Loader.vue2.js.map +1 -0
- package/dist/martyrs/src/components/LocationMarker/LocationMarker.vue.js +1 -1
- package/dist/martyrs/src/components/Media/Media.vue.js +1 -1
- package/dist/martyrs/src/components/Menu/{Menu.vue2.js → Menu.vue.js} +2 -2
- package/dist/martyrs/src/components/Menu/Menu.vue.js.map +1 -0
- package/dist/martyrs/src/components/SelectMulti/{SelectMulti.vue2.js → SelectMulti.vue.js} +2 -2
- package/dist/martyrs/src/components/SelectMulti/SelectMulti.vue.js.map +1 -0
- package/dist/martyrs/src/components/Spoiler/{Spoiler.vue.js → Spoiler.vue2.js} +2 -2
- package/dist/martyrs/src/components/Spoiler/Spoiler.vue2.js.map +1 -0
- package/dist/martyrs/src/components/Tab/{Tab.vue.js → Tab.vue2.js} +2 -2
- package/dist/martyrs/src/components/Tab/Tab.vue2.js.map +1 -0
- package/dist/martyrs/src/components/UploadImage/UploadImage.vue.js +1 -1
- package/dist/martyrs/src/components/UploadImageMultiple/UploadImageMultiple.vue.js +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/EnterCode.vue.js +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/EnterPassword.vue.js +2 -2
- package/dist/martyrs/src/modules/auth/views/components/pages/Invite.vue.js +2 -2
- package/dist/martyrs/src/modules/auth/views/components/pages/Profile.vue.js +3 -3
- package/dist/martyrs/src/modules/auth/views/components/pages/ProfileBlogposts.vue.js +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/ProfileEdit.vue.js +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/ProfileEditProfile.vue.js +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/ResetPassword.vue.js +2 -2
- package/dist/martyrs/src/modules/auth/views/components/pages/SignIn.vue.js +2 -2
- package/dist/martyrs/src/modules/auth/views/components/pages/SignUp.vue.js +2 -2
- package/dist/martyrs/src/modules/auth/views/components/sections/ProfileEditCredentials.vue.js +1 -1
- package/dist/martyrs/src/modules/backoffice/components/partials/Sidebar.vue.js +1 -1
- package/dist/martyrs/src/modules/community/components/pages/BlogPost.vue.js +1 -1
- package/dist/martyrs/src/modules/community/components/pages/CreateBlogPost.vue.js +1 -1
- package/dist/martyrs/src/modules/constructor/components/elements/Card.vue.js +1 -1
- package/dist/martyrs/src/modules/constructor/components/elements/Embed.vue.js +1 -1
- package/dist/martyrs/src/modules/core/views/components/blocks/BlockSearch.vue.js +1 -1
- package/dist/martyrs/src/modules/core/views/components/blocks/CardHeader.vue.js +1 -1
- package/dist/martyrs/src/modules/core/views/components/blocks/PopupDateSelector.vue.js +1 -1
- package/dist/martyrs/src/modules/core/views/components/layouts/Client.vue.js +3 -6
- package/dist/martyrs/src/modules/core/views/components/layouts/Client.vue.js.map +1 -1
- package/dist/martyrs/src/modules/core/views/components/partials/Header.vue.js +1 -1
- package/dist/martyrs/src/modules/core/views/components/partials/Header.vue.js.map +1 -1
- package/dist/martyrs/src/modules/core/views/components/partials/Navigation.vue.js +1 -1
- package/dist/martyrs/src/modules/core/views/components/sections/{Filters.vue.js → Filters.vue2.js} +60 -172
- package/dist/martyrs/src/modules/core/views/components/sections/Filters.vue2.js.map +1 -0
- package/dist/martyrs/src/modules/core/views/components/sections/SectionPageTitle.vue.js +1 -1
- package/dist/martyrs/src/modules/core/views/components/sections/filters/FilterCheckbox.vue2.js +64 -0
- package/dist/martyrs/src/modules/core/views/components/sections/filters/FilterCheckbox.vue2.js.map +1 -0
- package/dist/martyrs/src/modules/core/views/components/sections/filters/FilterDateRange.vue2.js +160 -0
- package/dist/martyrs/src/modules/core/views/components/sections/filters/FilterDateRange.vue2.js.map +1 -0
- package/dist/martyrs/src/modules/core/views/components/sections/filters/FilterOptions.vue.js +46 -0
- package/dist/martyrs/src/modules/core/views/components/sections/filters/FilterOptions.vue.js.map +1 -0
- package/dist/martyrs/src/modules/core/views/components/sections/filters/FilterRange.vue.js +105 -0
- package/dist/martyrs/src/modules/core/views/components/sections/filters/FilterRange.vue.js.map +1 -0
- package/dist/martyrs/src/modules/core/views/components/sections/filters/FiltersGroup.vue.js +168 -0
- package/dist/martyrs/src/modules/core/views/components/sections/filters/FiltersGroup.vue.js.map +1 -0
- package/dist/martyrs/src/modules/core/views/utils/vue-app-renderer.js +4 -0
- package/dist/martyrs/src/modules/core/views/utils/vue-app-renderer.js.map +1 -1
- package/dist/martyrs/src/modules/events/components/pages/EditEvent.vue.js +4 -4
- package/dist/martyrs/src/modules/events/components/pages/EditEventTickets.vue.js +1 -1
- package/dist/martyrs/src/modules/events/components/pages/Event.vue.js +5 -3
- package/dist/martyrs/src/modules/events/components/pages/Event.vue.js.map +1 -1
- package/dist/martyrs/src/modules/events/components/pages/EventsBackoffice.vue.js +1 -1
- package/dist/martyrs/src/modules/events/components/sections/EditTickets.vue.js +1 -1
- package/dist/martyrs/src/modules/events/components/sections/Feed.vue.js +1 -1
- package/dist/martyrs/src/modules/events/components/sections/List.vue.js +1 -1
- package/dist/martyrs/src/modules/gallery/components/sections/BackofficeGallery.vue.js +3 -3
- package/dist/martyrs/src/modules/inventory/components/forms/AdjustmentForm.vue.js +1 -1
- package/dist/martyrs/src/modules/inventory/components/forms/StockAlertsForm.vue.js +1 -1
- package/dist/martyrs/src/modules/inventory/components/pages/InventoryEdit.vue.js +1 -1
- package/dist/martyrs/src/modules/landing/components/sections/SectionGuide.vue.js +1 -1
- package/dist/martyrs/src/modules/marketplace/views/components/layouts/Marketplace.vue.js +159 -239
- package/dist/martyrs/src/modules/marketplace/views/components/layouts/Marketplace.vue.js.map +1 -1
- package/dist/martyrs/src/modules/marketplace/views/components/pages/Catalog.vue.js +5 -6
- package/dist/martyrs/src/modules/marketplace/views/components/pages/Catalog.vue.js.map +1 -1
- package/dist/martyrs/src/modules/marketplace/views/components/sections/SectionMenu.vue.js +1 -1
- package/dist/martyrs/src/modules/marketplace/views/store/marketplace.js +65 -2
- package/dist/martyrs/src/modules/marketplace/views/store/marketplace.js.map +1 -1
- package/dist/martyrs/src/modules/music/components/forms/AlbumForm.vue.js +1 -1
- package/dist/martyrs/src/modules/music/components/forms/ArtistForm.vue.js +2 -2
- package/dist/martyrs/src/modules/music/components/forms/PlaylistForm.vue.js +1 -1
- package/dist/martyrs/src/modules/music/components/forms/TrackForm.vue.js +1 -1
- package/dist/martyrs/src/modules/music/components/pages/Album.vue.js +1 -1
- package/dist/martyrs/src/modules/music/components/pages/Artist.vue.js +1 -1
- package/dist/martyrs/src/modules/music/components/pages/Playlist.vue.js +1 -1
- package/dist/martyrs/src/modules/music/components/pages/SearchResults.vue.js +1 -1
- package/dist/martyrs/src/modules/music/components/pages/Track.vue.js +1 -1
- package/dist/martyrs/src/modules/music/components/pages/TrackCreate.vue.js +1 -1
- package/dist/martyrs/src/modules/notifications/components/pages/Notifications.vue.js +1 -1
- package/dist/martyrs/src/modules/orders/components/forms/FormApplicationDetails.vue.js +1 -1
- package/dist/martyrs/src/modules/orders/components/forms/FormCustomerDetails.vue.js +1 -1
- package/dist/martyrs/src/modules/orders/components/forms/FormSelectCustomer.vue.js +1 -1
- package/dist/martyrs/src/modules/orders/components/pages/OrderCreateBackoffice.vue.js +2 -2
- package/dist/martyrs/src/modules/orders/components/pages/Orders.vue.js +1 -1
- package/dist/martyrs/src/modules/orders/components/sections/FormDelivery.vue.js +5 -3
- package/dist/martyrs/src/modules/orders/components/sections/FormDelivery.vue.js.map +1 -1
- package/dist/martyrs/src/modules/organizations/components/blocks/CardDepartment.vue.js +1 -1
- package/dist/martyrs/src/modules/organizations/components/blocks/CardOrganization.vue.js +4 -4
- package/dist/martyrs/src/modules/organizations/components/blocks/CardOrganization.vue.js.map +1 -1
- package/dist/martyrs/src/modules/organizations/components/forms/DepartmentForm.vue.js +2 -2
- package/dist/martyrs/src/modules/organizations/components/forms/InviteForm.vue.js +1 -1
- package/dist/martyrs/src/modules/organizations/components/pages/Department.vue.js +1 -1
- package/dist/martyrs/src/modules/organizations/components/pages/Organization.vue.js +1 -1
- package/dist/martyrs/src/modules/organizations/components/pages/OrganizationBackoffice.vue.js +2 -2
- package/dist/martyrs/src/modules/organizations/components/pages/OrganizationEdit.vue.js +3 -3
- package/dist/martyrs/src/modules/organizations/components/pages/Organizations.vue.js +1 -1
- package/dist/martyrs/src/modules/organizations/components/sections/Documents.vue.js +2 -2
- package/dist/martyrs/src/modules/organizations/components/sections/MembersAdd.vue.js +1 -1
- package/dist/martyrs/src/modules/organizations/components/sections/Organizations.vue.js +3 -3
- package/dist/martyrs/src/modules/pages/views/components/blocks/CardPage.vue.js +2 -2
- package/dist/martyrs/src/modules/pages/views/components/pages/PageEdit.vue.js +1 -1
- package/dist/martyrs/src/modules/products/components/elements/Image360.vue.js +1 -1
- package/dist/martyrs/src/modules/products/components/pages/Categories.vue.js +1 -1
- package/dist/martyrs/src/modules/products/components/pages/CategoryEdit.vue.js +5 -3
- package/dist/martyrs/src/modules/products/components/pages/CategoryEdit.vue.js.map +1 -1
- package/dist/martyrs/src/modules/products/components/pages/Product.vue.js +2 -2
- package/dist/martyrs/src/modules/products/components/pages/ProductEdit.vue.js +4 -4
- package/dist/martyrs/src/modules/products/components/pages/ProductRecommmendation.vue.js +1 -1
- package/dist/martyrs/src/modules/products/components/pages/Products.vue.js +4 -4
- package/dist/martyrs/src/modules/products/components/sections/EditAttributes.vue.js +1 -1
- package/dist/martyrs/src/modules/products/components/sections/EditDiscounts.vue.js +1 -1
- package/dist/martyrs/src/modules/products/components/sections/EditVariants.vue.js +2 -2
- package/dist/martyrs/src/modules/products/components/sections/FilterProducts.vue.js +1 -1
- package/dist/martyrs/src/modules/products/components/sections/SectionProduct.vue.js +1 -1
- package/dist/martyrs/src/modules/rents/views/components/pages/Gant/GanttToolbar.vue.js +1 -1
- package/dist/martyrs/src/modules/rents/views/components/pages/Rents.vue.js +1 -1
- package/dist/martyrs/src/modules/rents/views/components/pages/RentsEdit.vue.js +1 -1
- package/dist/martyrs/src/modules/spots/components/blocks/SpotMemberModify.vue.js +1 -1
- package/dist/martyrs/src/modules/spots/components/layouts/Spots.vue.js +2 -2
- package/dist/martyrs/src/modules/spots/components/pages/Spot.vue.js +1 -1
- package/dist/martyrs/src/modules/spots/components/pages/SpotEdit.vue.js +2 -2
- package/dist/martyrs/src/modules/spots/components/sections/WorktimeEdit.vue.js +1 -1
- package/dist/martyrs/src/modules/wallet/views/components/blocks/CardDeposit.vue.js +1 -1
- package/dist/martyrs/src/modules/wallet/views/components/blocks/CryptoDeposit.vue.js +1 -1
- package/dist/martyrs.css +1 -1
- package/dist/martyrs.es.js +1 -1
- package/dist/organizations.server.js +7 -2
- package/dist/style.css +10 -1
- package/dist/{web-Cyc6i_pv.js → web-Cq5tyhkl.js} +1 -1
- package/package.json +1 -1
- package/src/components/Button/Button.vue +1 -1
- package/src/components/Checkbox/Checkbox.vue +1 -1
- package/src/modules/core/views/components/layouts/Client.vue +7 -11
- package/src/modules/core/views/components/partials/Header.vue +1 -1
- package/src/modules/core/views/components/sections/Filters.vue +47 -161
- package/src/modules/core/views/components/sections/filters/FilterCheckbox.vue +12 -31
- package/src/modules/core/views/components/sections/filters/FilterDateRange.vue +15 -15
- package/src/modules/core/views/components/sections/filters/FilterOptions.vue +12 -43
- package/src/modules/core/views/components/sections/filters/FilterRange.vue +59 -36
- package/src/modules/core/views/components/sections/filters/FiltersGroup.vue +178 -0
- package/src/modules/core/views/utils/vue-app-renderer.js +12 -0
- package/src/modules/marketplace/controllers/marketplace.controller.js +123 -0
- package/src/modules/marketplace/controllers/utils/lookupConfigs.js +130 -0
- package/src/modules/marketplace/controllers/utils/queryProcessorMarketplace.js +211 -0
- package/src/modules/marketplace/marketplace.server.js +22 -0
- package/src/modules/marketplace/routes/marketplace.routes.js +34 -0
- package/src/modules/marketplace/views/components/layouts/Marketplace.vue +194 -275
- package/src/modules/marketplace/views/components/pages/Catalog.vue +6 -5
- package/src/modules/marketplace/views/router/marketplace.router.js +43 -28
- package/src/modules/marketplace/views/store/marketplace.js +74 -3
- package/src/modules/organizations/components/blocks/CardOrganization.vue +8 -8
- package/src/modules/organizations/controllers/organizations.controller.js +1 -1
- package/src/modules/organizations/controllers/utils/queryProcessorOrganizations.js +8 -1
- package/dist/martyrs/src/components/EditImages/EditImages.vue.js.map +0 -1
- package/dist/martyrs/src/components/Field/Field.vue.js.map +0 -1
- package/dist/martyrs/src/components/Loader/Loader.vue.js.map +0 -1
- package/dist/martyrs/src/components/Menu/Menu.vue2.js.map +0 -1
- package/dist/martyrs/src/components/SelectMulti/SelectMulti.vue2.js.map +0 -1
- package/dist/martyrs/src/components/Spoiler/Spoiler.vue.js.map +0 -1
- package/dist/martyrs/src/components/Tab/Tab.vue.js.map +0 -1
- package/dist/martyrs/src/modules/core/views/components/sections/Filters.vue.js.map +0 -1
- package/src/modules/core/views/components/sections/filters/FilterPrice.vue +0 -81
|
@@ -1,75 +1,98 @@
|
|
|
1
|
-
<!--
|
|
1
|
+
<!-- filters/FilterPrice.vue -->
|
|
2
2
|
<template>
|
|
3
|
-
<div class="filter-
|
|
4
|
-
<div class="flex gap-thin
|
|
3
|
+
<div class="filter-price">
|
|
4
|
+
<div class="flex flex-v-center gap-thin">
|
|
5
5
|
<Field
|
|
6
|
-
v-model="localValue.min"
|
|
7
|
-
:placeholder="minPlaceholder"
|
|
8
6
|
type="number"
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
v-model:field="localValue.min"
|
|
8
|
+
:placeholder="minPlaceholder"
|
|
9
|
+
:label="label"
|
|
10
|
+
class="flex-1 bg-light pd-regular radius-small"
|
|
11
|
+
@blur="updateValue"
|
|
11
12
|
/>
|
|
13
|
+
<span class="t-small">—</span>
|
|
12
14
|
<Field
|
|
13
|
-
v-model="localValue.max"
|
|
14
|
-
:placeholder="maxPlaceholder"
|
|
15
15
|
type="number"
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
v-model:field="localValue.max"
|
|
17
|
+
:placeholder="maxPlaceholder"
|
|
18
|
+
:label="label"
|
|
19
|
+
class="flex-1 bg-light pd-regular radius-small"
|
|
20
|
+
@blur="updateValue"
|
|
18
21
|
/>
|
|
19
22
|
</div>
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
|
|
24
|
+
<div v-if="config?.presets" class="mt-thin">
|
|
25
|
+
<button
|
|
26
|
+
v-for="preset in config.presets"
|
|
27
|
+
:key="preset.label"
|
|
28
|
+
@click="applyPreset(preset)"
|
|
29
|
+
class="btn btn-small mr-thin mb-thin"
|
|
30
|
+
:class="isPresetActive(preset) ? 'btn-primary' : 'btn-secondary'"
|
|
31
|
+
>
|
|
32
|
+
{{ preset.label }}
|
|
33
|
+
</button>
|
|
34
|
+
</div>
|
|
26
35
|
</div>
|
|
27
36
|
</template>
|
|
28
37
|
|
|
29
38
|
<script setup>
|
|
30
39
|
import { ref, watch } from 'vue'
|
|
31
|
-
import Field from '@martyrs/src/components/Field/Field.vue'
|
|
40
|
+
import Field from '@martyrs/src/components/Field/Field.vue';
|
|
32
41
|
|
|
33
42
|
const props = defineProps({
|
|
43
|
+
config: {
|
|
44
|
+
type: Object,
|
|
45
|
+
default: () => ({})
|
|
46
|
+
},
|
|
34
47
|
minPlaceholder: {
|
|
35
48
|
type: String,
|
|
36
|
-
default: '
|
|
49
|
+
default: 'Min'
|
|
37
50
|
},
|
|
38
51
|
maxPlaceholder: {
|
|
39
52
|
type: String,
|
|
40
|
-
default: '
|
|
53
|
+
default: 'Max'
|
|
54
|
+
},
|
|
55
|
+
label: {
|
|
56
|
+
type: String,
|
|
57
|
+
default: undefined
|
|
41
58
|
}
|
|
42
59
|
})
|
|
43
60
|
|
|
44
61
|
const model = defineModel({
|
|
45
62
|
type: Object,
|
|
46
|
-
default: () => ({ min:
|
|
63
|
+
default: () => ({ min: null, max: null })
|
|
47
64
|
})
|
|
48
65
|
|
|
49
66
|
const emit = defineEmits(['update:modelValue', 'apply'])
|
|
50
67
|
|
|
51
68
|
const localValue = ref({
|
|
52
|
-
min: model.value?.min ||
|
|
53
|
-
max: model.value?.max ||
|
|
69
|
+
min: model.value?.min || null,
|
|
70
|
+
max: model.value?.max || null
|
|
54
71
|
})
|
|
55
72
|
|
|
56
|
-
|
|
73
|
+
watch(model, (val) => {
|
|
74
|
+
if (val) {
|
|
75
|
+
localValue.value = {
|
|
76
|
+
min: val.min || null,
|
|
77
|
+
max: val.max || null
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}, { deep: true })
|
|
81
|
+
|
|
82
|
+
const updateValue = () => {
|
|
57
83
|
model.value = { ...localValue.value }
|
|
58
84
|
emit('apply')
|
|
59
85
|
}
|
|
60
86
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
max: newVal.max || ''
|
|
66
|
-
}
|
|
87
|
+
const applyPreset = (preset) => {
|
|
88
|
+
localValue.value = {
|
|
89
|
+
min: preset.min || null,
|
|
90
|
+
max: preset.max || null
|
|
67
91
|
}
|
|
68
|
-
|
|
69
|
-
|
|
92
|
+
updateValue()
|
|
93
|
+
}
|
|
70
94
|
|
|
71
|
-
|
|
72
|
-
.
|
|
73
|
-
width: 100%;
|
|
95
|
+
const isPresetActive = (preset) => {
|
|
96
|
+
return localValue.value.min === preset.min && localValue.value.max === preset.max
|
|
74
97
|
}
|
|
75
|
-
</
|
|
98
|
+
</script>
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div>
|
|
3
|
+
<div v-if="showHeader" class="flex-v-center flex-nowrap flex mn-b-medium">
|
|
4
|
+
<h3 class="flex-child-full">Filters</h3>
|
|
5
|
+
</div>
|
|
6
|
+
|
|
7
|
+
<div class="filters-content">
|
|
8
|
+
<div
|
|
9
|
+
v-for="filter in filters"
|
|
10
|
+
:key="filter.value"
|
|
11
|
+
class="mn-b-medium"
|
|
12
|
+
>
|
|
13
|
+
<h4 class="mn-b-small">{{ filter.title }}</h4>
|
|
14
|
+
|
|
15
|
+
<!-- Checkbox Filter -->
|
|
16
|
+
<FilterCheckbox
|
|
17
|
+
v-if="filter.type === 'checkbox'"
|
|
18
|
+
v-model="workingValues[filter.value]"
|
|
19
|
+
:options="filter.options"
|
|
20
|
+
@apply="handleApply(filter.value)"
|
|
21
|
+
/>
|
|
22
|
+
|
|
23
|
+
<!-- Range Filter -->
|
|
24
|
+
<FilterRange
|
|
25
|
+
v-else-if="filter.type === 'range'"
|
|
26
|
+
v-model="workingValues[filter.value]"
|
|
27
|
+
:minPlaceholder="filter.minPlaceholder || 'Min'"
|
|
28
|
+
:maxPlaceholder="filter.maxPlaceholder || 'Max'"
|
|
29
|
+
:label="filter.label"
|
|
30
|
+
@apply="handleApply(filter.value)"
|
|
31
|
+
/>
|
|
32
|
+
|
|
33
|
+
<!-- Date Filter -->
|
|
34
|
+
<FilterDateRange
|
|
35
|
+
v-else-if="filter.type === 'date'"
|
|
36
|
+
v-model="workingValues[filter.value]"
|
|
37
|
+
@apply="handleApply(filter.value)"
|
|
38
|
+
/>
|
|
39
|
+
|
|
40
|
+
<!-- Radio/Options Filter -->
|
|
41
|
+
<FilterOptions
|
|
42
|
+
v-else-if="filter.type === 'radio'"
|
|
43
|
+
v-model="workingValues[filter.value]"
|
|
44
|
+
:options="filter.options"
|
|
45
|
+
/>
|
|
46
|
+
</div>
|
|
47
|
+
</div>
|
|
48
|
+
|
|
49
|
+
<div class="flex gap-thin mn-t-medium">
|
|
50
|
+
<button
|
|
51
|
+
v-if="showApplyButton"
|
|
52
|
+
@click="applyFilters"
|
|
53
|
+
class="button bg-main flex-child-full"
|
|
54
|
+
>
|
|
55
|
+
Apply
|
|
56
|
+
</button>
|
|
57
|
+
<button
|
|
58
|
+
v-if="showResetButton"
|
|
59
|
+
@click="resetFilters"
|
|
60
|
+
class="button bg-light"
|
|
61
|
+
:class="{ 'flex-child-full': !showApplyButton }"
|
|
62
|
+
>
|
|
63
|
+
Reset Filters
|
|
64
|
+
</button>
|
|
65
|
+
</div>
|
|
66
|
+
</div>
|
|
67
|
+
</template>
|
|
68
|
+
|
|
69
|
+
<script setup>
|
|
70
|
+
import { ref, reactive, watch } from 'vue'
|
|
71
|
+
import { useGlobalMixins } from '@martyrs/src/modules/core/views/mixins/mixins.js'
|
|
72
|
+
import FilterCheckbox from './FilterCheckbox.vue'
|
|
73
|
+
import FilterRange from './FilterRange.vue'
|
|
74
|
+
import FilterDateRange from './FilterDateRange.vue'
|
|
75
|
+
import FilterOptions from './FilterOptions.vue'
|
|
76
|
+
|
|
77
|
+
const props = defineProps({
|
|
78
|
+
filters: {
|
|
79
|
+
type: Array,
|
|
80
|
+
required: true
|
|
81
|
+
},
|
|
82
|
+
immediate: {
|
|
83
|
+
type: Boolean,
|
|
84
|
+
default: false
|
|
85
|
+
},
|
|
86
|
+
showHeader: {
|
|
87
|
+
type: Boolean,
|
|
88
|
+
default: true
|
|
89
|
+
},
|
|
90
|
+
showApplyButton: {
|
|
91
|
+
type: Boolean,
|
|
92
|
+
default: false
|
|
93
|
+
},
|
|
94
|
+
showResetButton: {
|
|
95
|
+
type: Boolean,
|
|
96
|
+
default: true
|
|
97
|
+
}
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
const selected = defineModel('selected', {
|
|
101
|
+
type: Object,
|
|
102
|
+
default: () => ({})
|
|
103
|
+
})
|
|
104
|
+
|
|
105
|
+
const { returnCurrency } = useGlobalMixins()
|
|
106
|
+
|
|
107
|
+
const workingValues = reactive({})
|
|
108
|
+
|
|
109
|
+
// Initialize working values
|
|
110
|
+
watch(() => props.filters, (newFilters) => {
|
|
111
|
+
newFilters.forEach(filter => {
|
|
112
|
+
if (!workingValues[filter.value]) {
|
|
113
|
+
if (filter.type === 'checkbox') {
|
|
114
|
+
workingValues[filter.value] = [...(selected.value[filter.value] || [])]
|
|
115
|
+
} else if (filter.type === 'range') {
|
|
116
|
+
workingValues[filter.value] = { ...(selected.value[filter.value] || { min: '', max: '' }) }
|
|
117
|
+
} else if (filter.type === 'date') {
|
|
118
|
+
workingValues[filter.value] = selected.value[filter.value] || null
|
|
119
|
+
} else {
|
|
120
|
+
workingValues[filter.value] = selected.value[filter.value] || null
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
})
|
|
124
|
+
}, { immediate: true, deep: true })
|
|
125
|
+
|
|
126
|
+
// Sync selected to workingValues
|
|
127
|
+
watch(selected, (newValue) => {
|
|
128
|
+
Object.keys(newValue).forEach(key => {
|
|
129
|
+
const filter = props.filters.find(f => f.value === key)
|
|
130
|
+
if (filter) {
|
|
131
|
+
if (filter.type === 'checkbox') {
|
|
132
|
+
workingValues[key] = [...(newValue[key] || [])]
|
|
133
|
+
} else if (filter.type === 'range') {
|
|
134
|
+
workingValues[key] = { ...(newValue[key] || { min: '', max: '' }) }
|
|
135
|
+
} else {
|
|
136
|
+
workingValues[key] = newValue[key]
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
})
|
|
140
|
+
}, { deep: true })
|
|
141
|
+
|
|
142
|
+
const handleApply = (filterValue) => {
|
|
143
|
+
if (props.immediate) {
|
|
144
|
+
const updated = { ...selected.value }
|
|
145
|
+
updated[filterValue] = workingValues[filterValue]
|
|
146
|
+
selected.value = updated
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
const applyFilters = () => {
|
|
151
|
+
const updated = {}
|
|
152
|
+
Object.keys(workingValues).forEach(key => {
|
|
153
|
+
updated[key] = workingValues[key]
|
|
154
|
+
})
|
|
155
|
+
selected.value = updated
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
const resetFilters = () => {
|
|
159
|
+
props.filters.forEach(filter => {
|
|
160
|
+
if (filter.type === 'checkbox') {
|
|
161
|
+
workingValues[filter.value] = []
|
|
162
|
+
} else if (filter.type === 'range') {
|
|
163
|
+
workingValues[filter.value] = { min: '', max: '' }
|
|
164
|
+
} else if (filter.type === 'date') {
|
|
165
|
+
workingValues[filter.value] = null
|
|
166
|
+
} else {
|
|
167
|
+
workingValues[filter.value] = null
|
|
168
|
+
}
|
|
169
|
+
})
|
|
170
|
+
|
|
171
|
+
if (props.immediate) {
|
|
172
|
+
applyFilters()
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
</script>
|
|
176
|
+
|
|
177
|
+
<style scoped>
|
|
178
|
+
</style>
|
|
@@ -79,6 +79,8 @@ export function renderAndMountApp({ createApp, hooks = {} }) {
|
|
|
79
79
|
}
|
|
80
80
|
|
|
81
81
|
|
|
82
|
+
|
|
83
|
+
|
|
82
84
|
if (initialState) {
|
|
83
85
|
console.log('[AUTH COOKIE DEBUG] Browser initialState.auth:', initialState.auth);
|
|
84
86
|
console.log('[AUTH COOKIE DEBUG] Has token?', !!initialState?.auth?.access?.token);
|
|
@@ -89,6 +91,7 @@ export function renderAndMountApp({ createApp, hooks = {} }) {
|
|
|
89
91
|
|
|
90
92
|
if (initialState?.auth?.access?.token) {
|
|
91
93
|
console.log('[AUTH COOKIE DEBUG] Setting auth token from initialState');
|
|
94
|
+
|
|
92
95
|
setAuthToken(initialState.auth.access.token);
|
|
93
96
|
} else if (initialState?.auth && !initialState.auth.access?.status) {
|
|
94
97
|
// Если SSR сбросил auth (из-за ошибки), удаляем куку в браузере
|
|
@@ -106,6 +109,12 @@ export function renderAndMountApp({ createApp, hooks = {} }) {
|
|
|
106
109
|
}
|
|
107
110
|
}
|
|
108
111
|
|
|
112
|
+
const savedPosition = localStorage.getItem('position');
|
|
113
|
+
|
|
114
|
+
if (savedPosition) {
|
|
115
|
+
store.core.state.position = JSON.parse(savedPosition);
|
|
116
|
+
}
|
|
117
|
+
|
|
109
118
|
// app.config.globalProperties.$i18n.locale = router.currentRoute.value.params.locale
|
|
110
119
|
// app.config.globalProperties.$i18n.locale = router.currentRoute.value.params.locale
|
|
111
120
|
// If user browser locae supported then change locale
|
|
@@ -171,6 +180,9 @@ export async function render({ url, cookies, ssrContext, createApp}) {
|
|
|
171
180
|
}
|
|
172
181
|
}
|
|
173
182
|
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
|
|
174
186
|
if (user) {
|
|
175
187
|
// [LOADING 27] SSR auth initialization
|
|
176
188
|
performance.mark('loading-27-start');
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import Cache from '@martyrs/src/modules/core/controllers/classes/core.cache.js';
|
|
2
|
+
import queryProcessorCore from '@martyrs/src/modules/core/controllers/utils/queryProcessor.js';
|
|
3
|
+
import { getLookupStages } from '@martyrs/src/modules/organizations/controllers/utils/queryProcessorOrganizations.js';
|
|
4
|
+
import lookupConfigs from './utils/lookupConfigs.js';
|
|
5
|
+
import {
|
|
6
|
+
getBasicMatchConditions,
|
|
7
|
+
getPriceConditions,
|
|
8
|
+
getCategoryConditions,
|
|
9
|
+
getContainConditions,
|
|
10
|
+
getSpotsLocationStages,
|
|
11
|
+
} from './utils/queryProcessorMarketplace.js';
|
|
12
|
+
|
|
13
|
+
const controllerFactory = db => {
|
|
14
|
+
const Spot = db.spot;
|
|
15
|
+
|
|
16
|
+
const cache = new Cache({ ttlSeconds: 60 * 5 });
|
|
17
|
+
|
|
18
|
+
const readCatalog = async (req, res) => {
|
|
19
|
+
console.log('marketplace catalog query', req.query);
|
|
20
|
+
|
|
21
|
+
try {
|
|
22
|
+
const cacheKey = JSON.stringify(req.query);
|
|
23
|
+
|
|
24
|
+
let cachedResult = await cache.get(cacheKey);
|
|
25
|
+
if (cachedResult) {
|
|
26
|
+
return res.status(200).send(cachedResult);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const matchConditions = getBasicMatchConditions(req.query);
|
|
30
|
+
|
|
31
|
+
const stages = [
|
|
32
|
+
// Базовые фильтры spots (delivery, payment)
|
|
33
|
+
...(matchConditions.length > 0 ? [{ $match: { $and: matchConditions } }] : []),
|
|
34
|
+
|
|
35
|
+
// Геопоиск ПЕРВЫМ (если есть location)
|
|
36
|
+
...(req.query.location || req.query.city || req.query.state || req.query.country
|
|
37
|
+
? (await getSpotsLocationStages(req.query)).stages
|
|
38
|
+
: [{ $addFields: { distance: null } }]),
|
|
39
|
+
|
|
40
|
+
// Lookups (без availability пока)
|
|
41
|
+
...getLookupStages(['products', 'organizations'], lookupConfigs),
|
|
42
|
+
|
|
43
|
+
// Фильтр по наличию products
|
|
44
|
+
...getContainConditions(['products', 'organizations']),
|
|
45
|
+
|
|
46
|
+
// Фильтр по ценам
|
|
47
|
+
...getPriceConditions(req.query.priceMin, req.query.priceMax),
|
|
48
|
+
|
|
49
|
+
// Фильтр по категориям
|
|
50
|
+
...getCategoryConditions(req.query.categories),
|
|
51
|
+
|
|
52
|
+
// Group по organization
|
|
53
|
+
{
|
|
54
|
+
$group: {
|
|
55
|
+
_id: { $arrayElemAt: ['$organizations._id', 0] },
|
|
56
|
+
profile: { $first: { $arrayElemAt: ['$organizations.profile', 0] } },
|
|
57
|
+
rating: { $first: { $arrayElemAt: ['$organizations.rating', 0] } },
|
|
58
|
+
official: { $first: { $arrayElemAt: ['$organizations.official', 0] } },
|
|
59
|
+
views: { $first: { $arrayElemAt: ['$organizations.views', 0] } },
|
|
60
|
+
spots: {
|
|
61
|
+
$push: {
|
|
62
|
+
_id: '$_id',
|
|
63
|
+
name: '$profile.name',
|
|
64
|
+
address: '$address',
|
|
65
|
+
location: '$location',
|
|
66
|
+
distance: '$distance',
|
|
67
|
+
delivery: '$delivery',
|
|
68
|
+
payment: '$payment',
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
products: { $first: '$products' },
|
|
72
|
+
distance: { $min: '$distance' },
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
|
|
76
|
+
// Добавляем numberOfProducts
|
|
77
|
+
{
|
|
78
|
+
$addFields: {
|
|
79
|
+
numberOfProducts: { $size: { $ifNull: ['$products', []] } },
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
|
|
83
|
+
// Финальная структура
|
|
84
|
+
{
|
|
85
|
+
$project: {
|
|
86
|
+
_id: 1,
|
|
87
|
+
profile: 1,
|
|
88
|
+
rating: 1,
|
|
89
|
+
official: 1,
|
|
90
|
+
views: 1,
|
|
91
|
+
spots: 1,
|
|
92
|
+
products: 1,
|
|
93
|
+
distance: 1,
|
|
94
|
+
numberOfProducts: 1,
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
|
|
98
|
+
// Сортировка
|
|
99
|
+
...queryProcessorCore.getSortingOptions(req.query.sortParam || 'distance', req.query.sortOrder),
|
|
100
|
+
|
|
101
|
+
// Пагинация
|
|
102
|
+
...queryProcessorCore.getPaginationOptions(req.query.skip, req.query.limit),
|
|
103
|
+
].filter(Boolean);
|
|
104
|
+
|
|
105
|
+
console.log('Marketplace pipeline:', JSON.stringify(stages, null, 2));
|
|
106
|
+
|
|
107
|
+
const catalog = await Spot.aggregate(stages);
|
|
108
|
+
|
|
109
|
+
await cache.setWithTags(cacheKey, catalog, ['marketplace_catalog']);
|
|
110
|
+
|
|
111
|
+
res.status(200).send(catalog);
|
|
112
|
+
} catch (err) {
|
|
113
|
+
console.error('Marketplace catalog error:', err);
|
|
114
|
+
res.status(500).send({ message: err.message });
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
return {
|
|
119
|
+
readCatalog,
|
|
120
|
+
};
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
export default controllerFactory;
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
const lookupConfigs = {
|
|
2
|
+
availability: {
|
|
3
|
+
lookup: {
|
|
4
|
+
from: 'stockavailabilities',
|
|
5
|
+
localField: '_id',
|
|
6
|
+
foreignField: 'storage',
|
|
7
|
+
pipeline: [
|
|
8
|
+
{
|
|
9
|
+
$match: {
|
|
10
|
+
$expr: { $gt: ['$available', 0] },
|
|
11
|
+
},
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
$project: {
|
|
15
|
+
_id: 1,
|
|
16
|
+
product: 1,
|
|
17
|
+
variant: 1,
|
|
18
|
+
available: 1,
|
|
19
|
+
quantity: 1,
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
],
|
|
23
|
+
as: 'availability',
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
variants: {
|
|
27
|
+
lookup: {
|
|
28
|
+
from: 'variants',
|
|
29
|
+
let: { variantIds: '$availability.variant' },
|
|
30
|
+
pipeline: [
|
|
31
|
+
{
|
|
32
|
+
$match: {
|
|
33
|
+
$expr: {
|
|
34
|
+
$in: ['$_id', '$$variantIds'],
|
|
35
|
+
},
|
|
36
|
+
status: 'published',
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
$project: {
|
|
41
|
+
_id: 1,
|
|
42
|
+
product: 1,
|
|
43
|
+
name: 1,
|
|
44
|
+
price: 1,
|
|
45
|
+
unit: 1,
|
|
46
|
+
images: 1,
|
|
47
|
+
sku: 1,
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
],
|
|
51
|
+
as: 'variants',
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
products: {
|
|
55
|
+
lookup: {
|
|
56
|
+
from: 'products',
|
|
57
|
+
localField: 'organization',
|
|
58
|
+
foreignField: 'owner.target',
|
|
59
|
+
pipeline: [
|
|
60
|
+
{
|
|
61
|
+
$match: {
|
|
62
|
+
status: 'published',
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
$lookup: {
|
|
67
|
+
from: 'variants',
|
|
68
|
+
localField: '_id',
|
|
69
|
+
foreignField: 'product',
|
|
70
|
+
pipeline: [
|
|
71
|
+
{
|
|
72
|
+
$project: {
|
|
73
|
+
_id: 1,
|
|
74
|
+
name: 1,
|
|
75
|
+
price: 1,
|
|
76
|
+
unit: 1,
|
|
77
|
+
images: 1,
|
|
78
|
+
sku: 1,
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
],
|
|
82
|
+
as: 'variants',
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
$project: {
|
|
87
|
+
_id: 1,
|
|
88
|
+
name: 1,
|
|
89
|
+
description: 1,
|
|
90
|
+
images: 1,
|
|
91
|
+
category: 1,
|
|
92
|
+
'owner.target': 1,
|
|
93
|
+
'owner.type': 1,
|
|
94
|
+
variants: 1,
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
],
|
|
98
|
+
as: 'products',
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
organizations: {
|
|
102
|
+
lookup: {
|
|
103
|
+
from: 'organizations',
|
|
104
|
+
let: { orgIds: '$products.owner.target' },
|
|
105
|
+
pipeline: [
|
|
106
|
+
{
|
|
107
|
+
$match: {
|
|
108
|
+
$expr: {
|
|
109
|
+
$in: ['$_id', '$$orgIds'],
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
$project: {
|
|
115
|
+
_id: 1,
|
|
116
|
+
'profile.name': 1,
|
|
117
|
+
'profile.photo': 1,
|
|
118
|
+
'profile.description': 1,
|
|
119
|
+
'profile.tags': 1,
|
|
120
|
+
rating: 1,
|
|
121
|
+
official: 1,
|
|
122
|
+
},
|
|
123
|
+
},
|
|
124
|
+
],
|
|
125
|
+
as: 'organizations',
|
|
126
|
+
},
|
|
127
|
+
},
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
export default lookupConfigs;
|