@ozdao/martyrs 0.2.561 → 0.2.563
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/{abac-DC2x92Pa.js → abac-DYoheWuc.js} +2 -1
- package/dist/{core.logger-VRHh-WUW.js → core.cache-DALYFDdy.js} +10 -59
- package/dist/core.logger-C3q8A9dl.js +51 -0
- package/dist/core.server.js +1 -1
- package/dist/{crud-DFFgLl09.js → crud-C7FSTUes.js} +2 -1
- package/dist/inventory.server.js +4 -3
- package/dist/{main-DQtUY5ma.js → main-CmjWiDVF.js} +2837 -2548
- package/dist/marketplace.server.js +389 -0
- package/dist/martyrs/src/components/Button/{Button.vue.js → Button.vue2.js} +3 -3
- package/dist/martyrs/src/components/Button/Button.vue2.js.map +1 -0
- 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/FieldBig/FieldBig.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/Select/{Select.vue2.js → Select.vue.js} +2 -2
- package/dist/martyrs/src/components/Select/Select.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/modules/auth/views/components/pages/EnterPassword.vue.js +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/Invite.vue.js +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/Profile.vue.js +2 -2
- package/dist/martyrs/src/modules/auth/views/components/pages/ProfileEditAccount.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 +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/SignIn.vue.js +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/SignUp.vue.js +1 -1
- package/dist/martyrs/src/modules/auth/views/components/sections/ProfileEditCredentials.vue.js +1 -1
- package/dist/martyrs/src/modules/community/components/layouts/Community.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/core/views/components/blocks/CardHeader.vue.js +1 -1
- package/dist/martyrs/src/modules/core/views/components/blocks/PopupAuth.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 +3 -3
- 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/partials/NavigationBar.vue.js +1 -1
- package/dist/martyrs/src/modules/core/views/components/sections/Filters.vue.js +59 -171
- package/dist/martyrs/src/modules/core/views/components/sections/Filters.vue.js.map +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 +166 -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/elements/ButtonCheck.vue.js +1 -1
- package/dist/martyrs/src/modules/events/components/elements/ButtonJoin.vue.js +1 -1
- package/dist/martyrs/src/modules/events/components/pages/EditEvent.vue.js +1 -1
- package/dist/martyrs/src/modules/events/components/pages/EditEventTickets.vue.js +1 -1
- package/dist/martyrs/src/modules/events/components/pages/Event.vue.js +2 -0
- package/dist/martyrs/src/modules/events/components/pages/Event.vue.js.map +1 -1
- package/dist/martyrs/src/modules/events/components/sections/EditTickets.vue.js +1 -1
- package/dist/martyrs/src/modules/gallery/components/sections/BackofficeGallery.vue.js +2 -2
- package/dist/martyrs/src/modules/inventory/components/forms/AdjustmentForm.vue.js +2 -2
- package/dist/martyrs/src/modules/inventory/components/forms/ColumnSettingsMenu.vue.js +1 -1
- package/dist/martyrs/src/modules/inventory/components/forms/HistoryView.vue.js +1 -1
- package/dist/martyrs/src/modules/inventory/components/forms/StockAlertsForm.vue.js +2 -2
- package/dist/martyrs/src/modules/inventory/components/pages/InventoryEdit.vue.js +2 -2
- package/dist/martyrs/src/modules/landing/components/sections/SectionFeatures.vue.js +1 -1
- package/dist/martyrs/src/modules/landing/components/sections/SectionFeatures.vue.js.map +1 -1
- package/dist/martyrs/src/modules/landing/components/sections/SectionGuide.vue.js +1 -1
- package/dist/martyrs/src/modules/marketplace/marketplace.client.js +5 -9
- package/dist/martyrs/src/modules/marketplace/marketplace.client.js.map +1 -1
- package/dist/martyrs/src/modules/marketplace/views/components/pages/Marketplace.vue.js +242 -0
- package/dist/martyrs/src/modules/marketplace/views/components/pages/Marketplace.vue.js.map +1 -0
- package/dist/martyrs/src/modules/marketplace/views/router/marketplace.router.js +39 -0
- package/dist/martyrs/src/modules/marketplace/views/router/marketplace.router.js.map +1 -0
- 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/cards/AlbumCard.vue.js +1 -1
- package/dist/martyrs/src/modules/music/components/cards/ArtistCardSmall.vue.js +1 -1
- package/dist/martyrs/src/modules/music/components/cards/PlaylistCard.vue.js +1 -1
- package/dist/martyrs/src/modules/music/components/cards/TrackListCard.vue.js +1 -1
- package/dist/martyrs/src/modules/music/components/forms/AlbumForm.vue.js +2 -2
- 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/SearchForm.vue.js +1 -1
- package/dist/martyrs/src/modules/music/components/forms/TrackForm.vue.js +2 -2
- 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/MusicLibrary.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/music/components/player/MusicPlayer.vue.js +1 -1
- package/dist/martyrs/src/modules/orders/components/forms/FormApplicationDetails.vue.js +2 -2
- package/dist/martyrs/src/modules/orders/components/forms/FormCustomerDetails.vue.js +2 -2
- package/dist/martyrs/src/modules/orders/components/forms/FormSelectCustomer.vue.js +1 -1
- package/dist/martyrs/src/modules/orders/components/pages/OrderBackoffice.vue.js +2 -2
- package/dist/martyrs/src/modules/orders/components/pages/OrderCreate.vue.js +1 -1
- package/dist/martyrs/src/modules/orders/components/pages/OrderCreateBackoffice.vue.js +1 -1
- package/dist/martyrs/src/modules/orders/components/sections/ApplicationDetails.vue.js +1 -1
- package/dist/martyrs/src/modules/orders/components/sections/CustomerDetails.vue.js +1 -1
- package/dist/martyrs/src/modules/orders/components/sections/FormDelivery.vue.js +2 -0
- package/dist/martyrs/src/modules/orders/components/sections/FormDelivery.vue.js.map +1 -1
- package/dist/martyrs/src/modules/orders/components/sections/FormPayment.vue.js +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/elements/ButtonToggleMembership.vue.js +1 -1
- package/dist/martyrs/src/modules/organizations/components/forms/AddExistingMembersForm.vue.js +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 +1 -1
- package/dist/martyrs/src/modules/organizations/components/pages/OrganizationEdit.vue.js +2 -2
- package/dist/martyrs/src/modules/organizations/components/sections/Documents.vue.js +1 -1
- package/dist/martyrs/src/modules/organizations/components/sections/MembersAdd.vue.js +2 -2
- package/dist/martyrs/src/modules/organizations/components/sections/Organizations.vue.js +1 -1
- package/dist/martyrs/src/modules/pages/views/components/blocks/CardPage.vue.js +1 -1
- package/dist/martyrs/src/modules/pages/views/components/pages/PageEdit.vue.js +1 -1
- package/dist/martyrs/src/modules/pages/views/components/partials/SidebarPages.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 +4 -2
- 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 +1 -1
- package/dist/martyrs/src/modules/products/components/pages/ProductEdit.vue.js +2 -2
- package/dist/martyrs/src/modules/products/components/pages/Products.vue.js +1 -1
- package/dist/martyrs/src/modules/products/components/sections/EditAttributes.vue.js +1 -1
- package/dist/martyrs/src/modules/products/components/sections/EditDiscounts.vue.js +2 -2
- 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/ProductConfigurator.vue.js +1 -1
- package/dist/martyrs/src/modules/products/components/sections/ProductsRecommended.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/reports/components/sections/FormReport.vue.js +2 -2
- package/dist/martyrs/src/modules/spots/components/blocks/SpotMemberModify.vue.js +1 -1
- package/dist/martyrs/src/modules/spots/components/layouts/Spots.vue.js +1 -1
- package/dist/martyrs/src/modules/spots/components/pages/Map.vue.js +1 -1
- 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 +2 -2
- package/dist/martyrs/src/modules/wallet/views/components/blocks/CryptoDeposit.vue.js +1 -1
- package/dist/martyrs/src/modules/wallet/views/components/pages/Wallet.vue.js +2 -2
- package/dist/martyrs.css +1 -1
- package/dist/martyrs.es.js +1 -1
- package/dist/music.server.js +4 -3
- package/dist/node_modules/.pnpm/qrcode@1.5.4/node_modules/qrcode/lib/core/utils.js +1 -1
- package/dist/node_modules/.pnpm/qrcode@1.5.4/node_modules/qrcode/lib/renderer/utils.js +1 -1
- package/dist/orders.server.js +2 -2
- package/dist/organizations.server.js +10 -215
- package/dist/products.server.js +4 -3
- package/dist/queryProcessorOrganizations-BB11WFpc.js +221 -0
- package/dist/rents.server.js +2 -1
- package/dist/style.css +10 -1
- package/dist/{web-Cyc6i_pv.js → web-cNKIl_cL.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 +177 -0
- package/src/modules/core/views/utils/vue-app-renderer.js +12 -0
- package/src/modules/landing/components/sections/SectionFeatures.vue +1 -1
- 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.client.js +3 -10
- 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/pages/Marketplace.vue +273 -0
- package/src/modules/marketplace/views/router/marketplace.router.js +37 -30
- 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/Button/Button.vue.js.map +0 -1
- package/dist/martyrs/src/components/Menu/Menu.vue2.js.map +0 -1
- package/dist/martyrs/src/components/Select/Select.vue2.js.map +0 -1
- package/dist/martyrs/src/components/Spoiler/Spoiler.vue.js.map +0 -1
- package/dist/martyrs/src/modules/marketplace/marketplace.router.js +0 -63
- package/dist/martyrs/src/modules/marketplace/marketplace.router.js.map +0 -1
- package/dist/martyrs/src/modules/marketplace/views/components/layouts/Marketplace.vue.js +0 -326
- package/dist/martyrs/src/modules/marketplace/views/components/layouts/Marketplace.vue.js.map +0 -1
- package/dist/martyrs/src/modules/marketplace/views/components/pages/Catalog.vue.js +0 -74
- package/dist/martyrs/src/modules/marketplace/views/components/pages/Catalog.vue.js.map +0 -1
- package/src/modules/core/views/components/sections/filters/FilterPrice.vue +0 -81
- package/src/modules/marketplace/marketplace.router.js +0 -66
- package/src/modules/marketplace/views/components/layouts/Marketplace.vue +0 -363
- package/src/modules/marketplace/views/components/pages/Catalog.vue +0 -73
|
@@ -1,19 +1,16 @@
|
|
|
1
1
|
// Router
|
|
2
2
|
import addRoutes from '@martyrs/src/modules/core/views/router/addRoutes.js';
|
|
3
|
-
import { getRoutes } from './marketplace.router.js';
|
|
3
|
+
import { getRoutes } from './views/router/marketplace.router.js';
|
|
4
4
|
|
|
5
5
|
//Store
|
|
6
6
|
import * as storeMarketplace from './views/store/marketplace.js';
|
|
7
7
|
|
|
8
|
-
//
|
|
9
|
-
import Marketplace from './views/components/
|
|
8
|
+
// Pages
|
|
9
|
+
import Marketplace from './views/components/pages/Marketplace.vue';
|
|
10
10
|
|
|
11
11
|
// Sections
|
|
12
12
|
import SectionMenu from './views/components/sections/SectionMenu.vue';
|
|
13
13
|
|
|
14
|
-
// Pages
|
|
15
|
-
import Catalog from './views/components/pages/Catalog.vue';
|
|
16
|
-
|
|
17
14
|
// Пример функции инициализации для модуля маркетплейса
|
|
18
15
|
function initializeMarketplace(app, store, router, options = {}) {
|
|
19
16
|
const routes = getRoutes(options);
|
|
@@ -39,8 +36,6 @@ const ModuleMarketplace = {
|
|
|
39
36
|
// Sections
|
|
40
37
|
SectionMenu,
|
|
41
38
|
// Pages
|
|
42
|
-
Catalog,
|
|
43
|
-
// Layouts
|
|
44
39
|
Marketplace,
|
|
45
40
|
},
|
|
46
41
|
},
|
|
@@ -49,8 +44,6 @@ const ModuleMarketplace = {
|
|
|
49
44
|
export {
|
|
50
45
|
// Elements
|
|
51
46
|
// Pages
|
|
52
|
-
Catalog,
|
|
53
|
-
// Layouts
|
|
54
47
|
Marketplace,
|
|
55
48
|
// Blocks
|
|
56
49
|
// Sections
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import marketplaceRoutes from './routes/marketplace.routes.js';
|
|
2
|
+
|
|
3
|
+
function initializeMarketplace(app, db, origins, publicPath) {
|
|
4
|
+
// Marketplace использует существующие модели (Spot, StockAvailability, Variant, Product, Organization)
|
|
5
|
+
// Модели уже зарегистрированы в spots, inventory, products, organizations модулях
|
|
6
|
+
|
|
7
|
+
// Настраиваем маршруты
|
|
8
|
+
if (app) {
|
|
9
|
+
marketplaceRoutes(app, db, origins, publicPath);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export const routes = {
|
|
14
|
+
marketplaceRoutes,
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export const initialize = initializeMarketplace;
|
|
18
|
+
|
|
19
|
+
export default {
|
|
20
|
+
initialize: initializeMarketplace,
|
|
21
|
+
routes,
|
|
22
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import middlewareFactoryAuth from '@martyrs/src/modules/auth/controllers/middlewares/index.js';
|
|
2
|
+
import controllerFactory from '../controllers/marketplace.controller.js';
|
|
3
|
+
|
|
4
|
+
export default (function (app, db) {
|
|
5
|
+
const controller = controllerFactory(db);
|
|
6
|
+
const { authJwt } = middlewareFactoryAuth(db);
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* GET /api/marketplace/catalog
|
|
10
|
+
* Public endpoint for marketplace catalog
|
|
11
|
+
* Returns organizations with available products at nearby spots
|
|
12
|
+
*
|
|
13
|
+
* Query params:
|
|
14
|
+
* - location: { coordinates: [lng, lat] } or JSON string
|
|
15
|
+
* - locationRadius: number (km)
|
|
16
|
+
* - address/city/state/country: for geocoding
|
|
17
|
+
* - priceMin/priceMax: number
|
|
18
|
+
* - delivery: comma-separated string or array
|
|
19
|
+
* - payment: comma-separated string or array
|
|
20
|
+
* - categories: comma-separated string or array
|
|
21
|
+
* - isOpenNow: boolean
|
|
22
|
+
* - sortParam: 'distance' | 'rating' | 'views' (default: 'distance')
|
|
23
|
+
* - sortOrder: 'asc' | 'desc' (default: 'asc')
|
|
24
|
+
* - skip: number (default: 0)
|
|
25
|
+
* - limit: number (default: 18)
|
|
26
|
+
*/
|
|
27
|
+
app.get(
|
|
28
|
+
'/api/marketplace/catalog',
|
|
29
|
+
[
|
|
30
|
+
authJwt.verifyToken(true), // Optional authentication
|
|
31
|
+
],
|
|
32
|
+
controller.readCatalog
|
|
33
|
+
);
|
|
34
|
+
});
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="pos-relative">
|
|
3
|
+
<header class="pd-medium mn-b-thin">
|
|
4
|
+
<h2 class="">
|
|
5
|
+
<span class="">Weed Deliveries in </span>
|
|
6
|
+
|
|
7
|
+
<span
|
|
8
|
+
v-if="localPosition.city || localPosition.state || localPosition.country"
|
|
9
|
+
@click="a => { store.core.state.isOpenLocationPopup = true }"
|
|
10
|
+
class="t-main t-semi cursor-pointer "
|
|
11
|
+
>
|
|
12
|
+
<template v-if="localPosition.city">{{localPosition.city}}, </template>
|
|
13
|
+
<template v-if="localPosition.state">{{localPosition.state}}, </template>
|
|
14
|
+
<template v-if="localPosition.country">{{localPosition.country}}</template>
|
|
15
|
+
</span>
|
|
16
|
+
|
|
17
|
+
<span v-else @click="a => { store.core.state.isOpenLocationPopup = true }" class="t-main t-semi cursor-pointer">The World</span>
|
|
18
|
+
</h2>
|
|
19
|
+
</header>
|
|
20
|
+
|
|
21
|
+
<div class="cols-2-1_3 br-1px br-solid br-light z-index-3 pos-relative">
|
|
22
|
+
|
|
23
|
+
<div class="o-y-scroll br-r br-solid br-light pd-medium z-index-2 desktop-only h-100 pos-relative">
|
|
24
|
+
<div class="w-100 o-y-scroll h-100">
|
|
25
|
+
<!-- Location Filter -->
|
|
26
|
+
<div v-if="!route.params.country && !route.params.state && !route.params.city" class="mn-b-medium">
|
|
27
|
+
<h4 class="mn-b-small">Location</h4>
|
|
28
|
+
<Field
|
|
29
|
+
v-model="searchLocation"
|
|
30
|
+
placeholder="Search location..."
|
|
31
|
+
type="text"
|
|
32
|
+
class="w-100 bg-light pd-small radius-small mn-b-small"
|
|
33
|
+
/>
|
|
34
|
+
<div class="gap-micro">
|
|
35
|
+
<div
|
|
36
|
+
v-for="location in marketplace.state.locationOptions"
|
|
37
|
+
:key="location.label"
|
|
38
|
+
@click="router.push(location.path)"
|
|
39
|
+
class="cursor-pointer hover-t-underline mn-b-regular transition-all"
|
|
40
|
+
>
|
|
41
|
+
{{ location.label }}
|
|
42
|
+
</div>
|
|
43
|
+
</div>
|
|
44
|
+
</div>
|
|
45
|
+
|
|
46
|
+
<!-- Filters Group -->
|
|
47
|
+
<FiltersGroup
|
|
48
|
+
:filters="marketplace.state.filter.options"
|
|
49
|
+
v-model:selected="marketplace.state.filter.selected"
|
|
50
|
+
:immediate="true"
|
|
51
|
+
:showHeader="false"
|
|
52
|
+
:showApplyButton="false"
|
|
53
|
+
:showResetButton="true"
|
|
54
|
+
/>
|
|
55
|
+
</div>
|
|
56
|
+
</div>
|
|
57
|
+
|
|
58
|
+
<div class="w-100 rows-1 pd-thin pos-relative o-hidden">
|
|
59
|
+
<Feed
|
|
60
|
+
:search="true"
|
|
61
|
+
v-model:sort="marketplace.state.sort"
|
|
62
|
+
:showLoadMore="false"
|
|
63
|
+
:states="{
|
|
64
|
+
empty: {
|
|
65
|
+
title: 'No Shops Found',
|
|
66
|
+
description: 'Currently, there are no shops.'
|
|
67
|
+
}
|
|
68
|
+
}"
|
|
69
|
+
:store="{
|
|
70
|
+
read: (options) => marketplaceStore.readCatalog(options)
|
|
71
|
+
}"
|
|
72
|
+
:options="{
|
|
73
|
+
country: localPosition.country,
|
|
74
|
+
state: localPosition.state,
|
|
75
|
+
city: localPosition.city,
|
|
76
|
+
location: localLocation?.location,
|
|
77
|
+
lookup: ['products','spots'],
|
|
78
|
+
contain: ['products'],
|
|
79
|
+
priceMin: marketplace.state.filter.selected.price?.min,
|
|
80
|
+
priceMax: marketplace.state.filter.selected.price?.max,
|
|
81
|
+
delivery: marketplace.state.filter.selected.delivery?.length > 0 ? marketplace.state.filter.selected.delivery.join(',') : undefined,
|
|
82
|
+
payment: marketplace.state.filter.selected.payment?.length > 0 ? marketplace.state.filter.selected.payment.join(',') : undefined
|
|
83
|
+
}"
|
|
84
|
+
v-slot="{
|
|
85
|
+
items
|
|
86
|
+
}"
|
|
87
|
+
class="rows-1 gap-thin"
|
|
88
|
+
>
|
|
89
|
+
<div class="mn-b-thin mobile-only">
|
|
90
|
+
<Filters
|
|
91
|
+
v-model:filters="marketplace.state.filter.options"
|
|
92
|
+
v-model:selected="marketplace.state.filter.selected"
|
|
93
|
+
class=""
|
|
94
|
+
/>
|
|
95
|
+
</div>
|
|
96
|
+
|
|
97
|
+
<CardOrganization
|
|
98
|
+
v-for="organization in items"
|
|
99
|
+
:key="organization._id"
|
|
100
|
+
:organization="organization"
|
|
101
|
+
:showRating="true"
|
|
102
|
+
:showFollowers="false"
|
|
103
|
+
:showProducts="true"
|
|
104
|
+
class="bg-light w-100 o-hidden radius-medium pd-small "
|
|
105
|
+
/>
|
|
106
|
+
</Feed>
|
|
107
|
+
|
|
108
|
+
</div>
|
|
109
|
+
</div>
|
|
110
|
+
</div>
|
|
111
|
+
|
|
112
|
+
</template>
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
<script setup="props">
|
|
116
|
+
// Import libs
|
|
117
|
+
import { onMounted, watch, ref } from 'vue'
|
|
118
|
+
import { useRoute, useRouter } from 'vue-router'
|
|
119
|
+
import { useI18n } from 'vue-i18n'
|
|
120
|
+
|
|
121
|
+
import Feed from '@martyrs/src/components/Feed/Feed.vue'
|
|
122
|
+
import Filters from '@martyrs/src/modules/core/views/components/sections/Filters.vue'
|
|
123
|
+
import FiltersGroup from '@martyrs/src/modules/core/views/components/sections/filters/FiltersGroup.vue'
|
|
124
|
+
import Field from "@martyrs/src/components/Field/Field.vue"
|
|
125
|
+
|
|
126
|
+
import CardOrganization from '@martyrs/src/modules/organizations/components/blocks/CardOrganization.vue'
|
|
127
|
+
|
|
128
|
+
import { useStore } from '@martyrs/src/modules/core/views/store/core.store.js'
|
|
129
|
+
import * as organization from '@martyrs/src/modules/organizations/store/organizations.js'
|
|
130
|
+
import * as marketplace from '../../store/marketplace'
|
|
131
|
+
import marketplaceStore from '../../store/marketplace'
|
|
132
|
+
import { useGlobalMixins } from '@martyrs/src/modules/core/views/mixins/mixins.js'
|
|
133
|
+
|
|
134
|
+
const route = useRoute()
|
|
135
|
+
const router = useRouter()
|
|
136
|
+
const store = useStore()
|
|
137
|
+
const { returnCurrency } = useGlobalMixins()
|
|
138
|
+
|
|
139
|
+
const localPosition = ref({
|
|
140
|
+
city: null,
|
|
141
|
+
state: null,
|
|
142
|
+
country: null
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
const localLocation = ref(null);
|
|
146
|
+
// Location filter
|
|
147
|
+
const searchLocation = ref('');
|
|
148
|
+
|
|
149
|
+
if (route.params) {
|
|
150
|
+
// Загружаем новые значения из параметров маршрута в состояние
|
|
151
|
+
let newState = {
|
|
152
|
+
country: denormalizeUrlParam(route.params.country),
|
|
153
|
+
state: denormalizeUrlParam(route.params.state),
|
|
154
|
+
city: denormalizeUrlParam(route.params.city),
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
// Обновляем глобальное состояние
|
|
158
|
+
localPosition.value = newState;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
if (route.query) {
|
|
162
|
+
const query = route.query;
|
|
163
|
+
|
|
164
|
+
marketplace.state.filter.selected.categories = query.categories ? query.categories.split(',') : [];
|
|
165
|
+
marketplace.state.filter.selected.prices = query.prices ? query.prices.split(',') : [];
|
|
166
|
+
marketplace.state.filter.selected.delivery = query.delivery ? query.delivery.split(',') : [];
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
if (route.query.sortParam) marketplace.state.sort.param = route.query.sortParam
|
|
170
|
+
if (route.query.sortOrder) marketplace.state.sort.order = route.query.sortOrder
|
|
171
|
+
|
|
172
|
+
function denormalizeUrlParam(param) {
|
|
173
|
+
return param
|
|
174
|
+
.replace(/-/g, ' ')
|
|
175
|
+
.replace(/\b\w/g, l => l.toUpperCase());
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
function normalizeUrlParam(param) {
|
|
179
|
+
return param
|
|
180
|
+
.toLowerCase()
|
|
181
|
+
.replace(/ /g, '-')
|
|
182
|
+
.replace(/[^a-z0-9-]/g, '');
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
watch(() => marketplace.state.sort, (newSortValue, oldSortValue) => {
|
|
186
|
+
let query = { ...route.query}
|
|
187
|
+
|
|
188
|
+
query.sortParam = newSortValue.param
|
|
189
|
+
query.sortOrder = newSortValue.order
|
|
190
|
+
|
|
191
|
+
// replace the current route
|
|
192
|
+
router.replace({ query });
|
|
193
|
+
}, { deep: true });
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
watch(() => marketplace.state.filter.selectedFilters, (newFilterValue, oldFilterValue) => {
|
|
197
|
+
// Переводим фильтр в формат query
|
|
198
|
+
const query = { ...route.query };
|
|
199
|
+
|
|
200
|
+
// Удаляем старые значения фильтра из query
|
|
201
|
+
Object.keys(oldFilterValue).forEach(key => {
|
|
202
|
+
if (query[key]) {
|
|
203
|
+
delete query[key];
|
|
204
|
+
}
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
// Добавляем новые значения фильтра в query
|
|
208
|
+
const newQueryValues = Object.fromEntries(
|
|
209
|
+
Object.entries(newFilterValue)
|
|
210
|
+
.filter(([key, value]) => Array.isArray(value) && value.length > 0)
|
|
211
|
+
.map(([key, value]) => [key, value.join(',')])
|
|
212
|
+
);
|
|
213
|
+
|
|
214
|
+
delete query.options;
|
|
215
|
+
Object.assign(query, newQueryValues);
|
|
216
|
+
|
|
217
|
+
// Обновляем маршрут с новым query
|
|
218
|
+
router.replace({ query });
|
|
219
|
+
}, { deep: true })
|
|
220
|
+
|
|
221
|
+
watch(() => store.core.state.position, (newPosition) => {
|
|
222
|
+
// get the current route
|
|
223
|
+
const currentRoute = { ...router.currentRoute.value };
|
|
224
|
+
|
|
225
|
+
// create new parameters based on globals state position
|
|
226
|
+
let newParams = {
|
|
227
|
+
country: normalizeUrlParam(newPosition.country),
|
|
228
|
+
state: normalizeUrlParam(newPosition.state),
|
|
229
|
+
city: normalizeUrlParam(newPosition.city),
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
let newState = {
|
|
233
|
+
country: denormalizeUrlParam(newPosition.country),
|
|
234
|
+
state: denormalizeUrlParam(newPosition.state),
|
|
235
|
+
city: denormalizeUrlParam(newPosition.city),
|
|
236
|
+
};
|
|
237
|
+
|
|
238
|
+
// update route params
|
|
239
|
+
localPosition.value = newState;
|
|
240
|
+
currentRoute.params = newParams;
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
// replace the current route
|
|
244
|
+
router.replace(currentRoute);
|
|
245
|
+
}, { deep: true });
|
|
246
|
+
|
|
247
|
+
const text = {
|
|
248
|
+
locale: 'en',
|
|
249
|
+
messages: {
|
|
250
|
+
en: {
|
|
251
|
+
meta: {
|
|
252
|
+
title: "Marketplace – Shop Our Wide Selection of Quality Weed for Delivery",
|
|
253
|
+
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.",
|
|
254
|
+
}
|
|
255
|
+
},
|
|
256
|
+
ru: {
|
|
257
|
+
meta: {
|
|
258
|
+
title: "Маркетплейс – Выбирайте из нашего ассортимента качественной травки для доставки",
|
|
259
|
+
description: "Маркетплейс – Изучите наши продукты высокого качества и выбирайте из различных вариантов доставки. Закажите сейчас и получите свои любимые сорта на дом. Безопасно, быстро и надежно.",
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
const { t } = useI18n(text)
|
|
266
|
+
</script>
|
|
267
|
+
|
|
268
|
+
<style lang="scss">
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
</style>
|
|
272
|
+
|
|
273
|
+
|
|
@@ -1,35 +1,42 @@
|
|
|
1
|
-
|
|
1
|
+
function buildMarketplaceTree(options = {}) {
|
|
2
|
+
const marketplaceComponent = options.marketplaceComponent || (() => import(
|
|
3
|
+
/* webpackChunkName: 'marketplace-page' */
|
|
4
|
+
'../components/pages/Marketplace.vue'
|
|
5
|
+
));
|
|
2
6
|
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
en: 'Marketplace',
|
|
10
|
-
ru: 'Маркетплейс',
|
|
11
|
-
},
|
|
12
|
-
},
|
|
13
|
-
children: [
|
|
7
|
+
const buildName = (suffix) => {
|
|
8
|
+
const prefix = options.routeNamePrefix || '';
|
|
9
|
+
return suffix ? `${prefix}${suffix}` : prefix || undefined;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
return [
|
|
14
13
|
{
|
|
15
|
-
path: ':country?',
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
children: [
|
|
23
|
-
{
|
|
24
|
-
path: ':city?',
|
|
25
|
-
name: 'City',
|
|
26
|
-
component: () => import(/* webpackChunkName: 'Deliveries' */ '../components/pages/Catalog.vue'),
|
|
27
|
-
},
|
|
28
|
-
],
|
|
14
|
+
path: ':country?/:state?/:city?',
|
|
15
|
+
name: buildName('Marketplace') || 'Marketplace',
|
|
16
|
+
component: marketplaceComponent,
|
|
17
|
+
meta: {
|
|
18
|
+
title: {
|
|
19
|
+
en: 'Marketplace',
|
|
20
|
+
ru: 'Маркетплейс',
|
|
29
21
|
},
|
|
30
|
-
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
];
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function getRoutes(options = {}) {
|
|
28
|
+
const route = options.route || 'Home';
|
|
29
|
+
const routes = [];
|
|
30
|
+
|
|
31
|
+
routes.push({
|
|
32
|
+
parentName: route,
|
|
33
|
+
config: {
|
|
34
|
+
basePath: options.basePath || 'marketplace',
|
|
35
|
+
routes: buildMarketplaceTree(options),
|
|
31
36
|
},
|
|
32
|
-
|
|
33
|
-
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
return routes;
|
|
40
|
+
}
|
|
34
41
|
|
|
35
|
-
export default
|
|
42
|
+
export default { getRoutes };
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
import { reactive, watch } from 'vue';
|
|
2
|
+
import StoreManager from '@martyrs/src/modules/core/views/classes/store.manager.js';
|
|
3
|
+
import { useGlobalMixins } from '@martyrs/src/modules/core/views/mixins/mixins.js';
|
|
4
|
+
|
|
5
|
+
const { returnCurrency } = useGlobalMixins();
|
|
2
6
|
|
|
3
7
|
// State
|
|
4
8
|
const state = reactive({
|
|
@@ -13,20 +17,63 @@ const state = reactive({
|
|
|
13
17
|
current: '',
|
|
14
18
|
result: [],
|
|
15
19
|
},
|
|
20
|
+
locationOptions: [
|
|
21
|
+
{ label: 'All', path: '/marketplace' },
|
|
22
|
+
{ label: 'Phuket', path: '/marketplace/thailand/phuket' },
|
|
23
|
+
{ label: 'Bangkok', path: '/marketplace/thailand/bangkok' },
|
|
24
|
+
{ label: 'Chiang Mai', path: '/marketplace/thailand/chiang-mai' },
|
|
25
|
+
{ label: 'Pattaya', path: '/marketplace/thailand/pattaya' },
|
|
26
|
+
],
|
|
16
27
|
filter: {
|
|
17
28
|
active: false,
|
|
18
29
|
class: 'mobile-only',
|
|
19
30
|
selected: {},
|
|
20
31
|
options: [
|
|
32
|
+
{
|
|
33
|
+
title: 'Price',
|
|
34
|
+
value: 'price',
|
|
35
|
+
type: 'range',
|
|
36
|
+
minPlaceholder: 'From',
|
|
37
|
+
maxPlaceholder: 'To',
|
|
38
|
+
label: returnCurrency()
|
|
39
|
+
},
|
|
21
40
|
{
|
|
22
41
|
title: 'Delivery',
|
|
23
42
|
value: 'delivery',
|
|
43
|
+
type: 'checkbox',
|
|
24
44
|
options: [
|
|
25
45
|
{ label: 'Pickup', value: 'pickup' },
|
|
26
|
-
{ label: '
|
|
27
|
-
{ label: '
|
|
46
|
+
{ label: 'Delivery', value: 'courier' },
|
|
47
|
+
{ label: 'Mail', value: 'post' },
|
|
28
48
|
],
|
|
29
49
|
},
|
|
50
|
+
{
|
|
51
|
+
title: 'Payment',
|
|
52
|
+
value: 'payment',
|
|
53
|
+
type: 'checkbox',
|
|
54
|
+
options: [
|
|
55
|
+
{ label: 'Cash', value: 'cash' },
|
|
56
|
+
{ label: 'Card', value: 'card' },
|
|
57
|
+
{ label: 'Crypto', value: 'crypto' },
|
|
58
|
+
{ label: 'Bank Transfer', value: 'bank' },
|
|
59
|
+
],
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
title: 'Availability Date',
|
|
63
|
+
value: 'availabilityDate',
|
|
64
|
+
type: 'date'
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
title: 'Rating',
|
|
68
|
+
value: 'rating',
|
|
69
|
+
type: 'radio',
|
|
70
|
+
options: [
|
|
71
|
+
{ label: '5 stars', value: '5' },
|
|
72
|
+
{ label: '4+ stars', value: '4' },
|
|
73
|
+
{ label: '3+ stars', value: '3' },
|
|
74
|
+
{ label: 'Any rating', value: 'any' }
|
|
75
|
+
]
|
|
76
|
+
},
|
|
30
77
|
],
|
|
31
78
|
},
|
|
32
79
|
sort: {
|
|
@@ -58,5 +105,29 @@ watch(state, (newState, oldState) => {
|
|
|
58
105
|
history.push(newState);
|
|
59
106
|
});
|
|
60
107
|
|
|
108
|
+
// Actions через StoreManager
|
|
109
|
+
const marketplaceStore = new StoreManager('/api/marketplace');
|
|
110
|
+
|
|
111
|
+
// Custom action для каталога
|
|
112
|
+
marketplaceStore.readCatalog = async function(params = {}) {
|
|
113
|
+
console.log('Reading marketplace catalog with params:', params);
|
|
114
|
+
try {
|
|
115
|
+
const result = await this.request('/catalog', { params });
|
|
116
|
+
console.log(`Catalog returned ${result.length || 0} items`);
|
|
117
|
+
|
|
118
|
+
// Обновляем state.shops если нужно
|
|
119
|
+
if (result && Array.isArray(result)) {
|
|
120
|
+
state.shops = result;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return result;
|
|
124
|
+
} catch (error) {
|
|
125
|
+
console.error('Catalog read failed:', error);
|
|
126
|
+
throw error;
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
|
|
61
130
|
// Module Export
|
|
62
|
-
export { state };
|
|
131
|
+
export { state, marketplaceStore };
|
|
132
|
+
|
|
133
|
+
export default marketplaceStore;
|
|
@@ -97,20 +97,20 @@
|
|
|
97
97
|
<div class="w-max flex-nowrap flex gap-thin">
|
|
98
98
|
<CardOrderItem
|
|
99
99
|
@click.stop="$router.push(`/organizations/${organization._id}/products/${product._id}`)"
|
|
100
|
-
v-for="product in organization.products.slice(0,5)"
|
|
101
|
-
:key="product._id"
|
|
102
|
-
:editable="false"
|
|
100
|
+
v-for="product in organization.products.slice(0,5)"
|
|
101
|
+
:key="product._id"
|
|
102
|
+
:editable="false"
|
|
103
103
|
:productId="product._id"
|
|
104
|
-
:variantId="product.
|
|
104
|
+
:variantId="product.variants?.[0]?._id"
|
|
105
105
|
:images="product.images"
|
|
106
106
|
:name="product.name"
|
|
107
|
-
:quantity="product.quantity || 1"
|
|
108
|
-
:unit="product.unit"
|
|
107
|
+
:quantity="product.variants?.[0]?.quantity || 1"
|
|
108
|
+
:unit="product.variants?.[0]?.unit"
|
|
109
109
|
:dates="product.date"
|
|
110
110
|
:listing="product.listing"
|
|
111
|
-
:price="product.price"
|
|
111
|
+
:price="product.variants?.[0]?.price"
|
|
112
112
|
class="pd-thin w-15r radius-medium bg-white"
|
|
113
|
-
|
|
113
|
+
|
|
114
114
|
/>
|
|
115
115
|
<button class="pd-thin w-15r radius-medium bg-main button">
|
|
116
116
|
View menu
|
|
@@ -38,7 +38,7 @@ const controllerFactory = db => {
|
|
|
38
38
|
...queryProcessorCore.getSearchOptions(req.query.search, {
|
|
39
39
|
fields: requestedLookups.includes('products') ? ['profile.name', 'products.name'] : ['profile.name'],
|
|
40
40
|
}),
|
|
41
|
-
...(requestedLookups.includes('products') && req.query.prices ? getPriceConditions(req.query.prices) : []),
|
|
41
|
+
...(requestedLookups.includes('products') && (req.query.prices || req.query.priceMin || req.query.priceMax) ? getPriceConditions(req.query.prices, req.query.priceMin, req.query.priceMax) : []),
|
|
42
42
|
...(requestedLookups.includes('spots') ? (await getLocationStages(req.query)).stages : []),
|
|
43
43
|
...(requestedLookups.includes('memberships') ? [addUserStatusFields(req.query.user), addMembersQuantity(req.query.user)] : []),
|
|
44
44
|
...(matchConditions.length > 0 ? [{ $match: { $and: matchConditions } }] : []),
|
|
@@ -127,7 +127,14 @@ const getDistanceStages = location => [
|
|
|
127
127
|
},
|
|
128
128
|
},
|
|
129
129
|
];
|
|
130
|
-
const getPriceConditions = prices => {
|
|
130
|
+
const getPriceConditions = (prices, priceMin, priceMax) => {
|
|
131
|
+
// Если есть priceMin/priceMax, конвертируем в формат "min-max"
|
|
132
|
+
if ((priceMin && priceMin.trim() !== '') || (priceMax && priceMax.trim() !== '')) {
|
|
133
|
+
const min = (priceMin && priceMin.trim() !== '') ? priceMin : '0';
|
|
134
|
+
const max = (priceMax && priceMax.trim() !== '') ? priceMax : '999999';
|
|
135
|
+
prices = `${min}-${max}`;
|
|
136
|
+
}
|
|
137
|
+
|
|
131
138
|
if (!prices) return [];
|
|
132
139
|
const priceRanges = prices.split(',');
|
|
133
140
|
const priceConditions = priceRanges.map(priceRange => {
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Button.vue.js","sources":["../../../../../src/components/Button/Button.vue"],"sourcesContent":["<script setup>\nimport { ref } from 'vue'\n\nimport Loader from '@martyrs/src/components/Loader/Loader.vue'\n\nimport IconCheckmark from '@martyrs/src/modules/icons/navigation/IconCheckmark.vue';\nimport IconCross from '@martyrs/src/modules/icons/navigation/IconCross.vue';\n\nconst props = defineProps({\n submit: {\n type: Function,\n default: async () => { console.log('Button click.') }\n },\n text: {\n type: Object,\n default: () => ({\n success: null,\n error: null\n })\n },\n counter: {\n type: Object\n },\n callback: {\n type: Function,\n default: async () => { console.log('Button callback.') }\n },\n callbackDelay: {\n type: Number,\n default: 750\n },\n showSucces: {\n type: Boolean,\n default: true\n },\n showLoader: {\n type: Boolean,\n default: true\n },\n validation: {\n type: Boolean,\n default: false\n },\n})\n\nconst emits = defineEmits(['error'])\n\nconst button = ref(null)\nconst error = ref(null)\nconst loading = ref(false)\nconst finished = ref(false)\n\nasync function Submit() {\n console.log('click')\n \n button.value.style['pointer-events'] = 'none'\n error.value = null\n loading.value = true\n\n // Функция для сброса состояния кнопки\n const resetButton = () => {\n if (button.value) {\n button.value.style.pointerEvents = 'auto'\n loading.value = false\n finished.value = false\n error.value = null\n }\n }\n\n try {\n await props.submit()\n\n button.value.classList.replace('bg-main', 'bg-second')\n loading.value = false\n\n // Используем функцию сброса состояния кнопки здесь\n if (props.showSucces) { \n finished.value = true\n setTimeout(() => {\n resetButton()\n button.value.classList.replace('bg-second', 'bg-main')\n }, 500)\n } else {\n resetButton()\n button.value.classList.replace('bg-second', 'bg-main')\n }\n\n // Если есть callback, мы также установим таймер для его вызова\n if (props.callback) setTimeout(() => props.callback(), props.callbackDelay)\n\n } catch (err) {\n emits('error', err)\n // Если возникла ошибка, мы изменяем стили и устанавливаем сообщение об ошибке\n button.value.classList.replace('bg-main', 'bg-fourth-nano')\n loading.value = false\n error.value = true\n \n // После задержки снова сбрасываем состояние кнопки\n setTimeout(() => {\n resetButton()\n // Так как класс кнопки был изменен, вернем его в исходное состояние\n button.value.classList.replace('bg-fourth-nano', 'bg-main')\n }, 1330)\n }\n}\n</script>\n\n<template>\n <button \n @click.stop=\"Submit\"\n :disabled=\"validation\"\n ref=\"button\"\n\t\tclass=\"button\"\n :class=\"{ 'button--disabled': loading || validation }\"\n >\n <Transition name=\"content\" mode=\"out-in\">\n <!-- Default slot content -->\n <span v-if=\"!loading && !error && !finished || !showLoader\" class=\"button-content\">\n <slot></slot>\n </span>\n <!-- Loading state -->\n <Loader v-else-if=\"loading && !error && showLoader\" class=\"icon button-content pos-relative pos-t-0 pos-l-0 loading\"/>\n <!-- Success state -->\n <span v-else-if=\"finished && showSucces\" class=\"button-content t-semi t-center w-100 loading t-black\">\n <template v-if=\"text.success\">\n {{ text.success }}\n </template>\n <IconCheckmark v-else class=\"icon\" />\n </span>\n <!-- Error state -->\n <span v-else-if=\"error\" class=\"button-content t-center w-100 error\">\n <template v-if=\"text.error\">\n {{ text.error }}\n </template>\n <IconCross v-else class=\"icon\" />\n </span>\n </Transition>\n \n <!-- Counter -->\n <div v-if=\"counter\" class=\"button-counter flex flex-center\">\n <span>{{ counter }}</span>\n </div>\n </button>\n</template>\n\n<style lang=\"scss\">\nbutton[disabled] {\n opacity: 0.75 !important;\n pointer-events: none !important;\n cursor: default !important;\n color: rgba(var(--dark), 0.33) !important;\n background: rgba(var(--light), 1) !important;\n}\n\na.button {\n text-box: trim-both cap alphabetic;\n}\n\n.button {\n display: flex;\n padding: var(--small);\n border-radius: var(--small);\n text-box: trim-both cap alphabetic;\n transform: scale(1);\n opacity: 1;\n align-items: center;\n justify-content: center;\n color: black;\n text-align: center;\n font-size: 1rem;\n letter-spacing: 5%;\n transition: all 0.33s ease;\n\n &:hover {\n cursor: pointer;\n opacity: 0.9;\n }\n\n &:active {\n transform: scale(0.95);\n }\n\n &-small {\n padding: 0.75rem;\n border-radius: 0.5rem;\n height: fit-content;\n }\n\n .button-counter {\n position: absolute;\n right: -8px;\n bottom: -8px;\n background: yellow;\n height: 16px;\n border-radius: 16px;\n width: 16px;\n font-weight: 500;\n text-align: center;\n line-height: 16px;\n font-size: 10px;\n }\n}\n\n.button-content {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n}\n\n.icon {\n width: 1rem;\n height: 1rem;\n}\n\n/* Vue Transitions */\n.content-enter-active,\n.content-leave-active {\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.content-enter-from {\n opacity: 0;\n transform: translateY(8px) scale(0.95);\n}\n\n.content-leave-to {\n opacity: 0;\n transform: translateY(-8px) scale(0.95);\n}\n\n.content-enter-to,\n.content-leave-from {\n opacity: 1;\n transform: translateY(0) scale(1);\n}\n</style>"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAQA,UAAM,QAAQ;AAqCd,UAAM,QAAQ;AAEd,UAAM,SAAS,IAAI,IAAI;AACvB,UAAM,QAAQ,IAAI,IAAI;AACtB,UAAM,UAAU,IAAI,KAAK;AACzB,UAAM,WAAW,IAAI,KAAK;AAE1B,mBAAe,SAAS;AACtB,cAAQ,IAAI,OAAO;AAEnB,aAAO,MAAM,MAAM,gBAAgB,IAAI;AACvC,YAAM,QAAQ;AACd,cAAQ,QAAQ;AAGhB,YAAM,cAAc,MAAM;AACxB,YAAI,OAAO,OAAO;AAChB,iBAAO,MAAM,MAAM,gBAAgB;AACnC,kBAAQ,QAAQ;AAChB,mBAAS,QAAQ;AACjB,gBAAM,QAAQ;AAAA,QAChB;AAAA,MACF;AAEA,UAAI;AACF,cAAM,MAAM,OAAM;AAElB,eAAO,MAAM,UAAU,QAAQ,WAAW,WAAW;AACrD,gBAAQ,QAAQ;AAGhB,YAAI,MAAM,YAAY;AACpB,mBAAS,QAAQ;AACjB,qBAAW,MAAM;AACf,wBAAW;AACX,mBAAO,MAAM,UAAU,QAAQ,aAAa,SAAS;AAAA,UACvD,GAAG,GAAG;AAAA,QACR,OAAO;AACL,sBAAW;AACX,iBAAO,MAAM,UAAU,QAAQ,aAAa,SAAS;AAAA,QACvD;AAGA,YAAI,MAAM,SAAU,YAAW,MAAM,MAAM,SAAQ,GAAI,MAAM,aAAa;AAAA,MAE5E,SAAS,KAAK;AACZ,cAAM,SAAS,GAAG;AAElB,eAAO,MAAM,UAAU,QAAQ,WAAW,gBAAgB;AAC1D,gBAAQ,QAAQ;AAChB,cAAM,QAAQ;AAGd,mBAAW,MAAM;AACf,sBAAW;AAEX,iBAAO,MAAM,UAAU,QAAQ,kBAAkB,SAAS;AAAA,QAC5D,GAAG,IAAI;AAAA,MACT;AAAA,IACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Menu.vue2.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Select.vue2.js","sources":["../../../../../src/components/Select/Select.vue"],"sourcesContent":["<template>\n <!-- Input Wrapper -->\n <div \n ref=\"fieldWrapper\"\n tabindex=\"0\"\n @click.stop=\"toggleMenu\" \n v-click-outside=\"clickedOutside\" \n :class=\"$attrs.class\" \n class=\"cursor-pointer field-wrapper flex-v-center flex-nowrap flex pos-relative\"\n >\n <!-- Label -->\n <span v-if=\"label\" class=\"t-transp mn-r-small\">{{label}}</span>\n \n <!-- Input -->\n <span>\n {{ optionsSelected ? (optionsSelected.name || optionsSelected[props.value] || optionsSelected) : placeholder }}\n </span>\n <!-- Dropdown menu -->\n <transition mode=\"out-in\" name=\"TransitionTranslateY\">\n <ul \n v-show=\"showMenu\" \n class=\"bs-black pos-absolute pos-t-100 pos-l-0 z-index-5 pd-small radius-small bg-white mn-t-thin w-100\"\n style=\"min-width: max-content;\"\n >\n <li @click.stop=\"selectOption(option)\" v-for=\"option in optionsListed\" class=\"radius-thin hover-bg-light pd-thin text-box-trim\">\n <span v-if=\"option\" class=\"w-100\">\n {{ option.name || option[props.value] || option }}\n </span>\n </li>\n </ul>\n </transition>\n </div>\n <!-- Validation -->\n <transition mode=\"out-in\" name=\"fade\">\n <div v-if=\"validation\" class=\"mn-t-thin invalid-feedback\">\n * {{validation.message}}\n </div>\n </transition>\n</template>\n<script setup>\nimport { ref, computed, watch, nextTick } from 'vue'\nimport clickOutside from '../FieldPhone/click-outside.js';\nlet vClickOutside = clickOutside\nconst emit = defineEmits([\n 'update:select', \n 'focus', \n 'blur'\n])\nconst props = defineProps({\n label: String,\n placeholder: { type: String, default: 'Please select an item' },\n select: [String, Object],\n property: String,\n value: String,\n options: { type: Array, default: () => [] },\n validation: Boolean,\n})\nconst showMenu = ref(false)\nconst fieldWrapper = ref(null)\nconst optionsSelected = ref(\n props.property \n ? findObjectByValue(props.select, props.property, props.options) \n : props.select\n)\nconst optionsListed = computed(() => {\n return props.select \n ? props.options.filter(option => option !== props.select) \n : props.options\n})\nwatch(() => props.select, (newSelect) => {\n optionsSelected.value = \n props.property \n ? findObjectByValue(props.select, props.property, props.options) \n : props.select;\n});\nconst toggleMenu = async () => {\n showMenu.value = !showMenu.value\n \n if (showMenu.value) {\n await nextTick()\n fieldWrapper.value?.focus()\n emit('focus')\n } else {\n emit('blur')\n }\n}\nfunction clickedOutside () {\n showMenu.value = false\n}\nconst selectOption = option => {\n optionsSelected.value = option\n \n toggleMenu()\n if (props.property) { \n emit('update:select', optionsSelected.value[props.property])\n } else {\n emit('update:select', optionsSelected.value)\n }\n}\nfunction findObjectByValue (value, property, objects) {\n for (const object of objects) {\n if (object[property] === value || object === value) {\n return object;\n }\n }\n return null;\n}\n</script>\n<style lang=\"scss\" scoped>\n li {\n list-style-type: none;\n }\n ul li {\n line-height: 2;\n }\n .field-wrapper:focus {\n outline: none;\n }\n</style>"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0CA,QAAI,gBAAgB;AACpB,UAAM,OAAO;AAKb,UAAM,QAAQ;AASd,UAAM,WAAW,IAAI,KAAK;AAC1B,UAAM,eAAe,IAAI,IAAI;AAC7B,UAAM,kBAAkB;AAAA,MACtB,MAAM,WACJ,kBAAkB,MAAM,QAAQ,MAAM,UAAU,MAAM,OAAO,IAC7D,MAAM;AAAA,IACV;AACA,UAAM,gBAAgB,SAAS,MAAM;AACnC,aAAO,MAAM,SACX,MAAM,QAAQ,OAAO,YAAU,WAAW,MAAM,MAAM,IACtD,MAAM;AAAA,IACV,CAAC;AACD,UAAM,MAAM,MAAM,QAAQ,CAAC,cAAc;AACvC,sBAAgB,QAChB,MAAM,WACJ,kBAAkB,MAAM,QAAQ,MAAM,UAAU,MAAM,OAAO,IAC7D,MAAM;AAAA,IACV,CAAC;AACD,UAAM,aAAa,YAAY;AAC7B,eAAS,QAAQ,CAAC,SAAS;AAE3B,UAAI,SAAS,OAAO;AAClB,cAAM,SAAQ;AACd,qBAAa,OAAO,MAAK;AACzB,aAAK,OAAO;AAAA,MACd,OAAO;AACL,aAAK,MAAM;AAAA,MACb;AAAA,IACF;AACA,aAAS,iBAAkB;AACzB,eAAS,QAAQ;AAAA,IACnB;AACA,UAAM,eAAe,YAAU;AAC7B,sBAAgB,QAAQ;AAExB,iBAAU;AACV,UAAI,MAAM,UAAU;AAClB,aAAK,iBAAiB,gBAAgB,MAAM,MAAM,QAAQ,CAAC;AAAA,MAC7D,OAAO;AACL,aAAK,iBAAiB,gBAAgB,KAAK;AAAA,MAC7C;AAAA,IACF;AACA,aAAS,kBAAmB,OAAO,UAAU,SAAS;AACpD,iBAAW,UAAU,SAAS;AAC5B,YAAI,OAAO,QAAQ,MAAM,SAAS,WAAW,OAAO;AAClD,iBAAO;AAAA,QACT;AAAA,MACF;AACA,aAAO;AAAA,IACT;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Spoiler.vue.js","sources":["../../../../../src/components/Spoiler/Spoiler.vue"],"sourcesContent":["<template>\n <div>\n <div @click=\"toggleSpoiler\" class=\"flex-v-center flex-nowrap flex\">\n <slot name=\"header\" :isOpen=\"showSpoiler\"></slot>\n </div>\n <transition\n name=\"collapse\"\n @enter=\"onEnter\"\n @after-enter=\"onAfterEnter\"\n @leave=\"onLeave\"\n >\n <div v-show=\"showSpoiler\" class=\"spoiler\" ref=\"spoilerContent\">\n <slot name=\"content\"></slot>\n </div>\n </transition>\n </div>\n</template>\n<script setup>\nimport { ref, onMounted } from 'vue';\n\nconst props = defineProps({\n status: {\n type: Boolean,\n default: false\n }\n});\n\nconst showSpoiler = ref(false);\nconst spoilerContent = ref(null);\n\nonMounted(() => {\n if (props.status) {\n showSpoiler.value = props.status;\n }\n});\n\nconst toggleSpoiler = () => {\n showSpoiler.value = !showSpoiler.value;\n};\n\n// Анимация открытия\nconst onEnter = (el) => {\n el.style.height = '0';\n void el.offsetHeight; // force reflow\n el.style.height = el.scrollHeight + 'px';\n};\n\nconst onAfterEnter = (el) => {\n el.style.height = 'auto';\n};\n\n// Анимация закрытия\nconst onLeave = (el) => {\n el.style.height = el.scrollHeight + 'px';\n void el.offsetHeight; // force reflow\n el.style.height = '0';\n};\n\ndefineExpose({\n showSpoiler\n});\n</script>\n<style lang=\"scss\">\n.spoiler {\n overflow: hidden;\n transition: height 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n}\n</style>"],"names":[],"mappings":";;;;;;;;;;;AAoBA,UAAM,QAAQ;AAOd,UAAM,cAAc,IAAI,KAAK;AAC7B,UAAM,iBAAiB,IAAI,IAAI;AAE/B,cAAU,MAAM;AACd,UAAI,MAAM,QAAQ;AAChB,oBAAY,QAAQ,MAAM;AAAA,MAC5B;AAAA,IACF,CAAC;AAED,UAAM,gBAAgB,MAAM;AAC1B,kBAAY,QAAQ,CAAC,YAAY;AAAA,IACnC;AAGA,UAAM,UAAU,CAAC,OAAO;AACtB,SAAG,MAAM,SAAS;AAClB,WAAK,GAAG;AACR,SAAG,MAAM,SAAS,GAAG,eAAe;AAAA,IACtC;AAEA,UAAM,eAAe,CAAC,OAAO;AAC3B,SAAG,MAAM,SAAS;AAAA,IACpB;AAGA,UAAM,UAAU,CAAC,OAAO;AACtB,SAAG,MAAM,SAAS,GAAG,eAAe;AACpC,WAAK,GAAG;AACR,SAAG,MAAM,SAAS;AAAA,IACpB;AAEA,aAAa;AAAA,MACX;AAAA,IACF,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|