@ozdao/martyrs 0.2.492 → 0.2.494
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_virtual/index.cjs +4 -4
- package/dist/_virtual/index.js +4 -4
- package/dist/_virtual/index2.cjs +4 -4
- package/dist/_virtual/index2.js +4 -4
- package/dist/builder.cjs +53 -90
- package/dist/builder.js +54 -91
- package/dist/{crud-B-kQw3Z5.cjs → crud-JN_LFj01.cjs} +3 -0
- package/dist/{crud-Cwx5VlSm.js → crud-sE7GLPbj.js} +3 -0
- package/dist/globals.server.cjs +322 -3
- package/dist/globals.server.js +303 -1
- package/dist/{globals.verifier-D68mHEBl.cjs → globals.verifier-C0zj_LLo.cjs} +8 -1
- package/dist/{globals.verifier-CWFz5Gh2.js → globals.verifier-DFqKQ7hK.js} +8 -1
- package/dist/inventory.server.cjs +2 -2
- package/dist/inventory.server.js +2 -2
- package/dist/{main-SZQ1QjeP.js → main-CJm5myDI.js} +631 -607
- package/dist/{main-MzmGbSxs.cjs → main-DTaE01lg.cjs} +6 -6
- package/dist/martyrs/src/components/Calendar/Calendar.vue2.cjs +1 -1
- package/dist/martyrs/src/components/Calendar/Calendar.vue2.cjs.map +1 -1
- package/dist/martyrs/src/components/Calendar/Calendar.vue2.js +1 -1
- package/dist/martyrs/src/components/Calendar/Calendar.vue2.js.map +1 -1
- package/dist/martyrs/src/components/Feed/Feed.vue.cjs +33 -7
- package/dist/martyrs/src/components/Feed/Feed.vue.cjs.map +1 -1
- package/dist/martyrs/src/components/Feed/Feed.vue.js +33 -7
- package/dist/martyrs/src/components/Feed/Feed.vue.js.map +1 -1
- package/dist/martyrs/src/components/Field/{Field.vue2.cjs → Field.vue.cjs} +2 -2
- package/dist/martyrs/src/components/Field/{Field.vue2.js.map → Field.vue.cjs.map} +1 -1
- package/dist/martyrs/src/components/Field/{Field.vue2.js → Field.vue.js} +2 -2
- package/dist/martyrs/src/components/Field/Field.vue.js.map +1 -0
- package/dist/martyrs/src/components/FieldBig/FieldBig.vue.cjs +1 -1
- package/dist/martyrs/src/components/FieldBig/FieldBig.vue.js +1 -1
- package/dist/martyrs/src/components/FieldTags/FieldTags.vue.cjs +1 -1
- package/dist/martyrs/src/components/FieldTags/FieldTags.vue.js +1 -1
- package/dist/martyrs/src/components/Menu/{Menu.vue.cjs → Menu.vue2.cjs} +2 -2
- package/dist/martyrs/src/components/Menu/Menu.vue2.cjs.map +1 -0
- 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 +4 -4
- package/dist/martyrs/src/modules/auth/views/components/pages/EnterCode.vue.cjs +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/EnterCode.vue.js +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/EnterPassword.vue.cjs +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/EnterPassword.vue.js +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/Invite.vue.cjs +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/Invite.vue.js +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/Profile.vue.cjs +2 -2
- package/dist/martyrs/src/modules/auth/views/components/pages/Profile.vue.js +2 -2
- package/dist/martyrs/src/modules/auth/views/components/pages/ProfileEditProfile.vue.cjs +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/ProfileEditProfile.vue.js +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/ResetPassword.vue.cjs +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/ResetPassword.vue.js +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/SignIn.vue.cjs +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/SignIn.vue.js +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/SignUp.vue.cjs +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/SignUp.vue.js +1 -1
- package/dist/martyrs/src/modules/auth/views/components/sections/ProfileEditCredentials.vue.cjs +1 -1
- package/dist/martyrs/src/modules/auth/views/components/sections/ProfileEditCredentials.vue.js +1 -1
- package/dist/martyrs/src/modules/community/components/pages/CreateBlogPost.vue.cjs +2 -2
- package/dist/martyrs/src/modules/community/components/pages/CreateBlogPost.vue.js +2 -2
- package/dist/martyrs/src/modules/constructor/components/elements/Card.vue.cjs +1 -1
- package/dist/martyrs/src/modules/constructor/components/elements/Card.vue.js +1 -1
- package/dist/martyrs/src/modules/constructor/components/elements/Embed.vue.cjs +1 -1
- package/dist/martyrs/src/modules/constructor/components/elements/Embed.vue.js +1 -1
- package/dist/martyrs/src/modules/events/components/pages/EditEvent.vue.cjs +1 -1
- package/dist/martyrs/src/modules/events/components/pages/EditEvent.vue.js +1 -1
- package/dist/martyrs/src/modules/events/components/pages/EditEventTickets.vue.cjs +1 -1
- package/dist/martyrs/src/modules/events/components/pages/EditEventTickets.vue.js +1 -1
- package/dist/martyrs/src/modules/events/components/pages/Event.vue.cjs +1 -1
- package/dist/martyrs/src/modules/events/components/pages/Event.vue.js +1 -1
- package/dist/martyrs/src/modules/gallery/components/sections/BackofficeGallery.vue.cjs +1 -1
- package/dist/martyrs/src/modules/gallery/components/sections/BackofficeGallery.vue.js +1 -1
- package/dist/martyrs/src/modules/globals/views/classes/globals.i18n.cjs +1 -1
- package/dist/martyrs/src/modules/globals/views/classes/globals.i18n.js +1 -1
- package/dist/martyrs/src/modules/globals/views/components/blocks/BlockSearch.vue.cjs +1 -1
- package/dist/martyrs/src/modules/globals/views/components/blocks/BlockSearch.vue.js +1 -1
- package/dist/martyrs/src/modules/globals/views/components/layouts/Client.vue.cjs +5 -1
- package/dist/martyrs/src/modules/globals/views/components/layouts/Client.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/globals/views/components/layouts/Client.vue.js +5 -1
- package/dist/martyrs/src/modules/globals/views/components/layouts/Client.vue.js.map +1 -1
- package/dist/martyrs/src/modules/icons/entities/IconTime.vue.cjs +2 -2
- package/dist/martyrs/src/modules/icons/entities/IconTime.vue.js +2 -2
- package/dist/martyrs/src/modules/icons/navigation/IconChevronLeft.vue.cjs +2 -2
- package/dist/martyrs/src/modules/icons/navigation/IconChevronLeft.vue.js +2 -2
- package/dist/martyrs/src/modules/icons/navigation/IconChevronRight.vue.cjs +2 -2
- package/dist/martyrs/src/modules/icons/navigation/IconChevronRight.vue.js +2 -2
- package/dist/martyrs/src/modules/icons/pages/IconsPage.vue.js +6 -6
- package/dist/martyrs/src/modules/icons/pages/IconsPage.vue.js.map +1 -1
- package/dist/martyrs/src/modules/inventory/components/forms/AdjustmentForm.vue.cjs +1 -1
- package/dist/martyrs/src/modules/inventory/components/forms/AdjustmentForm.vue.js +1 -1
- package/dist/martyrs/src/modules/inventory/components/forms/StockAlertsForm.vue.cjs +1 -1
- package/dist/martyrs/src/modules/inventory/components/forms/StockAlertsForm.vue.js +1 -1
- package/dist/martyrs/src/modules/inventory/components/pages/Inventory.vue.cjs +1 -1
- package/dist/martyrs/src/modules/inventory/components/pages/InventoryEdit.vue.cjs +1 -1
- package/dist/martyrs/src/modules/inventory/components/pages/InventoryEdit.vue.js +1 -1
- package/dist/martyrs/src/modules/music/components/cards/AlbumCard.vue.cjs +22 -15
- package/dist/martyrs/src/modules/music/components/cards/AlbumCard.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/music/components/cards/AlbumCard.vue.js +23 -16
- package/dist/martyrs/src/modules/music/components/cards/AlbumCard.vue.js.map +1 -1
- package/dist/martyrs/src/modules/music/components/cards/ArtistCard.vue.cjs +2 -2
- package/dist/martyrs/src/modules/music/components/cards/ArtistCard.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/music/components/cards/ArtistCard.vue.js +2 -2
- package/dist/martyrs/src/modules/music/components/cards/ArtistCard.vue.js.map +1 -1
- package/dist/martyrs/src/modules/music/components/cards/PlaylistCard.vue.cjs +31 -13
- package/dist/martyrs/src/modules/music/components/cards/PlaylistCard.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/music/components/cards/PlaylistCard.vue.js +33 -15
- package/dist/martyrs/src/modules/music/components/cards/PlaylistCard.vue.js.map +1 -1
- package/dist/martyrs/src/modules/music/components/cards/TrackListCard.vue.cjs +39 -22
- package/dist/martyrs/src/modules/music/components/cards/TrackListCard.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/music/components/cards/TrackListCard.vue.js +39 -22
- package/dist/martyrs/src/modules/music/components/cards/TrackListCard.vue.js.map +1 -1
- package/dist/martyrs/src/modules/music/components/forms/AlbumForm.vue.cjs +1 -1
- package/dist/martyrs/src/modules/music/components/forms/AlbumForm.vue.js +1 -1
- package/dist/martyrs/src/modules/music/components/forms/ArtistForm.vue.cjs +1 -1
- package/dist/martyrs/src/modules/music/components/forms/ArtistForm.vue.js +1 -1
- package/dist/martyrs/src/modules/music/components/forms/PlaylistForm.vue.cjs +385 -125
- package/dist/martyrs/src/modules/music/components/forms/PlaylistForm.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/music/components/forms/PlaylistForm.vue.js +391 -131
- package/dist/martyrs/src/modules/music/components/forms/PlaylistForm.vue.js.map +1 -1
- package/dist/martyrs/src/modules/music/components/forms/SearchForm.vue.cjs +24 -7
- package/dist/martyrs/src/modules/music/components/forms/SearchForm.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/music/components/forms/SearchForm.vue.js +25 -8
- package/dist/martyrs/src/modules/music/components/forms/SearchForm.vue.js.map +1 -1
- package/dist/martyrs/src/modules/music/components/forms/TrackForm.vue.cjs +99 -87
- package/dist/martyrs/src/modules/music/components/forms/TrackForm.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/music/components/forms/TrackForm.vue.js +111 -99
- package/dist/martyrs/src/modules/music/components/forms/TrackForm.vue.js.map +1 -1
- package/dist/martyrs/src/modules/music/components/layouts/MusicBottomPlayer.vue.cjs +21 -0
- package/dist/martyrs/src/modules/music/components/layouts/MusicBottomPlayer.vue.cjs.map +1 -0
- package/dist/martyrs/src/modules/music/components/layouts/MusicBottomPlayer.vue.js +21 -0
- package/dist/martyrs/src/modules/music/components/layouts/MusicBottomPlayer.vue.js.map +1 -0
- package/dist/martyrs/src/modules/music/components/pages/Album.vue.cjs +442 -210
- package/dist/martyrs/src/modules/music/components/pages/Album.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/music/components/pages/Album.vue.js +445 -213
- package/dist/martyrs/src/modules/music/components/pages/Album.vue.js.map +1 -1
- package/dist/martyrs/src/modules/music/components/pages/Artist.vue.cjs +92 -117
- package/dist/martyrs/src/modules/music/components/pages/Artist.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/music/components/pages/Artist.vue.js +93 -118
- package/dist/martyrs/src/modules/music/components/pages/Artist.vue.js.map +1 -1
- package/dist/martyrs/src/modules/music/components/pages/MusicHome.vue.cjs +72 -113
- package/dist/martyrs/src/modules/music/components/pages/MusicHome.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/music/components/pages/MusicHome.vue.js +78 -119
- package/dist/martyrs/src/modules/music/components/pages/MusicHome.vue.js.map +1 -1
- package/dist/martyrs/src/modules/music/components/pages/MusicLibrary.vue.cjs +15 -12
- package/dist/martyrs/src/modules/music/components/pages/MusicLibrary.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/music/components/pages/MusicLibrary.vue.js +15 -12
- package/dist/martyrs/src/modules/music/components/pages/MusicLibrary.vue.js.map +1 -1
- package/dist/martyrs/src/modules/music/components/pages/Playlist.vue.cjs +558 -429
- package/dist/martyrs/src/modules/music/components/pages/Playlist.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/music/components/pages/Playlist.vue.js +560 -431
- package/dist/martyrs/src/modules/music/components/pages/Playlist.vue.js.map +1 -1
- package/dist/martyrs/src/modules/music/components/pages/SearchResults.vue.cjs +146 -284
- package/dist/martyrs/src/modules/music/components/pages/SearchResults.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/music/components/pages/SearchResults.vue.js +149 -287
- package/dist/martyrs/src/modules/music/components/pages/SearchResults.vue.js.map +1 -1
- package/dist/martyrs/src/modules/music/components/pages/Track.vue.cjs +460 -63
- package/dist/martyrs/src/modules/music/components/pages/Track.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/music/components/pages/Track.vue.js +462 -65
- package/dist/martyrs/src/modules/music/components/pages/Track.vue.js.map +1 -1
- package/dist/martyrs/src/modules/music/components/player/MusicPlayer.vue.cjs +126 -136
- package/dist/martyrs/src/modules/music/components/player/MusicPlayer.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/music/components/player/MusicPlayer.vue.js +129 -139
- package/dist/martyrs/src/modules/music/components/player/MusicPlayer.vue.js.map +1 -1
- package/dist/martyrs/src/modules/music/components/player/TrackProgress.vue.cjs +18 -15
- package/dist/martyrs/src/modules/music/components/player/TrackProgress.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/music/components/player/TrackProgress.vue.js +18 -15
- package/dist/martyrs/src/modules/music/components/player/TrackProgress.vue.js.map +1 -1
- package/dist/martyrs/src/modules/music/components/player/VolumeControl.vue.cjs +28 -23
- package/dist/martyrs/src/modules/music/components/player/VolumeControl.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/music/components/player/VolumeControl.vue.js +29 -24
- package/dist/martyrs/src/modules/music/components/player/VolumeControl.vue.js.map +1 -1
- package/dist/martyrs/src/modules/music/music.client.cjs +3 -6
- package/dist/martyrs/src/modules/music/music.client.cjs.map +1 -1
- package/dist/martyrs/src/modules/music/music.client.js +9 -12
- package/dist/martyrs/src/modules/music/music.client.js.map +1 -1
- package/dist/martyrs/src/modules/music/router/music.cjs +27 -1
- package/dist/martyrs/src/modules/music/router/music.cjs.map +1 -1
- package/dist/martyrs/src/modules/music/router/music.js +27 -1
- package/dist/martyrs/src/modules/music/router/music.js.map +1 -1
- package/dist/martyrs/src/modules/music/store/artists.cjs +6 -4
- package/dist/martyrs/src/modules/music/store/artists.cjs.map +1 -1
- package/dist/martyrs/src/modules/music/store/artists.js +6 -4
- package/dist/martyrs/src/modules/music/store/artists.js.map +1 -1
- package/dist/martyrs/src/modules/music/store/player.cjs +5 -0
- package/dist/martyrs/src/modules/music/store/player.cjs.map +1 -1
- package/dist/martyrs/src/modules/music/store/player.js +5 -0
- package/dist/martyrs/src/modules/music/store/player.js.map +1 -1
- package/dist/martyrs/src/modules/music/store/tracks.cjs +22 -0
- package/dist/martyrs/src/modules/music/store/tracks.cjs.map +1 -1
- package/dist/martyrs/src/modules/music/store/tracks.js +22 -0
- package/dist/martyrs/src/modules/music/store/tracks.js.map +1 -1
- package/dist/martyrs/src/modules/orders/components/blocks/CardOrderBackoffice.vue.js +2 -2
- package/dist/martyrs/src/modules/orders/components/pages/OrderBackoffice.vue.js +2 -2
- package/dist/martyrs/src/modules/orders/components/pages/OrderCreateBackoffice.vue.cjs +1 -1
- package/dist/martyrs/src/modules/orders/components/pages/OrderCreateBackoffice.vue.js +1 -1
- package/dist/martyrs/src/modules/orders/components/sections/FormAddCustomer.vue.cjs +1 -1
- package/dist/martyrs/src/modules/orders/components/sections/FormAddCustomer.vue.js +1 -1
- package/dist/martyrs/src/modules/orders/components/sections/FormCustomerDetails.vue.cjs +1 -1
- package/dist/martyrs/src/modules/orders/components/sections/FormCustomerDetails.vue.js +1 -1
- package/dist/martyrs/src/modules/orders/components/sections/FormDelivery.vue.cjs +1 -1
- package/dist/martyrs/src/modules/orders/components/sections/FormDelivery.vue.js +1 -1
- package/dist/martyrs/src/modules/organizations/components/blocks/CardOrganization.vue.js +2 -2
- package/dist/martyrs/src/modules/organizations/components/pages/DepartmentEdit.vue.cjs +1 -1
- package/dist/martyrs/src/modules/organizations/components/pages/DepartmentEdit.vue.js +1 -1
- package/dist/martyrs/src/modules/organizations/components/pages/Members.vue.cjs +1 -1
- package/dist/martyrs/src/modules/organizations/components/pages/Members.vue.js +1 -1
- package/dist/martyrs/src/modules/organizations/components/pages/Organization.vue.cjs +1 -1
- package/dist/martyrs/src/modules/organizations/components/pages/Organization.vue.js +1 -1
- package/dist/martyrs/src/modules/organizations/components/pages/OrganizationBackoffice.vue.cjs +1 -1
- package/dist/martyrs/src/modules/organizations/components/pages/OrganizationBackoffice.vue.js +1 -1
- package/dist/martyrs/src/modules/organizations/components/pages/OrganizationEdit.vue.cjs +1 -1
- package/dist/martyrs/src/modules/organizations/components/pages/OrganizationEdit.vue.js +1 -1
- package/dist/martyrs/src/modules/organizations/components/sections/Documents.vue.cjs +1 -1
- package/dist/martyrs/src/modules/organizations/components/sections/Documents.vue.js +1 -1
- package/dist/martyrs/src/modules/organizations/components/sections/MembersAdd.vue.cjs +1 -1
- package/dist/martyrs/src/modules/organizations/components/sections/MembersAdd.vue.js +1 -1
- package/dist/martyrs/src/modules/organizations/components/sections/Organizations.vue.cjs +1 -1
- package/dist/martyrs/src/modules/organizations/components/sections/Organizations.vue.js +1 -1
- package/dist/martyrs/src/modules/organizations/router/organizations.cjs +1 -1
- package/dist/martyrs/src/modules/organizations/router/organizations.js +1 -1
- package/dist/martyrs/src/modules/pages/views/components/blocks/CardPage.vue.cjs +1 -1
- package/dist/martyrs/src/modules/pages/views/components/blocks/CardPage.vue.js +1 -1
- package/dist/martyrs/src/modules/pages/views/components/pages/PageEdit.vue.cjs +1 -1
- package/dist/martyrs/src/modules/pages/views/components/pages/PageEdit.vue.js +1 -1
- package/dist/martyrs/src/modules/products/components/pages/CategoryEdit.vue.cjs +1 -1
- package/dist/martyrs/src/modules/products/components/pages/CategoryEdit.vue.js +1 -1
- package/dist/martyrs/src/modules/products/components/pages/ProductEdit.vue.cjs +1 -1
- package/dist/martyrs/src/modules/products/components/pages/ProductEdit.vue.js +1 -1
- package/dist/martyrs/src/modules/products/components/sections/EditAttributes.vue.cjs +1 -1
- package/dist/martyrs/src/modules/products/components/sections/EditAttributes.vue.js +1 -1
- package/dist/martyrs/src/modules/products/components/sections/EditDiscounts.vue.cjs +1 -1
- package/dist/martyrs/src/modules/products/components/sections/EditDiscounts.vue.js +1 -1
- package/dist/martyrs/src/modules/products/components/sections/EditVariants.vue.cjs +1 -1
- package/dist/martyrs/src/modules/products/components/sections/EditVariants.vue.js +1 -1
- package/dist/martyrs/src/modules/rents/views/components/pages/Gant/GanttBar.vue.cjs +4 -3
- package/dist/martyrs/src/modules/rents/views/components/pages/Gant/GanttBar.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/rents/views/components/pages/Gant/GanttBar.vue.js +4 -3
- 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.cjs +37 -70
- package/dist/martyrs/src/modules/rents/views/components/pages/Gant/GanttChart.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/rents/views/components/pages/Gant/GanttChart.vue.js +38 -71
- 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/GanttToolbar.vue.cjs +2 -1
- package/dist/martyrs/src/modules/rents/views/components/pages/Gant/GanttToolbar.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/rents/views/components/pages/Gant/GanttToolbar.vue.js +6 -5
- package/dist/martyrs/src/modules/rents/views/components/pages/Gant/GanttToolbar.vue.js.map +1 -1
- package/dist/martyrs/src/modules/rents/views/components/pages/Rents.vue.cjs +45 -52
- package/dist/martyrs/src/modules/rents/views/components/pages/Rents.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/rents/views/components/pages/Rents.vue.js +46 -53
- 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.cjs +1 -1
- package/dist/martyrs/src/modules/rents/views/components/pages/RentsEdit.vue.js +1 -1
- package/dist/martyrs/src/modules/spots/components/blocks/SpotMemberModify.vue.cjs +1 -1
- package/dist/martyrs/src/modules/spots/components/blocks/SpotMemberModify.vue.js +1 -1
- package/dist/martyrs/src/modules/spots/components/layouts/Spots.vue.cjs +1 -1
- package/dist/martyrs/src/modules/spots/components/layouts/Spots.vue.js +1 -1
- package/dist/martyrs/src/modules/spots/components/pages/SpotEdit.vue.cjs +1 -1
- package/dist/martyrs/src/modules/spots/components/pages/SpotEdit.vue.js +1 -1
- package/dist/martyrs/src/modules/spots/components/sections/WorktimeEdit.vue.cjs +1 -1
- package/dist/martyrs/src/modules/spots/components/sections/WorktimeEdit.vue.js +1 -1
- package/dist/martyrs/src/modules/wallet/views/components/blocks/CardDeposit.vue.cjs +1 -1
- package/dist/martyrs/src/modules/wallet/views/components/blocks/CardDeposit.vue.js +1 -1
- package/dist/martyrs/src/modules/wallet/views/components/blocks/CryptoDeposit.vue.cjs +1 -1
- package/dist/martyrs/src/modules/wallet/views/components/blocks/CryptoDeposit.vue.js +1 -1
- package/dist/martyrs.cjs.js +1 -1
- package/dist/martyrs.css +1 -1
- package/dist/martyrs.es.js +1 -1
- package/dist/music.server.cjs +124 -31
- package/dist/music.server.js +124 -31
- package/dist/organizations.server.cjs +1 -1
- package/dist/organizations.server.js +1 -1
- package/dist/products.server.cjs +2 -2
- package/dist/products.server.js +2 -2
- package/dist/rents.server.cjs +3 -3
- package/dist/rents.server.js +3 -3
- package/dist/style.css +373 -80
- package/dist/{web-D7lZjuC0.js → web-Dkk0_7TA.js} +1 -1
- package/dist/{web-D-YZ9KHz.cjs → web-stVkXd0l.cjs} +1 -1
- package/package.json +1 -1
- package/src/builder/modes/ssr.prod.js +21 -5
- package/src/builder/rspack/rspack.config.spa.client.js +0 -44
- package/src/builder/rspack/rspack.config.ssr.client.js +40 -40
- package/src/components/Calendar/Calendar.vue +378 -377
- package/src/components/Feed/Feed.vue +28 -2
- package/src/modules/globals/controllers/classes/crud/crud.policies.js +5 -0
- package/src/modules/globals/controllers/classes/globals.validator.js +8 -1
- package/src/modules/globals/views/components/layouts/Client.vue +7 -0
- package/src/modules/music/README.md +8 -0
- package/src/modules/music/components/SidebarMusic.vue +6 -9
- package/src/modules/music/components/cards/AlbumCard.vue +20 -14
- package/src/modules/music/components/cards/ArtistCard.vue +1 -1
- package/src/modules/music/components/cards/PlaylistCard.vue +31 -11
- package/src/modules/music/components/cards/TrackListCard.vue +24 -13
- package/src/modules/music/components/forms/PlaylistForm.vue +417 -107
- package/src/modules/music/components/forms/SearchForm.vue +31 -8
- package/src/modules/music/components/forms/TrackForm.vue +50 -32
- package/src/modules/music/components/layouts/MusicBottomPlayer.vue +17 -0
- package/src/modules/music/components/pages/Album.vue +373 -186
- package/src/modules/music/components/pages/Artist.vue +54 -94
- package/src/modules/music/components/pages/MusicHome.vue +59 -56
- package/src/modules/music/components/pages/MusicLibrary.vue +13 -11
- package/src/modules/music/components/pages/Playlist.vue +495 -379
- package/src/modules/music/components/pages/SearchResults.vue +185 -313
- package/src/modules/music/components/pages/Track.vue +363 -69
- package/src/modules/music/components/player/MusicPlayer.vue +368 -97
- package/src/modules/music/components/player/TrackProgress.vue +76 -22
- package/src/modules/music/components/player/VolumeControl.vue +61 -28
- package/src/modules/music/controllers/search.controller.js +3 -0
- package/src/modules/music/controllers/stream.controller.js +11 -3
- package/src/modules/music/middlewares/playlists.verifier.js +1 -1
- package/src/modules/music/music.client.js +3 -6
- package/src/modules/music/music.server.js +8 -4
- package/src/modules/music/router/music.js +8 -1
- package/src/modules/music/routes/albums.routes.js +37 -5
- package/src/modules/music/routes/artists.routes.js +14 -4
- package/src/modules/music/routes/genres.routes.js +5 -1
- package/src/modules/music/routes/playlists.routes.js +42 -9
- package/src/modules/music/routes/tracks.routes.js +27 -2
- package/src/modules/music/store/artists.js +6 -2
- package/src/modules/music/store/player.js +6 -0
- package/src/modules/music/store/tracks.js +31 -0
- package/src/modules/music/websocket/streaming.handler.js +7 -1
- package/src/modules/rents/controllers/services/rents.services.js +2 -2
- package/src/modules/rents/views/components/pages/Gant/GanttBar.vue +4 -3
- package/src/modules/rents/views/components/pages/Gant/GanttChart.vue +42 -40
- package/src/modules/rents/views/components/pages/Gant/GanttToolbar.vue +3 -1
- package/src/modules/rents/views/components/pages/Rents.vue +60 -56
- package/dist/globals.websocket-DzvdIBf6.js +0 -306
- package/dist/globals.websocket-k6_B1T7k.cjs +0 -322
- package/dist/martyrs/src/components/Field/Field.vue2.cjs.map +0 -1
- package/dist/martyrs/src/components/Menu/Menu.vue.cjs.map +0 -1
- package/dist/martyrs/src/components/Menu/Menu.vue.js.map +0 -1
- package/dist/martyrs/src/modules/music/components/cards/TrackCard.vue.cjs +0 -69
- package/dist/martyrs/src/modules/music/components/cards/TrackCard.vue.cjs.map +0 -1
- package/dist/martyrs/src/modules/music/components/cards/TrackCard.vue.js +0 -69
- package/dist/martyrs/src/modules/music/components/cards/TrackCard.vue.js.map +0 -1
- package/dist/martyrs/src/modules/music/components/layouts/MusicLayout.vue.cjs +0 -104
- package/dist/martyrs/src/modules/music/components/layouts/MusicLayout.vue.cjs.map +0 -1
- package/dist/martyrs/src/modules/music/components/layouts/MusicLayout.vue.js +0 -104
- package/dist/martyrs/src/modules/music/components/layouts/MusicLayout.vue.js.map +0 -1
- package/src/modules/music/components/cards/TrackCard.vue +0 -86
- package/src/modules/music/components/layouts/MusicLayout.vue +0 -83
|
@@ -26,17 +26,34 @@ const _sfc_main = {
|
|
|
26
26
|
const emit = __emit;
|
|
27
27
|
const searchInput = vue.ref(null);
|
|
28
28
|
const searchQuery = vue.ref(props.initialQuery);
|
|
29
|
+
let searchTimeout = null;
|
|
29
30
|
const handleSearch = () => {
|
|
30
|
-
|
|
31
|
-
emit("search", searchQuery.value.trim());
|
|
32
|
-
}
|
|
31
|
+
emit("search", searchQuery.value.trim());
|
|
33
32
|
};
|
|
34
33
|
const clearSearch = () => {
|
|
35
34
|
searchQuery.value = "";
|
|
36
|
-
|
|
35
|
+
emit("search", "");
|
|
36
|
+
searchInput.value?.focus();
|
|
37
37
|
};
|
|
38
|
-
vue.
|
|
39
|
-
if (
|
|
38
|
+
vue.watch(searchQuery, (newQuery) => {
|
|
39
|
+
if (searchTimeout) {
|
|
40
|
+
clearTimeout(searchTimeout);
|
|
41
|
+
}
|
|
42
|
+
if (newQuery.trim().length >= 2) {
|
|
43
|
+
searchTimeout = setTimeout(() => {
|
|
44
|
+
handleSearch();
|
|
45
|
+
}, 300);
|
|
46
|
+
} else if (newQuery.trim().length === 0) {
|
|
47
|
+
emit("search", "");
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
vue.watch(() => props.initialQuery, (newQuery) => {
|
|
51
|
+
if (newQuery !== searchQuery.value) {
|
|
52
|
+
searchQuery.value = newQuery;
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
vue.onMounted(() => {
|
|
56
|
+
if (props.initialQuery) {
|
|
40
57
|
searchQuery.value = props.initialQuery;
|
|
41
58
|
}
|
|
42
59
|
});
|
|
@@ -76,6 +93,6 @@ const _sfc_main = {
|
|
|
76
93
|
};
|
|
77
94
|
}
|
|
78
95
|
};
|
|
79
|
-
const SearchForm = /* @__PURE__ */ _pluginVue_exportHelper.default(_sfc_main, [["__scopeId", "data-v-
|
|
96
|
+
const SearchForm = /* @__PURE__ */ _pluginVue_exportHelper.default(_sfc_main, [["__scopeId", "data-v-405341b8"]]);
|
|
80
97
|
exports.default = SearchForm;
|
|
81
98
|
//# sourceMappingURL=SearchForm.vue.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SearchForm.vue.cjs","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-dark-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,
|
|
1
|
+
{"version":3,"file":"SearchForm.vue.cjs","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-dark-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":["ref","watch","onMounted"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AA8BA,UAAM,QAAQ;AAWd,UAAM,OAAO;AAEb,UAAM,cAAcA,IAAAA,IAAI,IAAI;AAC5B,UAAM,cAAcA,IAAAA,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;AAGAC,QAAAA,MAAM,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;AAGDA,QAAAA,MAAM,MAAM,MAAM,cAAc,CAAC,aAAa;AAC5C,UAAI,aAAa,YAAY,OAAO;AAClC,oBAAY,QAAQ;AAAA,MACtB;AAAA,IACF,CAAC;AAEDC,QAAAA,UAAU,MAAM;AACd,UAAI,MAAM,cAAc;AACtB,oBAAY,QAAQ,MAAM;AAAA,MAC5B;AAAA,IACF,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ref,
|
|
1
|
+
import { ref, watch, onMounted, createElementBlock, openBlock, createVNode, withDirectives, createBlock, createCommentVNode, createElementVNode, withKeys, vModelText, withCtx } from "vue";
|
|
2
2
|
import _sfc_main$2 from "../../../../components/Button/Button.vue.js";
|
|
3
3
|
import _sfc_main$1 from "../../../icons/navigation/IconSearch.vue.js";
|
|
4
4
|
import _sfc_main$3 from "../../../icons/navigation/IconCross.vue.js";
|
|
@@ -24,17 +24,34 @@ const _sfc_main = {
|
|
|
24
24
|
const emit = __emit;
|
|
25
25
|
const searchInput = ref(null);
|
|
26
26
|
const searchQuery = ref(props.initialQuery);
|
|
27
|
+
let searchTimeout = null;
|
|
27
28
|
const handleSearch = () => {
|
|
28
|
-
|
|
29
|
-
emit("search", searchQuery.value.trim());
|
|
30
|
-
}
|
|
29
|
+
emit("search", searchQuery.value.trim());
|
|
31
30
|
};
|
|
32
31
|
const clearSearch = () => {
|
|
33
32
|
searchQuery.value = "";
|
|
34
|
-
|
|
33
|
+
emit("search", "");
|
|
34
|
+
searchInput.value?.focus();
|
|
35
35
|
};
|
|
36
|
-
|
|
37
|
-
if (
|
|
36
|
+
watch(searchQuery, (newQuery) => {
|
|
37
|
+
if (searchTimeout) {
|
|
38
|
+
clearTimeout(searchTimeout);
|
|
39
|
+
}
|
|
40
|
+
if (newQuery.trim().length >= 2) {
|
|
41
|
+
searchTimeout = setTimeout(() => {
|
|
42
|
+
handleSearch();
|
|
43
|
+
}, 300);
|
|
44
|
+
} else if (newQuery.trim().length === 0) {
|
|
45
|
+
emit("search", "");
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
watch(() => props.initialQuery, (newQuery) => {
|
|
49
|
+
if (newQuery !== searchQuery.value) {
|
|
50
|
+
searchQuery.value = newQuery;
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
onMounted(() => {
|
|
54
|
+
if (props.initialQuery) {
|
|
38
55
|
searchQuery.value = props.initialQuery;
|
|
39
56
|
}
|
|
40
57
|
});
|
|
@@ -74,7 +91,7 @@ const _sfc_main = {
|
|
|
74
91
|
};
|
|
75
92
|
}
|
|
76
93
|
};
|
|
77
|
-
const SearchForm = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-
|
|
94
|
+
const SearchForm = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-405341b8"]]);
|
|
78
95
|
export {
|
|
79
96
|
SearchForm as default
|
|
80
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-dark-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,
|
|
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-dark-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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
|
|
3
3
|
const vue = require("vue");
|
|
4
4
|
const vueRouter = require("vue-router");
|
|
5
|
-
const Field = require("../../../../components/Field/Field.
|
|
5
|
+
const Field = require("../../../../components/Field/Field.vue.cjs");
|
|
6
6
|
const Block = require("../../../../components/Block/Block.vue.cjs");
|
|
7
7
|
const Button = require("../../../../components/Button/Button.vue.cjs");
|
|
8
8
|
const Checkbox = require("../../../../components/Checkbox/Checkbox.vue.cjs");
|
|
@@ -20,39 +20,39 @@ const auth = require("../../../auth/views/store/auth.cjs");
|
|
|
20
20
|
const _hoisted_1 = { class: "pd-medium" };
|
|
21
21
|
const _hoisted_2 = { class: "h2 mn-b-medium" };
|
|
22
22
|
const _hoisted_3 = { class: "bg-light pd-medium radius-medium" };
|
|
23
|
-
const _hoisted_4 = { class: "
|
|
24
|
-
const _hoisted_5 = { class: "
|
|
25
|
-
const _hoisted_6 =
|
|
26
|
-
const _hoisted_7 = { class: "
|
|
27
|
-
const _hoisted_8 =
|
|
28
|
-
const _hoisted_9 = { class: "
|
|
29
|
-
const _hoisted_10 = {
|
|
23
|
+
const _hoisted_4 = { class: "cols-2-fit-content mobile:cols-1 gap-medium" };
|
|
24
|
+
const _hoisted_5 = { class: "bg-light pd-medium radius-medium" };
|
|
25
|
+
const _hoisted_6 = { class: "flex-nowrap flex-v-center flex gap-thin" };
|
|
26
|
+
const _hoisted_7 = { class: "t-medium" };
|
|
27
|
+
const _hoisted_8 = ["onClick"];
|
|
28
|
+
const _hoisted_9 = { class: "flex-nowrap flex-v-center flex" };
|
|
29
|
+
const _hoisted_10 = { class: "w-100" };
|
|
30
|
+
const _hoisted_11 = { class: "t-medium" };
|
|
31
|
+
const _hoisted_12 = {
|
|
30
32
|
key: 0,
|
|
31
33
|
class: "t-small t-transp"
|
|
32
34
|
};
|
|
33
|
-
const
|
|
34
|
-
const
|
|
35
|
-
const
|
|
36
|
-
const
|
|
37
|
-
const
|
|
38
|
-
const
|
|
39
|
-
const
|
|
35
|
+
const _hoisted_13 = { class: "flex-nowrap flex-v-center flex gap-thin" };
|
|
36
|
+
const _hoisted_14 = { class: "t-medium" };
|
|
37
|
+
const _hoisted_15 = ["onClick"];
|
|
38
|
+
const _hoisted_16 = { class: "flex-nowrap flex-v-center flex" };
|
|
39
|
+
const _hoisted_17 = { class: "w-100" };
|
|
40
|
+
const _hoisted_18 = { class: "t-medium" };
|
|
41
|
+
const _hoisted_19 = {
|
|
40
42
|
key: 0,
|
|
41
43
|
class: "t-small t-transp"
|
|
42
44
|
};
|
|
43
|
-
const
|
|
44
|
-
const
|
|
45
|
-
const
|
|
46
|
-
const
|
|
47
|
-
const
|
|
48
|
-
const
|
|
49
|
-
const
|
|
45
|
+
const _hoisted_20 = { class: "flex-nowrap flex-v-center flex gap-thin" };
|
|
46
|
+
const _hoisted_21 = { class: "t-medium" };
|
|
47
|
+
const _hoisted_22 = ["onClick"];
|
|
48
|
+
const _hoisted_23 = { class: "flex-nowrap flex-v-center flex" };
|
|
49
|
+
const _hoisted_24 = { class: "w-100" };
|
|
50
|
+
const _hoisted_25 = { class: "t-medium" };
|
|
51
|
+
const _hoisted_26 = {
|
|
50
52
|
key: 0,
|
|
51
53
|
class: "t-small t-transp"
|
|
52
54
|
};
|
|
53
|
-
const
|
|
54
|
-
const _hoisted_26 = { class: "bg-light pd-medium radius-medium" };
|
|
55
|
-
const _hoisted_27 = { class: "cols-2 mobile:cols-1 gap-medium" };
|
|
55
|
+
const _hoisted_27 = { class: "bg-light pd-medium radius-medium" };
|
|
56
56
|
const _hoisted_28 = { class: "bg-light pd-medium radius-medium" };
|
|
57
57
|
const _hoisted_29 = { class: "bg-light pd-medium radius-medium" };
|
|
58
58
|
const _hoisted_30 = { class: "flex flex-justify-between" };
|
|
@@ -174,12 +174,24 @@ const _sfc_main = {
|
|
|
174
174
|
return;
|
|
175
175
|
}
|
|
176
176
|
try {
|
|
177
|
+
console.log("=== FORM DATA DEBUG ===");
|
|
178
|
+
console.log("form.artists:", form.artists);
|
|
179
|
+
console.log("form.albums:", form.albums);
|
|
180
|
+
console.log("form.albums.length:", form.albums.length);
|
|
181
|
+
console.log("form.albums[0]:", form.albums[0]);
|
|
182
|
+
console.log("form.albums[0]?._id:", form.albums[0]?._id);
|
|
177
183
|
const formData = {
|
|
178
184
|
...form,
|
|
179
185
|
artist: form.artists.length > 0 ? form.artists[0]._id || form.artists[0] : null,
|
|
180
|
-
album: form.albums.
|
|
181
|
-
|
|
186
|
+
album: form.albums && form.albums._id ? form.albums._id : null,
|
|
187
|
+
genre: form.genres.map((genre) => genre._id || genre)
|
|
182
188
|
};
|
|
189
|
+
delete formData.artists;
|
|
190
|
+
delete formData.albums;
|
|
191
|
+
delete formData.genres;
|
|
192
|
+
console.log("formData after preparation:", formData);
|
|
193
|
+
console.log("formData.album:", formData.album);
|
|
194
|
+
console.log("typeof formData.album:", typeof formData.album);
|
|
183
195
|
if (!props.editMode) {
|
|
184
196
|
formData.owner = {
|
|
185
197
|
type: "user",
|
|
@@ -229,10 +241,37 @@ const _sfc_main = {
|
|
|
229
241
|
class: "cols-1 gap-medium"
|
|
230
242
|
}, [
|
|
231
243
|
vue.createElementVNode("div", _hoisted_3, [
|
|
232
|
-
_cache[
|
|
244
|
+
_cache[17] || (_cache[17] = vue.createElementVNode("h3", { class: "h3 mn-b-medium" }, "Media", -1)),
|
|
245
|
+
vue.createElementVNode("div", _hoisted_4, [
|
|
246
|
+
vue.createElementVNode("div", null, [
|
|
247
|
+
_cache[15] || (_cache[15] = vue.createElementVNode("p", { class: "p-semi mn-b-small" }, "Cover Image", -1)),
|
|
248
|
+
vue.createVNode(UploadImage.default, {
|
|
249
|
+
photo: form.coverUrl,
|
|
250
|
+
"onUpdate:photo": _cache[0] || (_cache[0] = ($event) => form.coverUrl = $event),
|
|
251
|
+
uploadPath: "tracks/covers",
|
|
252
|
+
class: "aspect-1x1 h-15r radius-small o-hidden mn-b-small",
|
|
253
|
+
onError: handleUploadError
|
|
254
|
+
}, null, 8, ["photo"])
|
|
255
|
+
]),
|
|
256
|
+
vue.createElementVNode("div", null, [
|
|
257
|
+
_cache[16] || (_cache[16] = vue.createElementVNode("p", { class: "p-semi mn-b-small" }, "Audio File", -1)),
|
|
258
|
+
vue.createVNode(Upload.default, {
|
|
259
|
+
field: form.fileUrl,
|
|
260
|
+
"onUpdate:field": _cache[1] || (_cache[1] = ($event) => form.fileUrl = $event),
|
|
261
|
+
onFileChange: _cache[2] || (_cache[2] = (url) => form.fileUrl = url),
|
|
262
|
+
type: "file",
|
|
263
|
+
uploadPath: "tracks/audio",
|
|
264
|
+
class: "w-100 h-15r bg-white radius-small pd-small",
|
|
265
|
+
validation: validationErrors.fileUrl
|
|
266
|
+
}, null, 8, ["field", "validation"])
|
|
267
|
+
])
|
|
268
|
+
])
|
|
269
|
+
]),
|
|
270
|
+
vue.createElementVNode("div", _hoisted_5, [
|
|
271
|
+
_cache[18] || (_cache[18] = vue.createElementVNode("h3", { class: "h3 mn-b-medium" }, "Basic Information", -1)),
|
|
233
272
|
vue.createVNode(Field.default, {
|
|
234
273
|
field: form.title,
|
|
235
|
-
"onUpdate:field": _cache[
|
|
274
|
+
"onUpdate:field": _cache[3] || (_cache[3] = ($event) => form.title = $event),
|
|
236
275
|
label: "Track Title",
|
|
237
276
|
placeholder: "Enter track title",
|
|
238
277
|
class: "bg-white radius-small pd-small mn-b-thin",
|
|
@@ -240,14 +279,14 @@ const _sfc_main = {
|
|
|
240
279
|
}, null, 8, ["field", "validation"]),
|
|
241
280
|
vue.createVNode(Field.default, {
|
|
242
281
|
field: form.url,
|
|
243
|
-
"onUpdate:field": _cache[
|
|
282
|
+
"onUpdate:field": _cache[4] || (_cache[4] = ($event) => form.url = $event),
|
|
244
283
|
label: "URL",
|
|
245
284
|
placeholder: "Leave blank for auto-generation based on the track title",
|
|
246
285
|
class: "bg-white radius-small pd-small mn-b-small"
|
|
247
286
|
}, null, 8, ["field"]),
|
|
248
287
|
vue.createVNode(Field.default, {
|
|
249
288
|
field: form.releaseDate,
|
|
250
|
-
"onUpdate:field": _cache[
|
|
289
|
+
"onUpdate:field": _cache[5] || (_cache[5] = ($event) => form.releaseDate = $event),
|
|
251
290
|
label: "Release Date",
|
|
252
291
|
type: "date",
|
|
253
292
|
class: "bg-white radius-small pd-small mn-b-thin",
|
|
@@ -255,7 +294,7 @@ const _sfc_main = {
|
|
|
255
294
|
}, null, 8, ["field", "validation"]),
|
|
256
295
|
vue.createVNode(Field.default, {
|
|
257
296
|
field: form.duration,
|
|
258
|
-
"onUpdate:field": _cache[
|
|
297
|
+
"onUpdate:field": _cache[6] || (_cache[6] = ($event) => form.duration = $event),
|
|
259
298
|
label: "Duration (seconds)",
|
|
260
299
|
type: "number",
|
|
261
300
|
placeholder: "Track duration in seconds",
|
|
@@ -266,7 +305,7 @@ const _sfc_main = {
|
|
|
266
305
|
default: vue.withCtx(() => [
|
|
267
306
|
vue.createVNode(BlockMultiselect.default, {
|
|
268
307
|
modelValue: form.artists,
|
|
269
|
-
"onUpdate:modelValue": _cache[
|
|
308
|
+
"onUpdate:modelValue": _cache[7] || (_cache[7] = ($event) => form.artists = $event),
|
|
270
309
|
placeholder: "Search artists...",
|
|
271
310
|
multiple: false,
|
|
272
311
|
transform: (item) => ({ _id: item._id, name: item.name }),
|
|
@@ -304,21 +343,21 @@ const _sfc_main = {
|
|
|
304
343
|
classFeed: "h-max-30r gap-thin flex-column flex o-scroll"
|
|
305
344
|
}, {
|
|
306
345
|
selected: vue.withCtx(({ item, clear }) => [
|
|
307
|
-
vue.createElementVNode("div",
|
|
308
|
-
vue.createElementVNode("span",
|
|
346
|
+
vue.createElementVNode("div", _hoisted_6, [
|
|
347
|
+
vue.createElementVNode("span", _hoisted_7, vue.toDisplayString(item?.name || item), 1),
|
|
309
348
|
vue.createElementVNode("button", {
|
|
310
349
|
onClick: vue.withModifiers(clear, ["stop"]),
|
|
311
350
|
class: "i-small pd-micro bg-red radius-extra flex-center flex aspect-1x1 hover-scale-1"
|
|
312
351
|
}, [
|
|
313
352
|
vue.createVNode(IconCross.default, { class: "i-micro fill-white" })
|
|
314
|
-
], 8,
|
|
353
|
+
], 8, _hoisted_8)
|
|
315
354
|
])
|
|
316
355
|
]),
|
|
317
356
|
item: vue.withCtx(({ item }) => [
|
|
318
|
-
vue.createElementVNode("div",
|
|
319
|
-
vue.createElementVNode("div",
|
|
320
|
-
vue.createElementVNode("p",
|
|
321
|
-
item.bio ? (vue.openBlock(), vue.createElementBlock("p",
|
|
357
|
+
vue.createElementVNode("div", _hoisted_9, [
|
|
358
|
+
vue.createElementVNode("div", _hoisted_10, [
|
|
359
|
+
vue.createElementVNode("p", _hoisted_11, vue.toDisplayString(item.name), 1),
|
|
360
|
+
item.bio ? (vue.openBlock(), vue.createElementBlock("p", _hoisted_12, vue.toDisplayString(item.bio), 1)) : vue.createCommentVNode("", true)
|
|
322
361
|
])
|
|
323
362
|
])
|
|
324
363
|
]),
|
|
@@ -331,7 +370,7 @@ const _sfc_main = {
|
|
|
331
370
|
default: vue.withCtx(() => [
|
|
332
371
|
vue.createVNode(BlockMultiselect.default, {
|
|
333
372
|
modelValue: form.albums,
|
|
334
|
-
"onUpdate:modelValue": _cache[
|
|
373
|
+
"onUpdate:modelValue": _cache[8] || (_cache[8] = ($event) => form.albums = $event),
|
|
335
374
|
placeholder: "Search albums...",
|
|
336
375
|
multiple: false,
|
|
337
376
|
transform: (item) => ({ _id: item._id, title: item.title }),
|
|
@@ -369,21 +408,21 @@ const _sfc_main = {
|
|
|
369
408
|
classFeed: "h-max-30r gap-thin flex-column flex o-scroll"
|
|
370
409
|
}, {
|
|
371
410
|
selected: vue.withCtx(({ item, clear }) => [
|
|
372
|
-
vue.createElementVNode("div",
|
|
373
|
-
vue.createElementVNode("span",
|
|
411
|
+
vue.createElementVNode("div", _hoisted_13, [
|
|
412
|
+
vue.createElementVNode("span", _hoisted_14, vue.toDisplayString(item?.title || item), 1),
|
|
374
413
|
vue.createElementVNode("button", {
|
|
375
414
|
onClick: vue.withModifiers(clear, ["stop"]),
|
|
376
415
|
class: "i-small pd-micro bg-red radius-extra flex-center flex aspect-1x1 hover-scale-1"
|
|
377
416
|
}, [
|
|
378
417
|
vue.createVNode(IconCross.default, { class: "i-micro fill-white" })
|
|
379
|
-
], 8,
|
|
418
|
+
], 8, _hoisted_15)
|
|
380
419
|
])
|
|
381
420
|
]),
|
|
382
421
|
item: vue.withCtx(({ item }) => [
|
|
383
|
-
vue.createElementVNode("div",
|
|
384
|
-
vue.createElementVNode("div",
|
|
385
|
-
vue.createElementVNode("p",
|
|
386
|
-
item.description ? (vue.openBlock(), vue.createElementBlock("p",
|
|
422
|
+
vue.createElementVNode("div", _hoisted_16, [
|
|
423
|
+
vue.createElementVNode("div", _hoisted_17, [
|
|
424
|
+
vue.createElementVNode("p", _hoisted_18, vue.toDisplayString(item.title), 1),
|
|
425
|
+
item.description ? (vue.openBlock(), vue.createElementBlock("p", _hoisted_19, vue.toDisplayString(item.description), 1)) : vue.createCommentVNode("", true)
|
|
387
426
|
])
|
|
388
427
|
])
|
|
389
428
|
]),
|
|
@@ -396,7 +435,7 @@ const _sfc_main = {
|
|
|
396
435
|
default: vue.withCtx(() => [
|
|
397
436
|
vue.createVNode(BlockMultiselect.default, {
|
|
398
437
|
modelValue: form.genres,
|
|
399
|
-
"onUpdate:modelValue": _cache[
|
|
438
|
+
"onUpdate:modelValue": _cache[9] || (_cache[9] = ($event) => form.genres = $event),
|
|
400
439
|
placeholder: "Search genres...",
|
|
401
440
|
multiple: true,
|
|
402
441
|
transform: (item) => ({ _id: item._id, name: item.name }),
|
|
@@ -434,21 +473,21 @@ const _sfc_main = {
|
|
|
434
473
|
classFeed: "h-max-30r gap-thin flex-column flex o-scroll"
|
|
435
474
|
}, {
|
|
436
475
|
selected: vue.withCtx(({ item, clear }) => [
|
|
437
|
-
vue.createElementVNode("div",
|
|
438
|
-
vue.createElementVNode("span",
|
|
476
|
+
vue.createElementVNode("div", _hoisted_20, [
|
|
477
|
+
vue.createElementVNode("span", _hoisted_21, vue.toDisplayString(item?.name || item), 1),
|
|
439
478
|
vue.createElementVNode("button", {
|
|
440
479
|
onClick: vue.withModifiers(clear, ["stop"]),
|
|
441
480
|
class: "i-small pd-micro bg-red radius-extra flex-center flex aspect-1x1 hover-scale-1"
|
|
442
481
|
}, [
|
|
443
482
|
vue.createVNode(IconCross.default, { class: "i-micro fill-white" })
|
|
444
|
-
], 8,
|
|
483
|
+
], 8, _hoisted_22)
|
|
445
484
|
])
|
|
446
485
|
]),
|
|
447
486
|
item: vue.withCtx(({ item }) => [
|
|
448
|
-
vue.createElementVNode("div",
|
|
449
|
-
vue.createElementVNode("div",
|
|
450
|
-
vue.createElementVNode("p",
|
|
451
|
-
item.description ? (vue.openBlock(), vue.createElementBlock("p",
|
|
487
|
+
vue.createElementVNode("div", _hoisted_23, [
|
|
488
|
+
vue.createElementVNode("div", _hoisted_24, [
|
|
489
|
+
vue.createElementVNode("p", _hoisted_25, vue.toDisplayString(item.name), 1),
|
|
490
|
+
item.description ? (vue.openBlock(), vue.createElementBlock("p", _hoisted_26, vue.toDisplayString(item.description), 1)) : vue.createCommentVNode("", true)
|
|
452
491
|
])
|
|
453
492
|
])
|
|
454
493
|
]),
|
|
@@ -457,48 +496,21 @@ const _sfc_main = {
|
|
|
457
496
|
]),
|
|
458
497
|
_: 1
|
|
459
498
|
}),
|
|
460
|
-
vue.createElementVNode("div",
|
|
461
|
-
_cache[
|
|
499
|
+
vue.createElementVNode("div", _hoisted_27, [
|
|
500
|
+
_cache[19] || (_cache[19] = vue.createElementVNode("h3", { class: "h3 mn-b-medium" }, "Content Settings", -1)),
|
|
462
501
|
vue.createVNode(Checkbox.default, {
|
|
463
502
|
checkbox: form.isExplicit,
|
|
464
|
-
"onUpdate:checkbox": _cache[
|
|
503
|
+
"onUpdate:checkbox": _cache[10] || (_cache[10] = ($event) => form.isExplicit = $event),
|
|
465
504
|
label: "Explicit Content",
|
|
466
505
|
class: "bg-white radius-small pd-small mn-b-thin"
|
|
467
506
|
}, null, 8, ["checkbox"]),
|
|
468
507
|
vue.createVNode(Checkbox.default, {
|
|
469
508
|
checkbox: form.isPublic,
|
|
470
|
-
"onUpdate:checkbox": _cache[
|
|
509
|
+
"onUpdate:checkbox": _cache[11] || (_cache[11] = ($event) => form.isPublic = $event),
|
|
471
510
|
label: "Public Track",
|
|
472
511
|
class: "bg-white radius-small pd-small mn-b-thin"
|
|
473
512
|
}, null, 8, ["checkbox"])
|
|
474
513
|
]),
|
|
475
|
-
vue.createElementVNode("div", _hoisted_26, [
|
|
476
|
-
_cache[19] || (_cache[19] = vue.createElementVNode("h3", { class: "h3 mn-b-medium" }, "Media", -1)),
|
|
477
|
-
vue.createElementVNode("div", _hoisted_27, [
|
|
478
|
-
vue.createElementVNode("div", null, [
|
|
479
|
-
_cache[17] || (_cache[17] = vue.createElementVNode("p", { class: "p-semi mn-b-small" }, "Cover Image", -1)),
|
|
480
|
-
vue.createVNode(UploadImage.default, {
|
|
481
|
-
photo: form.coverUrl,
|
|
482
|
-
"onUpdate:photo": _cache[9] || (_cache[9] = ($event) => form.coverUrl = $event),
|
|
483
|
-
uploadPath: "tracks/covers",
|
|
484
|
-
class: "w-100 h-15r radius-small o-hidden mn-b-small",
|
|
485
|
-
onError: handleUploadError
|
|
486
|
-
}, null, 8, ["photo"])
|
|
487
|
-
]),
|
|
488
|
-
vue.createElementVNode("div", null, [
|
|
489
|
-
_cache[18] || (_cache[18] = vue.createElementVNode("p", { class: "p-semi mn-b-small" }, "Audio File", -1)),
|
|
490
|
-
vue.createVNode(Upload.default, {
|
|
491
|
-
field: form.fileUrl,
|
|
492
|
-
"onUpdate:field": _cache[10] || (_cache[10] = ($event) => form.fileUrl = $event),
|
|
493
|
-
onFileChange: _cache[11] || (_cache[11] = (url) => form.fileUrl = url),
|
|
494
|
-
type: "file",
|
|
495
|
-
uploadPath: "tracks/audio",
|
|
496
|
-
class: "w-100 h-15r bg-white radius-small pd-small",
|
|
497
|
-
validation: validationErrors.fileUrl
|
|
498
|
-
}, null, 8, ["field", "validation"])
|
|
499
|
-
])
|
|
500
|
-
])
|
|
501
|
-
]),
|
|
502
514
|
vue.createElementVNode("div", _hoisted_28, [
|
|
503
515
|
_cache[20] || (_cache[20] = vue.createElementVNode("h3", { class: "h3 mn-b-medium" }, "Additional Information", -1)),
|
|
504
516
|
vue.createVNode(Field.default, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TrackForm.vue.cjs","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-medium\">\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 <!-- 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 mobile:cols-1 gap-medium\">\n <!-- Track Cover -->\n <div>\n <p class=\"p-semi mn-b-small\">Cover Image</p>\n <UploadImage\n v-model:photo=\"form.coverUrl\"\n uploadPath=\"tracks/covers\"\n class=\"w-100 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-semi 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 <!-- 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/globals/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 * as globals from '@martyrs/src/modules/globals/views/store/globals.js';\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 globals.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 globals.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 // 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.length > 0 ?? form.albums.map(album => album._id || genre),\n genres: form.genres.map(genre => genre._id || genre)\n };\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 globals.actions.setError({\n message: 'Failed to save track'\n });\n }\n};\nconst handleUploadError = (error) => {\n console.error('Upload error:', error);\n globals.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>"],"names":["artistsStore","albumsStore","genresStore","useRouter","useRoute","reactive","ref","watch","tracksStore.actions","globals.actions","genre","auth.state","onMounted"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"TrackForm.vue.cjs","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-medium\">\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-medium\">\n <!-- Track Cover -->\n <div>\n <p class=\"p-semi 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-semi 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/globals/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 * as globals from '@martyrs/src/modules/globals/views/store/globals.js';\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 globals.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 globals.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 globals.actions.setError({\n message: 'Failed to save track'\n });\n }\n};\nconst handleUploadError = (error) => {\n console.error('Upload error:', error);\n globals.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>"],"names":["artistsStore","albumsStore","genresStore","useRouter","useRoute","reactive","ref","watch","tracksStore.actions","globals.actions","auth.state","onMounted"],"mappings":"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"}
|