@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.
Files changed (341) hide show
  1. package/dist/_virtual/index.cjs +4 -4
  2. package/dist/_virtual/index.js +4 -4
  3. package/dist/_virtual/index2.cjs +4 -4
  4. package/dist/_virtual/index2.js +4 -4
  5. package/dist/builder.cjs +53 -90
  6. package/dist/builder.js +54 -91
  7. package/dist/{crud-B-kQw3Z5.cjs → crud-JN_LFj01.cjs} +3 -0
  8. package/dist/{crud-Cwx5VlSm.js → crud-sE7GLPbj.js} +3 -0
  9. package/dist/globals.server.cjs +322 -3
  10. package/dist/globals.server.js +303 -1
  11. package/dist/{globals.verifier-D68mHEBl.cjs → globals.verifier-C0zj_LLo.cjs} +8 -1
  12. package/dist/{globals.verifier-CWFz5Gh2.js → globals.verifier-DFqKQ7hK.js} +8 -1
  13. package/dist/inventory.server.cjs +2 -2
  14. package/dist/inventory.server.js +2 -2
  15. package/dist/{main-SZQ1QjeP.js → main-CJm5myDI.js} +631 -607
  16. package/dist/{main-MzmGbSxs.cjs → main-DTaE01lg.cjs} +6 -6
  17. package/dist/martyrs/src/components/Calendar/Calendar.vue2.cjs +1 -1
  18. package/dist/martyrs/src/components/Calendar/Calendar.vue2.cjs.map +1 -1
  19. package/dist/martyrs/src/components/Calendar/Calendar.vue2.js +1 -1
  20. package/dist/martyrs/src/components/Calendar/Calendar.vue2.js.map +1 -1
  21. package/dist/martyrs/src/components/Feed/Feed.vue.cjs +33 -7
  22. package/dist/martyrs/src/components/Feed/Feed.vue.cjs.map +1 -1
  23. package/dist/martyrs/src/components/Feed/Feed.vue.js +33 -7
  24. package/dist/martyrs/src/components/Feed/Feed.vue.js.map +1 -1
  25. package/dist/martyrs/src/components/Field/{Field.vue2.cjs → Field.vue.cjs} +2 -2
  26. package/dist/martyrs/src/components/Field/{Field.vue2.js.map → Field.vue.cjs.map} +1 -1
  27. package/dist/martyrs/src/components/Field/{Field.vue2.js → Field.vue.js} +2 -2
  28. package/dist/martyrs/src/components/Field/Field.vue.js.map +1 -0
  29. package/dist/martyrs/src/components/FieldBig/FieldBig.vue.cjs +1 -1
  30. package/dist/martyrs/src/components/FieldBig/FieldBig.vue.js +1 -1
  31. package/dist/martyrs/src/components/FieldTags/FieldTags.vue.cjs +1 -1
  32. package/dist/martyrs/src/components/FieldTags/FieldTags.vue.js +1 -1
  33. package/dist/martyrs/src/components/Menu/{Menu.vue.cjs → Menu.vue2.cjs} +2 -2
  34. package/dist/martyrs/src/components/Menu/Menu.vue2.cjs.map +1 -0
  35. package/dist/martyrs/src/components/Menu/{Menu.vue.js → Menu.vue2.js} +2 -2
  36. package/dist/martyrs/src/components/Menu/Menu.vue2.js.map +1 -0
  37. package/dist/martyrs/src/components/Menu/MenuItem.vue.js +2 -2
  38. package/dist/martyrs/src/components/Menu/MenuItem.vue.js.map +1 -1
  39. package/dist/martyrs/src/components/PhotoViewer/PhotoViewer.vue.js +4 -4
  40. package/dist/martyrs/src/modules/auth/views/components/pages/EnterCode.vue.cjs +1 -1
  41. package/dist/martyrs/src/modules/auth/views/components/pages/EnterCode.vue.js +1 -1
  42. package/dist/martyrs/src/modules/auth/views/components/pages/EnterPassword.vue.cjs +1 -1
  43. package/dist/martyrs/src/modules/auth/views/components/pages/EnterPassword.vue.js +1 -1
  44. package/dist/martyrs/src/modules/auth/views/components/pages/Invite.vue.cjs +1 -1
  45. package/dist/martyrs/src/modules/auth/views/components/pages/Invite.vue.js +1 -1
  46. package/dist/martyrs/src/modules/auth/views/components/pages/Profile.vue.cjs +2 -2
  47. package/dist/martyrs/src/modules/auth/views/components/pages/Profile.vue.js +2 -2
  48. package/dist/martyrs/src/modules/auth/views/components/pages/ProfileEditProfile.vue.cjs +1 -1
  49. package/dist/martyrs/src/modules/auth/views/components/pages/ProfileEditProfile.vue.js +1 -1
  50. package/dist/martyrs/src/modules/auth/views/components/pages/ResetPassword.vue.cjs +1 -1
  51. package/dist/martyrs/src/modules/auth/views/components/pages/ResetPassword.vue.js +1 -1
  52. package/dist/martyrs/src/modules/auth/views/components/pages/SignIn.vue.cjs +1 -1
  53. package/dist/martyrs/src/modules/auth/views/components/pages/SignIn.vue.js +1 -1
  54. package/dist/martyrs/src/modules/auth/views/components/pages/SignUp.vue.cjs +1 -1
  55. package/dist/martyrs/src/modules/auth/views/components/pages/SignUp.vue.js +1 -1
  56. package/dist/martyrs/src/modules/auth/views/components/sections/ProfileEditCredentials.vue.cjs +1 -1
  57. package/dist/martyrs/src/modules/auth/views/components/sections/ProfileEditCredentials.vue.js +1 -1
  58. package/dist/martyrs/src/modules/community/components/pages/CreateBlogPost.vue.cjs +2 -2
  59. package/dist/martyrs/src/modules/community/components/pages/CreateBlogPost.vue.js +2 -2
  60. package/dist/martyrs/src/modules/constructor/components/elements/Card.vue.cjs +1 -1
  61. package/dist/martyrs/src/modules/constructor/components/elements/Card.vue.js +1 -1
  62. package/dist/martyrs/src/modules/constructor/components/elements/Embed.vue.cjs +1 -1
  63. package/dist/martyrs/src/modules/constructor/components/elements/Embed.vue.js +1 -1
  64. package/dist/martyrs/src/modules/events/components/pages/EditEvent.vue.cjs +1 -1
  65. package/dist/martyrs/src/modules/events/components/pages/EditEvent.vue.js +1 -1
  66. package/dist/martyrs/src/modules/events/components/pages/EditEventTickets.vue.cjs +1 -1
  67. package/dist/martyrs/src/modules/events/components/pages/EditEventTickets.vue.js +1 -1
  68. package/dist/martyrs/src/modules/events/components/pages/Event.vue.cjs +1 -1
  69. package/dist/martyrs/src/modules/events/components/pages/Event.vue.js +1 -1
  70. package/dist/martyrs/src/modules/gallery/components/sections/BackofficeGallery.vue.cjs +1 -1
  71. package/dist/martyrs/src/modules/gallery/components/sections/BackofficeGallery.vue.js +1 -1
  72. package/dist/martyrs/src/modules/globals/views/classes/globals.i18n.cjs +1 -1
  73. package/dist/martyrs/src/modules/globals/views/classes/globals.i18n.js +1 -1
  74. package/dist/martyrs/src/modules/globals/views/components/blocks/BlockSearch.vue.cjs +1 -1
  75. package/dist/martyrs/src/modules/globals/views/components/blocks/BlockSearch.vue.js +1 -1
  76. package/dist/martyrs/src/modules/globals/views/components/layouts/Client.vue.cjs +5 -1
  77. package/dist/martyrs/src/modules/globals/views/components/layouts/Client.vue.cjs.map +1 -1
  78. package/dist/martyrs/src/modules/globals/views/components/layouts/Client.vue.js +5 -1
  79. package/dist/martyrs/src/modules/globals/views/components/layouts/Client.vue.js.map +1 -1
  80. package/dist/martyrs/src/modules/icons/entities/IconTime.vue.cjs +2 -2
  81. package/dist/martyrs/src/modules/icons/entities/IconTime.vue.js +2 -2
  82. package/dist/martyrs/src/modules/icons/navigation/IconChevronLeft.vue.cjs +2 -2
  83. package/dist/martyrs/src/modules/icons/navigation/IconChevronLeft.vue.js +2 -2
  84. package/dist/martyrs/src/modules/icons/navigation/IconChevronRight.vue.cjs +2 -2
  85. package/dist/martyrs/src/modules/icons/navigation/IconChevronRight.vue.js +2 -2
  86. package/dist/martyrs/src/modules/icons/pages/IconsPage.vue.js +6 -6
  87. package/dist/martyrs/src/modules/icons/pages/IconsPage.vue.js.map +1 -1
  88. package/dist/martyrs/src/modules/inventory/components/forms/AdjustmentForm.vue.cjs +1 -1
  89. package/dist/martyrs/src/modules/inventory/components/forms/AdjustmentForm.vue.js +1 -1
  90. package/dist/martyrs/src/modules/inventory/components/forms/StockAlertsForm.vue.cjs +1 -1
  91. package/dist/martyrs/src/modules/inventory/components/forms/StockAlertsForm.vue.js +1 -1
  92. package/dist/martyrs/src/modules/inventory/components/pages/Inventory.vue.cjs +1 -1
  93. package/dist/martyrs/src/modules/inventory/components/pages/InventoryEdit.vue.cjs +1 -1
  94. package/dist/martyrs/src/modules/inventory/components/pages/InventoryEdit.vue.js +1 -1
  95. package/dist/martyrs/src/modules/music/components/cards/AlbumCard.vue.cjs +22 -15
  96. package/dist/martyrs/src/modules/music/components/cards/AlbumCard.vue.cjs.map +1 -1
  97. package/dist/martyrs/src/modules/music/components/cards/AlbumCard.vue.js +23 -16
  98. package/dist/martyrs/src/modules/music/components/cards/AlbumCard.vue.js.map +1 -1
  99. package/dist/martyrs/src/modules/music/components/cards/ArtistCard.vue.cjs +2 -2
  100. package/dist/martyrs/src/modules/music/components/cards/ArtistCard.vue.cjs.map +1 -1
  101. package/dist/martyrs/src/modules/music/components/cards/ArtistCard.vue.js +2 -2
  102. package/dist/martyrs/src/modules/music/components/cards/ArtistCard.vue.js.map +1 -1
  103. package/dist/martyrs/src/modules/music/components/cards/PlaylistCard.vue.cjs +31 -13
  104. package/dist/martyrs/src/modules/music/components/cards/PlaylistCard.vue.cjs.map +1 -1
  105. package/dist/martyrs/src/modules/music/components/cards/PlaylistCard.vue.js +33 -15
  106. package/dist/martyrs/src/modules/music/components/cards/PlaylistCard.vue.js.map +1 -1
  107. package/dist/martyrs/src/modules/music/components/cards/TrackListCard.vue.cjs +39 -22
  108. package/dist/martyrs/src/modules/music/components/cards/TrackListCard.vue.cjs.map +1 -1
  109. package/dist/martyrs/src/modules/music/components/cards/TrackListCard.vue.js +39 -22
  110. package/dist/martyrs/src/modules/music/components/cards/TrackListCard.vue.js.map +1 -1
  111. package/dist/martyrs/src/modules/music/components/forms/AlbumForm.vue.cjs +1 -1
  112. package/dist/martyrs/src/modules/music/components/forms/AlbumForm.vue.js +1 -1
  113. package/dist/martyrs/src/modules/music/components/forms/ArtistForm.vue.cjs +1 -1
  114. package/dist/martyrs/src/modules/music/components/forms/ArtistForm.vue.js +1 -1
  115. package/dist/martyrs/src/modules/music/components/forms/PlaylistForm.vue.cjs +385 -125
  116. package/dist/martyrs/src/modules/music/components/forms/PlaylistForm.vue.cjs.map +1 -1
  117. package/dist/martyrs/src/modules/music/components/forms/PlaylistForm.vue.js +391 -131
  118. package/dist/martyrs/src/modules/music/components/forms/PlaylistForm.vue.js.map +1 -1
  119. package/dist/martyrs/src/modules/music/components/forms/SearchForm.vue.cjs +24 -7
  120. package/dist/martyrs/src/modules/music/components/forms/SearchForm.vue.cjs.map +1 -1
  121. package/dist/martyrs/src/modules/music/components/forms/SearchForm.vue.js +25 -8
  122. package/dist/martyrs/src/modules/music/components/forms/SearchForm.vue.js.map +1 -1
  123. package/dist/martyrs/src/modules/music/components/forms/TrackForm.vue.cjs +99 -87
  124. package/dist/martyrs/src/modules/music/components/forms/TrackForm.vue.cjs.map +1 -1
  125. package/dist/martyrs/src/modules/music/components/forms/TrackForm.vue.js +111 -99
  126. package/dist/martyrs/src/modules/music/components/forms/TrackForm.vue.js.map +1 -1
  127. package/dist/martyrs/src/modules/music/components/layouts/MusicBottomPlayer.vue.cjs +21 -0
  128. package/dist/martyrs/src/modules/music/components/layouts/MusicBottomPlayer.vue.cjs.map +1 -0
  129. package/dist/martyrs/src/modules/music/components/layouts/MusicBottomPlayer.vue.js +21 -0
  130. package/dist/martyrs/src/modules/music/components/layouts/MusicBottomPlayer.vue.js.map +1 -0
  131. package/dist/martyrs/src/modules/music/components/pages/Album.vue.cjs +442 -210
  132. package/dist/martyrs/src/modules/music/components/pages/Album.vue.cjs.map +1 -1
  133. package/dist/martyrs/src/modules/music/components/pages/Album.vue.js +445 -213
  134. package/dist/martyrs/src/modules/music/components/pages/Album.vue.js.map +1 -1
  135. package/dist/martyrs/src/modules/music/components/pages/Artist.vue.cjs +92 -117
  136. package/dist/martyrs/src/modules/music/components/pages/Artist.vue.cjs.map +1 -1
  137. package/dist/martyrs/src/modules/music/components/pages/Artist.vue.js +93 -118
  138. package/dist/martyrs/src/modules/music/components/pages/Artist.vue.js.map +1 -1
  139. package/dist/martyrs/src/modules/music/components/pages/MusicHome.vue.cjs +72 -113
  140. package/dist/martyrs/src/modules/music/components/pages/MusicHome.vue.cjs.map +1 -1
  141. package/dist/martyrs/src/modules/music/components/pages/MusicHome.vue.js +78 -119
  142. package/dist/martyrs/src/modules/music/components/pages/MusicHome.vue.js.map +1 -1
  143. package/dist/martyrs/src/modules/music/components/pages/MusicLibrary.vue.cjs +15 -12
  144. package/dist/martyrs/src/modules/music/components/pages/MusicLibrary.vue.cjs.map +1 -1
  145. package/dist/martyrs/src/modules/music/components/pages/MusicLibrary.vue.js +15 -12
  146. package/dist/martyrs/src/modules/music/components/pages/MusicLibrary.vue.js.map +1 -1
  147. package/dist/martyrs/src/modules/music/components/pages/Playlist.vue.cjs +558 -429
  148. package/dist/martyrs/src/modules/music/components/pages/Playlist.vue.cjs.map +1 -1
  149. package/dist/martyrs/src/modules/music/components/pages/Playlist.vue.js +560 -431
  150. package/dist/martyrs/src/modules/music/components/pages/Playlist.vue.js.map +1 -1
  151. package/dist/martyrs/src/modules/music/components/pages/SearchResults.vue.cjs +146 -284
  152. package/dist/martyrs/src/modules/music/components/pages/SearchResults.vue.cjs.map +1 -1
  153. package/dist/martyrs/src/modules/music/components/pages/SearchResults.vue.js +149 -287
  154. package/dist/martyrs/src/modules/music/components/pages/SearchResults.vue.js.map +1 -1
  155. package/dist/martyrs/src/modules/music/components/pages/Track.vue.cjs +460 -63
  156. package/dist/martyrs/src/modules/music/components/pages/Track.vue.cjs.map +1 -1
  157. package/dist/martyrs/src/modules/music/components/pages/Track.vue.js +462 -65
  158. package/dist/martyrs/src/modules/music/components/pages/Track.vue.js.map +1 -1
  159. package/dist/martyrs/src/modules/music/components/player/MusicPlayer.vue.cjs +126 -136
  160. package/dist/martyrs/src/modules/music/components/player/MusicPlayer.vue.cjs.map +1 -1
  161. package/dist/martyrs/src/modules/music/components/player/MusicPlayer.vue.js +129 -139
  162. package/dist/martyrs/src/modules/music/components/player/MusicPlayer.vue.js.map +1 -1
  163. package/dist/martyrs/src/modules/music/components/player/TrackProgress.vue.cjs +18 -15
  164. package/dist/martyrs/src/modules/music/components/player/TrackProgress.vue.cjs.map +1 -1
  165. package/dist/martyrs/src/modules/music/components/player/TrackProgress.vue.js +18 -15
  166. package/dist/martyrs/src/modules/music/components/player/TrackProgress.vue.js.map +1 -1
  167. package/dist/martyrs/src/modules/music/components/player/VolumeControl.vue.cjs +28 -23
  168. package/dist/martyrs/src/modules/music/components/player/VolumeControl.vue.cjs.map +1 -1
  169. package/dist/martyrs/src/modules/music/components/player/VolumeControl.vue.js +29 -24
  170. package/dist/martyrs/src/modules/music/components/player/VolumeControl.vue.js.map +1 -1
  171. package/dist/martyrs/src/modules/music/music.client.cjs +3 -6
  172. package/dist/martyrs/src/modules/music/music.client.cjs.map +1 -1
  173. package/dist/martyrs/src/modules/music/music.client.js +9 -12
  174. package/dist/martyrs/src/modules/music/music.client.js.map +1 -1
  175. package/dist/martyrs/src/modules/music/router/music.cjs +27 -1
  176. package/dist/martyrs/src/modules/music/router/music.cjs.map +1 -1
  177. package/dist/martyrs/src/modules/music/router/music.js +27 -1
  178. package/dist/martyrs/src/modules/music/router/music.js.map +1 -1
  179. package/dist/martyrs/src/modules/music/store/artists.cjs +6 -4
  180. package/dist/martyrs/src/modules/music/store/artists.cjs.map +1 -1
  181. package/dist/martyrs/src/modules/music/store/artists.js +6 -4
  182. package/dist/martyrs/src/modules/music/store/artists.js.map +1 -1
  183. package/dist/martyrs/src/modules/music/store/player.cjs +5 -0
  184. package/dist/martyrs/src/modules/music/store/player.cjs.map +1 -1
  185. package/dist/martyrs/src/modules/music/store/player.js +5 -0
  186. package/dist/martyrs/src/modules/music/store/player.js.map +1 -1
  187. package/dist/martyrs/src/modules/music/store/tracks.cjs +22 -0
  188. package/dist/martyrs/src/modules/music/store/tracks.cjs.map +1 -1
  189. package/dist/martyrs/src/modules/music/store/tracks.js +22 -0
  190. package/dist/martyrs/src/modules/music/store/tracks.js.map +1 -1
  191. package/dist/martyrs/src/modules/orders/components/blocks/CardOrderBackoffice.vue.js +2 -2
  192. package/dist/martyrs/src/modules/orders/components/pages/OrderBackoffice.vue.js +2 -2
  193. package/dist/martyrs/src/modules/orders/components/pages/OrderCreateBackoffice.vue.cjs +1 -1
  194. package/dist/martyrs/src/modules/orders/components/pages/OrderCreateBackoffice.vue.js +1 -1
  195. package/dist/martyrs/src/modules/orders/components/sections/FormAddCustomer.vue.cjs +1 -1
  196. package/dist/martyrs/src/modules/orders/components/sections/FormAddCustomer.vue.js +1 -1
  197. package/dist/martyrs/src/modules/orders/components/sections/FormCustomerDetails.vue.cjs +1 -1
  198. package/dist/martyrs/src/modules/orders/components/sections/FormCustomerDetails.vue.js +1 -1
  199. package/dist/martyrs/src/modules/orders/components/sections/FormDelivery.vue.cjs +1 -1
  200. package/dist/martyrs/src/modules/orders/components/sections/FormDelivery.vue.js +1 -1
  201. package/dist/martyrs/src/modules/organizations/components/blocks/CardOrganization.vue.js +2 -2
  202. package/dist/martyrs/src/modules/organizations/components/pages/DepartmentEdit.vue.cjs +1 -1
  203. package/dist/martyrs/src/modules/organizations/components/pages/DepartmentEdit.vue.js +1 -1
  204. package/dist/martyrs/src/modules/organizations/components/pages/Members.vue.cjs +1 -1
  205. package/dist/martyrs/src/modules/organizations/components/pages/Members.vue.js +1 -1
  206. package/dist/martyrs/src/modules/organizations/components/pages/Organization.vue.cjs +1 -1
  207. package/dist/martyrs/src/modules/organizations/components/pages/Organization.vue.js +1 -1
  208. package/dist/martyrs/src/modules/organizations/components/pages/OrganizationBackoffice.vue.cjs +1 -1
  209. package/dist/martyrs/src/modules/organizations/components/pages/OrganizationBackoffice.vue.js +1 -1
  210. package/dist/martyrs/src/modules/organizations/components/pages/OrganizationEdit.vue.cjs +1 -1
  211. package/dist/martyrs/src/modules/organizations/components/pages/OrganizationEdit.vue.js +1 -1
  212. package/dist/martyrs/src/modules/organizations/components/sections/Documents.vue.cjs +1 -1
  213. package/dist/martyrs/src/modules/organizations/components/sections/Documents.vue.js +1 -1
  214. package/dist/martyrs/src/modules/organizations/components/sections/MembersAdd.vue.cjs +1 -1
  215. package/dist/martyrs/src/modules/organizations/components/sections/MembersAdd.vue.js +1 -1
  216. package/dist/martyrs/src/modules/organizations/components/sections/Organizations.vue.cjs +1 -1
  217. package/dist/martyrs/src/modules/organizations/components/sections/Organizations.vue.js +1 -1
  218. package/dist/martyrs/src/modules/organizations/router/organizations.cjs +1 -1
  219. package/dist/martyrs/src/modules/organizations/router/organizations.js +1 -1
  220. package/dist/martyrs/src/modules/pages/views/components/blocks/CardPage.vue.cjs +1 -1
  221. package/dist/martyrs/src/modules/pages/views/components/blocks/CardPage.vue.js +1 -1
  222. package/dist/martyrs/src/modules/pages/views/components/pages/PageEdit.vue.cjs +1 -1
  223. package/dist/martyrs/src/modules/pages/views/components/pages/PageEdit.vue.js +1 -1
  224. package/dist/martyrs/src/modules/products/components/pages/CategoryEdit.vue.cjs +1 -1
  225. package/dist/martyrs/src/modules/products/components/pages/CategoryEdit.vue.js +1 -1
  226. package/dist/martyrs/src/modules/products/components/pages/ProductEdit.vue.cjs +1 -1
  227. package/dist/martyrs/src/modules/products/components/pages/ProductEdit.vue.js +1 -1
  228. package/dist/martyrs/src/modules/products/components/sections/EditAttributes.vue.cjs +1 -1
  229. package/dist/martyrs/src/modules/products/components/sections/EditAttributes.vue.js +1 -1
  230. package/dist/martyrs/src/modules/products/components/sections/EditDiscounts.vue.cjs +1 -1
  231. package/dist/martyrs/src/modules/products/components/sections/EditDiscounts.vue.js +1 -1
  232. package/dist/martyrs/src/modules/products/components/sections/EditVariants.vue.cjs +1 -1
  233. package/dist/martyrs/src/modules/products/components/sections/EditVariants.vue.js +1 -1
  234. package/dist/martyrs/src/modules/rents/views/components/pages/Gant/GanttBar.vue.cjs +4 -3
  235. package/dist/martyrs/src/modules/rents/views/components/pages/Gant/GanttBar.vue.cjs.map +1 -1
  236. package/dist/martyrs/src/modules/rents/views/components/pages/Gant/GanttBar.vue.js +4 -3
  237. package/dist/martyrs/src/modules/rents/views/components/pages/Gant/GanttBar.vue.js.map +1 -1
  238. package/dist/martyrs/src/modules/rents/views/components/pages/Gant/GanttChart.vue.cjs +37 -70
  239. package/dist/martyrs/src/modules/rents/views/components/pages/Gant/GanttChart.vue.cjs.map +1 -1
  240. package/dist/martyrs/src/modules/rents/views/components/pages/Gant/GanttChart.vue.js +38 -71
  241. package/dist/martyrs/src/modules/rents/views/components/pages/Gant/GanttChart.vue.js.map +1 -1
  242. package/dist/martyrs/src/modules/rents/views/components/pages/Gant/GanttToolbar.vue.cjs +2 -1
  243. package/dist/martyrs/src/modules/rents/views/components/pages/Gant/GanttToolbar.vue.cjs.map +1 -1
  244. package/dist/martyrs/src/modules/rents/views/components/pages/Gant/GanttToolbar.vue.js +6 -5
  245. package/dist/martyrs/src/modules/rents/views/components/pages/Gant/GanttToolbar.vue.js.map +1 -1
  246. package/dist/martyrs/src/modules/rents/views/components/pages/Rents.vue.cjs +45 -52
  247. package/dist/martyrs/src/modules/rents/views/components/pages/Rents.vue.cjs.map +1 -1
  248. package/dist/martyrs/src/modules/rents/views/components/pages/Rents.vue.js +46 -53
  249. package/dist/martyrs/src/modules/rents/views/components/pages/Rents.vue.js.map +1 -1
  250. package/dist/martyrs/src/modules/rents/views/components/pages/RentsEdit.vue.cjs +1 -1
  251. package/dist/martyrs/src/modules/rents/views/components/pages/RentsEdit.vue.js +1 -1
  252. package/dist/martyrs/src/modules/spots/components/blocks/SpotMemberModify.vue.cjs +1 -1
  253. package/dist/martyrs/src/modules/spots/components/blocks/SpotMemberModify.vue.js +1 -1
  254. package/dist/martyrs/src/modules/spots/components/layouts/Spots.vue.cjs +1 -1
  255. package/dist/martyrs/src/modules/spots/components/layouts/Spots.vue.js +1 -1
  256. package/dist/martyrs/src/modules/spots/components/pages/SpotEdit.vue.cjs +1 -1
  257. package/dist/martyrs/src/modules/spots/components/pages/SpotEdit.vue.js +1 -1
  258. package/dist/martyrs/src/modules/spots/components/sections/WorktimeEdit.vue.cjs +1 -1
  259. package/dist/martyrs/src/modules/spots/components/sections/WorktimeEdit.vue.js +1 -1
  260. package/dist/martyrs/src/modules/wallet/views/components/blocks/CardDeposit.vue.cjs +1 -1
  261. package/dist/martyrs/src/modules/wallet/views/components/blocks/CardDeposit.vue.js +1 -1
  262. package/dist/martyrs/src/modules/wallet/views/components/blocks/CryptoDeposit.vue.cjs +1 -1
  263. package/dist/martyrs/src/modules/wallet/views/components/blocks/CryptoDeposit.vue.js +1 -1
  264. package/dist/martyrs.cjs.js +1 -1
  265. package/dist/martyrs.css +1 -1
  266. package/dist/martyrs.es.js +1 -1
  267. package/dist/music.server.cjs +124 -31
  268. package/dist/music.server.js +124 -31
  269. package/dist/organizations.server.cjs +1 -1
  270. package/dist/organizations.server.js +1 -1
  271. package/dist/products.server.cjs +2 -2
  272. package/dist/products.server.js +2 -2
  273. package/dist/rents.server.cjs +3 -3
  274. package/dist/rents.server.js +3 -3
  275. package/dist/style.css +373 -80
  276. package/dist/{web-D7lZjuC0.js → web-Dkk0_7TA.js} +1 -1
  277. package/dist/{web-D-YZ9KHz.cjs → web-stVkXd0l.cjs} +1 -1
  278. package/package.json +1 -1
  279. package/src/builder/modes/ssr.prod.js +21 -5
  280. package/src/builder/rspack/rspack.config.spa.client.js +0 -44
  281. package/src/builder/rspack/rspack.config.ssr.client.js +40 -40
  282. package/src/components/Calendar/Calendar.vue +378 -377
  283. package/src/components/Feed/Feed.vue +28 -2
  284. package/src/modules/globals/controllers/classes/crud/crud.policies.js +5 -0
  285. package/src/modules/globals/controllers/classes/globals.validator.js +8 -1
  286. package/src/modules/globals/views/components/layouts/Client.vue +7 -0
  287. package/src/modules/music/README.md +8 -0
  288. package/src/modules/music/components/SidebarMusic.vue +6 -9
  289. package/src/modules/music/components/cards/AlbumCard.vue +20 -14
  290. package/src/modules/music/components/cards/ArtistCard.vue +1 -1
  291. package/src/modules/music/components/cards/PlaylistCard.vue +31 -11
  292. package/src/modules/music/components/cards/TrackListCard.vue +24 -13
  293. package/src/modules/music/components/forms/PlaylistForm.vue +417 -107
  294. package/src/modules/music/components/forms/SearchForm.vue +31 -8
  295. package/src/modules/music/components/forms/TrackForm.vue +50 -32
  296. package/src/modules/music/components/layouts/MusicBottomPlayer.vue +17 -0
  297. package/src/modules/music/components/pages/Album.vue +373 -186
  298. package/src/modules/music/components/pages/Artist.vue +54 -94
  299. package/src/modules/music/components/pages/MusicHome.vue +59 -56
  300. package/src/modules/music/components/pages/MusicLibrary.vue +13 -11
  301. package/src/modules/music/components/pages/Playlist.vue +495 -379
  302. package/src/modules/music/components/pages/SearchResults.vue +185 -313
  303. package/src/modules/music/components/pages/Track.vue +363 -69
  304. package/src/modules/music/components/player/MusicPlayer.vue +368 -97
  305. package/src/modules/music/components/player/TrackProgress.vue +76 -22
  306. package/src/modules/music/components/player/VolumeControl.vue +61 -28
  307. package/src/modules/music/controllers/search.controller.js +3 -0
  308. package/src/modules/music/controllers/stream.controller.js +11 -3
  309. package/src/modules/music/middlewares/playlists.verifier.js +1 -1
  310. package/src/modules/music/music.client.js +3 -6
  311. package/src/modules/music/music.server.js +8 -4
  312. package/src/modules/music/router/music.js +8 -1
  313. package/src/modules/music/routes/albums.routes.js +37 -5
  314. package/src/modules/music/routes/artists.routes.js +14 -4
  315. package/src/modules/music/routes/genres.routes.js +5 -1
  316. package/src/modules/music/routes/playlists.routes.js +42 -9
  317. package/src/modules/music/routes/tracks.routes.js +27 -2
  318. package/src/modules/music/store/artists.js +6 -2
  319. package/src/modules/music/store/player.js +6 -0
  320. package/src/modules/music/store/tracks.js +31 -0
  321. package/src/modules/music/websocket/streaming.handler.js +7 -1
  322. package/src/modules/rents/controllers/services/rents.services.js +2 -2
  323. package/src/modules/rents/views/components/pages/Gant/GanttBar.vue +4 -3
  324. package/src/modules/rents/views/components/pages/Gant/GanttChart.vue +42 -40
  325. package/src/modules/rents/views/components/pages/Gant/GanttToolbar.vue +3 -1
  326. package/src/modules/rents/views/components/pages/Rents.vue +60 -56
  327. package/dist/globals.websocket-DzvdIBf6.js +0 -306
  328. package/dist/globals.websocket-k6_B1T7k.cjs +0 -322
  329. package/dist/martyrs/src/components/Field/Field.vue2.cjs.map +0 -1
  330. package/dist/martyrs/src/components/Menu/Menu.vue.cjs.map +0 -1
  331. package/dist/martyrs/src/components/Menu/Menu.vue.js.map +0 -1
  332. package/dist/martyrs/src/modules/music/components/cards/TrackCard.vue.cjs +0 -69
  333. package/dist/martyrs/src/modules/music/components/cards/TrackCard.vue.cjs.map +0 -1
  334. package/dist/martyrs/src/modules/music/components/cards/TrackCard.vue.js +0 -69
  335. package/dist/martyrs/src/modules/music/components/cards/TrackCard.vue.js.map +0 -1
  336. package/dist/martyrs/src/modules/music/components/layouts/MusicLayout.vue.cjs +0 -104
  337. package/dist/martyrs/src/modules/music/components/layouts/MusicLayout.vue.cjs.map +0 -1
  338. package/dist/martyrs/src/modules/music/components/layouts/MusicLayout.vue.js +0 -104
  339. package/dist/martyrs/src/modules/music/components/layouts/MusicLayout.vue.js.map +0 -1
  340. package/src/modules/music/components/cards/TrackCard.vue +0 -86
  341. package/src/modules/music/components/layouts/MusicLayout.vue +0 -83
@@ -1,169 +1,429 @@
1
1
  "use strict";
2
2
  Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
3
3
  const vue = require("vue");
4
- const Field = require("../../../../components/Field/Field.vue2.cjs");
5
- const Radio = require("../../../../components/Radio/Radio.vue.cjs");
4
+ const vueRouter = require("vue-router");
5
+ const Field = require("../../../../components/Field/Field.vue.cjs");
6
+ const Block = require("../../../../components/Block/Block.vue.cjs");
6
7
  const Button = require("../../../../components/Button/Button.vue.cjs");
8
+ const Radio = require("../../../../components/Radio/Radio.vue.cjs");
7
9
  const UploadImage = require("../../../../components/UploadImage/UploadImage.vue.cjs");
8
- const Media = require("../../../../components/Media/Media.vue.cjs");
9
- const IconMusic = require("../../../icons/entities/IconMusic.vue.cjs");
10
- const auth = require("../../../auth/views/store/auth.cjs");
10
+ const IconCross = require("../../../icons/navigation/IconCross.vue.cjs");
11
+ const BlockMultiselect = require("../../../globals/views/components/blocks/BlockMultiselect.vue.cjs");
11
12
  const playlists = require("../../store/playlists.cjs");
12
- const _hoisted_1 = { class: "playlist-form" };
13
- const _hoisted_2 = { class: "form-group mn-b-medium" };
14
- const _hoisted_3 = { class: "form-group mn-b-medium" };
15
- const _hoisted_4 = { class: "form-group mn-b-medium" };
16
- const _hoisted_5 = { class: "flex gap-small" };
17
- const _hoisted_6 = { class: "form-group mn-b-medium" };
18
- const _hoisted_7 = { class: "playlist-cover-upload flex gap-medium" };
19
- const _hoisted_8 = { class: "playlist-cover-preview bg-dark-transp-25 radius-small o-hidden" };
20
- const _hoisted_9 = {
21
- key: 1,
22
- class: "w-10r h-10r flex-center flex"
13
+ const tracks = require("../../store/tracks.cjs");
14
+ const globals = require("../../../globals/views/store/globals.cjs");
15
+ const auth = require("../../../auth/views/store/auth.cjs");
16
+ const _hoisted_1 = { class: "pd-medium" };
17
+ const _hoisted_2 = { class: "h2 mn-b-medium" };
18
+ const _hoisted_3 = { class: "bg-light pd-medium radius-medium" };
19
+ const _hoisted_4 = { class: "mn-b-medium" };
20
+ const _hoisted_5 = { class: "flex-nowrap flex-v-center flex gap-thin" };
21
+ const _hoisted_6 = ["onClick", "disabled"];
22
+ const _hoisted_7 = ["onClick", "disabled"];
23
+ const _hoisted_8 = { class: "flex-1" };
24
+ const _hoisted_9 = { class: "t-medium" };
25
+ const _hoisted_10 = { class: "t-small t-transp" };
26
+ const _hoisted_11 = { key: 0 };
27
+ const _hoisted_12 = {
28
+ key: 2,
29
+ class: "t-small t-transp"
30
+ };
31
+ const _hoisted_13 = ["onClick"];
32
+ const _hoisted_14 = { class: "flex-nowrap flex-v-center flex" };
33
+ const _hoisted_15 = { class: "w-100" };
34
+ const _hoisted_16 = { class: "t-medium" };
35
+ const _hoisted_17 = { class: "t-small t-transp" };
36
+ const _hoisted_18 = { key: 0 };
37
+ const _hoisted_19 = {
38
+ key: 0,
39
+ class: "t-small t-transp mn-l-small"
40
+ };
41
+ const _hoisted_20 = {
42
+ key: 0,
43
+ class: "t-small t-transp mn-t-small"
23
44
  };
24
- const _hoisted_10 = { class: "form-actions t-right" };
45
+ const _hoisted_21 = { class: "bg-light pd-medium radius-medium" };
46
+ const _hoisted_22 = { class: "mn-b-medium" };
47
+ const _hoisted_23 = { class: "flex gap-medium" };
48
+ const _hoisted_24 = { class: "mn-b-medium" };
49
+ const _hoisted_25 = { class: "flex gap-medium" };
50
+ const _hoisted_26 = { class: "flex flex-justify-between" };
25
51
  const _sfc_main = {
26
52
  __name: "PlaylistForm",
27
- emits: ["created", "cancel"],
28
- setup(__props, { emit: __emit }) {
29
- const emit = __emit;
30
- const form = vue.reactive({
53
+ props: {
54
+ editMode: {
55
+ type: Boolean,
56
+ default: false
57
+ },
58
+ url: {
59
+ type: String,
60
+ default: ""
61
+ }
62
+ },
63
+ setup(__props) {
64
+ const props = __props;
65
+ const router = vueRouter.useRouter();
66
+ vueRouter.useRoute();
67
+ const playlist = vue.reactive({
31
68
  title: "",
32
69
  description: "",
33
- isPublic: true,
34
70
  coverUrl: "",
35
- isCollaborative: false,
36
- tracks: []
71
+ tracks: [],
72
+ url: "",
73
+ isPublic: true,
74
+ isCollaborative: false
75
+ });
76
+ const validation = vue.reactive({
77
+ title: false,
78
+ description: false
79
+ });
80
+ const urlManuallySet = vue.ref(false);
81
+ const generateSlug = (text) => {
82
+ if (!text) return "";
83
+ return text.toLowerCase().replace(/[^a-z0-9\s-]/g, "").replace(/\s+/g, "-").replace(/-+/g, "-").trim("-");
84
+ };
85
+ vue.watch(() => playlist.title, (newTitle) => {
86
+ if (!urlManuallySet.value && !props.editMode) {
87
+ playlist.url = generateSlug(newTitle);
88
+ }
37
89
  });
38
- const validationErrors = vue.reactive({});
90
+ vue.watch(() => playlist.url, (newUrl, oldUrl) => {
91
+ if (newUrl !== generateSlug(playlist.title)) {
92
+ urlManuallySet.value = true;
93
+ }
94
+ });
95
+ const totalDuration = vue.computed(() => {
96
+ return playlist.tracks.reduce((sum, track) => sum + (track.duration || 0), 0);
97
+ });
98
+ const formatDuration = (seconds) => {
99
+ if (!seconds) return "0:00";
100
+ const hours = Math.floor(seconds / 3600);
101
+ const minutes = Math.floor(seconds % 3600 / 60);
102
+ const secs = seconds % 60;
103
+ if (hours > 0) {
104
+ return `${hours}:${minutes.toString().padStart(2, "0")}:${secs.toString().padStart(2, "0")}`;
105
+ }
106
+ return `${minutes}:${secs.toString().padStart(2, "0")}`;
107
+ };
108
+ const moveTrack = (index, direction) => {
109
+ const newIndex = direction === "up" ? index - 1 : index + 1;
110
+ if (newIndex < 0 || newIndex >= playlist.tracks.length) return;
111
+ const tracks2 = [...playlist.tracks];
112
+ [tracks2[index], tracks2[newIndex]] = [tracks2[newIndex], tracks2[index]];
113
+ playlist.tracks = tracks2;
114
+ };
115
+ const fetchPlaylist = async () => {
116
+ if (!props.url) return;
117
+ try {
118
+ const fetchedPlaylist = await playlists.actions.fetchPlaylistByUrl(props.url);
119
+ if (!fetchedPlaylist) {
120
+ globals.actions.setError({
121
+ message: "Playlist not found"
122
+ });
123
+ return;
124
+ }
125
+ Object.assign(playlist, {
126
+ title: fetchedPlaylist.title || "",
127
+ description: fetchedPlaylist.description || "",
128
+ coverUrl: fetchedPlaylist.coverUrl || "",
129
+ tracks: fetchedPlaylist.tracks || [],
130
+ url: fetchedPlaylist.url || "",
131
+ isPublic: fetchedPlaylist.isPublic !== false,
132
+ isCollaborative: fetchedPlaylist.isCollaborative || false,
133
+ _id: fetchedPlaylist._id
134
+ });
135
+ } catch (error) {
136
+ console.error("Error fetching playlist:", error);
137
+ globals.actions.setError({
138
+ message: "Failed to load playlist details"
139
+ });
140
+ }
141
+ };
142
+ const validateForm = () => {
143
+ let isValid = true;
144
+ if (!playlist.title.trim()) {
145
+ validation.title = {
146
+ message: "Playlist title is required"
147
+ };
148
+ isValid = false;
149
+ } else {
150
+ validation.title = false;
151
+ }
152
+ if (playlist.description && playlist.description.length > 2e3) {
153
+ validation.description = {
154
+ message: "Description is too long (max 2000 characters)"
155
+ };
156
+ isValid = false;
157
+ } else {
158
+ validation.description = false;
159
+ }
160
+ return isValid;
161
+ };
39
162
  const submitForm = async () => {
40
- validationErrors.title = !form.title ? { message: "Playlist name is required" } : null;
41
- if (Object.values(validationErrors).some((error) => error !== null)) {
163
+ if (!validateForm()) {
42
164
  return;
43
165
  }
44
- const playlistData = {
45
- ...form,
46
- creator: {
47
- type: "User",
48
- target: auth.state.user._id
49
- },
50
- owner: {
51
- type: "User",
52
- target: auth.state.user._id
53
- }
54
- };
55
166
  try {
56
- const playlist = await playlists.actions.createPlaylist(playlistData);
57
- emit("created", playlist);
167
+ const formData = {
168
+ ...playlist,
169
+ tracks: playlist.tracks.map((track) => ({
170
+ track: track._id || track,
171
+ addedAt: /* @__PURE__ */ new Date()
172
+ }))
173
+ };
174
+ if (!props.editMode) {
175
+ formData.creator = {
176
+ type: "user",
177
+ target: auth.state.user._id
178
+ };
179
+ formData.owner = {
180
+ type: "user",
181
+ target: auth.state.user._id
182
+ };
183
+ }
184
+ let result;
185
+ if (props.editMode) {
186
+ result = await playlists.actions.updatePlaylist(formData);
187
+ } else {
188
+ result = await playlists.actions.createPlaylist(formData);
189
+ }
190
+ setTimeout(() => {
191
+ router.push({
192
+ name: "playlist",
193
+ params: { url: result.url }
194
+ });
195
+ }, 1e3);
58
196
  } catch (error) {
59
- console.error("Error creating playlist:", error);
197
+ console.error("Error saving playlist:", error);
198
+ globals.actions.setError({
199
+ message: "Failed to save playlist"
200
+ });
60
201
  }
61
202
  };
203
+ const handleUploadError = (error) => {
204
+ console.error("Upload error:", error);
205
+ globals.actions.setError({
206
+ message: "Error uploading image"
207
+ });
208
+ };
209
+ vue.onMounted(async () => {
210
+ if (props.editMode) {
211
+ await fetchPlaylist();
212
+ urlManuallySet.value = true;
213
+ }
214
+ });
62
215
  return (_ctx, _cache) => {
63
216
  return vue.openBlock(), vue.createElementBlock("div", _hoisted_1, [
217
+ vue.createElementVNode("h2", _hoisted_2, vue.toDisplayString(__props.editMode ? "Edit Playlist" : "Create Playlist"), 1),
64
218
  vue.createElementVNode("form", {
65
- onSubmit: vue.withModifiers(submitForm, ["prevent"])
219
+ onSubmit: vue.withModifiers(submitForm, ["prevent"]),
220
+ class: "cols-1 gap-medium"
66
221
  }, [
67
- vue.createElementVNode("div", _hoisted_2, [
68
- _cache[6] || (_cache[6] = vue.createElementVNode("label", {
69
- for: "title",
70
- class: "t-medium mn-b-thin d-block"
71
- }, "Playlist Name", -1)),
72
- vue.createVNode(Field.default, {
73
- field: form.title,
74
- "onUpdate:field": _cache[0] || (_cache[0] = ($event) => form.title = $event),
75
- id: "title",
76
- type: "text",
77
- placeholder: "New Playlist",
78
- validation: validationErrors.title,
79
- class: "w-100 pd-small bg-dark-transp-25 radius-small"
80
- }, null, 8, ["field", "validation"])
81
- ]),
82
222
  vue.createElementVNode("div", _hoisted_3, [
83
- _cache[7] || (_cache[7] = vue.createElementVNode("label", {
84
- for: "description",
85
- class: "t-medium mn-b-thin d-block"
86
- }, "Description", -1)),
223
+ _cache[11] || (_cache[11] = vue.createElementVNode("h3", { class: "h3 mn-b-medium" }, "Basic Information", -1)),
224
+ vue.createElementVNode("div", _hoisted_4, [
225
+ _cache[10] || (_cache[10] = vue.createElementVNode("p", { class: "p-semi mn-b-small" }, "Playlist Cover", -1)),
226
+ vue.createVNode(UploadImage.default, {
227
+ photo: playlist.coverUrl,
228
+ "onUpdate:photo": _cache[0] || (_cache[0] = ($event) => playlist.coverUrl = $event),
229
+ uploadPath: "playlists/covers",
230
+ class: "w-100 h-15r radius-small o-hidden mn-b-small",
231
+ onError: handleUploadError
232
+ }, null, 8, ["photo"])
233
+ ]),
234
+ vue.createVNode(Field.default, {
235
+ field: playlist.title,
236
+ "onUpdate:field": _cache[1] || (_cache[1] = ($event) => playlist.title = $event),
237
+ label: "Title",
238
+ placeholder: "Enter playlist title",
239
+ class: "bg-white radius-small pd-small mn-b-thin",
240
+ validation: validation.title
241
+ }, null, 8, ["field", "validation"]),
87
242
  vue.createVNode(Field.default, {
88
- field: form.description,
89
- "onUpdate:field": _cache[1] || (_cache[1] = ($event) => form.description = $event),
90
- id: "description",
243
+ field: playlist.url,
244
+ "onUpdate:field": _cache[2] || (_cache[2] = ($event) => playlist.url = $event),
245
+ label: "URL",
246
+ placeholder: "Leave blank for auto-generation based on the playlist title",
247
+ class: "bg-white radius-small pd-small mn-b-small"
248
+ }, null, 8, ["field"]),
249
+ vue.createVNode(Field.default, {
250
+ field: playlist.description,
251
+ "onUpdate:field": _cache[3] || (_cache[3] = ($event) => playlist.description = $event),
252
+ label: "Description",
91
253
  type: "textarea",
92
- placeholder: "Add an optional description",
93
- validation: validationErrors.description,
94
- class: "w-100 pd-small bg-dark-transp-25 radius-small"
254
+ placeholder: "Enter playlist description",
255
+ class: "bg-white radius-small pd-small mn-b-thin",
256
+ validation: validation.description
95
257
  }, null, 8, ["field", "validation"])
96
258
  ]),
97
- vue.createElementVNode("div", _hoisted_4, [
98
- _cache[8] || (_cache[8] = vue.createElementVNode("label", { class: "t-medium mn-b-thin d-block" }, "Privacy", -1)),
99
- vue.createElementVNode("div", _hoisted_5, [
100
- vue.createVNode(Radio.default, {
101
- radio: form.isPublic,
102
- "onUpdate:radio": _cache[2] || (_cache[2] = ($event) => form.isPublic = $event),
103
- value: true,
104
- name: "privacy",
105
- label: "Public",
106
- class: ""
107
- }, null, 8, ["radio"]),
108
- vue.createVNode(Radio.default, {
109
- radio: form.isPublic,
110
- "onUpdate:radio": _cache[3] || (_cache[3] = ($event) => form.isPublic = $event),
111
- value: false,
112
- name: "privacy",
113
- label: "Private",
114
- class: ""
115
- }, null, 8, ["radio"])
259
+ vue.createVNode(Block.default, { title: "Tracks" }, {
260
+ default: vue.withCtx(() => [
261
+ vue.createVNode(BlockMultiselect.default, {
262
+ modelValue: playlist.tracks,
263
+ "onUpdate:modelValue": _cache[4] || (_cache[4] = ($event) => playlist.tracks = $event),
264
+ placeholder: "Search tracks...",
265
+ multiple: true,
266
+ transform: (item) => ({
267
+ _id: item._id,
268
+ title: item.title,
269
+ artists: item.artists,
270
+ album: item.album,
271
+ duration: item.duration
272
+ }),
273
+ store: {
274
+ read: (options) => tracks.actions.fetchTracks(options),
275
+ state: tracks.state
276
+ },
277
+ options: {
278
+ rootOnly: false,
279
+ excludeChildren: false,
280
+ limit: 50
281
+ },
282
+ skeleton: {
283
+ hide: false,
284
+ horizontal: true,
285
+ class: "radius-small",
286
+ structure: [{
287
+ block: "text",
288
+ size: "large"
289
+ }]
290
+ },
291
+ states: {
292
+ empty: {
293
+ title: "No tracks found",
294
+ description: "Try different search terms",
295
+ class: "radius-small"
296
+ }
297
+ },
298
+ key: "_id",
299
+ label: (item) => item.title,
300
+ classSearch: "bg-white radius-small",
301
+ classSelected: "bg-white pd-small radius-small",
302
+ classDropdown: "bg-white pd-small radius-medium bs-small",
303
+ classItem: "pd-small radius-small hover-bg-light cursor-pointer",
304
+ classFeed: "h-max-30r gap-thin flex-column flex o-scroll"
305
+ }, {
306
+ selected: vue.withCtx(({ item, clear, index }) => [
307
+ vue.createElementVNode("div", _hoisted_5, [
308
+ playlist.tracks.length > 1 ? (vue.openBlock(), vue.createElementBlock("button", {
309
+ key: 0,
310
+ onClick: vue.withModifiers(($event) => moveTrack(index, "up"), ["stop"]),
311
+ disabled: index === 0,
312
+ class: "i-small pd-micro bg-grey-nano radius-extra flex-center flex aspect-1x1 hover-scale-1"
313
+ }, [
314
+ vue.createVNode(IconCross.default, { class: "i-micro" })
315
+ ], 8, _hoisted_6)) : vue.createCommentVNode("", true),
316
+ playlist.tracks.length > 1 ? (vue.openBlock(), vue.createElementBlock("button", {
317
+ key: 1,
318
+ onClick: vue.withModifiers(($event) => moveTrack(index, "down"), ["stop"]),
319
+ disabled: index === playlist.tracks.length - 1,
320
+ class: "i-small pd-micro bg-grey-nano radius-extra flex-center flex aspect-1x1 hover-scale-1"
321
+ }, [
322
+ vue.createVNode(IconCross.default, { class: "i-micro" })
323
+ ], 8, _hoisted_7)) : vue.createCommentVNode("", true),
324
+ vue.createElementVNode("div", _hoisted_8, [
325
+ vue.createElementVNode("p", _hoisted_9, vue.toDisplayString(item.title), 1),
326
+ vue.createElementVNode("p", _hoisted_10, [
327
+ vue.createTextVNode(vue.toDisplayString(item.artists?.map((a) => a.name || a).join(", ")) + " ", 1),
328
+ item.album ? (vue.openBlock(), vue.createElementBlock("span", _hoisted_11, " • " + vue.toDisplayString(item.album.title || item.album), 1)) : vue.createCommentVNode("", true)
329
+ ])
330
+ ]),
331
+ item.duration ? (vue.openBlock(), vue.createElementBlock("span", _hoisted_12, vue.toDisplayString(formatDuration(item.duration)), 1)) : vue.createCommentVNode("", true),
332
+ vue.createElementVNode("button", {
333
+ onClick: vue.withModifiers(clear, ["stop"]),
334
+ class: "i-small pd-micro bg-red radius-extra flex-center flex aspect-1x1 hover-scale-1"
335
+ }, [
336
+ vue.createVNode(IconCross.default, { class: "i-micro fill-white" })
337
+ ], 8, _hoisted_13)
338
+ ])
339
+ ]),
340
+ item: vue.withCtx(({ item }) => [
341
+ vue.createElementVNode("div", _hoisted_14, [
342
+ vue.createElementVNode("div", _hoisted_15, [
343
+ vue.createElementVNode("p", _hoisted_16, vue.toDisplayString(item.title), 1),
344
+ vue.createElementVNode("p", _hoisted_17, [
345
+ vue.createTextVNode(vue.toDisplayString(item.artists?.map((a) => a.name || a).join(", ")) + " ", 1),
346
+ item.album ? (vue.openBlock(), vue.createElementBlock("span", _hoisted_18, " • " + vue.toDisplayString(item.album.title || item.album), 1)) : vue.createCommentVNode("", true)
347
+ ])
348
+ ]),
349
+ item.duration ? (vue.openBlock(), vue.createElementBlock("span", _hoisted_19, vue.toDisplayString(formatDuration(item.duration)), 1)) : vue.createCommentVNode("", true)
350
+ ])
351
+ ]),
352
+ _: 1
353
+ }, 8, ["modelValue", "transform", "store", "label"]),
354
+ playlist.tracks.length > 0 ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_20, vue.toDisplayString(playlist.tracks.length) + " tracks • " + vue.toDisplayString(formatDuration(totalDuration.value)), 1)) : vue.createCommentVNode("", true)
355
+ ]),
356
+ _: 1
357
+ }),
358
+ vue.createElementVNode("div", _hoisted_21, [
359
+ _cache[14] || (_cache[14] = vue.createElementVNode("h3", { class: "h3 mn-b-medium" }, "Privacy & Settings", -1)),
360
+ vue.createElementVNode("div", _hoisted_22, [
361
+ _cache[12] || (_cache[12] = vue.createElementVNode("p", { class: "p-semi mn-b-small" }, "Privacy", -1)),
362
+ vue.createElementVNode("div", _hoisted_23, [
363
+ vue.createVNode(Radio.default, {
364
+ radio: playlist.isPublic,
365
+ "onUpdate:radio": _cache[5] || (_cache[5] = ($event) => playlist.isPublic = $event),
366
+ value: true,
367
+ name: "privacy",
368
+ label: "Public",
369
+ class: "bg-white pd-small radius-small"
370
+ }, null, 8, ["radio"]),
371
+ vue.createVNode(Radio.default, {
372
+ radio: playlist.isPublic,
373
+ "onUpdate:radio": _cache[6] || (_cache[6] = ($event) => playlist.isPublic = $event),
374
+ value: false,
375
+ name: "privacy",
376
+ label: "Private",
377
+ class: "bg-white pd-small radius-small"
378
+ }, null, 8, ["radio"])
379
+ ])
380
+ ]),
381
+ vue.createElementVNode("div", _hoisted_24, [
382
+ _cache[13] || (_cache[13] = vue.createElementVNode("p", { class: "p-semi mn-b-small" }, "Collaborative Playlist", -1)),
383
+ vue.createElementVNode("div", _hoisted_25, [
384
+ vue.createVNode(Radio.default, {
385
+ radio: playlist.isCollaborative,
386
+ "onUpdate:radio": _cache[7] || (_cache[7] = ($event) => playlist.isCollaborative = $event),
387
+ value: true,
388
+ name: "collaborative",
389
+ label: "Yes",
390
+ class: "bg-white pd-small radius-small"
391
+ }, null, 8, ["radio"]),
392
+ vue.createVNode(Radio.default, {
393
+ radio: playlist.isCollaborative,
394
+ "onUpdate:radio": _cache[8] || (_cache[8] = ($event) => playlist.isCollaborative = $event),
395
+ value: false,
396
+ name: "collaborative",
397
+ label: "No",
398
+ class: "bg-white pd-small radius-small"
399
+ }, null, 8, ["radio"])
400
+ ])
116
401
  ])
117
402
  ]),
118
- vue.createElementVNode("div", _hoisted_6, [
119
- _cache[9] || (_cache[9] = vue.createElementVNode("label", { class: "t-medium mn-b-thin d-block" }, "Cover Image", -1)),
120
- vue.createElementVNode("div", _hoisted_7, [
121
- vue.createElementVNode("div", _hoisted_8, [
122
- form.coverUrl ? (vue.openBlock(), vue.createBlock(Media.default, {
123
- key: 0,
124
- url: form.coverUrl,
125
- class: "w-10r h-10r object-fit-cover"
126
- }, null, 8, ["url"])) : (vue.openBlock(), vue.createElementBlock("div", _hoisted_9, [
127
- vue.createVNode(IconMusic.default, {
128
- class: "i-big",
129
- fill: "rgb(var(--grey))"
130
- })
131
- ]))
132
- ]),
133
- vue.createVNode(UploadImage.default, {
134
- photo: form.coverUrl,
135
- "onUpdate:photo": _cache[4] || (_cache[4] = ($event) => form.coverUrl = $event),
136
- uploadPath: "playlists",
137
- class: "flex-1 h-10r bg-dark-transp-25 radius-small"
138
- }, null, 8, ["photo"])
139
- ])
140
- ]),
141
- vue.createElementVNode("div", _hoisted_10, [
403
+ vue.createElementVNode("div", _hoisted_26, [
142
404
  vue.createVNode(Button.default, {
143
- onClick: _cache[5] || (_cache[5] = ($event) => _ctx.$emit("cancel")),
144
- type: "button",
145
- class: "bg-dark-transp-25 pd-small radius-small mn-r-small hover-bg-dark",
146
- showLoader: false,
147
- showSucces: false
405
+ onClick: _cache[9] || (_cache[9] = ($event) => _ctx.$router.go(-1)),
406
+ class: "bg-grey-nano t-black",
407
+ showSucces: false,
408
+ showLoader: false
148
409
  }, {
149
- default: vue.withCtx(() => _cache[10] || (_cache[10] = [
410
+ default: vue.withCtx(() => _cache[15] || (_cache[15] = [
150
411
  vue.createTextVNode(" Cancel ")
151
412
  ])),
152
413
  _: 1
153
414
  }),
154
415
  vue.createVNode(Button.default, {
155
- type: "submit",
156
- class: "bg-main pd-small radius-small hover-scale-1",
157
416
  submit: submitForm,
158
- showLoader: true,
159
- showSucces: true,
160
- validation: !!Object.keys(validationErrors).length
417
+ class: "bg-main t-black",
418
+ text: {
419
+ success: __props.editMode ? "Updated!" : "Created!"
420
+ }
161
421
  }, {
162
- default: vue.withCtx(() => _cache[11] || (_cache[11] = [
163
- vue.createTextVNode(" Create Playlist ")
164
- ])),
422
+ default: vue.withCtx(() => [
423
+ vue.createTextVNode(vue.toDisplayString(__props.editMode ? "Update Playlist" : "Create Playlist"), 1)
424
+ ]),
165
425
  _: 1
166
- }, 8, ["validation"])
426
+ }, 8, ["text"])
167
427
  ])
168
428
  ], 32)
169
429
  ]);
@@ -1 +1 @@
1
- {"version":3,"file":"PlaylistForm.vue.cjs","sources":["../../../../../../../src/modules/music/components/forms/PlaylistForm.vue"],"sourcesContent":["<!-- components/forms/PlaylistForm.vue -->\n<template>\n <div class=\"playlist-form\">\n <form @submit.prevent=\"submitForm\">\n <div class=\"form-group mn-b-medium\">\n <label for=\"title\" class=\" t-medium mn-b-thin d-block\">Playlist Name</label>\n <Field \n v-model:field=\"form.title\"\n id=\"title\"\n type=\"text\"\n placeholder=\"New Playlist\"\n :validation=\"validationErrors.title\"\n class=\"w-100 pd-small bg-dark-transp-25 radius-small \"\n />\n </div>\n \n <div class=\"form-group mn-b-medium\">\n <label for=\"description\" class=\" t-medium mn-b-thin d-block\">Description</label>\n <Field \n v-model:field=\"form.description\"\n id=\"description\"\n type=\"textarea\"\n placeholder=\"Add an optional description\"\n :validation=\"validationErrors.description\"\n class=\"w-100 pd-small bg-dark-transp-25 radius-small \"\n />\n </div>\n \n <div class=\"form-group mn-b-medium\">\n <label class=\" t-medium mn-b-thin d-block\">Privacy</label>\n <div class=\"flex gap-small\">\n <Radio \n v-model:radio=\"form.isPublic\"\n :value=\"true\"\n name=\"privacy\"\n label=\"Public\"\n class=\"\"\n />\n <Radio \n v-model:radio=\"form.isPublic\"\n :value=\"false\"\n name=\"privacy\"\n label=\"Private\"\n class=\"\"\n />\n </div>\n </div>\n \n <div class=\"form-group mn-b-medium\">\n <label class=\" t-medium mn-b-thin d-block\">Cover Image</label>\n <div class=\"playlist-cover-upload flex gap-medium\">\n <div class=\"playlist-cover-preview bg-dark-transp-25 radius-small o-hidden\">\n <Media \n v-if=\"form.coverUrl\"\n :url=\"form.coverUrl\"\n class=\"w-10r h-10r object-fit-cover\"\n />\n <div v-else class=\"w-10r h-10r flex-center flex\">\n <IconMusic class=\"i-big\" fill=\"rgb(var(--grey))\"/>\n </div>\n </div>\n \n <UploadImage\n v-model:photo=\"form.coverUrl\"\n uploadPath=\"playlists\"\n class=\"flex-1 h-10r bg-dark-transp-25 radius-small\"\n />\n </div>\n </div>\n \n <div class=\"form-actions t-right\">\n <Button \n @click=\"$emit('cancel')\"\n type=\"button\"\n class=\"bg-dark-transp-25 pd-small radius-small mn-r-small hover-bg-dark\"\n :showLoader=\"false\" \n :showSucces=\"false\"\n >\n Cancel\n </Button>\n \n <Button \n type=\"submit\"\n class=\"bg-main pd-small radius-small hover-scale-1\"\n :submit=\"submitForm\"\n :showLoader=\"true\" \n :showSucces=\"true\"\n :validation=\"!!Object.keys(validationErrors).length\"\n >\n Create Playlist\n </Button>\n </div>\n </form>\n </div>\n</template>\n\n<script setup>\nimport { ref, reactive } from 'vue';\nimport Field from '@martyrs/src/components/Field/Field.vue';\nimport Radio from '@martyrs/src/components/Radio/Radio.vue';\nimport Button from '@martyrs/src/components/Button/Button.vue';\nimport UploadImage from '@martyrs/src/components/UploadImage/UploadImage.vue';\nimport Media from '@martyrs/src/components/Media/Media.vue';\nimport IconMusic from '@martyrs/src/modules/icons/entities/IconMusic.vue';\n\n// Import auth store and playlists store\nimport { state as authState } from '@martyrs/src/modules/auth/views/store/auth.js';\nimport { actions as playlistsActions } from '../../store/playlists.js';\n\nconst emit = defineEmits(['created', 'cancel']);\n\n// Form data\nconst form = reactive({\n title: '',\n description: '',\n isPublic: true,\n coverUrl: '',\n isCollaborative: false,\n tracks: []\n});\n\n// Validation\nconst validationErrors = reactive({});\n\n// Form submission\nconst submitForm = async () => {\n // Validate form\n validationErrors.title = !form.title ? { message: 'Playlist name is required' } : null;\n \n // If there are validation errors, don't submit\n if (Object.values(validationErrors).some(error => error !== null)) {\n return;\n }\n \n // Prepare playlist data\n const playlistData = {\n ...form,\n creator: {\n type: 'User',\n target: authState.user._id\n },\n owner: {\n type: 'User',\n target: authState.user._id\n }\n };\n \n try {\n const playlist = await playlistsActions.createPlaylist(playlistData);\n emit('created', playlist);\n } catch (error) {\n console.error('Error creating playlist:', error);\n // Handle error (could add form-level error message)\n }\n};\n</script>"],"names":["reactive","authState","playlistsActions"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6GA,UAAM,OAAO;AAGb,UAAM,OAAOA,IAAAA,SAAS;AAAA,MACpB,OAAO;AAAA,MACP,aAAa;AAAA,MACb,UAAU;AAAA,MACV,UAAU;AAAA,MACV,iBAAiB;AAAA,MACjB,QAAQ,CAAA;AAAA,IACV,CAAC;AAGD,UAAM,mBAAmBA,IAAAA,SAAS,EAAE;AAGpC,UAAM,aAAa,YAAY;AAE7B,uBAAiB,QAAQ,CAAC,KAAK,QAAQ,EAAE,SAAS,4BAA2B,IAAK;AAGlF,UAAI,OAAO,OAAO,gBAAgB,EAAE,KAAK,WAAS,UAAU,IAAI,GAAG;AACjE;AAAA,MACF;AAGA,YAAM,eAAe;AAAA,QACnB,GAAG;AAAA,QACH,SAAS;AAAA,UACP,MAAM;AAAA,UACN,QAAQC,KAAAA,MAAU,KAAK;AAAA,QAC7B;AAAA,QACI,OAAO;AAAA,UACL,MAAM;AAAA,UACN,QAAQA,KAAAA,MAAU,KAAK;AAAA,QAC7B;AAAA,MACA;AAEE,UAAI;AACF,cAAM,WAAW,MAAMC,kBAAiB,eAAe,YAAY;AACnE,aAAK,WAAW,QAAQ;AAAA,MAC1B,SAAS,OAAO;AACd,gBAAQ,MAAM,4BAA4B,KAAK;AAAA,MAEjD;AAAA,IACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"PlaylistForm.vue.cjs","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-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 <!-- Playlist Cover -->\n <div class=\"mn-b-medium\">\n <p class=\"p-semi 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-semi mn-b-small\">Privacy</p>\n <div class=\"flex gap-medium\">\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-semi mn-b-small\">Collaborative Playlist</p>\n <div class=\"flex gap-medium\">\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/globals/views/components/blocks/BlockMultiselect.vue';\n\n// Import stores\nimport * as playlistsStore from '../../store/playlists';\nimport * as tracksStore from '../../store/tracks';\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// 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 globals.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 globals.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 globals.actions.setError({\n message: 'Failed to save playlist'\n });\n }\n};\n\nconst handleUploadError = (error) => {\n console.error('Upload error:', error);\n globals.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>"],"names":["useRouter","useRoute","reactive","ref","watch","computed","tracks","playlistsStore.actions","globals.actions","auth.state","onMounted"],"mappings":"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"}