@ozdao/martyrs 0.2.524 → 0.2.525
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/_virtual/index.cjs +4 -4
- package/dist/_virtual/index.js +4 -4
- package/dist/_virtual/index2.cjs +4 -4
- package/dist/_virtual/index2.js +4 -4
- package/dist/community.server.cjs +1 -1
- package/dist/community.server.js +1 -1
- package/dist/{crud-CC6k6yY5.cjs → crud-DGM6Xa1R.cjs} +1 -1
- package/dist/{crud-BIFl1W1i.js → crud-Ed3dcRsC.js} +1 -1
- package/dist/events.server.cjs +1 -1
- package/dist/events.server.js +1 -1
- package/dist/gallery.server.cjs +1 -1
- package/dist/gallery.server.js +1 -1
- package/dist/{globals.verifier-DFqKQ7hK.js → globals.verifier-BhqUrneb.js} +31 -1
- package/dist/{globals.verifier-C0zj_LLo.cjs → globals.verifier-CJ1lr-NW.cjs} +31 -1
- package/dist/inventory.server.cjs +3 -3
- package/dist/inventory.server.js +3 -3
- package/dist/{main-BM3GslOO.cjs → main-4KvvKtzH.cjs} +6 -6
- package/dist/{main-Qcn7YlTx.js → main-Bk4xq-K0.js} +45 -37
- package/dist/martyrs/src/components/Button/{Button.vue.cjs → Button.vue2.cjs} +2 -2
- package/dist/martyrs/src/components/Button/Button.vue2.cjs.map +1 -0
- package/dist/martyrs/src/components/Button/{Button.vue.js → Button.vue2.js} +2 -2
- package/dist/martyrs/src/components/Button/{Button.vue.cjs.map → Button.vue2.js.map} +1 -1
- package/dist/martyrs/src/components/Chips/{Chips.vue.cjs → Chips.vue2.cjs} +2 -2
- package/dist/martyrs/src/components/Chips/Chips.vue2.cjs.map +1 -0
- package/dist/martyrs/src/components/Chips/{Chips.vue.js → Chips.vue2.js} +2 -2
- package/dist/martyrs/src/components/Chips/Chips.vue2.js.map +1 -0
- package/dist/martyrs/src/components/Dropdown/{Dropdown.vue.cjs → Dropdown.vue2.cjs} +2 -2
- package/dist/martyrs/src/components/Dropdown/Dropdown.vue2.cjs.map +1 -0
- package/dist/martyrs/src/components/Dropdown/{Dropdown.vue.js → Dropdown.vue2.js} +2 -2
- package/dist/martyrs/src/components/Dropdown/{Dropdown.vue.cjs.map → Dropdown.vue2.js.map} +1 -1
- package/dist/martyrs/src/components/Feed/Feed.vue.cjs +2 -2
- package/dist/martyrs/src/components/Feed/Feed.vue.cjs.map +1 -1
- package/dist/martyrs/src/components/Feed/Feed.vue.js +2 -2
- package/dist/martyrs/src/components/Feed/Feed.vue.js.map +1 -1
- package/dist/martyrs/src/components/FieldBig/FieldBig.vue.cjs +1 -1
- package/dist/martyrs/src/components/FieldBig/FieldBig.vue.js +1 -1
- package/dist/martyrs/src/components/FieldTags/FieldTags.vue.cjs +1 -1
- package/dist/martyrs/src/components/FieldTags/FieldTags.vue.js +1 -1
- package/dist/martyrs/src/components/Menu/{Menu.vue2.cjs → Menu.vue.cjs} +2 -2
- package/dist/martyrs/src/components/Menu/Menu.vue.cjs.map +1 -0
- 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.cjs → Select.vue.cjs} +2 -2
- package/dist/martyrs/src/components/Select/{Select.vue2.js.map → Select.vue.cjs.map} +1 -1
- 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.vue2.cjs → Spoiler.vue.cjs} +2 -2
- package/dist/martyrs/src/components/Spoiler/{Spoiler.vue2.js.map → Spoiler.vue.cjs.map} +1 -1
- package/dist/martyrs/src/components/Spoiler/{Spoiler.vue2.js → Spoiler.vue.js} +2 -2
- package/dist/martyrs/src/components/Spoiler/Spoiler.vue.js.map +1 -0
- package/dist/martyrs/src/components/Tree/Tree.vue.cjs +19 -33
- package/dist/martyrs/src/components/Tree/Tree.vue.cjs.map +1 -1
- package/dist/martyrs/src/components/Tree/Tree.vue.js +19 -33
- package/dist/martyrs/src/components/Tree/Tree.vue.js.map +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/EnterPassword.vue.cjs +1 -1
- 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.cjs +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.cjs +3 -3
- package/dist/martyrs/src/modules/auth/views/components/pages/Profile.vue.js +3 -3
- package/dist/martyrs/src/modules/auth/views/components/pages/ProfileEditAccount.vue.cjs +1 -1
- 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.cjs +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.cjs +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.cjs +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.cjs +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.cjs +1 -1
- package/dist/martyrs/src/modules/auth/views/components/sections/ProfileEditCredentials.vue.js +1 -1
- package/dist/martyrs/src/modules/community/components/blocks/CardBlogpost.vue.cjs +1 -1
- package/dist/martyrs/src/modules/community/components/blocks/CardBlogpost.vue.js +1 -1
- package/dist/martyrs/src/modules/community/components/layouts/Community.vue.cjs +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.cjs +2 -2
- package/dist/martyrs/src/modules/community/components/pages/BlogPost.vue.js +2 -2
- package/dist/martyrs/src/modules/community/components/pages/CreateBlogPost.vue.cjs +2 -2
- package/dist/martyrs/src/modules/community/components/pages/CreateBlogPost.vue.js +2 -2
- package/dist/martyrs/src/modules/events/components/blocks/CardEvent.vue.cjs +1 -1
- package/dist/martyrs/src/modules/events/components/blocks/CardEvent.vue.js +1 -1
- package/dist/martyrs/src/modules/events/components/elements/ButtonCheck.vue.cjs +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.cjs +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.cjs +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.cjs +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.cjs +2 -2
- package/dist/martyrs/src/modules/events/components/pages/Event.vue.js +2 -2
- package/dist/martyrs/src/modules/gallery/components/sections/BackofficeGallery.vue.cjs +3 -3
- package/dist/martyrs/src/modules/gallery/components/sections/BackofficeGallery.vue.js +3 -3
- package/dist/martyrs/src/modules/globals/views/classes/globals.i18n.cjs +1 -1
- package/dist/martyrs/src/modules/globals/views/classes/globals.i18n.js +1 -1
- package/dist/martyrs/src/modules/globals/views/components/blocks/CardHeader.vue.cjs +2 -2
- package/dist/martyrs/src/modules/globals/views/components/blocks/CardHeader.vue.js +2 -2
- package/dist/martyrs/src/modules/globals/views/components/blocks/PopupAuth.vue.cjs +1 -1
- package/dist/martyrs/src/modules/globals/views/components/blocks/PopupAuth.vue.js +1 -1
- package/dist/martyrs/src/modules/globals/views/components/blocks/PopupDateSelector.vue.cjs +2 -2
- package/dist/martyrs/src/modules/globals/views/components/blocks/PopupDateSelector.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/globals/views/components/blocks/PopupDateSelector.vue.js +2 -2
- package/dist/martyrs/src/modules/globals/views/components/blocks/PopupDateSelector.vue.js.map +1 -1
- package/dist/martyrs/src/modules/globals/views/components/layouts/Client.vue.cjs +1 -1
- package/dist/martyrs/src/modules/globals/views/components/layouts/Client.vue.js +1 -1
- package/dist/martyrs/src/modules/globals/views/components/partials/Header.vue.cjs +2 -2
- package/dist/martyrs/src/modules/globals/views/components/partials/Header.vue.js +2 -2
- package/dist/martyrs/src/modules/globals/views/components/partials/Navigation.vue.cjs +2 -2
- package/dist/martyrs/src/modules/globals/views/components/partials/Navigation.vue.js +2 -2
- package/dist/martyrs/src/modules/globals/views/components/partials/NavigationBar.vue.cjs +1 -1
- package/dist/martyrs/src/modules/globals/views/components/partials/NavigationBar.vue.js +1 -1
- package/dist/martyrs/src/modules/globals/views/store/globals.cjs +14 -2
- package/dist/martyrs/src/modules/globals/views/store/globals.cjs.map +1 -1
- package/dist/martyrs/src/modules/globals/views/store/globals.js +14 -2
- package/dist/martyrs/src/modules/globals/views/store/globals.js.map +1 -1
- package/dist/martyrs/src/modules/inventory/components/forms/AdjustmentForm.vue.cjs +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.cjs +1 -1
- package/dist/martyrs/src/modules/inventory/components/forms/ColumnSettingsMenu.vue.js +1 -1
- package/dist/martyrs/src/modules/inventory/components/forms/HistoryView.vue.cjs +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.cjs +2 -2
- package/dist/martyrs/src/modules/inventory/components/forms/StockAlertsForm.vue.js +2 -2
- package/dist/martyrs/src/modules/inventory/components/pages/Inventory.vue.cjs +3 -3
- package/dist/martyrs/src/modules/inventory/components/pages/Inventory.vue.js +2 -2
- package/dist/martyrs/src/modules/inventory/components/pages/InventoryEdit.vue.cjs +3 -3
- package/dist/martyrs/src/modules/inventory/components/pages/InventoryEdit.vue.js +3 -3
- package/dist/martyrs/src/modules/landing/components/sections/SectionGuide.vue.cjs +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.cjs +1 -1
- package/dist/martyrs/src/modules/marketplace/views/components/layouts/Marketplace.vue.js +1 -1
- package/dist/martyrs/src/modules/music/components/cards/AlbumCard.vue.cjs +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.cjs +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.cjs +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.cjs +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.cjs +2 -2
- package/dist/martyrs/src/modules/music/components/forms/AlbumForm.vue.js +2 -2
- package/dist/martyrs/src/modules/music/components/forms/ArtistForm.vue.cjs +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.cjs +1 -1
- package/dist/martyrs/src/modules/music/components/forms/PlaylistForm.vue.js +1 -1
- package/dist/martyrs/src/modules/music/components/forms/SearchForm.vue.cjs +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.cjs +2 -2
- package/dist/martyrs/src/modules/music/components/forms/TrackForm.vue.js +2 -2
- package/dist/martyrs/src/modules/music/components/pages/Album.vue.cjs +2 -2
- package/dist/martyrs/src/modules/music/components/pages/Album.vue.js +2 -2
- package/dist/martyrs/src/modules/music/components/pages/Artist.vue.cjs +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.cjs +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.cjs +2 -2
- package/dist/martyrs/src/modules/music/components/pages/Playlist.vue.js +2 -2
- package/dist/martyrs/src/modules/music/components/pages/SearchResults.vue.cjs +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.cjs +2 -2
- package/dist/martyrs/src/modules/music/components/pages/Track.vue.js +2 -2
- package/dist/martyrs/src/modules/music/components/pages/TrackCreate.vue.cjs +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.cjs +1 -1
- package/dist/martyrs/src/modules/music/components/player/MusicPlayer.vue.js +1 -1
- package/dist/martyrs/src/modules/music/router/music.cjs +2 -2
- package/dist/martyrs/src/modules/music/router/music.js +2 -2
- package/dist/martyrs/src/modules/notifications/notifications.client.cjs +0 -4
- package/dist/martyrs/src/modules/notifications/notifications.client.cjs.map +1 -1
- package/dist/martyrs/src/modules/notifications/notifications.client.js +0 -4
- package/dist/martyrs/src/modules/notifications/notifications.client.js.map +1 -1
- package/dist/martyrs/src/modules/orders/components/forms/FormApplicationDetails.vue.cjs +2 -2
- package/dist/martyrs/src/modules/orders/components/forms/FormApplicationDetails.vue.js +2 -2
- package/dist/martyrs/src/modules/orders/components/forms/FormCustomerDetails.vue.cjs +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.cjs +1 -1
- package/dist/martyrs/src/modules/orders/components/forms/FormSelectCustomer.vue.js +1 -1
- package/dist/martyrs/src/modules/orders/components/pages/OrderBackoffice.vue.cjs +2 -2
- package/dist/martyrs/src/modules/orders/components/pages/OrderBackoffice.vue.js +2 -2
- package/dist/martyrs/src/modules/orders/components/pages/OrderCreate.vue.cjs +1 -1
- package/dist/martyrs/src/modules/orders/components/pages/OrderCreate.vue.js +1 -1
- package/dist/martyrs/src/modules/orders/components/pages/OrderCreateBackoffice.vue.cjs +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.cjs +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.cjs +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.cjs +1 -1
- package/dist/martyrs/src/modules/orders/components/sections/FormDelivery.vue.js +1 -1
- package/dist/martyrs/src/modules/orders/components/sections/FormPayment.vue.cjs +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.cjs +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.cjs +1 -1
- package/dist/martyrs/src/modules/organizations/components/blocks/CardOrganization.vue.js +1 -1
- package/dist/martyrs/src/modules/organizations/components/elements/ButtonToggleMembership.vue.cjs +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.cjs +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.cjs +2 -2
- package/dist/martyrs/src/modules/organizations/components/forms/DepartmentForm.vue.js +2 -2
- package/dist/martyrs/src/modules/organizations/components/forms/InviteForm.vue.cjs +1 -1
- package/dist/martyrs/src/modules/organizations/components/forms/InviteForm.vue.js +1 -1
- package/dist/martyrs/src/modules/organizations/components/pages/Department.vue.cjs +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.cjs +3 -3
- package/dist/martyrs/src/modules/organizations/components/pages/Organization.vue.js +3 -3
- package/dist/martyrs/src/modules/organizations/components/pages/OrganizationBackoffice.vue.cjs +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.cjs +2 -2
- package/dist/martyrs/src/modules/organizations/components/pages/OrganizationEdit.vue.js +2 -2
- package/dist/martyrs/src/modules/organizations/components/sections/Documents.vue.cjs +1 -1
- package/dist/martyrs/src/modules/organizations/components/sections/Documents.vue.js +1 -1
- package/dist/martyrs/src/modules/organizations/components/sections/MembersAdd.vue.cjs +2 -2
- package/dist/martyrs/src/modules/organizations/components/sections/MembersAdd.vue.js +2 -2
- package/dist/martyrs/src/modules/organizations/components/sections/Organizations.vue.cjs +1 -1
- package/dist/martyrs/src/modules/organizations/components/sections/Organizations.vue.js +1 -1
- package/dist/martyrs/src/modules/organizations/router/organizations.cjs +1 -1
- package/dist/martyrs/src/modules/organizations/router/organizations.js +1 -1
- package/dist/martyrs/src/modules/pages/views/components/blocks/CardPage.vue.cjs +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.cjs +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.cjs +1 -1
- package/dist/martyrs/src/modules/pages/views/components/partials/SidebarPages.vue.js +1 -1
- package/dist/martyrs/src/modules/products/components/blocks/ProductDiscounts.vue.cjs +1 -1
- package/dist/martyrs/src/modules/products/components/blocks/ProductDiscounts.vue.js +1 -1
- package/dist/martyrs/src/modules/products/components/pages/Categories.vue.cjs +28 -20
- package/dist/martyrs/src/modules/products/components/pages/Categories.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/products/components/pages/Categories.vue.js +28 -20
- package/dist/martyrs/src/modules/products/components/pages/Categories.vue.js.map +1 -1
- package/dist/martyrs/src/modules/products/components/pages/CategoryEdit.vue.cjs +3 -3
- package/dist/martyrs/src/modules/products/components/pages/CategoryEdit.vue.js +3 -3
- package/dist/martyrs/src/modules/products/components/pages/Product.vue.cjs +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.cjs +78 -46
- package/dist/martyrs/src/modules/products/components/pages/ProductEdit.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/products/components/pages/ProductEdit.vue.js +78 -46
- package/dist/martyrs/src/modules/products/components/pages/ProductEdit.vue.js.map +1 -1
- package/dist/martyrs/src/modules/products/components/pages/Products.vue.cjs +1 -2
- package/dist/martyrs/src/modules/products/components/pages/Products.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/products/components/pages/Products.vue.js +1 -2
- package/dist/martyrs/src/modules/products/components/pages/Products.vue.js.map +1 -1
- package/dist/martyrs/src/modules/products/components/sections/EditAttributes.vue.cjs +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.cjs +2 -2
- package/dist/martyrs/src/modules/products/components/sections/EditDiscounts.vue.js +2 -2
- package/dist/martyrs/src/modules/products/components/sections/EditVariants.vue.cjs +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.cjs +1 -1
- package/dist/martyrs/src/modules/products/components/sections/FilterProducts.vue.js +1 -1
- package/dist/martyrs/src/modules/products/components/sections/ProductConfigurator.vue.cjs +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.cjs +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.cjs +1 -1
- package/dist/martyrs/src/modules/products/components/sections/SectionProduct.vue.js +1 -1
- package/dist/martyrs/src/modules/products/store/products.cjs +12 -2
- package/dist/martyrs/src/modules/products/store/products.cjs.map +1 -1
- package/dist/martyrs/src/modules/products/store/products.js +12 -2
- package/dist/martyrs/src/modules/products/store/products.js.map +1 -1
- package/dist/martyrs/src/modules/rents/views/components/pages/Gant/GanttToolbar.vue.cjs +2 -2
- package/dist/martyrs/src/modules/rents/views/components/pages/Gant/GanttToolbar.vue.js +2 -2
- package/dist/martyrs/src/modules/reports/components/sections/FormReport.vue.cjs +2 -2
- package/dist/martyrs/src/modules/reports/components/sections/FormReport.vue.js +2 -2
- package/dist/martyrs/src/modules/spots/components/blocks/CardSpot.vue.cjs +1 -1
- package/dist/martyrs/src/modules/spots/components/blocks/CardSpot.vue.js +1 -1
- package/dist/martyrs/src/modules/spots/components/blocks/SpotMemberModify.vue.cjs +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.cjs +2 -2
- package/dist/martyrs/src/modules/spots/components/layouts/Spots.vue.js +2 -2
- package/dist/martyrs/src/modules/spots/components/pages/Map.vue.cjs +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.cjs +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.cjs +2 -2
- package/dist/martyrs/src/modules/spots/components/pages/SpotEdit.vue.js +2 -2
- package/dist/martyrs/src/modules/spots/components/sections/WorktimeEdit.vue.cjs +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.cjs +1 -1
- 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.cjs +4 -4
- package/dist/martyrs/src/modules/wallet/views/components/pages/Wallet.vue.js +4 -4
- package/dist/martyrs.cjs.js +1 -1
- package/dist/martyrs.es.js +1 -1
- package/dist/music.server.cjs +2 -2
- package/dist/music.server.js +2 -2
- package/dist/orders.server.cjs +3 -3
- package/dist/orders.server.js +3 -3
- package/dist/organizations.server.cjs +2 -2
- package/dist/organizations.server.js +2 -2
- package/dist/products.server.cjs +34 -22
- package/dist/products.server.js +34 -22
- package/dist/{queryProcessor-B_X680wC.cjs → queryProcessor-DMSc5-r6.cjs} +17 -20
- package/dist/{queryProcessor-CVcLPEnv.js → queryProcessor-rukV_SBd.js} +17 -20
- package/dist/rents.server.cjs +2 -2
- package/dist/rents.server.js +2 -2
- package/dist/spots.server.cjs +1 -1
- package/dist/spots.server.js +1 -1
- package/dist/{web-DVR8m2fm.js → web-BS-4Xl3x.js} +1 -1
- package/dist/{web-B0cfxzgu.cjs → web-CjndIDjT.cjs} +1 -1
- package/package.json +1 -1
- package/src/components/Feed/Feed.vue +1 -1
- package/src/components/Tree/Tree.vue +27 -15
- package/src/modules/globals/controllers/classes/globals.validator.js +32 -1
- package/src/modules/globals/controllers/utils/queryProcessor.js +27 -20
- package/src/modules/globals/views/components/blocks/PopupDateSelector.vue +1 -1
- package/src/modules/globals/views/store/globals.js +19 -2
- package/src/modules/notifications/notifications.client.js +0 -5
- package/src/modules/products/components/pages/Categories.vue +41 -26
- package/src/modules/products/components/pages/ProductEdit.vue +45 -21
- package/src/modules/products/components/pages/Products.vue +0 -1
- package/src/modules/products/controllers/categories.controller.js +3 -17
- package/src/modules/products/controllers/products.controller.js +34 -1
- package/src/modules/products/middlewares/categories.verifier.js +1 -1
- package/src/modules/products/middlewares/variants.verifier.js +2 -2
- package/src/modules/products/store/products.js +10 -0
- package/dist/martyrs/src/components/Button/Button.vue.js.map +0 -1
- package/dist/martyrs/src/components/Chips/Chips.vue.cjs.map +0 -1
- package/dist/martyrs/src/components/Chips/Chips.vue.js.map +0 -1
- package/dist/martyrs/src/components/Dropdown/Dropdown.vue.js.map +0 -1
- package/dist/martyrs/src/components/Menu/Menu.vue2.cjs.map +0 -1
- package/dist/martyrs/src/components/Menu/Menu.vue2.js.map +0 -1
- package/dist/martyrs/src/components/Select/Select.vue2.cjs.map +0 -1
- package/dist/martyrs/src/components/Spoiler/Spoiler.vue2.cjs.map +0 -1
- package/src/modules/products/TASKS.MD +0 -1
|
@@ -151,13 +151,30 @@ function setError(error) {
|
|
|
151
151
|
|
|
152
152
|
errorData = error;
|
|
153
153
|
|
|
154
|
+
// Обработка ошибок из fetch API (Store class)
|
|
155
|
+
if (error?.info) errorData = error.info;
|
|
156
|
+
|
|
157
|
+
// Обработка ошибок из axios
|
|
154
158
|
if (error?.response?.data) errorData = error.response.data;
|
|
155
159
|
|
|
156
|
-
|
|
160
|
+
// Обработка ошибок верификации
|
|
161
|
+
if (errorData?.error === 'VALIDATION_ERROR' && errorData?.errors) {
|
|
162
|
+
// Собираем все сообщения об ошибках в одну строку
|
|
163
|
+
const errorMessages = [];
|
|
164
|
+
for (const field in errorData.errors) {
|
|
165
|
+
const fieldErrors = errorData.errors[field];
|
|
166
|
+
if (Array.isArray(fieldErrors)) {
|
|
167
|
+
errorMessages.push(...fieldErrors);
|
|
168
|
+
} else if (typeof fieldErrors === 'string') {
|
|
169
|
+
errorMessages.push(fieldErrors);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
state.error.message = errorMessages.join(', ') || 'Validation error';
|
|
173
|
+
} else if (error && errorData.errorCode) {
|
|
157
174
|
// state.error.message = i18n.global.t(`errors.${errorData.errorCode}`);
|
|
158
175
|
state.error.message = errorData.errorCode;
|
|
159
176
|
} else {
|
|
160
|
-
state.error.message = errorData.message || 'Unknown error';
|
|
177
|
+
state.error.message = errorData.message || error.message || 'Unknown error';
|
|
161
178
|
}
|
|
162
179
|
|
|
163
180
|
state.error.show = true;
|
|
@@ -380,9 +380,6 @@ function initializeNotifications(app, store, router, options = {}) {
|
|
|
380
380
|
const route = options.route || 'User Profile Root';
|
|
381
381
|
router.addRoute(route, routerNotifications);
|
|
382
382
|
store.addStore('notifications', storeNotifications);
|
|
383
|
-
|
|
384
|
-
console.log('[Notifications] Initializing, auth store exists:', !!store.auth);
|
|
385
|
-
console.log('[Notifications] Auth state:', store.auth?.state);
|
|
386
383
|
|
|
387
384
|
// Initialize global WebSocket if needed
|
|
388
385
|
if (options.wsUrl) {
|
|
@@ -409,7 +406,6 @@ function initializeNotifications(app, store, router, options = {}) {
|
|
|
409
406
|
notificationManager.initialize();
|
|
410
407
|
|
|
411
408
|
// Watch for user login/logout using auth store
|
|
412
|
-
console.log('[Notifications] Setting up auth watcher...');
|
|
413
409
|
if (!store.auth) {
|
|
414
410
|
console.error('[Notifications] Auth store not found! Cannot set up watcher.');
|
|
415
411
|
return;
|
|
@@ -418,7 +414,6 @@ function initializeNotifications(app, store, router, options = {}) {
|
|
|
418
414
|
watch(
|
|
419
415
|
() => store.auth.state.access.status,
|
|
420
416
|
async (isAuthenticated) => {
|
|
421
|
-
console.log('[Notifications] Auth status changed:', isAuthenticated);
|
|
422
417
|
if (isAuthenticated) {
|
|
423
418
|
// Re-register device for authenticated user
|
|
424
419
|
console.log('[Notifications] User logged in, re-registering device...');
|
|
@@ -48,7 +48,8 @@
|
|
|
48
48
|
<Tree
|
|
49
49
|
v-if="items"
|
|
50
50
|
:items="categories.state.all"
|
|
51
|
-
:state="categories.state.all"
|
|
51
|
+
:state="categories.state.all"
|
|
52
|
+
:parent-id="null"
|
|
52
53
|
@update="updateCategoriesOrder"
|
|
53
54
|
v-slot="{ item }"
|
|
54
55
|
>
|
|
@@ -117,45 +118,56 @@
|
|
|
117
118
|
});
|
|
118
119
|
|
|
119
120
|
// Функция для сбора затронутых категорий при drag-n-drop
|
|
120
|
-
function collectAffectedCategories(
|
|
121
|
+
function collectAffectedCategories(eventData) {
|
|
121
122
|
const result = {
|
|
122
123
|
movedCategory: null,
|
|
123
124
|
affectedCategories: []
|
|
124
125
|
};
|
|
125
126
|
|
|
126
|
-
|
|
127
|
-
function getLevelItems(items, parentId) {
|
|
128
|
-
if (!parentId) return items; // root level
|
|
129
|
-
|
|
130
|
-
for (const item of items) {
|
|
131
|
-
if (item._id === parentId) {
|
|
132
|
-
return item.children || [];
|
|
133
|
-
}
|
|
134
|
-
if (item.children?.length) {
|
|
135
|
-
const found = getLevelItems(item.children, parentId);
|
|
136
|
-
if (found) return found;
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
return [];
|
|
140
|
-
}
|
|
127
|
+
console.log('collectAffectedCategories - eventData:', eventData);
|
|
141
128
|
|
|
142
|
-
//
|
|
143
|
-
if (
|
|
129
|
+
// Проверяем, что это объект от Tree компонента с полной информацией
|
|
130
|
+
if (eventData && eventData.movedItem) {
|
|
131
|
+
// Если категория переместилась между уровнями
|
|
132
|
+
if (eventData.movedItem._id) {
|
|
133
|
+
result.movedCategory = {
|
|
134
|
+
_id: eventData.movedItem._id,
|
|
135
|
+
newParent: eventData.parentId // Используем parentId из события (null для корня)
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// Собираем все категории текущего уровня с их новым порядком
|
|
140
|
+
const items = eventData.items || [];
|
|
141
|
+
console.log('Level items:', items);
|
|
142
|
+
|
|
143
|
+
items.forEach((item, index) => {
|
|
144
|
+
result.affectedCategories.push({
|
|
145
|
+
_id: item._id,
|
|
146
|
+
order: index
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
} else if (eventData && eventData._id) {
|
|
150
|
+
// Fallback для старого формата (простой объект категории)
|
|
144
151
|
result.movedCategory = {
|
|
145
|
-
_id:
|
|
146
|
-
newParent:
|
|
152
|
+
_id: eventData._id,
|
|
153
|
+
newParent: eventData.parent || null
|
|
147
154
|
};
|
|
148
155
|
|
|
149
|
-
//
|
|
150
|
-
const
|
|
151
|
-
|
|
156
|
+
// Пытаемся найти категории того же уровня
|
|
157
|
+
const parentId = eventData.parent;
|
|
158
|
+
const sameLevel = parentId
|
|
159
|
+
? categories.state.all.find(c => c._id === parentId)?.children || []
|
|
160
|
+
: categories.state.all;
|
|
161
|
+
|
|
162
|
+
sameLevel.forEach((item, index) => {
|
|
152
163
|
result.affectedCategories.push({
|
|
153
164
|
_id: item._id,
|
|
154
165
|
order: index
|
|
155
166
|
});
|
|
156
167
|
});
|
|
157
168
|
} else {
|
|
158
|
-
//
|
|
169
|
+
// Если нет данных о перемещении, собираем корневые категории
|
|
170
|
+
console.log('No event data, collecting root level categories');
|
|
159
171
|
categories.state.all.forEach((item, index) => {
|
|
160
172
|
result.affectedCategories.push({
|
|
161
173
|
_id: item._id,
|
|
@@ -164,6 +176,8 @@
|
|
|
164
176
|
});
|
|
165
177
|
}
|
|
166
178
|
|
|
179
|
+
console.log('collectAffectedCategories - result:', result);
|
|
180
|
+
|
|
167
181
|
return result;
|
|
168
182
|
}
|
|
169
183
|
|
|
@@ -174,7 +188,8 @@
|
|
|
174
188
|
try {
|
|
175
189
|
const data = collectAffectedCategories(event);
|
|
176
190
|
|
|
177
|
-
|
|
191
|
+
// ОДИН КОНСОЛЬ ЛОГ НА ФРОНТЕНДЕ - ЧТО ОТПРАВЛЯЕМ
|
|
192
|
+
console.log('📤 FRONTEND SENDING:', JSON.stringify(data, null, 2));
|
|
178
193
|
await categories.actions.updateOrder(data);
|
|
179
194
|
console.log('Categories order updated successfully');
|
|
180
195
|
} catch (error) {
|
|
@@ -169,9 +169,33 @@
|
|
|
169
169
|
type="textarea"
|
|
170
170
|
/>
|
|
171
171
|
</Block>
|
|
172
|
-
<!-- Categories -->
|
|
173
|
-
|
|
174
172
|
|
|
173
|
+
<!-- Price Block (only for new products) -->
|
|
174
|
+
<Block v-if="!route.params.product" title="Price">
|
|
175
|
+
<div class="flex gap-thin mn-b-thin">
|
|
176
|
+
<Field
|
|
177
|
+
v-model:field="products.state.current.defaultVariant.price"
|
|
178
|
+
label="Price"
|
|
179
|
+
type="number"
|
|
180
|
+
placeholder="Enter price"
|
|
181
|
+
class="w-100 bg-white radius-small pd-medium"
|
|
182
|
+
/>
|
|
183
|
+
<Field
|
|
184
|
+
v-model:field="products.state.current.defaultVariant.quantity"
|
|
185
|
+
label="Quantity"
|
|
186
|
+
type="number"
|
|
187
|
+
placeholder="Enter quantity"
|
|
188
|
+
class="w-100 bg-white radius-small pd-medium"
|
|
189
|
+
/>
|
|
190
|
+
<Select
|
|
191
|
+
v-model:select="products.state.current.defaultVariant.unit"
|
|
192
|
+
label="Unit"
|
|
193
|
+
:options="['pcs', 'g', 'kg', 'ml', 'l', 'oz']"
|
|
194
|
+
placeholder="Select unit"
|
|
195
|
+
class="w-100 bg-white radius-small pd-medium"
|
|
196
|
+
/>
|
|
197
|
+
</div>
|
|
198
|
+
</Block>
|
|
175
199
|
|
|
176
200
|
<!-- Attributes -->
|
|
177
201
|
<EditAttributes
|
|
@@ -303,34 +327,25 @@ onMounted(async() => {
|
|
|
303
327
|
if (route.params.product) {
|
|
304
328
|
await products.actions.read({ _id: route.params.product, lookup: ['variants','categories','recommended'] });
|
|
305
329
|
} else {
|
|
306
|
-
// Создаем дефолтный вариант для нового товара
|
|
307
|
-
if (!products.state.current.variants || products.state.current.variants.length === 0) {
|
|
308
|
-
products.state.current.variants = [{
|
|
309
|
-
name: 'Default',
|
|
310
|
-
sku: '',
|
|
311
|
-
images: [],
|
|
312
|
-
price: 0,
|
|
313
|
-
cost: 0,
|
|
314
|
-
quantity: 1,
|
|
315
|
-
unit: 'pcs',
|
|
316
|
-
available: 0,
|
|
317
|
-
ingredients: [],
|
|
318
|
-
attributes: []
|
|
319
|
-
}];
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
|
|
323
330
|
// Убедимся, что массивы инициализированы
|
|
324
331
|
if (!products.state.current.translations) {
|
|
325
332
|
products.state.current.translations = []
|
|
326
333
|
}
|
|
327
|
-
|
|
334
|
+
// Убедимся, что массивы инициализированы
|
|
328
335
|
if (!products.state.current.recommended) {
|
|
329
336
|
products.state.current.recommended = []
|
|
330
337
|
}
|
|
331
338
|
if (!products.state.current.discounts) {
|
|
332
339
|
products.state.current.discounts = []
|
|
333
340
|
}
|
|
341
|
+
// Инициализируем defaultVariant для нового продукта
|
|
342
|
+
if (!products.state.current.defaultVariant) {
|
|
343
|
+
products.state.current.defaultVariant = {
|
|
344
|
+
price: null,
|
|
345
|
+
quantity: 1,
|
|
346
|
+
unit: 'pcs'
|
|
347
|
+
}
|
|
348
|
+
}
|
|
334
349
|
|
|
335
350
|
try {
|
|
336
351
|
// Data prefetching
|
|
@@ -344,6 +359,8 @@ onMounted(async() => {
|
|
|
344
359
|
console.error('error loading categories:', error);
|
|
345
360
|
}
|
|
346
361
|
|
|
362
|
+
}
|
|
363
|
+
|
|
347
364
|
emits('page-loaded');
|
|
348
365
|
isPageLoaded.value = true
|
|
349
366
|
})
|
|
@@ -362,7 +379,14 @@ async function onSubmit() {
|
|
|
362
379
|
type: 'user',
|
|
363
380
|
hidden: false
|
|
364
381
|
}
|
|
365
|
-
|
|
382
|
+
|
|
383
|
+
// Передаем defaultVariant на бекенд при создании
|
|
384
|
+
const productData = {
|
|
385
|
+
...products.state.current,
|
|
386
|
+
defaultVariant: products.state.current.defaultVariant
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
await products.actions.create(productData)
|
|
366
390
|
}
|
|
367
391
|
|
|
368
392
|
redirectTo()
|
|
@@ -175,7 +175,6 @@
|
|
|
175
175
|
:options="{
|
|
176
176
|
limit: 16,
|
|
177
177
|
owner: route.name?.includes('Organization') ? route.params._id : null,
|
|
178
|
-
search: route.query.search,
|
|
179
178
|
lookup: ['variants','rents','inventory'],
|
|
180
179
|
categories: route.params.categoryPath ? `/${route.params.categoryPath}` : null,
|
|
181
180
|
filters: processedFilters,
|
|
@@ -28,13 +28,12 @@ const controllerFactory = db => {
|
|
|
28
28
|
|
|
29
29
|
// Построение дерева из плоского массива используя url
|
|
30
30
|
const buildTreeFromUrl = (categories, sortParam = 'order', sortOrder = 'asc') => {
|
|
31
|
-
console.log('cat buildtree', categories)
|
|
32
31
|
// Сортируем по url для правильного порядка обработки
|
|
33
32
|
categories.sort((a, b) => a.url.localeCompare(b.url));
|
|
34
33
|
|
|
35
34
|
const tree = [];
|
|
36
35
|
const nodeMap = new Map();
|
|
37
|
-
|
|
36
|
+
|
|
38
37
|
categories.forEach(cat => {
|
|
39
38
|
const node = { ...cat, children: [] };
|
|
40
39
|
nodeMap.set(cat.url, node);
|
|
@@ -42,11 +41,9 @@ const controllerFactory = db => {
|
|
|
42
41
|
|
|
43
42
|
// Находим родителя по url
|
|
44
43
|
const parentUrl = cat.url.substring(0, cat.url.lastIndexOf('/'));
|
|
45
|
-
console.log('cat parent buildtree', parentUrl)
|
|
46
44
|
|
|
47
45
|
if (parentUrl && nodeMap.has(parentUrl)) {
|
|
48
46
|
nodeMap.get(parentUrl).children.push(node);
|
|
49
|
-
console.log('cat nodeMap buildtree', nodeMap)
|
|
50
47
|
} else if (cat.level === 0) {
|
|
51
48
|
tree.push(node);
|
|
52
49
|
}
|
|
@@ -370,9 +367,8 @@ const controllerFactory = db => {
|
|
|
370
367
|
async updateOrder(req, res) {
|
|
371
368
|
const startTime = Date.now();
|
|
372
369
|
try {
|
|
373
|
-
|
|
374
|
-
console.log('
|
|
375
|
-
console.log('Has moved category:', !!req.verifiedBody?.movedCategory);
|
|
370
|
+
// ОДИН КОНСОЛЬ ЛОГ НА БЕКЕНДЕ - ЧТО ПРИШЛО
|
|
371
|
+
console.log('📥 BACKEND RECEIVED:', JSON.stringify(req.body, null, 2));
|
|
376
372
|
|
|
377
373
|
const { movedCategory, affectedCategories } = req.verifiedBody;
|
|
378
374
|
|
|
@@ -388,16 +384,6 @@ const controllerFactory = db => {
|
|
|
388
384
|
}
|
|
389
385
|
}));
|
|
390
386
|
|
|
391
|
-
// Если есть перемещенная категория, добавляем обновление parent
|
|
392
|
-
if (movedCategory) {
|
|
393
|
-
bulkOps.push({
|
|
394
|
-
updateOne: {
|
|
395
|
-
filter: { _id: movedCategory._id },
|
|
396
|
-
update: { $set: { parent: movedCategory.newParent } }
|
|
397
|
-
}
|
|
398
|
-
});
|
|
399
|
-
}
|
|
400
|
-
|
|
401
387
|
// Выполняем все обновления одним запросом
|
|
402
388
|
console.log(`Starting bulkWrite with ${bulkOps.length} operations`);
|
|
403
389
|
const bulkStart = Date.now();
|
|
@@ -7,6 +7,14 @@ import productLookupConfigs from '@martyrs/src/modules/products/controllers/conf
|
|
|
7
7
|
|
|
8
8
|
const controllerFactory = db => {
|
|
9
9
|
const Product = db.product;
|
|
10
|
+
const Variant = db.variant;
|
|
11
|
+
|
|
12
|
+
// Функция генерации SKU для варианта
|
|
13
|
+
const generateSKU = () => {
|
|
14
|
+
const timestamp = Date.now().toString(36);
|
|
15
|
+
const random = Math.random().toString(36).substring(2, 5);
|
|
16
|
+
return `VAR-${timestamp}-${random}`.toUpperCase();
|
|
17
|
+
};
|
|
10
18
|
|
|
11
19
|
const Create = async (req, res) => {
|
|
12
20
|
try {
|
|
@@ -15,7 +23,32 @@ const controllerFactory = db => {
|
|
|
15
23
|
category: req.body.category?.map(cat => cat._id) || []
|
|
16
24
|
};
|
|
17
25
|
|
|
18
|
-
|
|
26
|
+
// Удаляем defaultVariant из данных продукта
|
|
27
|
+
const { defaultVariant, ...cleanProductData } = productData;
|
|
28
|
+
|
|
29
|
+
const product = await new Product(cleanProductData).save();
|
|
30
|
+
|
|
31
|
+
// Создаем дефолтный вариант если указана цена
|
|
32
|
+
if (defaultVariant && defaultVariant.price !== null && defaultVariant.price > 0) {
|
|
33
|
+
const variantData = {
|
|
34
|
+
product: product._id,
|
|
35
|
+
name: product.name,
|
|
36
|
+
price: parseFloat(defaultVariant.price),
|
|
37
|
+
quantity: parseInt(defaultVariant.quantity) || 1,
|
|
38
|
+
unit: defaultVariant.unit || 'pcs',
|
|
39
|
+
status: product.status, // используем статус из товара
|
|
40
|
+
sku: generateSKU(),
|
|
41
|
+
owner: product.owner,
|
|
42
|
+
creator: product.creator,
|
|
43
|
+
images: [],
|
|
44
|
+
cost: 0,
|
|
45
|
+
ingredients: [],
|
|
46
|
+
attributes: []
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
await new Variant(variantData).save();
|
|
50
|
+
}
|
|
51
|
+
|
|
19
52
|
return res.status(201).json(product);
|
|
20
53
|
} catch (err) {
|
|
21
54
|
console.log(err)
|
|
@@ -17,7 +17,7 @@ export default (function (db) {
|
|
|
17
17
|
rule: 'optional',
|
|
18
18
|
validator: Validator.schema()
|
|
19
19
|
.string()
|
|
20
|
-
.max
|
|
20
|
+
.length({ max: 5000 }, 'Description must not exceed 5000 characters')
|
|
21
21
|
},
|
|
22
22
|
sku: {
|
|
23
23
|
rule: 'optional',
|
|
@@ -112,7 +112,7 @@ export default (function (db) {
|
|
|
112
112
|
rule: 'optional',
|
|
113
113
|
validator: Validator.schema()
|
|
114
114
|
.string()
|
|
115
|
-
.max
|
|
115
|
+
.length({ max: 5000 }, 'Description must not exceed 5000 characters')
|
|
116
116
|
},
|
|
117
117
|
sku: {
|
|
118
118
|
rule: 'optional',
|
|
@@ -31,6 +31,11 @@ const state = reactive({
|
|
|
31
31
|
included: null,
|
|
32
32
|
ingredients: [],
|
|
33
33
|
description: '',
|
|
34
|
+
defaultVariant: {
|
|
35
|
+
price: null,
|
|
36
|
+
quantity: 1,
|
|
37
|
+
unit: 'pcs'
|
|
38
|
+
}
|
|
34
39
|
},
|
|
35
40
|
filter: {
|
|
36
41
|
active: false,
|
|
@@ -227,6 +232,11 @@ const mutations = {
|
|
|
227
232
|
discounts: [],
|
|
228
233
|
ingredients: [],
|
|
229
234
|
description: '',
|
|
235
|
+
defaultVariant: {
|
|
236
|
+
price: null,
|
|
237
|
+
quantity: 1,
|
|
238
|
+
unit: 'pcs'
|
|
239
|
+
}
|
|
230
240
|
};
|
|
231
241
|
},
|
|
232
242
|
};
|
|
@@ -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 text-transform: uppercase;\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":"Chips.vue.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Chips.vue.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Dropdown.vue.js","sources":["../../../../../src/components/Dropdown/Dropdown.vue"],"sourcesContent":["<template>\n <div class=\"dropdown pos-relative\" v-click-outside=\"clickedOutside\" @click.stop=\"isOpen = !isOpen\">\n <div v-if=\"isComponentLabel\" class=\"w-100 h-100 flex-center flex\">\n <component :is=\"label.component\" v-bind=\"label.props\" :class=\"label.class\"></component>\n </div>\n <div v-else>\n {{ label }}\n </div>\n <transition name=\"TransitionTranslateY\" mode=\"out-in\">\n <div \n v-show=\"isOpen\" \n :style=\"{ left: align === 'left' ? '0' : 'auto', right: align === 'right' ? '0' : 'auto' }\" \n class=\"dropdown-content radius-big\" \n >\n <slot></slot>\n </div>\n </transition>\n </div>\n</template>\n\n<script setup>\nimport { ref, computed } from 'vue';\nimport clickOutside from '../FieldPhone/click-outside.js';\n\nlet vClickOutside = clickOutside\n\nconst props = defineProps({\n label: {\n type: [String, Object],\n default: 'Open'\n },\n align: {\n type: String,\n default: 'left'\n }\n})\n\nconst isOpen = ref(false);\nconst isComponentLabel = computed(() => typeof props.label === 'object');\n\nfunction clickedOutside () {\n isOpen.value = false\n}\n</script>\n\n<style >\n.dropdown-content {\n display: block;\n position: absolute;\n box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);\n z-index: 1;\n}\n\n/*.dropdown:hover .dropdown-content {\n display: block;\n}*/\n</style>\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;AAwBA,QAAI,gBAAgB;AAEpB,UAAM,QAAQ;AAWd,UAAM,SAAS,IAAI,KAAK;AACxB,UAAM,mBAAmB,SAAS,MAAM,OAAO,MAAM,UAAU,QAAQ;AAEvE,aAAS,iBAAkB;AACzB,aAAO,QAAQ;AAAA,IACjB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Menu.vue2.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Menu.vue2.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Select.vue2.cjs","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":["clickOutside","ref","computed","watch","nextTick"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0CA,QAAI,gBAAgBA,aAAAA;AACpB,UAAM,OAAO;AAKb,UAAM,QAAQ;AASd,UAAM,WAAWC,IAAAA,IAAI,KAAK;AAC1B,UAAM,eAAeA,IAAAA,IAAI,IAAI;AAC7B,UAAM,kBAAkBA,IAAAA;AAAAA,MACtB,MAAM,WACJ,kBAAkB,MAAM,QAAQ,MAAM,UAAU,MAAM,OAAO,IAC7D,MAAM;AAAA,IACV;AACA,UAAM,gBAAgBC,IAAAA,SAAS,MAAM;AACnC,aAAO,MAAM,SACX,MAAM,QAAQ,OAAO,YAAU,WAAW,MAAM,MAAM,IACtD,MAAM;AAAA,IACV,CAAC;AACDC,QAAAA,MAAM,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,cAAMC,IAAAA,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.vue2.cjs","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":["ref","onMounted"],"mappings":";;;;;;;;;;;;;AAoBA,UAAM,QAAQ;AAOd,UAAM,cAAcA,IAAAA,IAAI,KAAK;AAC7B,UAAM,iBAAiBA,IAAAA,IAAI,IAAI;AAE/BC,QAAAA,UAAU,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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
ПРОВЕРИТЬ РАБОТУ ИНГРЕДИЕНТОВ НА БЕКЕНДЕ И ФРОНТЕНДЕ
|