@ozdao/martyrs 0.2.571 → 0.2.572
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/dayjs.min.js +1 -1
- package/dist/_virtual/weekOfYear.js +1 -1
- package/dist/builder.js +1194 -45
- package/dist/{main-BFvlam0J.js → main-BfEQkhXS.js} +1173 -1191
- package/dist/martyrs/dist/{main-BFvlam0J.js → main-BfEQkhXS.js} +94 -112
- package/dist/martyrs/dist/main-BfEQkhXS.js.map +1 -0
- package/dist/martyrs/dist/{web-CH5wzMHy.js → web-BqTV9va1.js} +3 -3
- package/dist/martyrs/dist/{web-CH5wzMHy.js.map → web-BqTV9va1.js.map} +1 -1
- package/dist/martyrs/node_modules/.pnpm/{@capacitor_core@7.0.1 → @capacitor_core@7.4.4}/node_modules/@capacitor/core/dist/index.js +2 -1
- package/dist/martyrs/node_modules/.pnpm/@capacitor_core@7.4.4/node_modules/@capacitor/core/dist/index.js.map +1 -0
- package/dist/martyrs/node_modules/.pnpm/{@capacitor_preferences@7.0.0_@capacitor_core@7.0.1 → @capacitor_preferences@7.0.2_@capacitor_core@7.4.4}/node_modules/@capacitor/preferences/dist/esm/index.js +1 -1
- package/dist/martyrs/node_modules/.pnpm/{@capacitor_preferences@7.0.0_@capacitor_core@7.0.1 → @capacitor_preferences@7.0.2_@capacitor_core@7.4.4}/node_modules/@capacitor/preferences/dist/esm/index.js.map +1 -1
- package/dist/martyrs/node_modules/.pnpm/{@capacitor_preferences@7.0.0_@capacitor_core@7.0.1 → @capacitor_preferences@7.0.2_@capacitor_core@7.4.4}/node_modules/@capacitor/preferences/dist/esm/web.js +1 -1
- package/dist/martyrs/node_modules/.pnpm/{@capacitor_preferences@7.0.0_@capacitor_core@7.0.1 → @capacitor_preferences@7.0.2_@capacitor_core@7.4.4}/node_modules/@capacitor/preferences/dist/esm/web.js.map +1 -1
- package/dist/{node_modules/.pnpm/@vue_server-renderer@3.5.13_vue@3.5.13_typescript@5.8.3_ → martyrs}/node_modules/@vue/server-renderer/dist/server-renderer.esm-bundler.js +1 -1
- package/dist/martyrs/node_modules/@vue/server-renderer/dist/server-renderer.esm-bundler.js.map +1 -0
- package/dist/martyrs/node_modules/@vue/shared/dist/shared.esm-bundler.js.map +1 -0
- package/dist/{node_modules/.pnpm/dayjs@1.11.13 → martyrs}/node_modules/dayjs/dayjs.min.js +1 -1
- package/dist/martyrs/node_modules/dayjs/dayjs.min.js.map +1 -0
- package/dist/{node_modules/.pnpm/dayjs@1.11.13 → martyrs}/node_modules/dayjs/plugin/weekOfYear.js +1 -1
- package/dist/martyrs/node_modules/dayjs/plugin/weekOfYear.js.map +1 -0
- package/dist/martyrs/node_modules/uuid/dist/esm-browser/regex.js +5 -0
- package/dist/martyrs/node_modules/uuid/dist/esm-browser/regex.js.map +1 -0
- package/dist/martyrs/node_modules/uuid/dist/esm-browser/rng.js +15 -0
- package/dist/martyrs/node_modules/uuid/dist/esm-browser/rng.js.map +1 -0
- package/dist/martyrs/node_modules/uuid/dist/esm-browser/stringify.js +17 -0
- package/dist/martyrs/node_modules/uuid/dist/esm-browser/stringify.js.map +1 -0
- package/dist/martyrs/node_modules/uuid/dist/esm-browser/v4.js +13 -0
- package/dist/martyrs/node_modules/uuid/dist/esm-browser/v4.js.map +1 -0
- package/dist/martyrs/node_modules/uuid/dist/esm-browser/validate.js +8 -0
- package/dist/martyrs/node_modules/uuid/dist/esm-browser/validate.js.map +1 -0
- package/dist/martyrs/src/components/Block/Block.vue.js +2 -2
- package/dist/martyrs/src/components/Block/Block.vue.js.map +1 -1
- package/dist/martyrs/src/components/BottomSheet/BottomSheet.vue.js +1 -1
- package/dist/martyrs/src/components/BottomSheet/BottomSheet.vue.js.map +1 -1
- package/dist/martyrs/src/components/Button/Button.vue2.js +1 -1
- package/dist/martyrs/src/components/Calendar/Calendar.vue2.js +6 -6
- package/dist/martyrs/src/components/Calendar/Calendar.vue2.js.map +1 -1
- package/dist/martyrs/src/components/Checkbox/Checkbox.vue.js +2 -2
- package/dist/martyrs/src/components/Checkbox/Checkbox.vue.js.map +1 -1
- package/dist/martyrs/src/components/Chips/Chips.vue.js +2 -2
- package/dist/martyrs/src/components/Countdown/Countdown.vue.js +5 -5
- package/dist/martyrs/src/components/Countdown/Countdown.vue.js.map +1 -1
- package/dist/martyrs/src/components/DatePicker/DatePicker.vue.js +4 -4
- package/dist/martyrs/src/components/DatePicker/DatePicker.vue.js.map +1 -1
- package/dist/martyrs/src/components/Dropdown/{Dropdown.vue.js → Dropdown.vue2.js} +2 -2
- package/dist/martyrs/src/components/Dropdown/Dropdown.vue2.js.map +1 -0
- package/dist/martyrs/src/components/EditImages/{EditImages.vue.js → EditImages.vue2.js} +3 -3
- package/dist/martyrs/src/components/EditImages/EditImages.vue2.js.map +1 -0
- package/dist/martyrs/src/components/Feed/Carousel.vue.js +1 -1
- package/dist/martyrs/src/components/Feed/Feed.vue.js +4 -4
- package/dist/martyrs/src/components/Feed/Feed.vue.js.map +1 -1
- package/dist/martyrs/src/components/FieldBig/FieldBig.vue.js +2 -2
- package/dist/martyrs/src/components/FieldBig/FieldBig.vue.js.map +1 -1
- package/dist/martyrs/src/components/FieldPhone/FieldPhone.vue.js +1 -1
- package/dist/martyrs/src/components/FieldPhone/FieldPhone.vue.js.map +1 -1
- package/dist/martyrs/src/components/FieldTags/BlockTags.vue.js +1 -1
- package/dist/martyrs/src/components/FieldTags/BlockTags.vue.js.map +1 -1
- package/dist/martyrs/src/components/Loader/{Loader.vue.js → Loader.vue2.js} +3 -3
- package/dist/martyrs/src/components/Loader/Loader.vue2.js.map +1 -0
- package/dist/martyrs/src/components/LocationMarker/LocationMarker.vue.js +1 -1
- package/dist/martyrs/src/components/Media/Media.vue.js +1 -1
- package/dist/martyrs/src/components/Menu/{Menu.vue.js → Menu.vue2.js} +2 -2
- package/dist/martyrs/src/components/Menu/Menu.vue2.js.map +1 -0
- package/dist/martyrs/src/components/Menu/MenuItem.vue.js +2 -2
- package/dist/martyrs/src/components/Menu/MenuItem.vue.js.map +1 -1
- package/dist/martyrs/src/components/PhotoViewer/PhotoViewer.vue.js +2 -2
- package/dist/martyrs/src/components/PhotoViewer/PhotoViewer.vue.js.map +1 -1
- package/dist/martyrs/src/components/Radio/Radio.vue.js +1 -1
- package/dist/martyrs/src/components/Radio/Radio.vue.js.map +1 -1
- package/dist/martyrs/src/components/Select/Select.vue.js +2 -2
- package/dist/martyrs/src/components/Select/Select.vue.js.map +1 -1
- package/dist/martyrs/src/components/Table/Table.vue.js +3 -3
- package/dist/martyrs/src/components/Table/Table.vue.js.map +1 -1
- package/dist/martyrs/src/components/Text/Text.vue.js +1 -1
- package/dist/martyrs/src/components/Text/Text.vue.js.map +1 -1
- package/dist/martyrs/src/components/Tooltip/{Tooltip.vue.js → Tooltip.vue2.js} +2 -2
- package/dist/martyrs/src/components/Tooltip/Tooltip.vue2.js.map +1 -0
- package/dist/martyrs/src/components/UploadImage/UploadImage.vue.js +4 -4
- package/dist/martyrs/src/components/UploadImage/UploadImage.vue.js.map +1 -1
- package/dist/martyrs/src/components/UploadImageMultiple/UploadImageMultiple.vue.js +4 -4
- package/dist/martyrs/src/components/UploadImageMultiple/UploadImageMultiple.vue.js.map +1 -1
- package/dist/martyrs/src/modules/auth/views/components/blocks/CardUser.vue.js +2 -2
- package/dist/martyrs/src/modules/auth/views/components/blocks/ProfileCard.vue.js +4 -4
- package/dist/martyrs/src/modules/auth/views/components/blocks/ProfileCard.vue.js.map +1 -1
- package/dist/martyrs/src/modules/auth/views/components/layouts/Auth.vue.js +1 -1
- package/dist/martyrs/src/modules/auth/views/components/layouts/Auth.vue.js.map +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/EnterPassword.vue.js +2 -2
- package/dist/martyrs/src/modules/auth/views/components/pages/EnterPassword.vue.js.map +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/Profile.vue.js +8 -8
- package/dist/martyrs/src/modules/auth/views/components/pages/Profile.vue.js.map +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/ProfileBlogposts.vue.js +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/ProfileBlogposts.vue.js.map +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/ProfileEdit.vue.js +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/ProfileEditAccount.vue.js +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/ProfileEditAccount.vue.js.map +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/ResetPassword.vue.js.map +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/SignIn.vue.js +3 -3
- package/dist/martyrs/src/modules/auth/views/components/pages/SignIn.vue.js.map +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/SignUp.vue.js +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/SignUp.vue.js.map +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/UserDashboard.vue.js +3 -3
- package/dist/martyrs/src/modules/auth/views/components/pages/UserDashboard.vue.js.map +1 -1
- package/dist/martyrs/src/modules/auth/views/components/sections/FeaturedUsers.vue.js +1 -1
- package/dist/martyrs/src/modules/auth/views/components/sections/FeaturedUsers.vue.js.map +1 -1
- package/dist/martyrs/src/modules/auth/views/components/sections/ProfileEditCredentials.vue.js +7 -7
- package/dist/martyrs/src/modules/auth/views/components/sections/ProfileEditCredentials.vue.js.map +1 -1
- package/dist/martyrs/src/modules/auth/views/components/sections/SliderFeatures.vue.js +1 -1
- package/dist/martyrs/src/modules/auth/views/components/sections/SliderFeatures.vue.js.map +1 -1
- package/dist/martyrs/src/modules/auth/views/store/auth.js +1 -1
- package/dist/martyrs/src/modules/backoffice/components/pages/Dashboard.vue.js +4 -4
- package/dist/martyrs/src/modules/backoffice/components/pages/Dashboard.vue.js.map +1 -1
- package/dist/martyrs/src/modules/backoffice/components/partials/Sidebar.vue.js +5 -5
- package/dist/martyrs/src/modules/backoffice/components/partials/Sidebar.vue.js.map +1 -1
- package/dist/martyrs/src/modules/chats/components/blocks/ChatMessage.vue.js +1 -1
- package/dist/martyrs/src/modules/chats/components/blocks/ChatMessage.vue.js.map +1 -1
- package/dist/martyrs/src/modules/chats/components/sections/ChatWindow.vue.js +2 -2
- package/dist/martyrs/src/modules/chats/components/sections/ChatWindow.vue.js.map +1 -1
- package/dist/martyrs/src/modules/community/components/blocks/Activity.vue.js +7 -7
- package/dist/martyrs/src/modules/community/components/blocks/CardBlogpost.vue.js +1 -1
- package/dist/martyrs/src/modules/community/components/blocks/CardBlogpost.vue.js.map +1 -1
- package/dist/martyrs/src/modules/community/components/blocks/FooterBlogpost.vue.js +4 -4
- package/dist/martyrs/src/modules/community/components/blocks/FooterBlogpost.vue.js.map +1 -1
- package/dist/martyrs/src/modules/community/components/layouts/Community.vue.js +10 -10
- package/dist/martyrs/src/modules/community/components/layouts/Community.vue.js.map +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/community/components/pages/CreateBlogPost.vue.js.map +1 -1
- package/dist/martyrs/src/modules/community/components/pages/Posts.vue.js +2 -2
- package/dist/martyrs/src/modules/community/components/pages/Posts.vue.js.map +1 -1
- package/dist/martyrs/src/modules/community/components/sections/Comment.vue.js +3 -3
- package/dist/martyrs/src/modules/community/components/sections/Comment.vue.js.map +1 -1
- package/dist/martyrs/src/modules/community/components/sections/Comments.vue.js +1 -1
- package/dist/martyrs/src/modules/constructor/components/elements/Audio.vue.js +1 -1
- package/dist/martyrs/src/modules/constructor/components/elements/Audio.vue.js.map +1 -1
- package/dist/martyrs/src/modules/constructor/components/elements/Embed.vue.js +1 -1
- package/dist/martyrs/src/modules/constructor/components/elements/Embed.vue.js.map +1 -1
- package/dist/martyrs/src/modules/constructor/components/elements/Textarea.vue2.js +1 -1
- package/dist/martyrs/src/modules/constructor/components/elements/Textarea.vue2.js.map +1 -1
- package/dist/martyrs/src/modules/constructor/components/elements/Video.vue.js +1 -1
- package/dist/martyrs/src/modules/constructor/components/elements/Video.vue.js.map +1 -1
- package/dist/martyrs/src/modules/constructor/components/sections/Constructor.vue.js +1 -1
- package/dist/martyrs/src/modules/core/views/classes/core.app.js +2 -1
- package/dist/martyrs/src/modules/core/views/classes/core.app.js.map +1 -1
- package/dist/martyrs/src/modules/core/views/components/blocks/BlockSorting.vue.js +2 -2
- package/dist/martyrs/src/modules/core/views/components/blocks/BlockSorting.vue.js.map +1 -1
- package/dist/martyrs/src/modules/core/views/components/blocks/CardHeader.vue.js +10 -10
- package/dist/martyrs/src/modules/core/views/components/blocks/CardHeader.vue.js.map +1 -1
- package/dist/martyrs/src/modules/core/views/components/blocks/HelpCard.vue.js +2 -2
- package/dist/martyrs/src/modules/core/views/components/blocks/HelpCard.vue.js.map +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/PopupAuth.vue.js.map +1 -1
- package/dist/martyrs/src/modules/core/views/components/blocks/PopupDateSelector.vue.js +1 -1
- package/dist/martyrs/src/modules/core/views/components/elements/ButtonDate.vue.js +1 -1
- package/dist/martyrs/src/modules/core/views/components/elements/ButtonDate.vue.js.map +1 -1
- package/dist/martyrs/src/modules/core/views/components/elements/PhotoStack.vue.js +3 -3
- package/dist/martyrs/src/modules/core/views/components/layouts/App.vue.js +25 -5
- package/dist/martyrs/src/modules/core/views/components/layouts/App.vue.js.map +1 -1
- package/dist/martyrs/src/modules/core/views/components/layouts/Client.vue.js +4 -4
- package/dist/martyrs/src/modules/core/views/components/layouts/Client.vue.js.map +1 -1
- package/dist/martyrs/src/modules/core/views/components/partials/BottomNavigationBar.vue.js +11 -11
- package/dist/martyrs/src/modules/core/views/components/partials/BottomNavigationBar.vue.js.map +1 -1
- package/dist/martyrs/src/modules/core/views/components/partials/CitySelection.vue.js +1 -1
- package/dist/martyrs/src/modules/core/views/components/partials/CitySelection.vue.js.map +1 -1
- package/dist/martyrs/src/modules/core/views/components/partials/Footer.vue.js +16 -16
- package/dist/martyrs/src/modules/core/views/components/partials/Footer.vue.js.map +1 -1
- package/dist/martyrs/src/modules/core/views/components/partials/Header.vue.js +7 -7
- package/dist/martyrs/src/modules/core/views/components/partials/Header.vue.js.map +1 -1
- package/dist/martyrs/src/modules/core/views/components/partials/LocationSelection.vue.js +1 -1
- package/dist/martyrs/src/modules/core/views/components/partials/LocationSelection.vue.js.map +1 -1
- package/dist/martyrs/src/modules/core/views/components/partials/Navigation.vue.js +24 -24
- package/dist/martyrs/src/modules/core/views/components/partials/Navigation.vue.js.map +1 -1
- package/dist/martyrs/src/modules/core/views/components/partials/NavigationBar.vue.js +3 -3
- package/dist/martyrs/src/modules/core/views/components/partials/NavigationBar.vue.js.map +1 -1
- package/dist/martyrs/src/modules/core/views/components/partials/Sidebar.vue.js +7 -7
- package/dist/martyrs/src/modules/core/views/components/partials/Sidebar.vue.js.map +1 -1
- package/dist/martyrs/src/modules/core/views/components/sections/{Filters.vue.js → Filters.vue2.js} +2 -2
- package/dist/martyrs/src/modules/core/views/components/sections/Filters.vue2.js.map +1 -0
- package/dist/martyrs/src/modules/core/views/components/sections/SectionPageTitle.vue.js +2 -2
- package/dist/martyrs/src/modules/core/views/components/sections/SectionPageTitle.vue.js.map +1 -1
- package/dist/martyrs/src/modules/core/views/components/sections/Walkthrough.vue.js +1 -1
- package/dist/martyrs/src/modules/core/views/components/sections/filters/FilterCheckbox.vue2.js +2 -2
- package/dist/martyrs/src/modules/core/views/components/sections/filters/FilterCheckbox.vue2.js.map +1 -1
- package/dist/martyrs/src/modules/core/views/components/sections/filters/FilterDateRange.vue2.js +3 -3
- package/dist/martyrs/src/modules/core/views/components/sections/filters/FilterDateRange.vue2.js.map +1 -1
- package/dist/martyrs/src/modules/core/views/components/sections/filters/FilterRange.vue.js +2 -2
- package/dist/martyrs/src/modules/core/views/components/sections/filters/FilterRange.vue.js.map +1 -1
- package/dist/martyrs/src/modules/core/views/store/core.store.js +29 -47
- package/dist/martyrs/src/modules/core/views/store/core.store.js.map +1 -1
- package/dist/martyrs/src/modules/core/views/utils/vue-app-renderer.js +21 -2
- package/dist/martyrs/src/modules/core/views/utils/vue-app-renderer.js.map +1 -1
- package/dist/martyrs/src/modules/events/components/blocks/CardEvent.vue.js +5 -5
- package/dist/martyrs/src/modules/events/components/blocks/CardEvent.vue.js.map +1 -1
- package/dist/martyrs/src/modules/events/components/blocks/CardEventShort.vue.js +3 -3
- package/dist/martyrs/src/modules/events/components/blocks/CardEventShort.vue.js.map +1 -1
- package/dist/martyrs/src/modules/events/components/pages/EditEvent.vue.js +3 -3
- package/dist/martyrs/src/modules/events/components/pages/EditEvent.vue.js.map +1 -1
- package/dist/martyrs/src/modules/events/components/pages/EditEventTickets.vue.js +19 -19
- package/dist/martyrs/src/modules/events/components/pages/EditEventTickets.vue.js.map +1 -1
- package/dist/martyrs/src/modules/events/components/pages/Event.vue.js +8 -8
- package/dist/martyrs/src/modules/events/components/pages/Event.vue.js.map +1 -1
- package/dist/martyrs/src/modules/events/components/pages/Events.vue.js +2 -2
- package/dist/martyrs/src/modules/events/components/pages/Events.vue.js.map +1 -1
- package/dist/martyrs/src/modules/events/components/pages/EventsBackoffice.vue.js +2 -2
- package/dist/martyrs/src/modules/events/components/pages/EventsBackoffice.vue.js.map +1 -1
- package/dist/martyrs/src/modules/events/components/sections/EditTickets.vue.js +5 -5
- package/dist/martyrs/src/modules/events/components/sections/EditTickets.vue.js.map +1 -1
- package/dist/martyrs/src/modules/events/components/sections/EventsHot.vue.js +2 -2
- package/dist/martyrs/src/modules/events/components/sections/EventsHot.vue.js.map +1 -1
- package/dist/martyrs/src/modules/events/components/sections/Feed.vue.js +1 -1
- package/dist/martyrs/src/modules/events/components/sections/List.vue.js +2 -2
- package/dist/martyrs/src/modules/events/components/sections/List.vue.js.map +1 -1
- package/dist/martyrs/src/modules/events/components/sections/SelectDate.vue.js +1 -1
- package/dist/martyrs/src/modules/events/components/sections/SelectDate.vue.js.map +1 -1
- package/dist/martyrs/src/modules/gallery/components/pages/Gallery.vue.js +1 -1
- package/dist/martyrs/src/modules/gallery/components/pages/Gallery.vue.js.map +1 -1
- package/dist/martyrs/src/modules/gallery/components/sections/BackofficeGallery.vue.js +2 -2
- package/dist/martyrs/src/modules/gallery/components/sections/BackofficeGallery.vue.js.map +1 -1
- package/dist/martyrs/src/modules/icons/components/IconSearchPopup.vue.js +4 -4
- package/dist/martyrs/src/modules/icons/components/IconSearchPopup.vue.js.map +1 -1
- package/dist/martyrs/src/modules/icons/navigation/IconSort.vue.js +4 -4
- package/dist/martyrs/src/modules/icons/pages/IconsPage.vue.js +7 -7
- package/dist/martyrs/src/modules/icons/pages/IconsPage.vue.js.map +1 -1
- package/dist/martyrs/src/modules/inventory/components/forms/AdjustmentForm.vue.js +3 -3
- package/dist/martyrs/src/modules/inventory/components/forms/AdjustmentForm.vue.js.map +1 -1
- package/dist/martyrs/src/modules/inventory/components/forms/HistoryView.vue.js +2 -2
- package/dist/martyrs/src/modules/inventory/components/forms/HistoryView.vue.js.map +1 -1
- package/dist/martyrs/src/modules/inventory/components/forms/StockAlertsForm.vue.js +1 -1
- package/dist/martyrs/src/modules/inventory/components/forms/StockAlertsForm.vue.js.map +1 -1
- package/dist/martyrs/src/modules/inventory/components/pages/Inventory.vue.js +11 -11
- package/dist/martyrs/src/modules/inventory/components/pages/Inventory.vue.js.map +1 -1
- package/dist/martyrs/src/modules/inventory/components/pages/InventoryEdit.vue.js +6 -6
- package/dist/martyrs/src/modules/inventory/components/pages/InventoryEdit.vue.js.map +1 -1
- package/dist/martyrs/src/modules/landing/components/sections/SectionEarn.vue.js +5 -5
- package/dist/martyrs/src/modules/landing/components/sections/SectionEarn.vue.js.map +1 -1
- package/dist/martyrs/src/modules/landing/components/sections/SectionGuide.vue.js +2 -2
- package/dist/martyrs/src/modules/landing/components/sections/SectionGuide.vue.js.map +1 -1
- package/dist/martyrs/src/modules/landing/components/sections/SectionHeroToken.vue.js +1 -1
- package/dist/martyrs/src/modules/landing/components/sections/SectionHeroToken.vue.js.map +1 -1
- package/dist/martyrs/src/modules/landing/components/sections/SectionJoinUs.vue.js +2 -2
- package/dist/martyrs/src/modules/landing/components/sections/SectionJoinUs.vue.js.map +1 -1
- package/dist/martyrs/src/modules/landing/components/sections/SectionMobileApp.vue.js +3 -3
- package/dist/martyrs/src/modules/landing/components/sections/SectionMobileApp.vue.js.map +1 -1
- package/dist/martyrs/src/modules/landing/components/sections/SectionOverview.vue.js +2 -2
- package/dist/martyrs/src/modules/landing/components/sections/SectionOverview.vue.js.map +1 -1
- package/dist/martyrs/src/modules/landing/components/sections/SectionRoadmap.vue.js +3 -3
- package/dist/martyrs/src/modules/landing/components/sections/SectionRoadmap.vue.js.map +1 -1
- package/dist/martyrs/src/modules/marketplace/views/components/pages/Marketplace.vue.js +6 -6
- package/dist/martyrs/src/modules/marketplace/views/components/pages/Marketplace.vue.js.map +1 -1
- package/dist/martyrs/src/modules/marketplace/views/components/sections/SectionMenu.vue.js +4 -4
- package/dist/martyrs/src/modules/marketplace/views/components/sections/SectionMenu.vue.js.map +1 -1
- package/dist/martyrs/src/modules/music/components/blocks/ActionButtons.vue.js +3 -3
- package/dist/martyrs/src/modules/music/components/blocks/ActionButtons.vue.js.map +1 -1
- package/dist/martyrs/src/modules/music/components/cards/AlbumCard.vue.js +5 -5
- package/dist/martyrs/src/modules/music/components/cards/AlbumCard.vue.js.map +1 -1
- package/dist/martyrs/src/modules/music/components/cards/ArtistCard.vue.js +4 -4
- package/dist/martyrs/src/modules/music/components/cards/ArtistCard.vue.js.map +1 -1
- package/dist/martyrs/src/modules/music/components/cards/ArtistCardSmall.vue.js +3 -3
- package/dist/martyrs/src/modules/music/components/cards/ArtistCardSmall.vue.js.map +1 -1
- package/dist/martyrs/src/modules/music/components/cards/PlaylistCard.vue.js +5 -5
- package/dist/martyrs/src/modules/music/components/cards/PlaylistCard.vue.js.map +1 -1
- package/dist/martyrs/src/modules/music/components/cards/TrackListCard.vue.js +5 -5
- package/dist/martyrs/src/modules/music/components/cards/TrackListCard.vue.js.map +1 -1
- package/dist/martyrs/src/modules/music/components/forms/AlbumForm.vue.js +8 -8
- package/dist/martyrs/src/modules/music/components/forms/AlbumForm.vue.js.map +1 -1
- package/dist/martyrs/src/modules/music/components/forms/ArtistForm.vue.js +5 -5
- package/dist/martyrs/src/modules/music/components/forms/ArtistForm.vue.js.map +1 -1
- package/dist/martyrs/src/modules/music/components/forms/PlaylistForm.vue.js +7 -7
- package/dist/martyrs/src/modules/music/components/forms/PlaylistForm.vue.js.map +1 -1
- package/dist/martyrs/src/modules/music/components/forms/SearchForm.vue.js +2 -2
- package/dist/martyrs/src/modules/music/components/forms/SearchForm.vue.js.map +1 -1
- package/dist/martyrs/src/modules/music/components/forms/TrackForm.vue.js +13 -13
- package/dist/martyrs/src/modules/music/components/forms/TrackForm.vue.js.map +1 -1
- package/dist/martyrs/src/modules/music/components/pages/Album.vue.js +24 -24
- package/dist/martyrs/src/modules/music/components/pages/Album.vue.js.map +1 -1
- package/dist/martyrs/src/modules/music/components/pages/Artist.vue.js +8 -8
- package/dist/martyrs/src/modules/music/components/pages/Artist.vue.js.map +1 -1
- package/dist/martyrs/src/modules/music/components/pages/MusicHome.vue.js +10 -13
- package/dist/martyrs/src/modules/music/components/pages/MusicHome.vue.js.map +1 -1
- package/dist/martyrs/src/modules/music/components/pages/MusicLibrary.vue.js +9 -9
- package/dist/martyrs/src/modules/music/components/pages/MusicLibrary.vue.js.map +1 -1
- package/dist/martyrs/src/modules/music/components/pages/Playlist.vue.js +27 -27
- package/dist/martyrs/src/modules/music/components/pages/Playlist.vue.js.map +1 -1
- package/dist/martyrs/src/modules/music/components/pages/SearchResults.vue.js +17 -17
- package/dist/martyrs/src/modules/music/components/pages/SearchResults.vue.js.map +1 -1
- package/dist/martyrs/src/modules/music/components/pages/Track.vue.js +27 -27
- package/dist/martyrs/src/modules/music/components/pages/Track.vue.js.map +1 -1
- package/dist/martyrs/src/modules/music/components/pages/TrackCreate.vue.js +1 -1
- package/dist/martyrs/src/modules/music/components/player/FullscreenPlayer.vue.js +8 -8
- package/dist/martyrs/src/modules/music/components/player/FullscreenPlayer.vue.js.map +1 -1
- package/dist/martyrs/src/modules/music/music.client.js +6 -6
- package/dist/martyrs/src/modules/music/music.client.js.map +1 -1
- package/dist/martyrs/src/modules/notifications/components/blocks/NotificationItem.vue.js +2 -2
- package/dist/martyrs/src/modules/notifications/components/blocks/NotificationItem.vue.js.map +1 -1
- package/dist/martyrs/src/modules/notifications/components/elements/NotificationBadge.vue.js +1 -1
- package/dist/martyrs/src/modules/notifications/components/elements/NotificationBadge.vue.js.map +1 -1
- package/dist/martyrs/src/modules/notifications/notifications.client.js +2 -2
- package/dist/martyrs/src/modules/notifications/store/notifications.store.js +1 -1
- package/dist/martyrs/src/modules/orders/components/blocks/CardApplication.vue.js +2 -2
- package/dist/martyrs/src/modules/orders/components/blocks/CardCustomer.vue.js +2 -2
- package/dist/martyrs/src/modules/orders/components/blocks/CardOrder.vue.js +9 -9
- package/dist/martyrs/src/modules/orders/components/blocks/CardOrder.vue.js.map +1 -1
- package/dist/martyrs/src/modules/orders/components/blocks/CardOrderBackoffice.vue.js +5 -5
- package/dist/martyrs/src/modules/orders/components/blocks/CardOrderBackoffice.vue.js.map +1 -1
- package/dist/martyrs/src/modules/orders/components/blocks/CardOrderItem.vue.js +9 -9
- package/dist/martyrs/src/modules/orders/components/blocks/CardOrderItem.vue.js.map +1 -1
- package/dist/martyrs/src/modules/orders/components/blocks/CardOrderUser.vue.js +5 -5
- package/dist/martyrs/src/modules/orders/components/blocks/CardOrderUser.vue.js.map +1 -1
- package/dist/martyrs/src/modules/orders/components/blocks/StatusHistory.vue.js +2 -2
- package/dist/martyrs/src/modules/orders/components/blocks/StatusHistory.vue.js.map +1 -1
- package/dist/martyrs/src/modules/orders/components/elements/FieldSubscribeNewsletter.vue.js +1 -1
- package/dist/martyrs/src/modules/orders/components/elements/FieldSubscribeNewsletter.vue.js.map +1 -1
- package/dist/martyrs/src/modules/orders/components/elements/PriceTotal.vue.js +3 -3
- package/dist/martyrs/src/modules/orders/components/elements/PriceTotal.vue.js.map +1 -1
- package/dist/martyrs/src/modules/orders/components/forms/FormApplicationDetails.vue.js +2 -2
- package/dist/martyrs/src/modules/orders/components/forms/FormApplicationDetails.vue.js.map +1 -1
- package/dist/martyrs/src/modules/orders/components/forms/FormCustomerDetails.vue.js +3 -3
- package/dist/martyrs/src/modules/orders/components/forms/FormCustomerDetails.vue.js.map +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.js +17 -17
- package/dist/martyrs/src/modules/orders/components/pages/OrderBackoffice.vue.js.map +1 -1
- package/dist/martyrs/src/modules/orders/components/pages/OrderCreate.vue.js +2 -2
- package/dist/martyrs/src/modules/orders/components/pages/OrderCreate.vue.js.map +1 -1
- package/dist/martyrs/src/modules/orders/components/pages/OrderCreateBackoffice.vue.js +4 -4
- package/dist/martyrs/src/modules/orders/components/pages/OrderCreateBackoffice.vue.js.map +1 -1
- package/dist/martyrs/src/modules/orders/components/partials/ShopCart.vue.js +2 -2
- package/dist/martyrs/src/modules/orders/components/partials/ShopCart.vue.js.map +1 -1
- package/dist/martyrs/src/modules/orders/components/sections/ApplicationDetails.vue.js +3 -3
- package/dist/martyrs/src/modules/orders/components/sections/ApplicationDetails.vue.js.map +1 -1
- package/dist/martyrs/src/modules/orders/components/sections/AskToLogin.vue.js +1 -1
- package/dist/martyrs/src/modules/orders/components/sections/AskToLogin.vue.js.map +1 -1
- package/dist/martyrs/src/modules/orders/components/sections/CustomerDetails.vue.js +3 -3
- package/dist/martyrs/src/modules/orders/components/sections/CustomerDetails.vue.js.map +1 -1
- package/dist/martyrs/src/modules/orders/components/sections/FormDelivery.vue.js +3 -3
- package/dist/martyrs/src/modules/orders/components/sections/Succes.vue.js +3 -3
- package/dist/martyrs/src/modules/orders/store/shopcart.js +1 -1
- package/dist/martyrs/src/modules/organizations/components/blocks/CardDepartment.vue.js +2 -2
- package/dist/martyrs/src/modules/organizations/components/blocks/CardOrganization.vue.js +3 -3
- package/dist/martyrs/src/modules/organizations/components/blocks/CardOrganization.vue.js.map +1 -1
- package/dist/martyrs/src/modules/organizations/components/blocks/Contacts.vue.js +8 -8
- package/dist/martyrs/src/modules/organizations/components/blocks/Contacts.vue.js.map +1 -1
- package/dist/martyrs/src/modules/organizations/components/blocks/Rating.vue.js +1 -1
- package/dist/martyrs/src/modules/organizations/components/forms/AddExistingMembersForm.vue.js +3 -3
- package/dist/martyrs/src/modules/organizations/components/forms/AddExistingMembersForm.vue.js.map +1 -1
- package/dist/martyrs/src/modules/organizations/components/forms/DepartmentForm.vue.js +1 -1
- package/dist/martyrs/src/modules/organizations/components/forms/DepartmentForm.vue.js.map +1 -1
- package/dist/martyrs/src/modules/organizations/components/forms/InviteForm.vue.js +1 -1
- package/dist/martyrs/src/modules/organizations/components/forms/InviteForm.vue.js.map +1 -1
- package/dist/martyrs/src/modules/organizations/components/pages/Department.vue.js +2 -2
- package/dist/martyrs/src/modules/organizations/components/pages/Department.vue.js.map +1 -1
- package/dist/martyrs/src/modules/organizations/components/pages/Members.vue.js +1 -1
- package/dist/martyrs/src/modules/organizations/components/pages/Members.vue.js.map +1 -1
- package/dist/martyrs/src/modules/organizations/components/pages/Organization.vue.js +7 -7
- package/dist/martyrs/src/modules/organizations/components/pages/Organization.vue.js.map +1 -1
- package/dist/martyrs/src/modules/organizations/components/pages/OrganizationBackoffice.vue.js +1 -1
- package/dist/martyrs/src/modules/organizations/components/pages/Organizations.vue.js +2 -2
- package/dist/martyrs/src/modules/organizations/components/pages/Organizations.vue.js.map +1 -1
- package/dist/martyrs/src/modules/organizations/components/sections/Documents.vue.js +4 -4
- package/dist/martyrs/src/modules/organizations/components/sections/Documents.vue.js.map +1 -1
- package/dist/martyrs/src/modules/organizations/components/sections/MembersAdd.vue.js +1 -1
- package/dist/martyrs/src/modules/organizations/components/sections/MembersAdd.vue.js.map +1 -1
- 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 +3 -3
- package/dist/martyrs/src/modules/pages/views/components/blocks/CardPage.vue.js.map +1 -1
- package/dist/martyrs/src/modules/pages/views/components/pages/Page.vue.js +5 -5
- package/dist/martyrs/src/modules/pages/views/components/pages/Page.vue.js.map +1 -1
- package/dist/martyrs/src/modules/pages/views/components/pages/PageEdit.vue.js +1 -1
- package/dist/martyrs/src/modules/products/components/blocks/CardCategory.vue.js +1 -1
- package/dist/martyrs/src/modules/products/components/blocks/CardCategory.vue.js.map +1 -1
- package/dist/martyrs/src/modules/products/components/blocks/CardPosition.vue.js +4 -4
- package/dist/martyrs/src/modules/products/components/blocks/CardPosition.vue.js.map +1 -1
- package/dist/martyrs/src/modules/products/components/blocks/CardProduct.vue.js +3 -3
- package/dist/martyrs/src/modules/products/components/blocks/CardProduct.vue.js.map +1 -1
- package/dist/martyrs/src/modules/products/components/blocks/ProductDiscounts.vue.js +5 -5
- package/dist/martyrs/src/modules/products/components/blocks/ProductDiscounts.vue.js.map +1 -1
- package/dist/martyrs/src/modules/products/components/blocks/ProductImages.vue.js +3 -3
- package/dist/martyrs/src/modules/products/components/blocks/ProductImages.vue.js.map +1 -1
- package/dist/martyrs/src/modules/products/components/blocks/ProductVariants.vue.js +2 -2
- package/dist/martyrs/src/modules/products/components/blocks/ProductVariants.vue.js.map +1 -1
- package/dist/martyrs/src/modules/products/components/elements/Image360.vue.js +5 -5
- package/dist/martyrs/src/modules/products/components/elements/Image360.vue.js.map +1 -1
- package/dist/martyrs/src/modules/products/components/elements/Price.vue.js +2 -2
- package/dist/martyrs/src/modules/products/components/elements/Price.vue.js.map +1 -1
- package/dist/martyrs/src/modules/products/components/elements/QuantitySelector.vue.js +3 -3
- package/dist/martyrs/src/modules/products/components/elements/QuantitySelector.vue.js.map +1 -1
- package/dist/martyrs/src/modules/products/components/elements/THC.vue.js +1 -1
- package/dist/martyrs/src/modules/products/components/pages/Categories.vue.js +2 -2
- package/dist/martyrs/src/modules/products/components/pages/Categories.vue.js.map +1 -1
- package/dist/martyrs/src/modules/products/components/pages/CategoryEdit.vue.js +4 -4
- 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 +7 -7
- package/dist/martyrs/src/modules/products/components/pages/Product.vue.js.map +1 -1
- package/dist/martyrs/src/modules/products/components/pages/ProductEdit.vue.js +7 -7
- package/dist/martyrs/src/modules/products/components/pages/ProductEdit.vue.js.map +1 -1
- package/dist/martyrs/src/modules/products/components/pages/Products.vue.js +12 -12
- package/dist/martyrs/src/modules/products/components/pages/Products.vue.js.map +1 -1
- package/dist/martyrs/src/modules/products/components/sections/EditAttributes.vue.js +4 -4
- package/dist/martyrs/src/modules/products/components/sections/EditAttributes.vue.js.map +1 -1
- package/dist/martyrs/src/modules/products/components/sections/EditDiscounts.vue.js +6 -6
- package/dist/martyrs/src/modules/products/components/sections/EditDiscounts.vue.js.map +1 -1
- package/dist/martyrs/src/modules/products/components/sections/EditRecommended.vue.js +1 -1
- package/dist/martyrs/src/modules/products/components/sections/EditRecommended.vue.js.map +1 -1
- package/dist/martyrs/src/modules/products/components/sections/EditVariants.vue.js +9 -9
- package/dist/martyrs/src/modules/products/components/sections/EditVariants.vue.js.map +1 -1
- package/dist/martyrs/src/modules/products/components/sections/FilterProducts.vue.js +3 -3
- package/dist/martyrs/src/modules/products/components/sections/FilterProducts.vue.js.map +1 -1
- package/dist/martyrs/src/modules/products/components/sections/ProductConfigurator.vue.js +2 -2
- package/dist/martyrs/src/modules/products/components/sections/ProductConfigurator.vue.js.map +1 -1
- package/dist/martyrs/src/modules/products/components/sections/ProductsRecommended.vue.js +2 -2
- package/dist/martyrs/src/modules/products/components/sections/ProductsRecommended.vue.js.map +1 -1
- package/dist/martyrs/src/modules/products/components/sections/SectionProduct.vue.js +6 -6
- package/dist/martyrs/src/modules/products/components/sections/SectionProduct.vue.js.map +1 -1
- package/dist/martyrs/src/modules/rents/views/components/blocks/CardRent.vue.js +1 -1
- package/dist/martyrs/src/modules/rents/views/components/blocks/CardRent.vue.js.map +1 -1
- package/dist/martyrs/src/modules/rents/views/components/pages/Gant/DateLabel.vue.js +1 -1
- package/dist/martyrs/src/modules/rents/views/components/pages/Gant/GanttBar.vue.js +2 -2
- package/dist/martyrs/src/modules/rents/views/components/pages/Gant/GanttBar.vue.js.map +1 -1
- package/dist/martyrs/src/modules/rents/views/components/pages/Gant/GanttChart.vue.js +8 -8
- package/dist/martyrs/src/modules/rents/views/components/pages/Gant/GanttChart.vue.js.map +1 -1
- package/dist/martyrs/src/modules/rents/views/components/pages/Gant/GanttHeaderCell.vue.js +1 -1
- package/dist/martyrs/src/modules/rents/views/components/pages/Gant/GanttHeaderCell.vue.js.map +1 -1
- package/dist/martyrs/src/modules/rents/views/components/pages/Gant/GanttToolbar.vue.js +1 -1
- package/dist/martyrs/src/modules/rents/views/components/pages/Rents.vue.js +1 -1
- package/dist/martyrs/src/modules/rents/views/components/pages/Rents.vue.js.map +1 -1
- package/dist/martyrs/src/modules/rents/views/components/pages/RentsEdit.vue.js +6 -6
- package/dist/martyrs/src/modules/rents/views/components/pages/RentsEdit.vue.js.map +1 -1
- package/dist/martyrs/src/modules/reports/components/pages/BackofficeReports.vue.js +3 -3
- package/dist/martyrs/src/modules/reports/components/pages/BackofficeReports.vue.js.map +1 -1
- package/dist/martyrs/src/modules/reports/components/sections/FormReport.vue.js +1 -1
- package/dist/martyrs/src/modules/reports/components/sections/FormReport.vue.js.map +1 -1
- package/dist/martyrs/src/modules/spots/components/blocks/CardSpot.vue.js +5 -5
- package/dist/martyrs/src/modules/spots/components/blocks/CardSpot.vue.js.map +1 -1
- package/dist/martyrs/src/modules/spots/components/blocks/SpotMemberModify.vue.js +2 -2
- package/dist/martyrs/src/modules/spots/components/blocks/SpotMemberModify.vue.js.map +1 -1
- package/dist/martyrs/src/modules/spots/components/layouts/Spots.vue.js +3 -3
- package/dist/martyrs/src/modules/spots/components/layouts/Spots.vue.js.map +1 -1
- package/dist/martyrs/src/modules/spots/components/pages/Spot.vue.js +6 -6
- package/dist/martyrs/src/modules/spots/components/pages/Spot.vue.js.map +1 -1
- package/dist/martyrs/src/modules/spots/components/pages/SpotEdit.vue.js +2 -2
- package/dist/martyrs/src/modules/spots/components/pages/SpotEdit.vue.js.map +1 -1
- package/dist/martyrs/src/modules/spots/components/pages/Spots.vue.js +3 -3
- package/dist/martyrs/src/modules/spots/components/pages/Spots.vue.js.map +1 -1
- package/dist/martyrs/src/modules/spots/components/sections/WorktimeEdit.vue.js +5 -5
- package/dist/martyrs/src/modules/spots/components/sections/WorktimeEdit.vue.js.map +1 -1
- package/dist/martyrs/src/modules/wallet/views/components/blocks/CardBalanceReplenished.vue.js +5 -5
- package/dist/martyrs/src/modules/wallet/views/components/blocks/CardBalanceReplenished.vue.js.map +1 -1
- package/dist/martyrs/src/modules/wallet/views/components/blocks/CardDeposit.vue.js +5 -5
- package/dist/martyrs/src/modules/wallet/views/components/blocks/CardDeposit.vue.js.map +1 -1
- package/dist/martyrs/src/modules/wallet/views/components/blocks/CashDeposit.vue.js +2 -2
- package/dist/martyrs/src/modules/wallet/views/components/blocks/CashDeposit.vue.js.map +1 -1
- package/dist/martyrs/src/modules/wallet/views/components/blocks/CryptoDeposit.vue.js +4 -4
- package/dist/martyrs/src/modules/wallet/views/components/blocks/CryptoDeposit.vue.js.map +1 -1
- package/dist/martyrs/src/modules/wallet/views/components/blocks/CryptoDepositProcessing.vue.js +12 -12
- package/dist/martyrs/src/modules/wallet/views/components/blocks/CryptoDepositProcessing.vue.js.map +1 -1
- package/dist/martyrs/src/modules/wallet/views/components/elements/ConnectMetamask.vue.js +4 -4
- package/dist/martyrs/src/modules/wallet/views/components/elements/ConnectMetamask.vue.js.map +1 -1
- package/dist/martyrs/src/modules/wallet/views/components/pages/Wallet.vue.js +24 -24
- package/dist/martyrs/src/modules/wallet/views/components/pages/Wallet.vue.js.map +1 -1
- package/dist/martyrs.css +1 -1
- package/dist/martyrs.es.js +1 -1
- 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/style.css +194 -202
- package/dist/{web-CH5wzMHy.js → web-BqTV9va1.js} +1 -1
- package/package.json +6 -8
- package/src/builder/modes/ssr.prod.js +1 -0
- package/src/builder/modes/ssr.rspack.dev.js +13 -6
- package/src/builder/rspack/rspack.config.base.js +7 -0
- package/src/builder/rspack/rspack.config.ssr.client.js +19 -44
- package/src/builder/templates/page.js +21 -0
- package/src/components/Block/Block.vue +1 -1
- package/src/components/BottomSheet/BottomSheet.vue +1 -1
- package/src/components/Calendar/Calendar.vue +5 -5
- package/src/components/Checkbox/Checkbox.vue +2 -2
- package/src/components/Chips/Chips.vue +2 -2
- package/src/components/Completion/Completion.vue +2 -2
- package/src/components/Countdown/Countdown.vue +5 -5
- package/src/components/DatePicker/DatePicker.vue +4 -4
- package/src/components/EditImages/EditImages.vue +1 -1
- package/src/components/Feed/Feed.old.vue +1 -1
- package/src/components/Feed/Feed.vue +1 -1
- package/src/components/FieldBig/FieldBig.vue +2 -2
- package/src/components/FieldPhone/FieldPhone.vue +1 -1
- package/src/components/FieldTags/BlockTags.vue +1 -1
- package/src/components/Loader/Loader.vue +1 -1
- package/src/components/Menu/MenuItem.vue +2 -2
- package/src/components/PhotoViewer/PhotoViewer.vue +1 -1
- package/src/components/Radio/Radio.vue +1 -1
- package/src/components/Select/Select.vue +1 -1
- package/src/components/Table/Table.vue +2 -2
- package/src/components/Text/Text.vue +1 -1
- package/src/components/UploadImage/UploadImage.vue +2 -2
- package/src/components/UploadImageMultiple/UploadImageMultiple.vue +3 -3
- package/src/configurator/components/layouts/layoutConfigurator.vue +1 -1
- package/src/configurator/components/pages/Styles.vue +2 -2
- package/src/jit/.claude/settings.local.json +10 -0
- package/src/jit/CLAUDE.md +387 -0
- package/src/jit/core.js +274 -0
- package/src/jit/extractor.js +140 -0
- package/src/jit/index.js +19 -0
- package/src/jit/loader.js +46 -0
- package/src/jit/plugin.js +209 -0
- package/src/jit/rules.js +474 -0
- package/src/jit/variants.js +128 -0
- package/src/modules/auth/views/components/blocks/CardUser.vue +2 -2
- package/src/modules/auth/views/components/blocks/ProfileCard.vue +4 -4
- package/src/modules/auth/views/components/layouts/Auth.vue +1 -1
- package/src/modules/auth/views/components/pages/EnterPassword.vue +2 -2
- package/src/modules/auth/views/components/pages/Profile.vue +5 -5
- package/src/modules/auth/views/components/pages/ProfileBlogposts.vue +1 -1
- package/src/modules/auth/views/components/pages/ProfileEditAccount.vue +2 -2
- package/src/modules/auth/views/components/pages/ResetPassword.vue +1 -1
- package/src/modules/auth/views/components/pages/SignIn.vue +3 -3
- package/src/modules/auth/views/components/pages/SignUp.vue +1 -1
- package/src/modules/auth/views/components/pages/UserDashboard.vue +3 -3
- package/src/modules/auth/views/components/sections/FeaturedUsers.vue +1 -1
- package/src/modules/auth/views/components/sections/ProfileCompletion.vue +2 -2
- package/src/modules/auth/views/components/sections/ProfileEditCredentials.vue +7 -7
- package/src/modules/auth/views/components/sections/SliderFeatures.vue +1 -1
- package/src/modules/backoffice/components/admin/Backcalls.vue +1 -1
- package/src/modules/backoffice/components/admin/FastOrders.vue +1 -1
- package/src/modules/backoffice/components/admin/ProductEdit.vue +2 -2
- package/src/modules/backoffice/components/admin/UserEdit.vue +1 -1
- package/src/modules/backoffice/components/admin/Users.vue +2 -2
- package/src/modules/backoffice/components/pages/Dashboard.vue +4 -4
- package/src/modules/backoffice/components/partials/Sidebar.vue +5 -5
- package/src/modules/chats/components/blocks/ChatMessage.vue +1 -1
- package/src/modules/chats/components/sections/ChatWindow.vue +2 -2
- package/src/modules/community/components/blocks/Activity.vue +7 -7
- package/src/modules/community/components/blocks/CardBlogpost.vue +1 -1
- package/src/modules/community/components/blocks/FooterBlogpost.vue +4 -4
- package/src/modules/community/components/layouts/Community.vue +10 -10
- package/src/modules/community/components/pages/CreateBlogPost.vue +1 -1
- package/src/modules/community/components/pages/Posts.vue +2 -2
- package/src/modules/community/components/sections/Comment.vue +2 -2
- package/src/modules/constructor/components/elements/Audio.vue +1 -1
- package/src/modules/constructor/components/elements/Caption.vue +1 -1
- package/src/modules/constructor/components/elements/Embed.vue +1 -1
- package/src/modules/constructor/components/elements/Textarea.vue +1 -1
- package/src/modules/constructor/components/elements/Video.vue +1 -1
- package/src/modules/core/views/classes/core.app.js +2 -1
- package/src/modules/core/views/components/blocks/BlockSorting.vue +2 -2
- package/src/modules/core/views/components/blocks/CardFooter.vue +4 -4
- package/src/modules/core/views/components/blocks/CardHeader.vue +7 -7
- package/src/modules/core/views/components/blocks/HelpCard.vue +1 -1
- package/src/modules/core/views/components/blocks/PopupAuth.vue +1 -1
- package/src/modules/core/views/components/elements/ButtonDate.vue +1 -1
- package/src/modules/core/views/components/elements/PhotoStack.vue +3 -3
- package/src/modules/core/views/components/layouts/App.vue +28 -4
- package/src/modules/core/views/components/layouts/Client.vue +4 -4
- package/src/modules/core/views/components/partials/BottomNavigationBar.vue +15 -15
- package/src/modules/core/views/components/partials/CitySelection.vue +1 -1
- package/src/modules/core/views/components/partials/Footer.centered.vue +17 -17
- package/src/modules/core/views/components/partials/Footer.vue +18 -18
- package/src/modules/core/views/components/partials/Header.vue +10 -11
- package/src/modules/core/views/components/partials/LocationSelection.vue +1 -1
- package/src/modules/core/views/components/partials/Navigation.vue +20 -19
- package/src/modules/core/views/components/partials/NavigationBar.vue +3 -3
- package/src/modules/core/views/components/partials/Sidebar.vue +6 -6
- package/src/modules/core/views/components/sections/SectionPageTitle.vue +2 -2
- package/src/modules/core/views/components/sections/filters/FilterCheckbox.vue +1 -1
- package/src/modules/core/views/components/sections/filters/FilterDateRange.vue +2 -2
- package/src/modules/core/views/components/sections/filters/FilterPrice.vue +2 -2
- package/src/modules/core/views/components/sections/filters/FilterRange.vue +2 -2
- package/src/modules/core/views/store/core.store.js +36 -60
- package/src/modules/core/views/utils/vue-app-renderer.js +31 -1
- package/src/modules/events/components/blocks/CardEvent.vue +6 -6
- package/src/modules/events/components/blocks/CardEventShort.vue +3 -3
- package/src/modules/events/components/pages/EditEvent.vue +1 -1
- package/src/modules/events/components/pages/EditEventTickets.vue +18 -18
- package/src/modules/events/components/pages/Event.vue +5 -5
- package/src/modules/events/components/pages/Events.vue +2 -2
- package/src/modules/events/components/pages/EventsBackoffice.vue +2 -2
- package/src/modules/events/components/sections/EditTickets.vue +5 -5
- package/src/modules/events/components/sections/EventsHot.vue +2 -2
- package/src/modules/events/components/sections/List.vue +1 -1
- package/src/modules/events/components/sections/SelectDate.vue +1 -1
- package/src/modules/gallery/components/pages/Gallery.vue +1 -1
- package/src/modules/gallery/components/sections/BackofficeGallery.vue +1 -1
- package/src/modules/governance/reactcode/src/components/CreateInitiativeForm.tsx +14 -14
- package/src/modules/governance/reactcode/src/components/CreateMilestoneForm.tsx +13 -13
- package/src/modules/governance/reactcode/src/components/EmptyState.tsx +2 -2
- package/src/modules/governance/reactcode/src/components/InitiativeCard.tsx +1 -1
- package/src/modules/governance/reactcode/src/components/LinkedEntityCard.tsx +1 -1
- package/src/modules/governance/reactcode/src/components/MilestoneCard.tsx +2 -2
- package/src/modules/governance/reactcode/src/components/ProductRepositories.tsx +6 -6
- package/src/modules/governance/reactcode/src/components/ProductSummary.tsx +18 -18
- package/src/modules/governance/reactcode/src/components/ProductTeam.tsx +7 -7
- package/src/modules/governance/reactcode/src/components/ProposeTaskForm.tsx +9 -9
- package/src/modules/governance/reactcode/src/components/TaskAssignForm.tsx +4 -4
- package/src/modules/governance/reactcode/src/components/TaskCard.tsx +1 -1
- package/src/modules/governance/reactcode/src/components/TaskStatusBadge.tsx +1 -1
- package/src/modules/governance/reactcode/src/components/VoteForm.tsx +6 -6
- package/src/modules/governance/reactcode/src/components/VotingCard.tsx +2 -2
- package/src/modules/governance/reactcode/src/components/VotingResults.tsx +15 -15
- package/src/modules/governance/reactcode/src/pages/InitiativeDetailPage.tsx +41 -41
- package/src/modules/governance/reactcode/src/pages/InitiativeMilestonesPage.tsx +8 -8
- package/src/modules/governance/reactcode/src/pages/InitiativesListPage.tsx +6 -6
- package/src/modules/governance/reactcode/src/pages/MilestoneDetailPage.tsx +9 -9
- package/src/modules/governance/reactcode/src/pages/RoadmapPage.tsx +14 -14
- package/src/modules/governance/reactcode/src/pages/TaskDetailPage.tsx +44 -44
- package/src/modules/governance/reactcode/src/pages/VotingDetailPage.tsx +8 -8
- package/src/modules/governance/reactcode/src/pages/VotingsListPage.tsx +3 -3
- package/src/modules/governance/reactcode-2/App.tsx +28 -0
- package/src/modules/governance/reactcode-2/README.md +20 -0
- package/src/modules/governance/reactcode-2/components/Charts.tsx +58 -0
- package/src/modules/governance/reactcode-2/components/Layout.tsx +457 -0
- package/src/modules/governance/reactcode-2/components/TaskPage.tsx +325 -0
- package/src/modules/governance/reactcode-2/components/VoteBadge.tsx +27 -0
- package/src/modules/governance/reactcode-2/components/VotingsFeedPage.tsx +328 -0
- package/src/modules/governance/reactcode-2/constants.ts +154 -0
- package/src/modules/governance/reactcode-2/index.html +70 -0
- package/src/modules/governance/reactcode-2/index.tsx +15 -0
- package/src/modules/governance/reactcode-2/metadata.json +5 -0
- package/src/modules/governance/reactcode-2/package.json +23 -0
- package/src/modules/governance/reactcode-2/pnpm-lock.yaml +1410 -0
- package/src/modules/governance/reactcode-2/tsconfig.json +29 -0
- package/src/modules/governance/reactcode-2/types.ts +48 -0
- package/src/modules/governance/reactcode-2/vite.config.ts +23 -0
- package/src/modules/governance/views/components/blocks/CardInitiativeItem.vue +10 -10
- package/src/modules/governance/views/components/blocks/CardMilestoneItem.vue +15 -15
- package/src/modules/governance/views/components/blocks/CardTaskItem.vue +9 -9
- package/src/modules/governance/views/components/blocks/CardVotingItem.vue +11 -11
- package/src/modules/governance/views/components/layouts/Governance.vue +1 -1
- package/src/modules/governance/views/components/pages/Governance.vue +3 -3
- package/src/modules/governance/views/components/pages/Initiative.vue +112 -112
- package/src/modules/governance/views/components/pages/InitiativeMilestones.vue +31 -31
- package/src/modules/governance/views/components/pages/Initiatives.vue +20 -22
- package/src/modules/governance/views/components/pages/Milestone.vue +25 -25
- package/src/modules/governance/views/components/pages/Roadmap.vue +47 -47
- package/src/modules/governance/views/components/pages/Task.vue +106 -106
- package/src/modules/governance/views/components/pages/Tasks.vue +16 -16
- package/src/modules/governance/views/components/pages/Voting.vue +23 -23
- package/src/modules/governance/views/components/pages/Votings.vue +7 -7
- package/src/modules/governance/views/components/partials/EmptyState.vue +3 -3
- package/src/modules/governance/views/components/partials/LinkedEntityCard.vue +11 -11
- package/src/modules/governance/views/components/partials/TaskStatusBadge.vue +4 -4
- package/src/modules/governance/views/components/partials/VoteForm.vue +14 -14
- package/src/modules/governance/views/components/partials/VotingResults.vue +22 -22
- package/src/modules/icons/components/IconSearchPopup.vue +3 -3
- package/src/modules/icons/entities/IconCash.vue +23 -0
- package/src/modules/icons/navigation/IconSort.vue +4 -4
- package/src/modules/icons/pages/IconsPage.vue +7 -7
- package/src/modules/inventory/components/forms/AdjustmentForm.vue +3 -3
- package/src/modules/inventory/components/forms/HistoryView.vue +1 -1
- package/src/modules/inventory/components/forms/StockAlertsForm.vue +1 -1
- package/src/modules/inventory/components/pages/Inventory.vue +10 -10
- package/src/modules/inventory/components/pages/InventoryEdit.vue +6 -6
- package/src/modules/landing/components/blocks/MapBlock.vue +2 -2
- package/src/modules/landing/components/sections/Examples.vue +1 -1
- package/src/modules/landing/components/sections/InstagramSection.vue +1 -1
- package/src/modules/landing/components/sections/SectionEarn.vue +4 -4
- package/src/modules/landing/components/sections/SectionFeature.vue +1 -1
- package/src/modules/landing/components/sections/SectionFocus.vue +2 -2
- package/src/modules/landing/components/sections/SectionGuide.vue +2 -2
- package/src/modules/landing/components/sections/SectionHeroToken.vue +1 -1
- package/src/modules/landing/components/sections/SectionHeroVideo.vue +2 -2
- package/src/modules/landing/components/sections/SectionJoinUs.vue +2 -2
- package/src/modules/landing/components/sections/SectionMobileApp.vue +3 -3
- package/src/modules/landing/components/sections/SectionOverview.vue +2 -2
- package/src/modules/landing/components/sections/SectionRoadmap.vue +2 -2
- package/src/modules/marketplace/views/components/layouts/Marketplace.vue +8 -8
- package/src/modules/marketplace/views/components/pages/Marketplace.vue +5 -5
- package/src/modules/marketplace/views/components/sections/SectionMenu.vue +2 -2
- package/src/modules/music/components/SidebarMusic.vue +11 -11
- package/src/modules/music/components/blocks/ActionButtons.vue +2 -2
- package/src/modules/music/components/cards/AlbumCard.vue +4 -4
- package/src/modules/music/components/cards/ArtistCard.vue +3 -8
- package/src/modules/music/components/cards/ArtistCardSmall.vue +2 -2
- package/src/modules/music/components/cards/PlaylistCard.vue +4 -4
- package/src/modules/music/components/cards/TrackListCard.vue +5 -5
- package/src/modules/music/components/forms/AlbumForm.vue +8 -8
- package/src/modules/music/components/forms/ArtistForm.vue +4 -4
- package/src/modules/music/components/forms/PlaylistForm.vue +7 -7
- package/src/modules/music/components/forms/SearchForm.vue +1 -1
- package/src/modules/music/components/forms/TrackForm.vue +13 -13
- package/src/modules/music/components/pages/Album.vue +22 -22
- package/src/modules/music/components/pages/Artist.vue +7 -7
- package/src/modules/music/components/pages/MusicHome.vue +13 -18
- package/src/modules/music/components/pages/MusicLibrary.vue +9 -9
- package/src/modules/music/components/pages/Playlist.vue +25 -25
- package/src/modules/music/components/pages/SearchResults.vue +15 -15
- package/src/modules/music/components/pages/Track.vue +25 -25
- package/src/modules/music/components/player/FullscreenPlayer.vue +5 -5
- package/src/modules/notifications/components/blocks/NotificationItem.vue +1 -1
- package/src/modules/notifications/components/elements/NotificationBadge.vue +1 -1
- package/src/modules/orders/components/blocks/CardApplication.vue +1 -1
- package/src/modules/orders/components/blocks/CardCustomer.vue +1 -1
- package/src/modules/orders/components/blocks/CardOrder.vue +9 -9
- package/src/modules/orders/components/blocks/CardOrderBackoffice.vue +5 -5
- package/src/modules/orders/components/blocks/CardOrderItem.vue +9 -9
- package/src/modules/orders/components/blocks/CardOrderUser.vue +3 -3
- package/src/modules/orders/components/blocks/CardOrderVar1.vue +4 -4
- package/src/modules/orders/components/blocks/StatusHistory.vue +3 -3
- package/src/modules/orders/components/elements/FieldSubscribeNewsletter.vue +1 -1
- package/src/modules/orders/components/elements/PriceTotal.vue +3 -3
- package/src/modules/orders/components/forms/FormApplicationDetails.vue +2 -2
- package/src/modules/orders/components/forms/FormCustomerDetails.vue +3 -3
- package/src/modules/orders/components/pages/Favorites.vue +1 -1
- package/src/modules/orders/components/pages/OrderBackoffice.vue +15 -15
- package/src/modules/orders/components/pages/OrderCreate.vue +2 -2
- package/src/modules/orders/components/pages/OrderCreateBackoffice.vue +4 -4
- package/src/modules/orders/components/pages/Orders_refact.vue +3 -3
- package/src/modules/orders/components/partials/ShopCart.vue +2 -2
- package/src/modules/orders/components/sections/ApplicationDetails.vue +2 -2
- package/src/modules/orders/components/sections/AskToLogin.vue +1 -1
- package/src/modules/orders/components/sections/CustomerDetails.vue +2 -2
- package/src/modules/orders/components/sections/Succes.vue +4 -4
- package/src/modules/organizations/components/blocks/CardDepartment.vue +1 -1
- package/src/modules/organizations/components/blocks/CardOrganization.vue +4 -4
- package/src/modules/organizations/components/blocks/Contacts.vue +8 -8
- package/src/modules/organizations/components/blocks/Rating.vue +1 -1
- package/src/modules/organizations/components/forms/AddExistingMembersForm.vue +3 -3
- package/src/modules/organizations/components/forms/DepartmentForm.vue +1 -1
- package/src/modules/organizations/components/forms/InviteForm.vue +1 -1
- package/src/modules/organizations/components/pages/Department.vue +2 -2
- package/src/modules/organizations/components/pages/DepartmentEdit.vue +1 -1
- package/src/modules/organizations/components/pages/Members.vue +1 -1
- package/src/modules/organizations/components/pages/Organization.new.vue +8 -8
- package/src/modules/organizations/components/pages/Organization.vue +6 -6
- package/src/modules/organizations/components/pages/OrganizationDocuments.vue +2 -2
- package/src/modules/organizations/components/pages/Organizations.vue +3 -3
- package/src/modules/organizations/components/sections/Documents.vue +2 -2
- package/src/modules/organizations/components/sections/MembersAdd.vue +1 -1
- package/src/modules/organizations/components/sections/Unit.vue +1 -1
- package/src/modules/pages/views/components/blocks/CardPage.vue +2 -2
- package/src/modules/pages/views/components/pages/Page.vue +5 -5
- package/src/modules/products/components/blocks/CardCategory.vue +1 -1
- package/src/modules/products/components/blocks/CardPosition.vue +4 -4
- package/src/modules/products/components/blocks/CardProduct.vue +3 -3
- package/src/modules/products/components/blocks/ProductDiscounts.vue +3 -3
- package/src/modules/products/components/blocks/ProductImages.vue +2 -2
- package/src/modules/products/components/blocks/ProductVariants.vue +2 -2
- package/src/modules/products/components/elements/Image360.vue +2 -2
- package/src/modules/products/components/elements/Price.vue +2 -2
- package/src/modules/products/components/elements/QuantitySelector.vue +3 -3
- package/src/modules/products/components/elements/THC.vue +1 -1
- package/src/modules/products/components/forms/ReorderSettingsForm.vue +1 -1
- package/src/modules/products/components/forms/StockAuditForm.vue +2 -2
- package/src/modules/products/components/forms/StockHistoryView.vue +1 -1
- package/src/modules/products/components/pages/Categories.vue +1 -1
- package/src/modules/products/components/pages/CategoryEdit.vue +2 -2
- package/src/modules/products/components/pages/Product.vue +6 -6
- package/src/modules/products/components/pages/ProductEdit.vue +6 -6
- package/src/modules/products/components/pages/Products.vue +11 -11
- package/src/modules/products/components/sections/EditAttributes.vue +4 -4
- package/src/modules/products/components/sections/EditCategories.vue +1 -1
- package/src/modules/products/components/sections/EditDiscounts.vue +6 -6
- package/src/modules/products/components/sections/EditRecommended.vue +1 -1
- package/src/modules/products/components/sections/EditVariants.vue +8 -8
- package/src/modules/products/components/sections/FilterProducts.vue +3 -3
- package/src/modules/products/components/sections/ProductConfigurator.vue +2 -2
- package/src/modules/products/components/sections/ProductInformationSection.vue +10 -10
- package/src/modules/products/components/sections/ProductsRecommended.vue +2 -2
- package/src/modules/products/components/sections/SectionProduct.vue +7 -7
- package/src/modules/products/experiments/product-recommendation/components/HeroRecommendation.vue +3 -3
- package/src/modules/rents/views/components/blocks/CardRent.vue +1 -1
- package/src/modules/rents/views/components/pages/Gant/DateLabel.vue +1 -1
- package/src/modules/rents/views/components/pages/Gant/GanttBar.vue +2 -2
- package/src/modules/rents/views/components/pages/Gant/GanttChart.vue +8 -8
- package/src/modules/rents/views/components/pages/Gant/GanttHeaderCell.vue +1 -1
- package/src/modules/rents/views/components/pages/Rents.vue +1 -1
- package/src/modules/rents/views/components/pages/RentsEdit.vue +6 -6
- package/src/modules/reports/components/pages/BackofficeReports.vue +3 -3
- package/src/modules/reports/components/sections/FormReport.vue +1 -1
- package/src/modules/spots/components/blocks/CardSpot.vue +4 -4
- package/src/modules/spots/components/blocks/SpotMemberModify.vue +1 -1
- package/src/modules/spots/components/layouts/Spots.vue +2 -2
- package/src/modules/spots/components/pages/Spot.vue +5 -5
- package/src/modules/spots/components/pages/SpotEdit.vue +2 -2
- package/src/modules/spots/components/pages/Spots.vue +3 -3
- package/src/modules/spots/components/sections/MapSection.vue +1 -1
- package/src/modules/spots/components/sections/WorktimeEdit.vue +4 -4
- package/src/modules/wallet/views/components/blocks/CardBalanceReplenished.vue +5 -5
- package/src/modules/wallet/views/components/blocks/CardDeposit.vue +5 -5
- package/src/modules/wallet/views/components/blocks/CashDeposit.vue +2 -2
- package/src/modules/wallet/views/components/blocks/CryptoDeposit.vue +4 -4
- package/src/modules/wallet/views/components/blocks/CryptoDepositProcessing.vue +11 -11
- package/src/modules/wallet/views/components/elements/ConnectMetamask.vue +4 -4
- package/src/modules/wallet/views/components/pages/Wallet.vue +22 -22
- package/src/styles/config.scss +193 -507
- package/src/styles/layout.scss +81 -1
- package/src/styles/reset.scss +2 -0
- package/src/styles/theme.scss +1 -8
- package/dist/martyrs/dist/main-BFvlam0J.js.map +0 -1
- package/dist/martyrs/node_modules/.pnpm/@capacitor_core@7.0.1/node_modules/@capacitor/core/dist/index.js.map +0 -1
- package/dist/martyrs/src/components/Dropdown/Dropdown.vue.js.map +0 -1
- package/dist/martyrs/src/components/EditImages/EditImages.vue.js.map +0 -1
- package/dist/martyrs/src/components/Loader/Loader.vue.js.map +0 -1
- package/dist/martyrs/src/components/Menu/Menu.vue.js.map +0 -1
- package/dist/martyrs/src/components/Tooltip/Tooltip.vue.js.map +0 -1
- package/dist/martyrs/src/modules/core/views/components/sections/Filters.vue.js.map +0 -1
- package/dist/node_modules/.pnpm/@vue_server-renderer@3.5.13_vue@3.5.13_typescript@5.8.3_/node_modules/@vue/server-renderer/dist/server-renderer.esm-bundler.js.map +0 -1
- package/dist/node_modules/.pnpm/@vue_shared@3.5.13/node_modules/@vue/shared/dist/shared.esm-bundler.js.map +0 -1
- package/dist/node_modules/.pnpm/dayjs@1.11.13/node_modules/dayjs/dayjs.min.js.map +0 -1
- package/dist/node_modules/.pnpm/dayjs@1.11.13/node_modules/dayjs/plugin/weekOfYear.js.map +0 -1
- package/dist/node_modules/.pnpm/uuid@11.1.0/node_modules/uuid/dist/esm-browser/native.js +0 -6
- package/dist/node_modules/.pnpm/uuid@11.1.0/node_modules/uuid/dist/esm-browser/native.js.map +0 -1
- package/dist/node_modules/.pnpm/uuid@11.1.0/node_modules/uuid/dist/esm-browser/rng.js +0 -15
- package/dist/node_modules/.pnpm/uuid@11.1.0/node_modules/uuid/dist/esm-browser/rng.js.map +0 -1
- package/dist/node_modules/.pnpm/uuid@11.1.0/node_modules/uuid/dist/esm-browser/stringify.js +0 -11
- package/dist/node_modules/.pnpm/uuid@11.1.0/node_modules/uuid/dist/esm-browser/stringify.js.map +0 -1
- package/dist/node_modules/.pnpm/uuid@11.1.0/node_modules/uuid/dist/esm-browser/v4.js +0 -20
- package/dist/node_modules/.pnpm/uuid@11.1.0/node_modules/uuid/dist/esm-browser/v4.js.map +0 -1
- package/src/modules/LAYOUT.MD +0 -767
- package/src/modules/STYLES.MD +0 -298
- package/src/modules/inventory/inventory.router.js +0 -72
- package/src/modules/products/products.router.js +0 -299
- package/src/styles/base/all.scss +0 -233
- package/src/styles/base/backgrounds.scss +0 -70
- package/src/styles/base/borders.scss +0 -407
- package/src/styles/base/scrolling.scss +0 -137
- package/src/styles/base/shadow_transitions_hover_refactor.scss +0 -158
- package/src/styles/base/transitions.scss +0 -109
- package/src/styles/responsive.scss +0 -152
- package/src/styles/typography.scss +0 -161
- /package/dist/{node_modules/.pnpm/@vue_shared@3.5.13 → martyrs}/node_modules/@vue/shared/dist/shared.esm-bundler.js +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ArtistForm.vue.js","sources":["../../../../../../../src/modules/music/components/forms/ArtistForm.vue"],"sourcesContent":["<template>\n <div class=\"pd-medium\">\n <h2 class=\"h2 mn-b-medium\">{{ editMode ? 'Edit Artist' : 'Create Artist' }}</h2>\n \n <form @submit.prevent=\"submitForm\" class=\"cols-1 gap-regular\">\n <!-- Basic Info Section -->\n <div class=\"bg-light pd-medium radius-medium\">\n <h3 class=\"h3 mn-b-medium\">Basic Information</h3>\n \n <div class=\"cols-2 mobile:cols-1 gap-regular\">\n <!-- Artist Photo -->\n <div>\n <p class=\"p-medium mn-b-small\">Artist Photo</p>\n <UploadImage\n v-model:photo=\"artist.photoUrl\"\n uploadPath=\"artists/photos\"\n class=\"w-100 h-15r radius-small o-hidden mn-b-small\"\n @error=\"handleUploadError\"\n />\n </div>\n \n <!-- Artist Cover -->\n <div>\n <p class=\"p-medium mn-b-small\">Cover Image</p>\n <UploadImage\n v-model:photo=\"artist.coverUrl\"\n uploadPath=\"artists/covers\"\n class=\"w-100 h-15r radius-small o-hidden mn-b-small\"\n @error=\"handleUploadError\"\n />\n </div>\n </div>\n \n <!-- Name -->\n <Field\n v-model:field=\"artist.name\"\n label=\"Name\"\n placeholder=\"Enter artist name\"\n class=\"bg-white radius-small pd-small mn-b-thin\"\n :validation=\"validation.name\"\n />\n <!-- URL -->\n <Field\n v-model:field=\"artist.url\"\n label=\"URL\"\n placeholder=\"Leave blank for auto-generation based on the artist name\"\n class=\"bg-white radius-small pd-small mn-b-small\"\n />\n \n <!-- Bio -->\n <Field\n v-model:field=\"artist.bio\"\n label=\"Biography\"\n type=\"textarea\"\n placeholder=\"Enter artist biography\"\n class=\"bg-white radius-small pd-small mn-b-thin\"\n :validation=\"validation.bio\"\n />\n \n <!-- Location -->\n <Field\n v-model:field=\"artist.location\"\n label=\"Location\"\n placeholder=\"e.g., Los Angeles, CA\"\n class=\"bg-white radius-small pd-small mn-b-thin\"\n />\n \n <!-- Website -->\n <Field\n v-model:field=\"artist.website\"\n label=\"Website\"\n placeholder=\"https://example.com\"\n class=\"bg-white radius-small pd-small mn-b-thin\"\n />\n \n \n </div>\n \n <!-- Social Media Section -->\n <div class=\"bg-light pd-medium radius-medium\">\n <h3 class=\"h3 mn-b-medium\">Social Media</h3>\n \n <div class=\"cols-2 mobile:cols-1 gap-thin\">\n <!-- Telegram -->\n <Field\n v-model:field=\"artist.socials.telegram\"\n label=\"Telegram\"\n placeholder=\"@username\"\n class=\"bg-white radius-small pd-small\"\n />\n \n <!-- Twitter -->\n <Field\n v-model:field=\"artist.socials.twitter\"\n label=\"Twitter\"\n placeholder=\"@username\"\n class=\"bg-white radius-small pd-small\"\n />\n \n <!-- Facebook -->\n <Field\n v-model:field=\"artist.socials.facebook\"\n label=\"Facebook\"\n placeholder=\"username or page-name\"\n class=\"bg-white radius-small pd-small\"\n />\n \n <!-- Instagram -->\n <Field\n v-model:field=\"artist.socials.instagram\"\n label=\"Instagram\"\n placeholder=\"@username\"\n class=\"bg-white radius-small pd-small\"\n />\n </div>\n </div>\n \n <!-- Genres Section (assuming genres are available) -->\n <Block title=\"Genres\">\n <BlockMultiselect\n v-model=\"artist.genres\"\n placeholder=\"Search genres...\"\n :multiple=\"true\"\n :transform=\"(item) => ({ _id: item._id, name: item.name })\"\n :store=\"{\n read: (options) => genresStore.actions.fetchGenres(options),\n state: genresStore.state\n }\"\n :options=\"{\n rootOnly: false,\n excludeChildren: false,\n limit: 50\n }\"\n :skeleton=\"{\n hide: false,\n horizontal: true,\n class: 'radius-small',\n structure: [{ \n block: 'text', size: 'large'\n }]\n }\"\n :states=\"{\n empty: {\n title: 'No genres found',\n description: 'Try different search terms or create a new genre',\n class: 'radius-small'\n }\n }\"\n key=\"_id\"\n :label=\"item => item.name\"\n classSearch=\"bg-white radius-small\"\n classSelected=\"bg-white pd-small radius-small\"\n classDropdown=\"bg-white pd-small radius-medium bs-small\"\n classItem=\"pd-small radius-small hover-bg-light cursor-pointer\"\n classFeed=\"h-max-30r gap-thin flex-column flex o-scroll\"\n >\n <!-- Слот для выбранных жанров -->\n <template #selected=\"{ item, clear }\">\n <div class=\"flex-nowrap flex-v-center flex gap-thin\">\n <span class=\"t-medium\">{{ item?.name || item }}</span>\n <button \n @click.stop=\"clear\"\n class=\"i-small pd-micro bg-red radius-extra flex-center flex aspect-1x1 hover-scale-1\"\n >\n <IconCross class=\"i-micro fill-white\" />\n </button>\n </div>\n </template>\n \n <!-- Слот для элементов в списке -->\n <template #item=\"{ item }\">\n <div class=\"flex-nowrap flex-v-center flex\">\n <div class=\"w-100\">\n <p class=\"t-medium\">{{ item.name }}</p>\n <p v-if=\"item.description\" class=\"t-small t-transp\">{{ item.description }}</p>\n </div>\n </div>\n </template>\n </BlockMultiselect>\n </Block>\n \n <!-- Status Section -->\n <div class=\"bg-light pd-medium radius-medium\">\n <h3 class=\"h3 mn-b-medium\">Publishing Status</h3>\n \n <Select\n v-model:select=\"artist.status\"\n :options=\"statusOptions\"\n label=\"Status\"\n class=\"bg-white radius-small pd-small mn-b-thin\"\n />\n \n <Checkbox\n v-model:active=\"artist.isVerified\"\n label=\"Verified Artist\"\n class=\"bg-white radius-small pd-small mn-b-thin\"\n />\n </div>\n \n <!-- Submit Button -->\n <div class=\"flex flex-justify-between\">\n <Button\n @click=\"$router.go(-1)\"\n class=\"bg-grey-nano t-black\"\n :showSucces=\"false\"\n :showLoader=\"false\"\n >\n Cancel\n </Button>\n \n <Button\n :submit=\"submitForm\"\n class=\"bg-main t-black\"\n :text=\"{\n success: editMode ? 'Updated!' : 'Created!'\n }\"\n >\n {{ editMode ? 'Update Artist' : 'Create Artist' }}\n </Button>\n </div>\n </form>\n </div>\n</template>\n\n<script setup>\nimport { ref, reactive, onMounted, computed, watch } from 'vue';\nimport { useRouter, useRoute } from 'vue-router';\n\n// Import Martyrs components\nimport Field from '@martyrs/src/components/Field/Field.vue';\nimport Block from '@martyrs/src/components/Block/Block.vue';\nimport Button from '@martyrs/src/components/Button/Button.vue';\nimport Checkbox from '@martyrs/src/components/Checkbox/Checkbox.vue';\nimport Select from '@martyrs/src/components/Select/Select.vue';\nimport UploadImage from '@martyrs/src/components/UploadImage/UploadImage.vue';\nimport Loader from '@martyrs/src/components/Loader/Loader.vue';\n\n\nimport BlockMultiselect from '@martyrs/src/modules/core/views/components/blocks/BlockMultiselect.vue';\nimport IconCross from '@martyrs/src/modules/icons/navigation/IconCross.vue';\n\n// Import store\nimport * as artistsStore from '../../store/artists';\nimport * as genresStore from '../../store/genres';\nimport { useStore } from '@martyrs/src/modules/core/views/store/core.store.js';\n\nconst store = useStore();\nimport * as auth from '@martyrs/src/modules/auth/views/store/auth.js';\n\n// Props\nconst props = defineProps({\n editMode: {\n type: Boolean,\n default: false\n },\n url: {\n type: String,\n default: ''\n }\n});\n\n// Router and route\nconst router = useRouter();\nconst route = useRoute();\n\n// State\nconst artist = reactive({\n name: '',\n bio: '',\n photoUrl: '',\n coverUrl: '',\n website: '',\n location: '',\n isVerified: false,\n status: 'draft',\n socials: {\n telegram: '',\n twitter: '',\n facebook: '',\n instagram: ''\n },\n url: '',\n genres: []\n});\n\nconst validation = reactive({\n name: false,\n bio: false\n});\n\n// Track if URL was manually entered\nconst urlManuallySet = ref(false);\n\n// Function to generate URL-friendly slug from text\nconst generateSlug = (text) => {\n if (!text) return '';\n return text\n .toLowerCase()\n .replace(/[^a-z0-9\\s-]/g, '') // Remove special characters\n .replace(/\\s+/g, '-') // Replace spaces with hyphens\n .replace(/-+/g, '-') // Replace multiple hyphens with single\n .trim('-'); // Remove leading/trailing hyphens\n};\n\n// Watch for changes in artist name to auto-generate URL\nwatch(() => artist.name, (newName) => {\n // Only auto-generate if URL hasn't been manually set and we're not in edit mode\n if (!urlManuallySet.value && !props.editMode) {\n artist.url = generateSlug(newName);\n }\n});\n\n// Watch for manual changes to URL field\nwatch(() => artist.url, (newUrl, oldUrl) => {\n // If user manually changes URL, mark as manually set\n if (newUrl !== generateSlug(artist.name)) {\n urlManuallySet.value = true;\n }\n});\n\n// Status options\nconst statusOptions = [\n 'draft',\n 'published',\n 'archived'\n];\n\n\nconst fetchArtist = async () => {\n if (!props.url) return;\n \n try {\n const fetchedArtist = await artistsStore.actions.fetchArtistByUrl(props.url);\n \n if (!fetchedArtist) {\n store.core.actions.setError({\n message: 'Artist not found'\n });\n return;\n }\n \n // Update local artist data\n Object.assign(artist, {\n name: fetchedArtist.name || '',\n bio: fetchedArtist.bio || '',\n photoUrl: fetchedArtist.photoUrl || '',\n coverUrl: fetchedArtist.coverUrl || '',\n website: fetchedArtist.website || '',\n location: fetchedArtist.location || '',\n isVerified: fetchedArtist.isVerified || false,\n status: fetchedArtist.status || 'draft',\n url: fetchedArtist.url || '',\n genres: fetchedArtist.genres || [],\n _id: fetchedArtist._id,\n socials: {\n telegram: fetchedArtist.socials?.telegram || '',\n twitter: fetchedArtist.socials?.twitter || '',\n facebook: fetchedArtist.socials?.facebook || '',\n instagram: fetchedArtist.socials?.instagram || ''\n }\n });\n \n } catch (error) {\n console.error('Error fetching artist:', error);\n store.core.actions.setError({\n message: 'Failed to load artist details'\n });\n }\n};\n\nconst validateForm = () => {\n let isValid = true;\n \n // Validate name\n if (!artist.name.trim()) {\n validation.name = {\n message: 'Artist name is required'\n };\n isValid = false;\n } else {\n validation.name = false;\n }\n \n // Validate bio\n if (artist.bio && artist.bio.length > 2000) {\n validation.bio = {\n message: 'Biography is too long (max 2000 characters)'\n };\n isValid = false;\n } else {\n validation.bio = false;\n }\n \n return isValid;\n};\n\nconst submitForm = async () => {\n if (!validateForm()) {\n return;\n }\n \n try {\n // Prepare data for submission\n const formData = {\n ...artist,\n genres: artist.genres.map(genre => genre._id || genre)\n };\n \n // Add ownership data if creating new artist\n if (!props.editMode) {\n formData.owner = {\n type: 'user',\n target: auth.state.user._id\n };\n formData.creator = {\n type: 'user',\n target: auth.state.user._id\n };\n }\n \n let result;\n if (props.editMode) {\n result = await artistsStore.actions.updateArtist(formData);\n } else {\n result = await artistsStore.actions.createArtist(formData);\n }\n \n // Navigate to artist detail page\n setTimeout(() => {\n router.push({\n name: 'artist',\n params: { url: result.url }\n });\n }, 1000);\n \n } catch (error) {\n console.error('Error saving artist:', error);\n store.core.actions.setError({\n message: 'Failed to save artist'\n });\n }\n};\n\nconst handleUploadError = (error) => {\n console.error('Upload error:', error);\n store.core.actions.setError({\n message: 'Error uploading image'\n });\n};\n\n// Lifecycle hooks\nonMounted(async () => {\n if (props.editMode) {\n await fetchArtist();\n // Mark URL as manually set in edit mode to prevent auto-generation\n urlManuallySet.value = true;\n }\n});\n</script>\n"],"names":["artistsStore.actions","auth.state"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ArtistForm.vue.js","sources":["../../../../../../../src/modules/music/components/forms/ArtistForm.vue"],"sourcesContent":["<template>\n <div class=\"pd-medium\">\n <h2 class=\"h2 mn-b-medium\">{{ editMode ? 'Edit Artist' : 'Create Artist' }}</h2>\n \n <form @submit.prevent=\"submitForm\" class=\"cols-1 gap-regular\">\n <!-- Basic Info Section -->\n <div class=\"bg-light pd-medium radius-medium\">\n <h3 class=\"h3 mn-b-medium\">Basic Information</h3>\n \n <div class=\"cols-2 mobile:cols-1 gap-regular\">\n <!-- Artist Photo -->\n <div>\n <p class=\"p-medium mn-b-small\">Artist Photo</p>\n <UploadImage\n v-model:photo=\"artist.photoUrl\"\n uploadPath=\"artists/photos\"\n class=\"w-100 h-15r radius-small o-hidden mn-b-small\"\n @error=\"handleUploadError\"\n />\n </div>\n \n <!-- Artist Cover -->\n <div>\n <p class=\"p-medium mn-b-small\">Cover Image</p>\n <UploadImage\n v-model:photo=\"artist.coverUrl\"\n uploadPath=\"artists/covers\"\n class=\"w-100 h-15r radius-small o-hidden mn-b-small\"\n @error=\"handleUploadError\"\n />\n </div>\n </div>\n \n <!-- Name -->\n <Field\n v-model:field=\"artist.name\"\n label=\"Name\"\n placeholder=\"Enter artist name\"\n class=\"bg-white radius-small pd-small mn-b-thin\"\n :validation=\"validation.name\"\n />\n <!-- URL -->\n <Field\n v-model:field=\"artist.url\"\n label=\"URL\"\n placeholder=\"Leave blank for auto-generation based on the artist name\"\n class=\"bg-white radius-small pd-small mn-b-small\"\n />\n \n <!-- Bio -->\n <Field\n v-model:field=\"artist.bio\"\n label=\"Biography\"\n type=\"textarea\"\n placeholder=\"Enter artist biography\"\n class=\"bg-white radius-small pd-small mn-b-thin\"\n :validation=\"validation.bio\"\n />\n \n <!-- Location -->\n <Field\n v-model:field=\"artist.location\"\n label=\"Location\"\n placeholder=\"e.g., Los Angeles, CA\"\n class=\"bg-white radius-small pd-small mn-b-thin\"\n />\n \n <!-- Website -->\n <Field\n v-model:field=\"artist.website\"\n label=\"Website\"\n placeholder=\"https://example.com\"\n class=\"bg-white radius-small pd-small mn-b-thin\"\n />\n \n \n </div>\n \n <!-- Social Media Section -->\n <div class=\"bg-light pd-medium radius-medium\">\n <h3 class=\"h3 mn-b-medium\">Social Media</h3>\n \n <div class=\"cols-2 mobile:cols-1 gap-thin\">\n <!-- Telegram -->\n <Field\n v-model:field=\"artist.socials.telegram\"\n label=\"Telegram\"\n placeholder=\"@username\"\n class=\"bg-white radius-small pd-small\"\n />\n \n <!-- Twitter -->\n <Field\n v-model:field=\"artist.socials.twitter\"\n label=\"Twitter\"\n placeholder=\"@username\"\n class=\"bg-white radius-small pd-small\"\n />\n \n <!-- Facebook -->\n <Field\n v-model:field=\"artist.socials.facebook\"\n label=\"Facebook\"\n placeholder=\"username or page-name\"\n class=\"bg-white radius-small pd-small\"\n />\n \n <!-- Instagram -->\n <Field\n v-model:field=\"artist.socials.instagram\"\n label=\"Instagram\"\n placeholder=\"@username\"\n class=\"bg-white radius-small pd-small\"\n />\n </div>\n </div>\n \n <!-- Genres Section (assuming genres are available) -->\n <Block title=\"Genres\">\n <BlockMultiselect\n v-model=\"artist.genres\"\n placeholder=\"Search genres...\"\n :multiple=\"true\"\n :transform=\"(item) => ({ _id: item._id, name: item.name })\"\n :store=\"{\n read: (options) => genresStore.actions.fetchGenres(options),\n state: genresStore.state\n }\"\n :options=\"{\n rootOnly: false,\n excludeChildren: false,\n limit: 50\n }\"\n :skeleton=\"{\n hide: false,\n horizontal: true,\n class: 'radius-small',\n structure: [{ \n block: 'text', size: 'large'\n }]\n }\"\n :states=\"{\n empty: {\n title: 'No genres found',\n description: 'Try different search terms or create a new genre',\n class: 'radius-small'\n }\n }\"\n key=\"_id\"\n :label=\"item => item.name\"\n classSearch=\"bg-white radius-small\"\n classSelected=\"bg-white pd-small radius-small\"\n classDropdown=\"bg-white pd-small radius-medium bs-small\"\n classItem=\"pd-small radius-small hover:bg-light cursor-pointer\"\n classFeed=\"h-max-30r gap-thin flex-column flex o-scroll\"\n >\n <!-- Слот для выбранных жанров -->\n <template #selected=\"{ item, clear }\">\n <div class=\"flex-nowrap flex-v-center flex gap-thin\">\n <span class=\"fw-medium\">{{ item?.name || item }}</span>\n <button \n @click.stop=\"clear\"\n class=\"i-small pd-micro bg-red radius-extra flex-center flex aspect-1x1 hover:scale-[1.05]\"\n >\n <IconCross class=\"i-micro fill-white\" />\n </button>\n </div>\n </template>\n \n <!-- Слот для элементов в списке -->\n <template #item=\"{ item }\">\n <div class=\"flex-nowrap flex-v-center flex\">\n <div class=\"w-100\">\n <p class=\"fw-medium\">{{ item.name }}</p>\n <p v-if=\"item.description\" class=\"t-small t-transp\">{{ item.description }}</p>\n </div>\n </div>\n </template>\n </BlockMultiselect>\n </Block>\n \n <!-- Status Section -->\n <div class=\"bg-light pd-medium radius-medium\">\n <h3 class=\"h3 mn-b-medium\">Publishing Status</h3>\n \n <Select\n v-model:select=\"artist.status\"\n :options=\"statusOptions\"\n label=\"Status\"\n class=\"bg-white radius-small pd-small mn-b-thin\"\n />\n \n <Checkbox\n v-model:active=\"artist.isVerified\"\n label=\"Verified Artist\"\n class=\"bg-white radius-small pd-small mn-b-thin\"\n />\n </div>\n \n <!-- Submit Button -->\n <div class=\"flex flex-justify-between\">\n <Button\n @click=\"$router.go(-1)\"\n class=\"bg-grey-nano t-black\"\n :showSucces=\"false\"\n :showLoader=\"false\"\n >\n Cancel\n </Button>\n \n <Button\n :submit=\"submitForm\"\n class=\"bg-main t-black\"\n :text=\"{\n success: editMode ? 'Updated!' : 'Created!'\n }\"\n >\n {{ editMode ? 'Update Artist' : 'Create Artist' }}\n </Button>\n </div>\n </form>\n </div>\n</template>\n\n<script setup>\nimport { ref, reactive, onMounted, computed, watch } from 'vue';\nimport { useRouter, useRoute } from 'vue-router';\n\n// Import Martyrs components\nimport Field from '@martyrs/src/components/Field/Field.vue';\nimport Block from '@martyrs/src/components/Block/Block.vue';\nimport Button from '@martyrs/src/components/Button/Button.vue';\nimport Checkbox from '@martyrs/src/components/Checkbox/Checkbox.vue';\nimport Select from '@martyrs/src/components/Select/Select.vue';\nimport UploadImage from '@martyrs/src/components/UploadImage/UploadImage.vue';\nimport Loader from '@martyrs/src/components/Loader/Loader.vue';\n\n\nimport BlockMultiselect from '@martyrs/src/modules/core/views/components/blocks/BlockMultiselect.vue';\nimport IconCross from '@martyrs/src/modules/icons/navigation/IconCross.vue';\n\n// Import store\nimport * as artistsStore from '../../store/artists';\nimport * as genresStore from '../../store/genres';\nimport { useStore } from '@martyrs/src/modules/core/views/store/core.store.js';\n\nconst store = useStore();\nimport * as auth from '@martyrs/src/modules/auth/views/store/auth.js';\n\n// Props\nconst props = defineProps({\n editMode: {\n type: Boolean,\n default: false\n },\n url: {\n type: String,\n default: ''\n }\n});\n\n// Router and route\nconst router = useRouter();\nconst route = useRoute();\n\n// State\nconst artist = reactive({\n name: '',\n bio: '',\n photoUrl: '',\n coverUrl: '',\n website: '',\n location: '',\n isVerified: false,\n status: 'draft',\n socials: {\n telegram: '',\n twitter: '',\n facebook: '',\n instagram: ''\n },\n url: '',\n genres: []\n});\n\nconst validation = reactive({\n name: false,\n bio: false\n});\n\n// Track if URL was manually entered\nconst urlManuallySet = ref(false);\n\n// Function to generate URL-friendly slug from text\nconst generateSlug = (text) => {\n if (!text) return '';\n return text\n .toLowerCase()\n .replace(/[^a-z0-9\\s-]/g, '') // Remove special characters\n .replace(/\\s+/g, '-') // Replace spaces with hyphens\n .replace(/-+/g, '-') // Replace multiple hyphens with single\n .trim('-'); // Remove leading/trailing hyphens\n};\n\n// Watch for changes in artist name to auto-generate URL\nwatch(() => artist.name, (newName) => {\n // Only auto-generate if URL hasn't been manually set and we're not in edit mode\n if (!urlManuallySet.value && !props.editMode) {\n artist.url = generateSlug(newName);\n }\n});\n\n// Watch for manual changes to URL field\nwatch(() => artist.url, (newUrl, oldUrl) => {\n // If user manually changes URL, mark as manually set\n if (newUrl !== generateSlug(artist.name)) {\n urlManuallySet.value = true;\n }\n});\n\n// Status options\nconst statusOptions = [\n 'draft',\n 'published',\n 'archived'\n];\n\n\nconst fetchArtist = async () => {\n if (!props.url) return;\n \n try {\n const fetchedArtist = await artistsStore.actions.fetchArtistByUrl(props.url);\n \n if (!fetchedArtist) {\n store.core.actions.setError({\n message: 'Artist not found'\n });\n return;\n }\n \n // Update local artist data\n Object.assign(artist, {\n name: fetchedArtist.name || '',\n bio: fetchedArtist.bio || '',\n photoUrl: fetchedArtist.photoUrl || '',\n coverUrl: fetchedArtist.coverUrl || '',\n website: fetchedArtist.website || '',\n location: fetchedArtist.location || '',\n isVerified: fetchedArtist.isVerified || false,\n status: fetchedArtist.status || 'draft',\n url: fetchedArtist.url || '',\n genres: fetchedArtist.genres || [],\n _id: fetchedArtist._id,\n socials: {\n telegram: fetchedArtist.socials?.telegram || '',\n twitter: fetchedArtist.socials?.twitter || '',\n facebook: fetchedArtist.socials?.facebook || '',\n instagram: fetchedArtist.socials?.instagram || ''\n }\n });\n \n } catch (error) {\n console.error('Error fetching artist:', error);\n store.core.actions.setError({\n message: 'Failed to load artist details'\n });\n }\n};\n\nconst validateForm = () => {\n let isValid = true;\n \n // Validate name\n if (!artist.name.trim()) {\n validation.name = {\n message: 'Artist name is required'\n };\n isValid = false;\n } else {\n validation.name = false;\n }\n \n // Validate bio\n if (artist.bio && artist.bio.length > 2000) {\n validation.bio = {\n message: 'Biography is too long (max 2000 characters)'\n };\n isValid = false;\n } else {\n validation.bio = false;\n }\n \n return isValid;\n};\n\nconst submitForm = async () => {\n if (!validateForm()) {\n return;\n }\n \n try {\n // Prepare data for submission\n const formData = {\n ...artist,\n genres: artist.genres.map(genre => genre._id || genre)\n };\n \n // Add ownership data if creating new artist\n if (!props.editMode) {\n formData.owner = {\n type: 'user',\n target: auth.state.user._id\n };\n formData.creator = {\n type: 'user',\n target: auth.state.user._id\n };\n }\n \n let result;\n if (props.editMode) {\n result = await artistsStore.actions.updateArtist(formData);\n } else {\n result = await artistsStore.actions.createArtist(formData);\n }\n \n // Navigate to artist detail page\n setTimeout(() => {\n router.push({\n name: 'artist',\n params: { url: result.url }\n });\n }, 1000);\n \n } catch (error) {\n console.error('Error saving artist:', error);\n store.core.actions.setError({\n message: 'Failed to save artist'\n });\n }\n};\n\nconst handleUploadError = (error) => {\n console.error('Upload error:', error);\n store.core.actions.setError({\n message: 'Error uploading image'\n });\n};\n\n// Lifecycle hooks\nonMounted(async () => {\n if (props.editMode) {\n await fetchArtist();\n // Mark URL as manually set in edit mode to prevent auto-generation\n urlManuallySet.value = true;\n }\n});\n</script>\n"],"names":["artistsStore.actions","auth.state"],"mappings":"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"}
|
|
@@ -18,8 +18,8 @@ const _hoisted_4 = { class: "mn-b-medium" };
|
|
|
18
18
|
const _hoisted_5 = { class: "flex-nowrap flex-v-center flex gap-thin" };
|
|
19
19
|
const _hoisted_6 = ["onClick", "disabled"];
|
|
20
20
|
const _hoisted_7 = ["onClick", "disabled"];
|
|
21
|
-
const _hoisted_8 = { class: "flex-1" };
|
|
22
|
-
const _hoisted_9 = { class: "
|
|
21
|
+
const _hoisted_8 = { class: "flex-child-1" };
|
|
22
|
+
const _hoisted_9 = { class: "fw-medium" };
|
|
23
23
|
const _hoisted_10 = { class: "t-small t-transp" };
|
|
24
24
|
const _hoisted_11 = { key: 0 };
|
|
25
25
|
const _hoisted_12 = {
|
|
@@ -29,7 +29,7 @@ const _hoisted_12 = {
|
|
|
29
29
|
const _hoisted_13 = ["onClick"];
|
|
30
30
|
const _hoisted_14 = { class: "flex-nowrap flex-v-center flex" };
|
|
31
31
|
const _hoisted_15 = { class: "w-100" };
|
|
32
|
-
const _hoisted_16 = { class: "
|
|
32
|
+
const _hoisted_16 = { class: "fw-medium" };
|
|
33
33
|
const _hoisted_17 = { class: "t-small t-transp" };
|
|
34
34
|
const _hoisted_18 = { key: 0 };
|
|
35
35
|
const _hoisted_19 = {
|
|
@@ -299,7 +299,7 @@ const _sfc_main = {
|
|
|
299
299
|
classSearch: "bg-white radius-small",
|
|
300
300
|
classSelected: "bg-white pd-small radius-small",
|
|
301
301
|
classDropdown: "bg-white pd-small radius-medium bs-small",
|
|
302
|
-
classItem: "pd-small radius-small hover
|
|
302
|
+
classItem: "pd-small radius-small hover:bg-light cursor-pointer",
|
|
303
303
|
classFeed: "h-max-30r gap-thin flex-column flex o-scroll"
|
|
304
304
|
}, {
|
|
305
305
|
selected: withCtx(({ item, clear, index }) => [
|
|
@@ -308,7 +308,7 @@ const _sfc_main = {
|
|
|
308
308
|
key: 0,
|
|
309
309
|
onClick: withModifiers(($event) => moveTrack(index, "up"), ["stop"]),
|
|
310
310
|
disabled: index === 0,
|
|
311
|
-
class: "i-small pd-micro bg-grey-nano radius-extra flex-center flex aspect-1x1 hover
|
|
311
|
+
class: "i-small pd-micro bg-grey-nano radius-extra flex-center flex aspect-1x1 hover:scale-[1.05]"
|
|
312
312
|
}, [
|
|
313
313
|
createVNode(_sfc_main$2, { class: "i-micro" })
|
|
314
314
|
], 8, _hoisted_6)) : createCommentVNode("", true),
|
|
@@ -316,7 +316,7 @@ const _sfc_main = {
|
|
|
316
316
|
key: 1,
|
|
317
317
|
onClick: withModifiers(($event) => moveTrack(index, "down"), ["stop"]),
|
|
318
318
|
disabled: index === playlist.tracks.length - 1,
|
|
319
|
-
class: "i-small pd-micro bg-grey-nano radius-extra flex-center flex aspect-1x1 hover
|
|
319
|
+
class: "i-small pd-micro bg-grey-nano radius-extra flex-center flex aspect-1x1 hover:scale-[1.05]"
|
|
320
320
|
}, [
|
|
321
321
|
createVNode(_sfc_main$2, { class: "i-micro" })
|
|
322
322
|
], 8, _hoisted_7)) : createCommentVNode("", true),
|
|
@@ -330,7 +330,7 @@ const _sfc_main = {
|
|
|
330
330
|
item.duration ? (openBlock(), createElementBlock("span", _hoisted_12, toDisplayString(formatDuration(item.duration)), 1)) : createCommentVNode("", true),
|
|
331
331
|
createElementVNode("button", {
|
|
332
332
|
onClick: withModifiers(clear, ["stop"]),
|
|
333
|
-
class: "i-small pd-micro bg-red radius-extra flex-center flex aspect-1x1 hover
|
|
333
|
+
class: "i-small pd-micro bg-red radius-extra flex-center flex aspect-1x1 hover:scale-[1.05]"
|
|
334
334
|
}, [
|
|
335
335
|
createVNode(_sfc_main$2, { class: "i-micro fill-white" })
|
|
336
336
|
], 8, _hoisted_13)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PlaylistForm.vue.js","sources":["../../../../../../../src/modules/music/components/forms/PlaylistForm.vue"],"sourcesContent":["<template>\n <div class=\"pd-medium\">\n <h2 class=\"h2 mn-b-medium\">{{ editMode ? 'Edit Playlist' : 'Create Playlist' }}</h2>\n \n <form @submit.prevent=\"submitForm\" class=\"cols-1 gap-regular\">\n <!-- Basic Info Section -->\n <div class=\"bg-light pd-medium radius-medium\">\n <h3 class=\"h3 mn-b-medium\">Basic Information</h3>\n \n <!-- Playlist Cover -->\n <div class=\"mn-b-medium\">\n <p class=\"p-medium mn-b-small\">Playlist Cover</p>\n <UploadImage\n v-model:photo=\"playlist.coverUrl\"\n uploadPath=\"playlists/covers\"\n class=\"w-100 h-15r radius-small o-hidden mn-b-small\"\n @error=\"handleUploadError\"\n />\n </div>\n \n <!-- Title -->\n <Field\n v-model:field=\"playlist.title\"\n label=\"Title\"\n placeholder=\"Enter playlist title\"\n class=\"bg-white radius-small pd-small mn-b-thin\"\n :validation=\"validation.title\"\n />\n \n <!-- URL -->\n <Field\n v-model:field=\"playlist.url\"\n label=\"URL\"\n placeholder=\"Leave blank for auto-generation based on the playlist title\"\n class=\"bg-white radius-small pd-small mn-b-small\"\n />\n \n <!-- Description -->\n <Field\n v-model:field=\"playlist.description\"\n label=\"Description\"\n type=\"textarea\"\n placeholder=\"Enter playlist description\"\n class=\"bg-white radius-small pd-small mn-b-thin\"\n :validation=\"validation.description\"\n />\n </div>\n \n <!-- Tracks Section -->\n <Block title=\"Tracks\">\n <BlockMultiselect\n v-model=\"playlist.tracks\"\n placeholder=\"Search tracks...\"\n :multiple=\"true\"\n :transform=\"(item) => ({ \n _id: item._id, \n title: item.title,\n artists: item.artists,\n album: item.album,\n duration: item.duration \n })\"\n :store=\"{\n read: (options) => tracksStore.actions.fetchTracks(options),\n state: tracksStore.state\n }\"\n :options=\"{\n rootOnly: false,\n excludeChildren: false,\n limit: 50\n }\"\n :skeleton=\"{\n hide: false,\n horizontal: true,\n class: 'radius-small',\n structure: [{ \n block: 'text', size: 'large'\n }]\n }\"\n :states=\"{\n empty: {\n title: 'No tracks found',\n description: 'Try different search terms',\n class: 'radius-small'\n }\n }\"\n key=\"_id\"\n :label=\"item => item.title\"\n classSearch=\"bg-white radius-small\"\n classSelected=\"bg-white pd-small radius-small\"\n classDropdown=\"bg-white pd-small radius-medium bs-small\"\n classItem=\"pd-small radius-small hover-bg-light cursor-pointer\"\n classFeed=\"h-max-30r gap-thin flex-column flex o-scroll\"\n >\n <!-- Selected tracks with reorder support -->\n <template #selected=\"{ item, clear, index }\">\n <div class=\"flex-nowrap flex-v-center flex gap-thin\">\n <button \n v-if=\"playlist.tracks.length > 1\"\n @click.stop=\"moveTrack(index, 'up')\"\n :disabled=\"index === 0\"\n class=\"i-small pd-micro bg-grey-nano radius-extra flex-center flex aspect-1x1 hover-scale-1\"\n >\n <IconArrowUp class=\"i-micro\" />\n </button>\n \n <button \n v-if=\"playlist.tracks.length > 1\"\n @click.stop=\"moveTrack(index, 'down')\"\n :disabled=\"index === playlist.tracks.length - 1\"\n class=\"i-small pd-micro bg-grey-nano radius-extra flex-center flex aspect-1x1 hover-scale-1\"\n >\n <IconArrowDown class=\"i-micro\" />\n </button>\n \n <div class=\"flex-1\">\n <p class=\"t-medium\">{{ item.title }}</p>\n <p class=\"t-small t-transp\">\n {{ item.artists?.map(a => a.name || a).join(', ') }}\n <span v-if=\"item.album\"> • {{ item.album.title || item.album }}</span>\n </p>\n </div>\n \n <span v-if=\"item.duration\" class=\"t-small t-transp\">\n {{ formatDuration(item.duration) }}\n </span>\n \n <button \n @click.stop=\"clear\"\n class=\"i-small pd-micro bg-red radius-extra flex-center flex aspect-1x1 hover-scale-1\"\n >\n <IconCross class=\"i-micro fill-white\" />\n </button>\n </div>\n </template>\n \n <!-- Track items in dropdown -->\n <template #item=\"{ item }\">\n <div class=\"flex-nowrap flex-v-center flex\">\n <div class=\"w-100\">\n <p class=\"t-medium\">{{ item.title }}</p>\n <p class=\"t-small t-transp\">\n {{ item.artists?.map(a => a.name || a).join(', ') }}\n <span v-if=\"item.album\"> • {{ item.album.title || item.album }}</span>\n </p>\n </div>\n <span v-if=\"item.duration\" class=\"t-small t-transp mn-l-small\">\n {{ formatDuration(item.duration) }}\n </span>\n </div>\n </template>\n </BlockMultiselect>\n \n <!-- Tracks summary -->\n <div v-if=\"playlist.tracks.length > 0\" class=\"t-small t-transp mn-t-small\">\n {{ playlist.tracks.length }} tracks • {{ formatDuration(totalDuration) }}\n </div>\n </Block>\n \n <!-- Privacy & Settings Section -->\n <div class=\"bg-light pd-medium radius-medium\">\n <h3 class=\"h3 mn-b-medium\">Privacy & Settings</h3>\n \n <!-- Privacy -->\n <div class=\"mn-b-medium\">\n <p class=\"p-medium mn-b-small\">Privacy</p>\n <div class=\"flex gap-regular\">\n <Radio\n v-model:radio=\"playlist.isPublic\"\n :value=\"true\"\n name=\"privacy\"\n label=\"Public\"\n class=\"bg-white pd-small radius-small\"\n />\n <Radio\n v-model:radio=\"playlist.isPublic\"\n :value=\"false\"\n name=\"privacy\"\n label=\"Private\"\n class=\"bg-white pd-small radius-small\"\n />\n </div>\n </div>\n \n <!-- Collaborative -->\n <div class=\"mn-b-medium\">\n <p class=\"p-medium mn-b-small\">Collaborative Playlist</p>\n <div class=\"flex gap-regular\">\n <Radio\n v-model:radio=\"playlist.isCollaborative\"\n :value=\"true\"\n name=\"collaborative\"\n label=\"Yes\"\n class=\"bg-white pd-small radius-small\"\n />\n <Radio\n v-model:radio=\"playlist.isCollaborative\"\n :value=\"false\"\n name=\"collaborative\"\n label=\"No\"\n class=\"bg-white pd-small radius-small\"\n />\n </div>\n </div>\n </div>\n \n <!-- Submit Button -->\n <div class=\"flex flex-justify-between\">\n <Button\n @click=\"$router.go(-1)\"\n class=\"bg-grey-nano t-black\"\n :showSucces=\"false\"\n :showLoader=\"false\"\n >\n Cancel\n </Button>\n \n <Button\n :submit=\"submitForm\"\n class=\"bg-main t-black\"\n :text=\"{\n success: editMode ? 'Updated!' : 'Created!'\n }\"\n >\n {{ editMode ? 'Update Playlist' : 'Create Playlist' }}\n </Button>\n </div>\n </form>\n </div>\n</template>\n\n<script setup>\nimport { ref, reactive, onMounted, watch, computed } from 'vue';\nimport { useRouter, useRoute } from 'vue-router';\n\n// Import Martyrs components\nimport Field from '@martyrs/src/components/Field/Field.vue';\nimport Block from '@martyrs/src/components/Block/Block.vue';\nimport Button from '@martyrs/src/components/Button/Button.vue';\nimport Radio from '@martyrs/src/components/Radio/Radio.vue';\nimport UploadImage from '@martyrs/src/components/UploadImage/UploadImage.vue';\nimport IconCross from '@martyrs/src/modules/icons/navigation/IconCross.vue';\nimport IconArrowUp from '@martyrs/src/modules/icons/navigation/IconCross.vue';\nimport IconArrowDown from '@martyrs/src/modules/icons/navigation/IconCross.vue';\n\nimport BlockMultiselect from '@martyrs/src/modules/core/views/components/blocks/BlockMultiselect.vue';\n\n// Import stores\nimport * as playlistsStore from '../../store/playlists';\nimport * as tracksStore from '../../store/tracks';\nimport { useStore } from '@martyrs/src/modules/core/views/store/core.store.js';\n\nconst store = useStore();\nimport * as auth from '@martyrs/src/modules/auth/views/store/auth.js';\n\n// Props\nconst props = defineProps({\n editMode: {\n type: Boolean,\n default: false\n },\n url: {\n type: String,\n default: ''\n }\n});\n\n// Router and route\nconst router = useRouter();\nconst route = useRoute();\n\n// State\nconst playlist = reactive({\n title: '',\n description: '',\n coverUrl: '',\n tracks: [],\n url: '',\n isPublic: true,\n isCollaborative: false\n});\n\nconst validation = reactive({\n title: false,\n description: false\n});\n\n// Track if URL was manually entered\nconst urlManuallySet = ref(false);\n\n// Function to generate URL-friendly slug from text\nconst generateSlug = (text) => {\n if (!text) return '';\n return text\n .toLowerCase()\n .replace(/[^a-z0-9\\s-]/g, '') // Remove special characters\n .replace(/\\s+/g, '-') // Replace spaces with hyphens\n .replace(/-+/g, '-') // Replace multiple hyphens with single\n .trim('-'); // Remove leading/trailing hyphens\n};\n\n// Watch for changes in playlist title to auto-generate URL\nwatch(() => playlist.title, (newTitle) => {\n // Only auto-generate if URL hasn't been manually set and we're not in edit mode\n if (!urlManuallySet.value && !props.editMode) {\n playlist.url = generateSlug(newTitle);\n }\n});\n\n// Watch for manual changes to URL field\nwatch(() => playlist.url, (newUrl, oldUrl) => {\n // If user manually changes URL, mark as manually set\n if (newUrl !== generateSlug(playlist.title)) {\n urlManuallySet.value = true;\n }\n});\n\n// Computed\nconst totalDuration = computed(() => {\n return playlist.tracks.reduce((sum, track) => sum + (track.duration || 0), 0);\n});\n\n// Methods\nconst formatDuration = (seconds) => {\n if (!seconds) return '0:00';\n const hours = Math.floor(seconds / 3600);\n const minutes = Math.floor((seconds % 3600) / 60);\n const secs = seconds % 60;\n \n if (hours > 0) {\n return `${hours}:${minutes.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;\n }\n return `${minutes}:${secs.toString().padStart(2, '0')}`;\n};\n\nconst moveTrack = (index, direction) => {\n const newIndex = direction === 'up' ? index - 1 : index + 1;\n if (newIndex < 0 || newIndex >= playlist.tracks.length) return;\n \n const tracks = [...playlist.tracks];\n [tracks[index], tracks[newIndex]] = [tracks[newIndex], tracks[index]];\n playlist.tracks = tracks;\n};\n\nconst fetchPlaylist = async () => {\n if (!props.url) return;\n \n try {\n const fetchedPlaylist = await playlistsStore.actions.fetchPlaylistByUrl(props.url);\n \n if (!fetchedPlaylist) {\n store.core.actions.setError({\n message: 'Playlist not found'\n });\n return;\n }\n \n // Update local playlist data\n Object.assign(playlist, {\n title: fetchedPlaylist.title || '',\n description: fetchedPlaylist.description || '',\n coverUrl: fetchedPlaylist.coverUrl || '',\n tracks: fetchedPlaylist.tracks || [],\n url: fetchedPlaylist.url || '',\n isPublic: fetchedPlaylist.isPublic !== false,\n isCollaborative: fetchedPlaylist.isCollaborative || false,\n _id: fetchedPlaylist._id\n });\n \n } catch (error) {\n console.error('Error fetching playlist:', error);\n store.core.actions.setError({\n message: 'Failed to load playlist details'\n });\n }\n};\n\nconst validateForm = () => {\n let isValid = true;\n \n // Validate title\n if (!playlist.title.trim()) {\n validation.title = {\n message: 'Playlist title is required'\n };\n isValid = false;\n } else {\n validation.title = false;\n }\n \n // Validate description\n if (playlist.description && playlist.description.length > 2000) {\n validation.description = {\n message: 'Description is too long (max 2000 characters)'\n };\n isValid = false;\n } else {\n validation.description = false;\n }\n \n return isValid;\n};\n\nconst submitForm = async () => {\n if (!validateForm()) {\n return;\n }\n \n try {\n // Prepare data for submission\n const formData = {\n ...playlist,\n tracks: playlist.tracks.map(track => ({\n track: track._id || track,\n addedAt: new Date()\n }))\n };\n \n // Add ownership data if creating new playlist\n if (!props.editMode) {\n formData.creator = {\n type: 'user',\n target: auth.state.user._id\n };\n formData.owner = {\n type: 'user',\n target: auth.state.user._id\n };\n }\n \n let result;\n if (props.editMode) {\n result = await playlistsStore.actions.updatePlaylist(formData);\n } else {\n result = await playlistsStore.actions.createPlaylist(formData);\n }\n \n // Navigate to playlist detail page\n setTimeout(() => {\n router.push({\n name: 'playlist',\n params: { url: result.url }\n });\n }, 1000);\n \n } catch (error) {\n console.error('Error saving playlist:', error);\n store.core.actions.setError({\n message: 'Failed to save playlist'\n });\n }\n};\n\nconst handleUploadError = (error) => {\n console.error('Upload error:', error);\n store.core.actions.setError({\n message: 'Error uploading image'\n });\n};\n\n// Lifecycle hooks\nonMounted(async () => {\n if (props.editMode) {\n await fetchPlaylist();\n // Mark URL as manually set in edit mode to prevent auto-generation\n urlManuallySet.value = true;\n }\n});\n</script>\n"],"names":["playlistsStore.actions","auth.state"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"PlaylistForm.vue.js","sources":["../../../../../../../src/modules/music/components/forms/PlaylistForm.vue"],"sourcesContent":["<template>\n <div class=\"pd-medium\">\n <h2 class=\"h2 mn-b-medium\">{{ editMode ? 'Edit Playlist' : 'Create Playlist' }}</h2>\n \n <form @submit.prevent=\"submitForm\" class=\"cols-1 gap-regular\">\n <!-- Basic Info Section -->\n <div class=\"bg-light pd-medium radius-medium\">\n <h3 class=\"h3 mn-b-medium\">Basic Information</h3>\n \n <!-- Playlist Cover -->\n <div class=\"mn-b-medium\">\n <p class=\"p-medium mn-b-small\">Playlist Cover</p>\n <UploadImage\n v-model:photo=\"playlist.coverUrl\"\n uploadPath=\"playlists/covers\"\n class=\"w-100 h-15r radius-small o-hidden mn-b-small\"\n @error=\"handleUploadError\"\n />\n </div>\n \n <!-- Title -->\n <Field\n v-model:field=\"playlist.title\"\n label=\"Title\"\n placeholder=\"Enter playlist title\"\n class=\"bg-white radius-small pd-small mn-b-thin\"\n :validation=\"validation.title\"\n />\n \n <!-- URL -->\n <Field\n v-model:field=\"playlist.url\"\n label=\"URL\"\n placeholder=\"Leave blank for auto-generation based on the playlist title\"\n class=\"bg-white radius-small pd-small mn-b-small\"\n />\n \n <!-- Description -->\n <Field\n v-model:field=\"playlist.description\"\n label=\"Description\"\n type=\"textarea\"\n placeholder=\"Enter playlist description\"\n class=\"bg-white radius-small pd-small mn-b-thin\"\n :validation=\"validation.description\"\n />\n </div>\n \n <!-- Tracks Section -->\n <Block title=\"Tracks\">\n <BlockMultiselect\n v-model=\"playlist.tracks\"\n placeholder=\"Search tracks...\"\n :multiple=\"true\"\n :transform=\"(item) => ({ \n _id: item._id, \n title: item.title,\n artists: item.artists,\n album: item.album,\n duration: item.duration \n })\"\n :store=\"{\n read: (options) => tracksStore.actions.fetchTracks(options),\n state: tracksStore.state\n }\"\n :options=\"{\n rootOnly: false,\n excludeChildren: false,\n limit: 50\n }\"\n :skeleton=\"{\n hide: false,\n horizontal: true,\n class: 'radius-small',\n structure: [{ \n block: 'text', size: 'large'\n }]\n }\"\n :states=\"{\n empty: {\n title: 'No tracks found',\n description: 'Try different search terms',\n class: 'radius-small'\n }\n }\"\n key=\"_id\"\n :label=\"item => item.title\"\n classSearch=\"bg-white radius-small\"\n classSelected=\"bg-white pd-small radius-small\"\n classDropdown=\"bg-white pd-small radius-medium bs-small\"\n classItem=\"pd-small radius-small hover:bg-light cursor-pointer\"\n classFeed=\"h-max-30r gap-thin flex-column flex o-scroll\"\n >\n <!-- Selected tracks with reorder support -->\n <template #selected=\"{ item, clear, index }\">\n <div class=\"flex-nowrap flex-v-center flex gap-thin\">\n <button \n v-if=\"playlist.tracks.length > 1\"\n @click.stop=\"moveTrack(index, 'up')\"\n :disabled=\"index === 0\"\n class=\"i-small pd-micro bg-grey-nano radius-extra flex-center flex aspect-1x1 hover:scale-[1.05]\"\n >\n <IconArrowUp class=\"i-micro\" />\n </button>\n \n <button \n v-if=\"playlist.tracks.length > 1\"\n @click.stop=\"moveTrack(index, 'down')\"\n :disabled=\"index === playlist.tracks.length - 1\"\n class=\"i-small pd-micro bg-grey-nano radius-extra flex-center flex aspect-1x1 hover:scale-[1.05]\"\n >\n <IconArrowDown class=\"i-micro\" />\n </button>\n \n <div class=\"flex-child-1\">\n <p class=\"fw-medium\">{{ item.title }}</p>\n <p class=\"t-small t-transp\">\n {{ item.artists?.map(a => a.name || a).join(', ') }}\n <span v-if=\"item.album\"> • {{ item.album.title || item.album }}</span>\n </p>\n </div>\n \n <span v-if=\"item.duration\" class=\"t-small t-transp\">\n {{ formatDuration(item.duration) }}\n </span>\n \n <button \n @click.stop=\"clear\"\n class=\"i-small pd-micro bg-red radius-extra flex-center flex aspect-1x1 hover:scale-[1.05]\"\n >\n <IconCross class=\"i-micro fill-white\" />\n </button>\n </div>\n </template>\n \n <!-- Track items in dropdown -->\n <template #item=\"{ item }\">\n <div class=\"flex-nowrap flex-v-center flex\">\n <div class=\"w-100\">\n <p class=\"fw-medium\">{{ item.title }}</p>\n <p class=\"t-small t-transp\">\n {{ item.artists?.map(a => a.name || a).join(', ') }}\n <span v-if=\"item.album\"> • {{ item.album.title || item.album }}</span>\n </p>\n </div>\n <span v-if=\"item.duration\" class=\"t-small t-transp mn-l-small\">\n {{ formatDuration(item.duration) }}\n </span>\n </div>\n </template>\n </BlockMultiselect>\n \n <!-- Tracks summary -->\n <div v-if=\"playlist.tracks.length > 0\" class=\"t-small t-transp mn-t-small\">\n {{ playlist.tracks.length }} tracks • {{ formatDuration(totalDuration) }}\n </div>\n </Block>\n \n <!-- Privacy & Settings Section -->\n <div class=\"bg-light pd-medium radius-medium\">\n <h3 class=\"h3 mn-b-medium\">Privacy & Settings</h3>\n \n <!-- Privacy -->\n <div class=\"mn-b-medium\">\n <p class=\"p-medium mn-b-small\">Privacy</p>\n <div class=\"flex gap-regular\">\n <Radio\n v-model:radio=\"playlist.isPublic\"\n :value=\"true\"\n name=\"privacy\"\n label=\"Public\"\n class=\"bg-white pd-small radius-small\"\n />\n <Radio\n v-model:radio=\"playlist.isPublic\"\n :value=\"false\"\n name=\"privacy\"\n label=\"Private\"\n class=\"bg-white pd-small radius-small\"\n />\n </div>\n </div>\n \n <!-- Collaborative -->\n <div class=\"mn-b-medium\">\n <p class=\"p-medium mn-b-small\">Collaborative Playlist</p>\n <div class=\"flex gap-regular\">\n <Radio\n v-model:radio=\"playlist.isCollaborative\"\n :value=\"true\"\n name=\"collaborative\"\n label=\"Yes\"\n class=\"bg-white pd-small radius-small\"\n />\n <Radio\n v-model:radio=\"playlist.isCollaborative\"\n :value=\"false\"\n name=\"collaborative\"\n label=\"No\"\n class=\"bg-white pd-small radius-small\"\n />\n </div>\n </div>\n </div>\n \n <!-- Submit Button -->\n <div class=\"flex flex-justify-between\">\n <Button\n @click=\"$router.go(-1)\"\n class=\"bg-grey-nano t-black\"\n :showSucces=\"false\"\n :showLoader=\"false\"\n >\n Cancel\n </Button>\n \n <Button\n :submit=\"submitForm\"\n class=\"bg-main t-black\"\n :text=\"{\n success: editMode ? 'Updated!' : 'Created!'\n }\"\n >\n {{ editMode ? 'Update Playlist' : 'Create Playlist' }}\n </Button>\n </div>\n </form>\n </div>\n</template>\n\n<script setup>\nimport { ref, reactive, onMounted, watch, computed } from 'vue';\nimport { useRouter, useRoute } from 'vue-router';\n\n// Import Martyrs components\nimport Field from '@martyrs/src/components/Field/Field.vue';\nimport Block from '@martyrs/src/components/Block/Block.vue';\nimport Button from '@martyrs/src/components/Button/Button.vue';\nimport Radio from '@martyrs/src/components/Radio/Radio.vue';\nimport UploadImage from '@martyrs/src/components/UploadImage/UploadImage.vue';\nimport IconCross from '@martyrs/src/modules/icons/navigation/IconCross.vue';\nimport IconArrowUp from '@martyrs/src/modules/icons/navigation/IconCross.vue';\nimport IconArrowDown from '@martyrs/src/modules/icons/navigation/IconCross.vue';\n\nimport BlockMultiselect from '@martyrs/src/modules/core/views/components/blocks/BlockMultiselect.vue';\n\n// Import stores\nimport * as playlistsStore from '../../store/playlists';\nimport * as tracksStore from '../../store/tracks';\nimport { useStore } from '@martyrs/src/modules/core/views/store/core.store.js';\n\nconst store = useStore();\nimport * as auth from '@martyrs/src/modules/auth/views/store/auth.js';\n\n// Props\nconst props = defineProps({\n editMode: {\n type: Boolean,\n default: false\n },\n url: {\n type: String,\n default: ''\n }\n});\n\n// Router and route\nconst router = useRouter();\nconst route = useRoute();\n\n// State\nconst playlist = reactive({\n title: '',\n description: '',\n coverUrl: '',\n tracks: [],\n url: '',\n isPublic: true,\n isCollaborative: false\n});\n\nconst validation = reactive({\n title: false,\n description: false\n});\n\n// Track if URL was manually entered\nconst urlManuallySet = ref(false);\n\n// Function to generate URL-friendly slug from text\nconst generateSlug = (text) => {\n if (!text) return '';\n return text\n .toLowerCase()\n .replace(/[^a-z0-9\\s-]/g, '') // Remove special characters\n .replace(/\\s+/g, '-') // Replace spaces with hyphens\n .replace(/-+/g, '-') // Replace multiple hyphens with single\n .trim('-'); // Remove leading/trailing hyphens\n};\n\n// Watch for changes in playlist title to auto-generate URL\nwatch(() => playlist.title, (newTitle) => {\n // Only auto-generate if URL hasn't been manually set and we're not in edit mode\n if (!urlManuallySet.value && !props.editMode) {\n playlist.url = generateSlug(newTitle);\n }\n});\n\n// Watch for manual changes to URL field\nwatch(() => playlist.url, (newUrl, oldUrl) => {\n // If user manually changes URL, mark as manually set\n if (newUrl !== generateSlug(playlist.title)) {\n urlManuallySet.value = true;\n }\n});\n\n// Computed\nconst totalDuration = computed(() => {\n return playlist.tracks.reduce((sum, track) => sum + (track.duration || 0), 0);\n});\n\n// Methods\nconst formatDuration = (seconds) => {\n if (!seconds) return '0:00';\n const hours = Math.floor(seconds / 3600);\n const minutes = Math.floor((seconds % 3600) / 60);\n const secs = seconds % 60;\n \n if (hours > 0) {\n return `${hours}:${minutes.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;\n }\n return `${minutes}:${secs.toString().padStart(2, '0')}`;\n};\n\nconst moveTrack = (index, direction) => {\n const newIndex = direction === 'up' ? index - 1 : index + 1;\n if (newIndex < 0 || newIndex >= playlist.tracks.length) return;\n \n const tracks = [...playlist.tracks];\n [tracks[index], tracks[newIndex]] = [tracks[newIndex], tracks[index]];\n playlist.tracks = tracks;\n};\n\nconst fetchPlaylist = async () => {\n if (!props.url) return;\n \n try {\n const fetchedPlaylist = await playlistsStore.actions.fetchPlaylistByUrl(props.url);\n \n if (!fetchedPlaylist) {\n store.core.actions.setError({\n message: 'Playlist not found'\n });\n return;\n }\n \n // Update local playlist data\n Object.assign(playlist, {\n title: fetchedPlaylist.title || '',\n description: fetchedPlaylist.description || '',\n coverUrl: fetchedPlaylist.coverUrl || '',\n tracks: fetchedPlaylist.tracks || [],\n url: fetchedPlaylist.url || '',\n isPublic: fetchedPlaylist.isPublic !== false,\n isCollaborative: fetchedPlaylist.isCollaborative || false,\n _id: fetchedPlaylist._id\n });\n \n } catch (error) {\n console.error('Error fetching playlist:', error);\n store.core.actions.setError({\n message: 'Failed to load playlist details'\n });\n }\n};\n\nconst validateForm = () => {\n let isValid = true;\n \n // Validate title\n if (!playlist.title.trim()) {\n validation.title = {\n message: 'Playlist title is required'\n };\n isValid = false;\n } else {\n validation.title = false;\n }\n \n // Validate description\n if (playlist.description && playlist.description.length > 2000) {\n validation.description = {\n message: 'Description is too long (max 2000 characters)'\n };\n isValid = false;\n } else {\n validation.description = false;\n }\n \n return isValid;\n};\n\nconst submitForm = async () => {\n if (!validateForm()) {\n return;\n }\n \n try {\n // Prepare data for submission\n const formData = {\n ...playlist,\n tracks: playlist.tracks.map(track => ({\n track: track._id || track,\n addedAt: new Date()\n }))\n };\n \n // Add ownership data if creating new playlist\n if (!props.editMode) {\n formData.creator = {\n type: 'user',\n target: auth.state.user._id\n };\n formData.owner = {\n type: 'user',\n target: auth.state.user._id\n };\n }\n \n let result;\n if (props.editMode) {\n result = await playlistsStore.actions.updatePlaylist(formData);\n } else {\n result = await playlistsStore.actions.createPlaylist(formData);\n }\n \n // Navigate to playlist detail page\n setTimeout(() => {\n router.push({\n name: 'playlist',\n params: { url: result.url }\n });\n }, 1000);\n \n } catch (error) {\n console.error('Error saving playlist:', error);\n store.core.actions.setError({\n message: 'Failed to save playlist'\n });\n }\n};\n\nconst handleUploadError = (error) => {\n console.error('Upload error:', error);\n store.core.actions.setError({\n message: 'Error uploading image'\n });\n};\n\n// Lifecycle hooks\nonMounted(async () => {\n if (props.editMode) {\n await fetchPlaylist();\n // Mark URL as manually set in edit mode to prevent auto-generation\n urlManuallySet.value = true;\n }\n});\n</script>\n"],"names":["playlistsStore.actions","auth.state"],"mappings":"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"}
|
|
@@ -67,7 +67,7 @@ const _sfc_main = {
|
|
|
67
67
|
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => searchQuery.value = $event),
|
|
68
68
|
type: "text",
|
|
69
69
|
placeholder: __props.placeholder,
|
|
70
|
-
class: "bg-transparent border-none flex-1",
|
|
70
|
+
class: "bg-transparent border-none flex-child-1",
|
|
71
71
|
onKeydown: withKeys(handleSearch, ["enter"])
|
|
72
72
|
}, null, 40, _hoisted_2), [
|
|
73
73
|
[vModelText, searchQuery.value]
|
|
@@ -91,7 +91,7 @@ const _sfc_main = {
|
|
|
91
91
|
};
|
|
92
92
|
}
|
|
93
93
|
};
|
|
94
|
-
const SearchForm = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-
|
|
94
|
+
const SearchForm = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-120f776b"]]);
|
|
95
95
|
export {
|
|
96
96
|
SearchForm as default
|
|
97
97
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SearchForm.vue.js","sources":["../../../../../../../src/modules/music/components/forms/SearchForm.vue"],"sourcesContent":["<!-- components/forms/SearchForm.vue -->\n<template>\n <div class=\"search-form flex-v-center flex bg-white-transp-50 pd-thin radius-extra\">\n <IconSearch class=\"i-small mn-r-small\" fill=\"rgb(var(--grey))\"/>\n <input \n ref=\"searchInput\"\n v-model=\"searchQuery\"\n type=\"text\"\n :placeholder=\"placeholder\"\n class=\"bg-transparent border-none flex-1\"\n @keydown.enter=\"handleSearch\"\n />\n <Button \n v-if=\"searchQuery.length > 0\"\n @click=\"clearSearch\"\n class=\"bg-transparent border-none pd-zero\"\n :showLoader=\"false\" \n :showSucces=\"false\"\n >\n <IconCross class=\"i-small\" fill=\"rgb(var(--grey))\"/>\n </Button>\n </div>\n</template>\n\n<script setup>\nimport { ref, watch, onMounted, defineEmits } from 'vue';\nimport Button from '@martyrs/src/components/Button/Button.vue';\nimport IconSearch from '@martyrs/src/modules/icons/navigation/IconSearch.vue';\nimport IconCross from '@martyrs/src/modules/icons/navigation/IconCross.vue';\n\nconst props = defineProps({\n placeholder: {\n type: String,\n default: 'Search...'\n },\n initialQuery: {\n type: String,\n default: ''\n }\n});\n\nconst emit = defineEmits(['search']);\n\nconst searchInput = ref(null);\nconst searchQuery = ref(props.initialQuery);\nlet searchTimeout = null;\n\nconst handleSearch = () => {\n emit('search', searchQuery.value.trim());\n};\n\nconst clearSearch = () => {\n searchQuery.value = '';\n emit('search', '');\n searchInput.value?.focus();\n};\n\n// Watch for changes in search query and emit search with debounce\nwatch(searchQuery, (newQuery) => {\n // Clear previous timeout\n if (searchTimeout) {\n clearTimeout(searchTimeout);\n }\n \n if (newQuery.trim().length >= 2) {\n // Set new timeout for debounce\n searchTimeout = setTimeout(() => {\n handleSearch();\n }, 300);\n } else if (newQuery.trim().length === 0) {\n emit('search', '');\n }\n});\n\n// Watch for changes in initialQuery prop\nwatch(() => props.initialQuery, (newQuery) => {\n if (newQuery !== searchQuery.value) {\n searchQuery.value = newQuery;\n }\n});\n\nonMounted(() => {\n if (props.initialQuery) {\n searchQuery.value = props.initialQuery;\n }\n});\n</script>\n\n<style scoped>\n.search-form {\n transition: background-color 0.2s ease;\n}\n\n.search-form:focus-within {\n background-color: rgba(var(--dark), 0.8);\n}\n\ninput::placeholder {\n color: rgba(var(--grey), 0.8);\n}\n\ninput:focus {\n outline: none;\n}\n</style>"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;AA8BA,UAAM,QAAQ;AAWd,UAAM,OAAO;AAEb,UAAM,cAAc,IAAI,IAAI;AAC5B,UAAM,cAAc,IAAI,MAAM,YAAY;AAC1C,QAAI,gBAAgB;AAEpB,UAAM,eAAe,MAAM;AACzB,WAAK,UAAU,YAAY,MAAM,KAAI,CAAE;AAAA,IACzC;AAEA,UAAM,cAAc,MAAM;AACxB,kBAAY,QAAQ;AACpB,WAAK,UAAU,EAAE;AACjB,kBAAY,OAAO,MAAK;AAAA,IAC1B;AAGA,UAAM,aAAa,CAAC,aAAa;AAE/B,UAAI,eAAe;AACjB,qBAAa,aAAa;AAAA,MAC5B;AAEA,UAAI,SAAS,OAAO,UAAU,GAAG;AAE/B,wBAAgB,WAAW,MAAM;AAC/B,uBAAY;AAAA,QACd,GAAG,GAAG;AAAA,MACR,WAAW,SAAS,KAAI,EAAG,WAAW,GAAG;AACvC,aAAK,UAAU,EAAE;AAAA,MACnB;AAAA,IACF,CAAC;AAGD,UAAM,MAAM,MAAM,cAAc,CAAC,aAAa;AAC5C,UAAI,aAAa,YAAY,OAAO;AAClC,oBAAY,QAAQ;AAAA,MACtB;AAAA,IACF,CAAC;AAED,cAAU,MAAM;AACd,UAAI,MAAM,cAAc;AACtB,oBAAY,QAAQ,MAAM;AAAA,MAC5B;AAAA,IACF,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
1
|
+
{"version":3,"file":"SearchForm.vue.js","sources":["../../../../../../../src/modules/music/components/forms/SearchForm.vue"],"sourcesContent":["<!-- components/forms/SearchForm.vue -->\n<template>\n <div class=\"search-form flex-v-center flex bg-white-transp-50 pd-thin radius-extra\">\n <IconSearch class=\"i-small mn-r-small\" fill=\"rgb(var(--grey))\"/>\n <input \n ref=\"searchInput\"\n v-model=\"searchQuery\"\n type=\"text\"\n :placeholder=\"placeholder\"\n class=\"bg-transparent border-none flex-child-1\"\n @keydown.enter=\"handleSearch\"\n />\n <Button \n v-if=\"searchQuery.length > 0\"\n @click=\"clearSearch\"\n class=\"bg-transparent border-none pd-zero\"\n :showLoader=\"false\" \n :showSucces=\"false\"\n >\n <IconCross class=\"i-small\" fill=\"rgb(var(--grey))\"/>\n </Button>\n </div>\n</template>\n\n<script setup>\nimport { ref, watch, onMounted, defineEmits } from 'vue';\nimport Button from '@martyrs/src/components/Button/Button.vue';\nimport IconSearch from '@martyrs/src/modules/icons/navigation/IconSearch.vue';\nimport IconCross from '@martyrs/src/modules/icons/navigation/IconCross.vue';\n\nconst props = defineProps({\n placeholder: {\n type: String,\n default: 'Search...'\n },\n initialQuery: {\n type: String,\n default: ''\n }\n});\n\nconst emit = defineEmits(['search']);\n\nconst searchInput = ref(null);\nconst searchQuery = ref(props.initialQuery);\nlet searchTimeout = null;\n\nconst handleSearch = () => {\n emit('search', searchQuery.value.trim());\n};\n\nconst clearSearch = () => {\n searchQuery.value = '';\n emit('search', '');\n searchInput.value?.focus();\n};\n\n// Watch for changes in search query and emit search with debounce\nwatch(searchQuery, (newQuery) => {\n // Clear previous timeout\n if (searchTimeout) {\n clearTimeout(searchTimeout);\n }\n \n if (newQuery.trim().length >= 2) {\n // Set new timeout for debounce\n searchTimeout = setTimeout(() => {\n handleSearch();\n }, 300);\n } else if (newQuery.trim().length === 0) {\n emit('search', '');\n }\n});\n\n// Watch for changes in initialQuery prop\nwatch(() => props.initialQuery, (newQuery) => {\n if (newQuery !== searchQuery.value) {\n searchQuery.value = newQuery;\n }\n});\n\nonMounted(() => {\n if (props.initialQuery) {\n searchQuery.value = props.initialQuery;\n }\n});\n</script>\n\n<style scoped>\n.search-form {\n transition: background-color 0.2s ease;\n}\n\n.search-form:focus-within {\n background-color: rgba(var(--dark), 0.8);\n}\n\ninput::placeholder {\n color: rgba(var(--grey), 0.8);\n}\n\ninput:focus {\n outline: none;\n}\n</style>"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;AA8BA,UAAM,QAAQ;AAWd,UAAM,OAAO;AAEb,UAAM,cAAc,IAAI,IAAI;AAC5B,UAAM,cAAc,IAAI,MAAM,YAAY;AAC1C,QAAI,gBAAgB;AAEpB,UAAM,eAAe,MAAM;AACzB,WAAK,UAAU,YAAY,MAAM,KAAI,CAAE;AAAA,IACzC;AAEA,UAAM,cAAc,MAAM;AACxB,kBAAY,QAAQ;AACpB,WAAK,UAAU,EAAE;AACjB,kBAAY,OAAO,MAAK;AAAA,IAC1B;AAGA,UAAM,aAAa,CAAC,aAAa;AAE/B,UAAI,eAAe;AACjB,qBAAa,aAAa;AAAA,MAC5B;AAEA,UAAI,SAAS,OAAO,UAAU,GAAG;AAE/B,wBAAgB,WAAW,MAAM;AAC/B,uBAAY;AAAA,QACd,GAAG,GAAG;AAAA,MACR,WAAW,SAAS,KAAI,EAAG,WAAW,GAAG;AACvC,aAAK,UAAU,EAAE;AAAA,MACnB;AAAA,IACF,CAAC;AAGD,UAAM,MAAM,MAAM,cAAc,CAAC,aAAa;AAC5C,UAAI,aAAa,YAAY,OAAO;AAClC,oBAAY,QAAQ;AAAA,MACtB;AAAA,IACF,CAAC;AAED,cAAU,MAAM;AACd,UAAI,MAAM,cAAc;AACtB,oBAAY,QAAQ,MAAM;AAAA,MAC5B;AAAA,IACF,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -18,34 +18,34 @@ import { state } from "../../../auth/views/store/auth.js";
|
|
|
18
18
|
const _hoisted_1 = { class: "pd-medium" };
|
|
19
19
|
const _hoisted_2 = { class: "h2 mn-b-medium" };
|
|
20
20
|
const _hoisted_3 = { class: "bg-light pd-medium radius-medium" };
|
|
21
|
-
const _hoisted_4 = { class: "cols-
|
|
21
|
+
const _hoisted_4 = { class: "cols-[fit-content(100%)_1fr] mobile:cols-1 gap-regular" };
|
|
22
22
|
const _hoisted_5 = { class: "bg-light pd-medium radius-medium" };
|
|
23
23
|
const _hoisted_6 = { class: "flex-nowrap flex-v-center flex gap-thin" };
|
|
24
|
-
const _hoisted_7 = { class: "
|
|
24
|
+
const _hoisted_7 = { class: "fw-medium" };
|
|
25
25
|
const _hoisted_8 = ["onClick"];
|
|
26
26
|
const _hoisted_9 = { class: "flex-nowrap flex-v-center flex" };
|
|
27
27
|
const _hoisted_10 = { class: "w-100" };
|
|
28
|
-
const _hoisted_11 = { class: "
|
|
28
|
+
const _hoisted_11 = { class: "fw-medium" };
|
|
29
29
|
const _hoisted_12 = {
|
|
30
30
|
key: 0,
|
|
31
31
|
class: "t-small t-transp"
|
|
32
32
|
};
|
|
33
33
|
const _hoisted_13 = { class: "flex-nowrap flex-v-center flex gap-thin" };
|
|
34
|
-
const _hoisted_14 = { class: "
|
|
34
|
+
const _hoisted_14 = { class: "fw-medium" };
|
|
35
35
|
const _hoisted_15 = ["onClick"];
|
|
36
36
|
const _hoisted_16 = { class: "flex-nowrap flex-v-center flex" };
|
|
37
37
|
const _hoisted_17 = { class: "w-100" };
|
|
38
|
-
const _hoisted_18 = { class: "
|
|
38
|
+
const _hoisted_18 = { class: "fw-medium" };
|
|
39
39
|
const _hoisted_19 = {
|
|
40
40
|
key: 0,
|
|
41
41
|
class: "t-small t-transp"
|
|
42
42
|
};
|
|
43
43
|
const _hoisted_20 = { class: "flex-nowrap flex-v-center flex gap-thin" };
|
|
44
|
-
const _hoisted_21 = { class: "
|
|
44
|
+
const _hoisted_21 = { class: "fw-medium" };
|
|
45
45
|
const _hoisted_22 = ["onClick"];
|
|
46
46
|
const _hoisted_23 = { class: "flex-nowrap flex-v-center flex" };
|
|
47
47
|
const _hoisted_24 = { class: "w-100" };
|
|
48
|
-
const _hoisted_25 = { class: "
|
|
48
|
+
const _hoisted_25 = { class: "fw-medium" };
|
|
49
49
|
const _hoisted_26 = {
|
|
50
50
|
key: 0,
|
|
51
51
|
class: "t-small t-transp"
|
|
@@ -338,7 +338,7 @@ const _sfc_main = {
|
|
|
338
338
|
classSearch: "bg-white radius-small",
|
|
339
339
|
classSelected: "bg-white pd-small radius-small",
|
|
340
340
|
classDropdown: "bg-white pd-small radius-medium bs-small",
|
|
341
|
-
classItem: "pd-small radius-small hover
|
|
341
|
+
classItem: "pd-small radius-small hover:bg-light cursor-pointer",
|
|
342
342
|
classFeed: "h-max-30r gap-thin flex-column flex o-scroll"
|
|
343
343
|
}, {
|
|
344
344
|
selected: withCtx(({ item, clear }) => [
|
|
@@ -346,7 +346,7 @@ const _sfc_main = {
|
|
|
346
346
|
createElementVNode("span", _hoisted_7, toDisplayString(item?.name || item), 1),
|
|
347
347
|
createElementVNode("button", {
|
|
348
348
|
onClick: withModifiers(clear, ["stop"]),
|
|
349
|
-
class: "i-small pd-micro bg-red radius-extra flex-center flex aspect-1x1 hover
|
|
349
|
+
class: "i-small pd-micro bg-red radius-extra flex-center flex aspect-1x1 hover:scale-[1.05]"
|
|
350
350
|
}, [
|
|
351
351
|
createVNode(_sfc_main$2, { class: "i-micro fill-white" })
|
|
352
352
|
], 8, _hoisted_8)
|
|
@@ -403,7 +403,7 @@ const _sfc_main = {
|
|
|
403
403
|
classSearch: "bg-white radius-small",
|
|
404
404
|
classSelected: "bg-white pd-small radius-small",
|
|
405
405
|
classDropdown: "bg-white pd-small radius-medium bs-small",
|
|
406
|
-
classItem: "pd-small radius-small hover
|
|
406
|
+
classItem: "pd-small radius-small hover:bg-light cursor-pointer",
|
|
407
407
|
classFeed: "h-max-30r gap-thin flex-column flex o-scroll"
|
|
408
408
|
}, {
|
|
409
409
|
selected: withCtx(({ item, clear }) => [
|
|
@@ -411,7 +411,7 @@ const _sfc_main = {
|
|
|
411
411
|
createElementVNode("span", _hoisted_14, toDisplayString(item?.title || item), 1),
|
|
412
412
|
createElementVNode("button", {
|
|
413
413
|
onClick: withModifiers(clear, ["stop"]),
|
|
414
|
-
class: "i-small pd-micro bg-red radius-extra flex-center flex aspect-1x1 hover
|
|
414
|
+
class: "i-small pd-micro bg-red radius-extra flex-center flex aspect-1x1 hover:scale-[1.05]"
|
|
415
415
|
}, [
|
|
416
416
|
createVNode(_sfc_main$2, { class: "i-micro fill-white" })
|
|
417
417
|
], 8, _hoisted_15)
|
|
@@ -468,7 +468,7 @@ const _sfc_main = {
|
|
|
468
468
|
classSearch: "bg-white radius-small",
|
|
469
469
|
classSelected: "bg-white pd-small radius-small",
|
|
470
470
|
classDropdown: "bg-white pd-small radius-medium bs-small",
|
|
471
|
-
classItem: "pd-small radius-small hover
|
|
471
|
+
classItem: "pd-small radius-small hover:bg-light cursor-pointer",
|
|
472
472
|
classFeed: "h-max-30r gap-thin flex-column flex o-scroll"
|
|
473
473
|
}, {
|
|
474
474
|
selected: withCtx(({ item, clear }) => [
|
|
@@ -476,7 +476,7 @@ const _sfc_main = {
|
|
|
476
476
|
createElementVNode("span", _hoisted_21, toDisplayString(item?.name || item), 1),
|
|
477
477
|
createElementVNode("button", {
|
|
478
478
|
onClick: withModifiers(clear, ["stop"]),
|
|
479
|
-
class: "i-small pd-micro bg-red radius-extra flex-center flex aspect-1x1 hover
|
|
479
|
+
class: "i-small pd-micro bg-red radius-extra flex-center flex aspect-1x1 hover:scale-[1.05]"
|
|
480
480
|
}, [
|
|
481
481
|
createVNode(_sfc_main$2, { class: "i-micro fill-white" })
|
|
482
482
|
], 8, _hoisted_22)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TrackForm.vue.js","sources":["../../../../../../../src/modules/music/components/forms/TrackForm.vue"],"sourcesContent":["<!-- components/forms/TrackForm.vue -->\n<template>\n <div class=\"pd-medium\">\n <h2 class=\"h2 mn-b-medium\">{{ editMode ? 'Edit Track' : 'Upload Track' }}</h2>\n \n <form @submit.prevent=\"submitForm\" class=\"cols-1 gap-regular\">\n <!-- Media Section -->\n <div class=\"bg-light pd-medium radius-medium\">\n <h3 class=\"h3 mn-b-medium\">Media</h3>\n \n <div class=\"cols-2-fit-content mobile:cols-1 gap-regular\">\n <!-- Track Cover -->\n <div>\n <p class=\"p-medium mn-b-small\">Cover Image</p>\n <UploadImage\n v-model:photo=\"form.coverUrl\"\n uploadPath=\"tracks/covers\"\n class=\"aspect-1x1 h-15r radius-small o-hidden mn-b-small\"\n @error=\"handleUploadError\"\n />\n </div>\n \n <!-- Audio File -->\n <div>\n <p class=\"p-medium mn-b-small\">Audio File</p>\n <Upload\n v-model:field=\"form.fileUrl\"\n @file-change=\"(url) => form.fileUrl = url\"\n type=\"file\"\n uploadPath=\"tracks/audio\"\n class=\"w-100 h-15r bg-white radius-small pd-small\"\n :validation=\"validationErrors.fileUrl\"\n />\n </div>\n </div>\n </div>\n \n <!-- Basic Info Section -->\n <div class=\"bg-light pd-medium radius-medium\">\n <h3 class=\"h3 mn-b-medium\">Basic Information</h3>\n \n <!-- Track Title -->\n <Field\n v-model:field=\"form.title\"\n label=\"Track Title\"\n placeholder=\"Enter track title\"\n class=\"bg-white radius-small pd-small mn-b-thin\"\n :validation=\"validationErrors.title\"\n />\n \n <!-- URL -->\n <Field\n v-model:field=\"form.url\"\n label=\"URL\"\n placeholder=\"Leave blank for auto-generation based on the track title\"\n class=\"bg-white radius-small pd-small mn-b-small\"\n />\n\n <!-- Artist Selection -->\n \n\n \n \n <!-- Release Date -->\n <Field\n v-model:field=\"form.releaseDate\"\n label=\"Release Date\"\n type=\"date\"\n class=\"bg-white radius-small pd-small mn-b-thin\"\n :validation=\"validationErrors.releaseDate\"\n />\n \n <!-- Duration -->\n <Field\n v-model:field=\"form.duration\"\n label=\"Duration (seconds)\"\n type=\"number\"\n placeholder=\"Track duration in seconds\"\n class=\"bg-white radius-small pd-small mn-b-thin\"\n />\n </div> \n\n <Block title=\"Artist\">\n <BlockMultiselect\n v-model=\"form.artists\"\n placeholder=\"Search artists...\"\n :multiple=\"false\"\n :transform=\"(item) => ({ _id: item._id, name: item.name })\"\n :store=\"{\n read: (options) => artistsActions.fetchArtists(options),\n state: artistsState\n }\"\n :options=\"{\n rootOnly: false,\n excludeChildren: false,\n limit: 50\n }\"\n :skeleton=\"{\n hide: false,\n horizontal: true,\n class: 'radius-small',\n structure: [{ \n block: 'text', size: 'large'\n }]\n }\"\n :states=\"{\n empty: {\n title: 'No artists found',\n description: 'Try different search terms or create a new artist',\n class: 'radius-small'\n }\n }\"\n key=\"_id\"\n :label=\"item => item.name\"\n classSearch=\"bg-white radius-small\"\n classSelected=\"bg-white pd-small radius-small\"\n classDropdown=\"bg-white pd-small radius-medium bs-small\"\n classItem=\"pd-small radius-small hover-bg-light cursor-pointer\"\n classFeed=\"h-max-30r gap-thin flex-column flex o-scroll\"\n >\n <!-- Selected artist slot -->\n <template #selected=\"{ item, clear }\">\n <div class=\"flex-nowrap flex-v-center flex gap-thin\">\n <span class=\"t-medium\">{{ item?.name || item }}</span>\n <button \n @click.stop=\"clear\"\n class=\"i-small pd-micro bg-red radius-extra flex-center flex aspect-1x1 hover-scale-1\"\n >\n <IconCross class=\"i-micro fill-white\" />\n </button>\n </div>\n </template>\n \n <!-- Artist item slot -->\n <template #item=\"{ item }\">\n <div class=\"flex-nowrap flex-v-center flex\">\n <div class=\"w-100\">\n <p class=\"t-medium\">{{ item.name }}</p>\n <p v-if=\"item.bio\" class=\"t-small t-transp\">{{ item.bio }}</p>\n </div>\n </div>\n </template>\n </BlockMultiselect>\n </Block>\n\n <!-- Album Selection -->\n <Block title=\"Album (Optional)\">\n <BlockMultiselect\n v-model=\"form.albums\"\n placeholder=\"Search albums...\"\n :multiple=\"false\"\n :transform=\"(item) => ({ _id: item._id, title: item.title })\"\n :store=\"{\n read: (options) => albumsActions.fetchAlbums(options),\n state: albumsState\n }\"\n :options=\"{\n rootOnly: false,\n excludeChildren: false,\n limit: 50\n }\"\n :skeleton=\"{\n hide: false,\n horizontal: true,\n class: 'radius-small',\n structure: [{ \n block: 'text', size: 'large'\n }]\n }\"\n :states=\"{\n empty: {\n title: 'No albums found',\n description: 'Try different search terms or create a new album',\n class: 'radius-small'\n }\n }\"\n key=\"_id\"\n :label=\"item => item.title\"\n classSearch=\"bg-white radius-small\"\n classSelected=\"bg-white pd-small radius-small\"\n classDropdown=\"bg-white pd-small radius-medium bs-small\"\n classItem=\"pd-small radius-small hover-bg-light cursor-pointer\"\n classFeed=\"h-max-30r gap-thin flex-column flex o-scroll\"\n >\n <!-- Selected album slot -->\n <template #selected=\"{ item, clear }\">\n <div class=\"flex-nowrap flex-v-center flex gap-thin\">\n <span class=\"t-medium\">{{ item?.title || item }}</span>\n <button \n @click.stop=\"clear\"\n class=\"i-small pd-micro bg-red radius-extra flex-center flex aspect-1x1 hover-scale-1\"\n >\n <IconCross class=\"i-micro fill-white\" />\n </button>\n </div>\n </template>\n \n <!-- Album item slot -->\n <template #item=\"{ item }\">\n <div class=\"flex-nowrap flex-v-center flex\">\n <div class=\"w-100\">\n <p class=\"t-medium\">{{ item.title }}</p>\n <p v-if=\"item.description\" class=\"t-small t-transp\">{{ item.description }}</p>\n </div>\n </div>\n </template>\n </BlockMultiselect>\n </Block>\n \n <!-- Genres Section -->\n <Block title=\"Genres\">\n <BlockMultiselect\n v-model=\"form.genres\"\n placeholder=\"Search genres...\"\n :multiple=\"true\"\n :transform=\"(item) => ({ _id: item._id, name: item.name })\"\n :store=\"{\n read: (options) => genresActions.fetchGenres(options),\n state: genresState\n }\"\n :options=\"{\n rootOnly: false,\n excludeChildren: false,\n limit: 50\n }\"\n :skeleton=\"{\n hide: false,\n horizontal: true,\n class: 'radius-small',\n structure: [{ \n block: 'text', size: 'large'\n }]\n }\"\n :states=\"{\n empty: {\n title: 'No genres found',\n description: 'Try different search terms or create a new genre',\n class: 'radius-small'\n }\n }\"\n key=\"_id\"\n :label=\"item => item.name\"\n classSearch=\"bg-white radius-small\"\n classSelected=\"bg-white pd-small radius-small\"\n classDropdown=\"bg-white pd-small radius-medium bs-small\"\n classItem=\"pd-small radius-small hover-bg-light cursor-pointer\"\n classFeed=\"h-max-30r gap-thin flex-column flex o-scroll\"\n >\n <!-- Selected genres slot -->\n <template #selected=\"{ item, clear }\">\n <div class=\"flex-nowrap flex-v-center flex gap-thin\">\n <span class=\"t-medium\">{{ item?.name || item }}</span>\n <button \n @click.stop=\"clear\"\n class=\"i-small pd-micro bg-red radius-extra flex-center flex aspect-1x1 hover-scale-1\"\n >\n <IconCross class=\"i-micro fill-white\" />\n </button>\n </div>\n </template>\n \n <!-- Genre item slot -->\n <template #item=\"{ item }\">\n <div class=\"flex-nowrap flex-v-center flex\">\n <div class=\"w-100\">\n <p class=\"t-medium\">{{ item.name }}</p>\n <p v-if=\"item.description\" class=\"t-small t-transp\">{{ item.description }}</p>\n </div>\n </div>\n </template>\n </BlockMultiselect>\n </Block>\n \n <!-- Content Settings Section -->\n <div class=\"bg-light pd-medium radius-medium\">\n <h3 class=\"h3 mn-b-medium\">Content Settings</h3>\n \n <Checkbox\n v-model:checkbox=\"form.isExplicit\"\n label=\"Explicit Content\"\n class=\"bg-white radius-small pd-small mn-b-thin\"\n />\n \n <Checkbox\n v-model:checkbox=\"form.isPublic\"\n label=\"Public Track\"\n class=\"bg-white radius-small pd-small mn-b-thin\"\n />\n </div>\n \n \n \n <!-- Additional Info Section -->\n <div class=\"bg-light pd-medium radius-medium\">\n <h3 class=\"h3 mn-b-medium\">Additional Information</h3>\n \n <!-- Lyrics -->\n <Field\n v-model:field=\"form.lyrics\"\n label=\"Lyrics (Optional)\"\n type=\"textarea\"\n placeholder=\"Enter track lyrics\"\n class=\"bg-white radius-small pd-small mn-b-thin\"\n />\n </div>\n \n <!-- Status Section -->\n <div class=\"bg-light pd-medium radius-medium\">\n <h3 class=\"h3 mn-b-medium\">Publishing Status</h3>\n \n <Select\n v-model:select=\"form.status\"\n :options=\"statusOptions\"\n label=\"Status\"\n class=\"bg-white radius-small pd-small mn-b-thin\"\n />\n </div>\n \n <!-- Submit Button -->\n <div class=\"flex flex-justify-between\">\n <Button\n @click=\"router.go(-1)\"\n class=\"bg-grey-nano t-black\"\n :showSucces=\"false\"\n :showLoader=\"false\"\n >\n Cancel\n </Button>\n \n <Button\n :submit=\"submitForm\"\n class=\"bg-main t-black\"\n :text=\"{\n success: editMode ? 'Updated!' : 'Uploaded!'\n }\"\n >\n {{ editMode ? 'Update Track' : 'Upload Track' }}\n </Button>\n </div>\n </form>\n </div>\n</template>\n\n<script setup>\nimport { ref, reactive, onMounted, watch } from 'vue';\nimport { useRouter, useRoute } from 'vue-router';\n\n// Import Martyrs components\nimport Field from '@martyrs/src/components/Field/Field.vue';\nimport Block from '@martyrs/src/components/Block/Block.vue';\nimport Button from '@martyrs/src/components/Button/Button.vue';\nimport Checkbox from '@martyrs/src/components/Checkbox/Checkbox.vue';\nimport Select from '@martyrs/src/components/Select/Select.vue';\nimport UploadImage from '@martyrs/src/components/UploadImage/UploadImage.vue';\nimport Upload from '@martyrs/src/components/Upload/Upload.vue';\nimport IconCross from '@martyrs/src/modules/icons/navigation/IconCross.vue';\n\nimport BlockMultiselect from '@martyrs/src/modules/core/views/components/blocks/BlockMultiselect.vue';\n\n// Import stores\nimport * as tracksStore from '../../store/tracks';\nimport * as artistsStore from '../../store/artists';\nimport * as albumsStore from '../../store/albums';\nimport * as genresStore from '../../store/genres';\nimport { useStore } from '@martyrs/src/modules/core/views/store/core.store.js';\n\nconst store = useStore();\nimport * as auth from '@martyrs/src/modules/auth/views/store/auth.js';\n\n// Store states and actions\nconst { state: artistsState, actions: artistsActions } = artistsStore;\nconst { state: albumsState, actions: albumsActions } = albumsStore;\nconst { state: genresState, actions: genresActions } = genresStore;\n\n// Props\nconst props = defineProps({\n editMode: {\n type: Boolean,\n default: false\n },\n url: {\n type: String,\n default: ''\n }\n});\n\n// Router and route\nconst router = useRouter();\nconst route = useRoute();\n\nconst emit = defineEmits(['uploaded']);\n\n// State\nconst form = reactive({\n title: '',\n artists: [],\n albums: [],\n genres: [],\n duration: 0,\n fileUrl: '',\n coverUrl: '',\n releaseDate: new Date().toISOString().split('T')[0],\n isExplicit: false,\n isPublic: true,\n lyrics: '',\n url: '',\n status: 'draft'\n});\n\nconst validationErrors = reactive({\n title: false,\n fileUrl: false,\n releaseDate: false\n});\n\n// Track if URL was manually entered\nconst urlManuallySet = ref(false);\n\n// Status options\nconst statusOptions = [\n 'draft',\n 'published',\n 'archived'\n];\n\n// Function to generate URL-friendly slug from text\nconst generateSlug = (text) => {\n if (!text) return '';\n return text\n .toLowerCase()\n .replace(/[^a-z0-9\\s-]/g, '') // Remove special characters\n .replace(/\\s+/g, '-') // Replace spaces with hyphens\n .replace(/-+/g, '-') // Replace multiple hyphens with single\n .trim('-'); // Remove leading/trailing hyphens\n};\n\n// Watch for changes in track title to auto-generate URL\nwatch(() => form.title, (newTitle) => {\n // Only auto-generate if URL hasn't been manually set and we're not in edit mode\n if (!urlManuallySet.value && !props.editMode) {\n form.url = generateSlug(newTitle);\n }\n});\n\n// Watch for manual changes to URL field\nwatch(() => form.url, (newUrl, oldUrl) => {\n // If user manually changes URL, mark as manually set\n if (newUrl !== generateSlug(form.title)) {\n urlManuallySet.value = true;\n }\n});\n\nconst fetchTrack = async () => {\n if (!props.url) return;\n \n try {\n const fetchedTrack = await tracksStore.actions.fetchTrackByUrl(props.url);\n \n if (!fetchedTrack) {\n store.core.actions.setError({\n message: 'Track not found'\n });\n return;\n }\n \n // Update local track data\n Object.assign(form, {\n title: fetchedTrack.title || '',\n artists: fetchedTrack.artist ? [fetchedTrack.artist] : [],\n albums: fetchedTrack.album ? [fetchedTrack.album] : [],\n genres: fetchedTrack.genres || [],\n duration: fetchedTrack.duration || 0,\n fileUrl: fetchedTrack.fileUrl || '',\n coverUrl: fetchedTrack.coverUrl || '',\n releaseDate: fetchedTrack.releaseDate ? new Date(fetchedTrack.releaseDate).toISOString().split('T')[0] : '',\n isExplicit: fetchedTrack.isExplicit || false,\n isPublic: fetchedTrack.isPublic !== false,\n lyrics: fetchedTrack.lyrics || '',\n url: fetchedTrack.url || '',\n status: fetchedTrack.status || 'draft',\n _id: fetchedTrack._id\n });\n \n } catch (error) {\n console.error('Error fetching track:', error);\n store.core.actions.setError({\n message: 'Failed to load track details'\n });\n }\n};\n\nconst validateForm = () => {\n let isValid = true;\n \n // Validate title\n if (!form.title.trim()) {\n validationErrors.title = {\n message: 'Track title is required'\n };\n isValid = false;\n } else {\n validationErrors.title = false;\n }\n \n // Validate file URL\n if (!form.fileUrl) {\n validationErrors.fileUrl = {\n message: 'Audio file is required'\n };\n isValid = false;\n } else {\n validationErrors.fileUrl = false;\n }\n \n return isValid;\n};\n\nconst submitForm = async () => {\n if (!validateForm()) {\n return;\n }\n \n try {\n console.log('=== FORM DATA DEBUG ===');\n console.log('form.artists:', form.artists);\n console.log('form.albums:', form.albums);\n console.log('form.albums.length:', form.albums.length);\n console.log('form.albums[0]:', form.albums[0]);\n console.log('form.albums[0]?._id:', form.albums[0]?._id);\n \n // Prepare data for submission\n const formData = {\n ...form,\n artist: form.artists.length > 0 ? (form.artists[0]._id || form.artists[0]) : null,\n album: form.albums && form.albums._id ? form.albums._id : null,\n genre: form.genres.map(genre => genre._id || genre)\n };\n \n // Remove the original arrays/objects to avoid conflicts\n delete formData.artists;\n delete formData.albums;\n delete formData.genres;\n \n console.log('formData after preparation:', formData);\n console.log('formData.album:', formData.album);\n console.log('typeof formData.album:', typeof formData.album);\n \n // Add ownership data if creating new track\n if (!props.editMode) {\n formData.owner = {\n type: 'user',\n target: auth.state.user._id\n };\n formData.creator = {\n type: 'user',\n target: auth.state.user._id\n };\n }\n \n let result;\n if (props.editMode) {\n result = await tracksStore.actions.updateTrack(formData);\n } else {\n result = await tracksStore.actions.createTrack(formData);\n }\n \n // Navigate to track detail page\n setTimeout(() => {\n router.push({\n name: 'track',\n params: { url: result.url }\n });\n }, 1000);\n \n } catch (error) {\n console.error('Error saving track:', error);\n store.core.actions.setError({\n message: 'Failed to save track'\n });\n }\n};\nconst handleUploadError = (error) => {\n console.error('Upload error:', error);\n store.core.actions.setError({\n message: 'Error uploading file'\n });\n};\n\n// Lifecycle hooks\nonMounted(async () => {\n if (props.editMode) {\n await fetchTrack();\n // Mark URL as manually set in edit mode to prevent auto-generation\n urlManuallySet.value = true;\n }\n});\n</script>\n"],"names":["artistsStore","albumsStore","genresStore","tracksStore.actions","auth.state"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"TrackForm.vue.js","sources":["../../../../../../../src/modules/music/components/forms/TrackForm.vue"],"sourcesContent":["<!-- components/forms/TrackForm.vue -->\n<template>\n <div class=\"pd-medium\">\n <h2 class=\"h2 mn-b-medium\">{{ editMode ? 'Edit Track' : 'Upload Track' }}</h2>\n \n <form @submit.prevent=\"submitForm\" class=\"cols-1 gap-regular\">\n <!-- Media Section -->\n <div class=\"bg-light pd-medium radius-medium\">\n <h3 class=\"h3 mn-b-medium\">Media</h3>\n \n <div class=\"cols-[fit-content(100%)_1fr] mobile:cols-1 gap-regular\">\n <!-- Track Cover -->\n <div>\n <p class=\"p-medium mn-b-small\">Cover Image</p>\n <UploadImage\n v-model:photo=\"form.coverUrl\"\n uploadPath=\"tracks/covers\"\n class=\"aspect-1x1 h-15r radius-small o-hidden mn-b-small\"\n @error=\"handleUploadError\"\n />\n </div>\n \n <!-- Audio File -->\n <div>\n <p class=\"p-medium mn-b-small\">Audio File</p>\n <Upload\n v-model:field=\"form.fileUrl\"\n @file-change=\"(url) => form.fileUrl = url\"\n type=\"file\"\n uploadPath=\"tracks/audio\"\n class=\"w-100 h-15r bg-white radius-small pd-small\"\n :validation=\"validationErrors.fileUrl\"\n />\n </div>\n </div>\n </div>\n \n <!-- Basic Info Section -->\n <div class=\"bg-light pd-medium radius-medium\">\n <h3 class=\"h3 mn-b-medium\">Basic Information</h3>\n \n <!-- Track Title -->\n <Field\n v-model:field=\"form.title\"\n label=\"Track Title\"\n placeholder=\"Enter track title\"\n class=\"bg-white radius-small pd-small mn-b-thin\"\n :validation=\"validationErrors.title\"\n />\n \n <!-- URL -->\n <Field\n v-model:field=\"form.url\"\n label=\"URL\"\n placeholder=\"Leave blank for auto-generation based on the track title\"\n class=\"bg-white radius-small pd-small mn-b-small\"\n />\n\n <!-- Artist Selection -->\n \n\n \n \n <!-- Release Date -->\n <Field\n v-model:field=\"form.releaseDate\"\n label=\"Release Date\"\n type=\"date\"\n class=\"bg-white radius-small pd-small mn-b-thin\"\n :validation=\"validationErrors.releaseDate\"\n />\n \n <!-- Duration -->\n <Field\n v-model:field=\"form.duration\"\n label=\"Duration (seconds)\"\n type=\"number\"\n placeholder=\"Track duration in seconds\"\n class=\"bg-white radius-small pd-small mn-b-thin\"\n />\n </div> \n\n <Block title=\"Artist\">\n <BlockMultiselect\n v-model=\"form.artists\"\n placeholder=\"Search artists...\"\n :multiple=\"false\"\n :transform=\"(item) => ({ _id: item._id, name: item.name })\"\n :store=\"{\n read: (options) => artistsActions.fetchArtists(options),\n state: artistsState\n }\"\n :options=\"{\n rootOnly: false,\n excludeChildren: false,\n limit: 50\n }\"\n :skeleton=\"{\n hide: false,\n horizontal: true,\n class: 'radius-small',\n structure: [{ \n block: 'text', size: 'large'\n }]\n }\"\n :states=\"{\n empty: {\n title: 'No artists found',\n description: 'Try different search terms or create a new artist',\n class: 'radius-small'\n }\n }\"\n key=\"_id\"\n :label=\"item => item.name\"\n classSearch=\"bg-white radius-small\"\n classSelected=\"bg-white pd-small radius-small\"\n classDropdown=\"bg-white pd-small radius-medium bs-small\"\n classItem=\"pd-small radius-small hover:bg-light cursor-pointer\"\n classFeed=\"h-max-30r gap-thin flex-column flex o-scroll\"\n >\n <!-- Selected artist slot -->\n <template #selected=\"{ item, clear }\">\n <div class=\"flex-nowrap flex-v-center flex gap-thin\">\n <span class=\"fw-medium\">{{ item?.name || item }}</span>\n <button \n @click.stop=\"clear\"\n class=\"i-small pd-micro bg-red radius-extra flex-center flex aspect-1x1 hover:scale-[1.05]\"\n >\n <IconCross class=\"i-micro fill-white\" />\n </button>\n </div>\n </template>\n \n <!-- Artist item slot -->\n <template #item=\"{ item }\">\n <div class=\"flex-nowrap flex-v-center flex\">\n <div class=\"w-100\">\n <p class=\"fw-medium\">{{ item.name }}</p>\n <p v-if=\"item.bio\" class=\"t-small t-transp\">{{ item.bio }}</p>\n </div>\n </div>\n </template>\n </BlockMultiselect>\n </Block>\n\n <!-- Album Selection -->\n <Block title=\"Album (Optional)\">\n <BlockMultiselect\n v-model=\"form.albums\"\n placeholder=\"Search albums...\"\n :multiple=\"false\"\n :transform=\"(item) => ({ _id: item._id, title: item.title })\"\n :store=\"{\n read: (options) => albumsActions.fetchAlbums(options),\n state: albumsState\n }\"\n :options=\"{\n rootOnly: false,\n excludeChildren: false,\n limit: 50\n }\"\n :skeleton=\"{\n hide: false,\n horizontal: true,\n class: 'radius-small',\n structure: [{ \n block: 'text', size: 'large'\n }]\n }\"\n :states=\"{\n empty: {\n title: 'No albums found',\n description: 'Try different search terms or create a new album',\n class: 'radius-small'\n }\n }\"\n key=\"_id\"\n :label=\"item => item.title\"\n classSearch=\"bg-white radius-small\"\n classSelected=\"bg-white pd-small radius-small\"\n classDropdown=\"bg-white pd-small radius-medium bs-small\"\n classItem=\"pd-small radius-small hover:bg-light cursor-pointer\"\n classFeed=\"h-max-30r gap-thin flex-column flex o-scroll\"\n >\n <!-- Selected album slot -->\n <template #selected=\"{ item, clear }\">\n <div class=\"flex-nowrap flex-v-center flex gap-thin\">\n <span class=\"fw-medium\">{{ item?.title || item }}</span>\n <button \n @click.stop=\"clear\"\n class=\"i-small pd-micro bg-red radius-extra flex-center flex aspect-1x1 hover:scale-[1.05]\"\n >\n <IconCross class=\"i-micro fill-white\" />\n </button>\n </div>\n </template>\n \n <!-- Album item slot -->\n <template #item=\"{ item }\">\n <div class=\"flex-nowrap flex-v-center flex\">\n <div class=\"w-100\">\n <p class=\"fw-medium\">{{ item.title }}</p>\n <p v-if=\"item.description\" class=\"t-small t-transp\">{{ item.description }}</p>\n </div>\n </div>\n </template>\n </BlockMultiselect>\n </Block>\n \n <!-- Genres Section -->\n <Block title=\"Genres\">\n <BlockMultiselect\n v-model=\"form.genres\"\n placeholder=\"Search genres...\"\n :multiple=\"true\"\n :transform=\"(item) => ({ _id: item._id, name: item.name })\"\n :store=\"{\n read: (options) => genresActions.fetchGenres(options),\n state: genresState\n }\"\n :options=\"{\n rootOnly: false,\n excludeChildren: false,\n limit: 50\n }\"\n :skeleton=\"{\n hide: false,\n horizontal: true,\n class: 'radius-small',\n structure: [{ \n block: 'text', size: 'large'\n }]\n }\"\n :states=\"{\n empty: {\n title: 'No genres found',\n description: 'Try different search terms or create a new genre',\n class: 'radius-small'\n }\n }\"\n key=\"_id\"\n :label=\"item => item.name\"\n classSearch=\"bg-white radius-small\"\n classSelected=\"bg-white pd-small radius-small\"\n classDropdown=\"bg-white pd-small radius-medium bs-small\"\n classItem=\"pd-small radius-small hover:bg-light cursor-pointer\"\n classFeed=\"h-max-30r gap-thin flex-column flex o-scroll\"\n >\n <!-- Selected genres slot -->\n <template #selected=\"{ item, clear }\">\n <div class=\"flex-nowrap flex-v-center flex gap-thin\">\n <span class=\"fw-medium\">{{ item?.name || item }}</span>\n <button \n @click.stop=\"clear\"\n class=\"i-small pd-micro bg-red radius-extra flex-center flex aspect-1x1 hover:scale-[1.05]\"\n >\n <IconCross class=\"i-micro fill-white\" />\n </button>\n </div>\n </template>\n \n <!-- Genre item slot -->\n <template #item=\"{ item }\">\n <div class=\"flex-nowrap flex-v-center flex\">\n <div class=\"w-100\">\n <p class=\"fw-medium\">{{ item.name }}</p>\n <p v-if=\"item.description\" class=\"t-small t-transp\">{{ item.description }}</p>\n </div>\n </div>\n </template>\n </BlockMultiselect>\n </Block>\n \n <!-- Content Settings Section -->\n <div class=\"bg-light pd-medium radius-medium\">\n <h3 class=\"h3 mn-b-medium\">Content Settings</h3>\n \n <Checkbox\n v-model:checkbox=\"form.isExplicit\"\n label=\"Explicit Content\"\n class=\"bg-white radius-small pd-small mn-b-thin\"\n />\n \n <Checkbox\n v-model:checkbox=\"form.isPublic\"\n label=\"Public Track\"\n class=\"bg-white radius-small pd-small mn-b-thin\"\n />\n </div>\n \n \n \n <!-- Additional Info Section -->\n <div class=\"bg-light pd-medium radius-medium\">\n <h3 class=\"h3 mn-b-medium\">Additional Information</h3>\n \n <!-- Lyrics -->\n <Field\n v-model:field=\"form.lyrics\"\n label=\"Lyrics (Optional)\"\n type=\"textarea\"\n placeholder=\"Enter track lyrics\"\n class=\"bg-white radius-small pd-small mn-b-thin\"\n />\n </div>\n \n <!-- Status Section -->\n <div class=\"bg-light pd-medium radius-medium\">\n <h3 class=\"h3 mn-b-medium\">Publishing Status</h3>\n \n <Select\n v-model:select=\"form.status\"\n :options=\"statusOptions\"\n label=\"Status\"\n class=\"bg-white radius-small pd-small mn-b-thin\"\n />\n </div>\n \n <!-- Submit Button -->\n <div class=\"flex flex-justify-between\">\n <Button\n @click=\"router.go(-1)\"\n class=\"bg-grey-nano t-black\"\n :showSucces=\"false\"\n :showLoader=\"false\"\n >\n Cancel\n </Button>\n \n <Button\n :submit=\"submitForm\"\n class=\"bg-main t-black\"\n :text=\"{\n success: editMode ? 'Updated!' : 'Uploaded!'\n }\"\n >\n {{ editMode ? 'Update Track' : 'Upload Track' }}\n </Button>\n </div>\n </form>\n </div>\n</template>\n\n<script setup>\nimport { ref, reactive, onMounted, watch } from 'vue';\nimport { useRouter, useRoute } from 'vue-router';\n\n// Import Martyrs components\nimport Field from '@martyrs/src/components/Field/Field.vue';\nimport Block from '@martyrs/src/components/Block/Block.vue';\nimport Button from '@martyrs/src/components/Button/Button.vue';\nimport Checkbox from '@martyrs/src/components/Checkbox/Checkbox.vue';\nimport Select from '@martyrs/src/components/Select/Select.vue';\nimport UploadImage from '@martyrs/src/components/UploadImage/UploadImage.vue';\nimport Upload from '@martyrs/src/components/Upload/Upload.vue';\nimport IconCross from '@martyrs/src/modules/icons/navigation/IconCross.vue';\n\nimport BlockMultiselect from '@martyrs/src/modules/core/views/components/blocks/BlockMultiselect.vue';\n\n// Import stores\nimport * as tracksStore from '../../store/tracks';\nimport * as artistsStore from '../../store/artists';\nimport * as albumsStore from '../../store/albums';\nimport * as genresStore from '../../store/genres';\nimport { useStore } from '@martyrs/src/modules/core/views/store/core.store.js';\n\nconst store = useStore();\nimport * as auth from '@martyrs/src/modules/auth/views/store/auth.js';\n\n// Store states and actions\nconst { state: artistsState, actions: artistsActions } = artistsStore;\nconst { state: albumsState, actions: albumsActions } = albumsStore;\nconst { state: genresState, actions: genresActions } = genresStore;\n\n// Props\nconst props = defineProps({\n editMode: {\n type: Boolean,\n default: false\n },\n url: {\n type: String,\n default: ''\n }\n});\n\n// Router and route\nconst router = useRouter();\nconst route = useRoute();\n\nconst emit = defineEmits(['uploaded']);\n\n// State\nconst form = reactive({\n title: '',\n artists: [],\n albums: [],\n genres: [],\n duration: 0,\n fileUrl: '',\n coverUrl: '',\n releaseDate: new Date().toISOString().split('T')[0],\n isExplicit: false,\n isPublic: true,\n lyrics: '',\n url: '',\n status: 'draft'\n});\n\nconst validationErrors = reactive({\n title: false,\n fileUrl: false,\n releaseDate: false\n});\n\n// Track if URL was manually entered\nconst urlManuallySet = ref(false);\n\n// Status options\nconst statusOptions = [\n 'draft',\n 'published',\n 'archived'\n];\n\n// Function to generate URL-friendly slug from text\nconst generateSlug = (text) => {\n if (!text) return '';\n return text\n .toLowerCase()\n .replace(/[^a-z0-9\\s-]/g, '') // Remove special characters\n .replace(/\\s+/g, '-') // Replace spaces with hyphens\n .replace(/-+/g, '-') // Replace multiple hyphens with single\n .trim('-'); // Remove leading/trailing hyphens\n};\n\n// Watch for changes in track title to auto-generate URL\nwatch(() => form.title, (newTitle) => {\n // Only auto-generate if URL hasn't been manually set and we're not in edit mode\n if (!urlManuallySet.value && !props.editMode) {\n form.url = generateSlug(newTitle);\n }\n});\n\n// Watch for manual changes to URL field\nwatch(() => form.url, (newUrl, oldUrl) => {\n // If user manually changes URL, mark as manually set\n if (newUrl !== generateSlug(form.title)) {\n urlManuallySet.value = true;\n }\n});\n\nconst fetchTrack = async () => {\n if (!props.url) return;\n \n try {\n const fetchedTrack = await tracksStore.actions.fetchTrackByUrl(props.url);\n \n if (!fetchedTrack) {\n store.core.actions.setError({\n message: 'Track not found'\n });\n return;\n }\n \n // Update local track data\n Object.assign(form, {\n title: fetchedTrack.title || '',\n artists: fetchedTrack.artist ? [fetchedTrack.artist] : [],\n albums: fetchedTrack.album ? [fetchedTrack.album] : [],\n genres: fetchedTrack.genres || [],\n duration: fetchedTrack.duration || 0,\n fileUrl: fetchedTrack.fileUrl || '',\n coverUrl: fetchedTrack.coverUrl || '',\n releaseDate: fetchedTrack.releaseDate ? new Date(fetchedTrack.releaseDate).toISOString().split('T')[0] : '',\n isExplicit: fetchedTrack.isExplicit || false,\n isPublic: fetchedTrack.isPublic !== false,\n lyrics: fetchedTrack.lyrics || '',\n url: fetchedTrack.url || '',\n status: fetchedTrack.status || 'draft',\n _id: fetchedTrack._id\n });\n \n } catch (error) {\n console.error('Error fetching track:', error);\n store.core.actions.setError({\n message: 'Failed to load track details'\n });\n }\n};\n\nconst validateForm = () => {\n let isValid = true;\n \n // Validate title\n if (!form.title.trim()) {\n validationErrors.title = {\n message: 'Track title is required'\n };\n isValid = false;\n } else {\n validationErrors.title = false;\n }\n \n // Validate file URL\n if (!form.fileUrl) {\n validationErrors.fileUrl = {\n message: 'Audio file is required'\n };\n isValid = false;\n } else {\n validationErrors.fileUrl = false;\n }\n \n return isValid;\n};\n\nconst submitForm = async () => {\n if (!validateForm()) {\n return;\n }\n \n try {\n console.log('=== FORM DATA DEBUG ===');\n console.log('form.artists:', form.artists);\n console.log('form.albums:', form.albums);\n console.log('form.albums.length:', form.albums.length);\n console.log('form.albums[0]:', form.albums[0]);\n console.log('form.albums[0]?._id:', form.albums[0]?._id);\n \n // Prepare data for submission\n const formData = {\n ...form,\n artist: form.artists.length > 0 ? (form.artists[0]._id || form.artists[0]) : null,\n album: form.albums && form.albums._id ? form.albums._id : null,\n genre: form.genres.map(genre => genre._id || genre)\n };\n \n // Remove the original arrays/objects to avoid conflicts\n delete formData.artists;\n delete formData.albums;\n delete formData.genres;\n \n console.log('formData after preparation:', formData);\n console.log('formData.album:', formData.album);\n console.log('typeof formData.album:', typeof formData.album);\n \n // Add ownership data if creating new track\n if (!props.editMode) {\n formData.owner = {\n type: 'user',\n target: auth.state.user._id\n };\n formData.creator = {\n type: 'user',\n target: auth.state.user._id\n };\n }\n \n let result;\n if (props.editMode) {\n result = await tracksStore.actions.updateTrack(formData);\n } else {\n result = await tracksStore.actions.createTrack(formData);\n }\n \n // Navigate to track detail page\n setTimeout(() => {\n router.push({\n name: 'track',\n params: { url: result.url }\n });\n }, 1000);\n \n } catch (error) {\n console.error('Error saving track:', error);\n store.core.actions.setError({\n message: 'Failed to save track'\n });\n }\n};\nconst handleUploadError = (error) => {\n console.error('Upload error:', error);\n store.core.actions.setError({\n message: 'Error uploading file'\n });\n};\n\n// Lifecycle hooks\nonMounted(async () => {\n if (props.editMode) {\n await fetchTrack();\n // Mark URL as manually set in edit mode to prevent auto-generation\n urlManuallySet.value = true;\n }\n});\n</script>\n"],"names":["artistsStore","albumsStore","genresStore","tracksStore.actions","auth.state"],"mappings":"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"}
|