@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,16 +1,24 @@
1
- import { ref, computed, onMounted, watch, createElementBlock, openBlock, createVNode, createElementVNode, createCommentVNode, toDisplayString, withCtx, Fragment, renderList, createBlock } from "vue";
1
+ import { ref, computed, onMounted, resolveComponent, createElementBlock, openBlock, createCommentVNode, createBlock, createVNode, createElementVNode, toDisplayString, withCtx, createTextVNode, Fragment, renderList } from "vue";
2
2
  import { useRoute, useRouter } from "vue-router";
3
+ import _sfc_main$1 from "../../../../components/Button/Button.vue.js";
3
4
  import Loader from "../../../../components/Loader/Loader.vue2.js";
4
- /* empty css */
5
- /* empty css */
6
- /* empty css */
7
- /* empty css */
8
- import _sfc_main$1 from "../../../../components/Feed/Feed.vue.js";
9
- import TrackCard from "../cards/TrackCard.vue.js";
5
+ import Media from "../../../../components/Media/Media.vue.js";
6
+ import _sfc_main$5 from "../../../../components/Dropdown/Dropdown.vue.js";
7
+ import _sfc_main$c from "../../../../components/Popup/Popup.vue.js";
8
+ import _sfc_main$a from "../../../../components/Feed/Feed.vue.js";
9
+ import _sfc_main$2 from "../../../icons/navigation/IconPlay.vue.js";
10
+ import _sfc_main$3 from "../../../icons/navigation/IconLike.vue.js";
11
+ import _sfc_main$6 from "../../../icons/navigation/IconEllipsis.vue.js";
12
+ import _sfc_main$4 from "../../../icons/navigation/IconAdd.vue.js";
13
+ import IconClock from "../../../icons/entities/IconTime.vue.js";
14
+ import _sfc_main$8 from "../../../icons/entities/IconCalendar.vue.js";
15
+ import _sfc_main$7 from "../../../icons/navigation/IconCheckmark.vue.js";
16
+ import _sfc_main$9 from "../../../icons/actions/IconShow.vue.js";
17
+ import _sfc_main$b from "../cards/TrackListCard.vue.js";
10
18
  import { state, actions } from "../../store/tracks.js";
11
- import "../../store/player.js";
19
+ import { actions as actions$1 } from "../../store/player.js";
12
20
  import { state as state$1 } from "../../../auth/views/store/auth.js";
13
- const _hoisted_1 = { class: "track-page" };
21
+ const _hoisted_1 = { class: "track-page pd-small" };
14
22
  const _hoisted_2 = {
15
23
  key: 0,
16
24
  class: "w-100 h-25r flex-center flex"
@@ -19,88 +27,477 @@ const _hoisted_3 = {
19
27
  key: 1,
20
28
  class: "t-center pd-big"
21
29
  };
22
- const _hoisted_4 = { key: 2 };
23
- const _hoisted_5 = {
30
+ const _hoisted_4 = {
31
+ key: 2,
32
+ class: "track-content cols-2-fit-content mobile:cols-1 gap-big"
33
+ };
34
+ const _hoisted_5 = { class: "pos-sticky pos-t-0 mobile:pos-relative track-cover-section" };
35
+ const _hoisted_6 = { class: "cover-container relative mn-b-medium radius-big overflow-hidden shadow-big" };
36
+ const _hoisted_7 = { class: "stats-grid grid cols-2 gap-small" };
37
+ const _hoisted_8 = { class: "stat-card bg-light pd-medium radius-medium t-center" };
38
+ const _hoisted_9 = { class: "mn-b-thin" };
39
+ const _hoisted_10 = { class: "stat-card bg-light pd-medium radius-medium t-center" };
40
+ const _hoisted_11 = { class: "mn-b-thin" };
41
+ const _hoisted_12 = { class: "track-details-section" };
42
+ const _hoisted_13 = { class: "flex items-center gap-small mn-b-small" };
43
+ const _hoisted_14 = {
44
+ key: 0,
45
+ class: "badge bg-danger-transp-20 t-danger pd-thin-big radius-small t-small"
46
+ };
47
+ const _hoisted_15 = { class: "h1 mn-b-medium" };
48
+ const _hoisted_16 = { class: "flex gap-small mn-b-medium" };
49
+ const _hoisted_17 = { class: "dropdown-menu bg-dark pd-small radius-medium shadow-big mn-t-thin" };
50
+ const _hoisted_18 = { class: "artist-card bg-light pd-medium radius-medium flex items-center gap-medium mn-b-big" };
51
+ const _hoisted_19 = { class: "artist-avatar" };
52
+ const _hoisted_20 = {
53
+ key: 1,
54
+ class: "w-4r h-4r radius-full bg-primary flex-center"
55
+ };
56
+ const _hoisted_21 = { class: "flex items-center gap-thin" };
57
+ const _hoisted_22 = { class: "t-large" };
58
+ const _hoisted_23 = { class: "metadata-grid grid cols-2 gap-small mn-b-big" };
59
+ const _hoisted_24 = { class: "metadata-card bg-light pd-medium radius-medium flex items-center gap-medium" };
60
+ const _hoisted_25 = { class: "icon-wrapper bg-primary-transp-20 w-3r h-3r radius-small flex-center" };
61
+ const _hoisted_26 = { class: "t-medium" };
62
+ const _hoisted_27 = { class: "metadata-card bg-light pd-medium radius-medium flex items-center gap-medium" };
63
+ const _hoisted_28 = { class: "icon-wrapper bg-primary-transp-20 w-3r h-3r radius-small flex-center" };
64
+ const _hoisted_29 = { class: "t-medium" };
65
+ const _hoisted_30 = { class: "metadata-card bg-light pd-medium radius-medium flex items-center gap-medium" };
66
+ const _hoisted_31 = { class: "icon-wrapper bg-success-transp-20 w-3r h-3r radius-small flex-center" };
67
+ const _hoisted_32 = { class: "t-medium t-success" };
68
+ const _hoisted_33 = { class: "metadata-card bg-light pd-medium radius-medium flex items-center gap-medium" };
69
+ const _hoisted_34 = { class: "icon-wrapper bg-primary-transp-20 w-3r h-3r radius-small flex-center" };
70
+ const _hoisted_35 = { class: "t-medium" };
71
+ const _hoisted_36 = {
24
72
  key: 0,
25
- class: "track-lyrics mn-b-medium pd-medium bg-dark-transp-10 radius-medium"
73
+ class: "album-card bg-light pd-medium radius-medium mn-b-medium"
26
74
  };
27
- const _hoisted_6 = { class: "t-grey" };
28
- const _hoisted_7 = {
75
+ const _hoisted_37 = { class: "t-medium" };
76
+ const _hoisted_38 = {
29
77
  key: 1,
30
- class: "related-tracks mn-b-medium"
78
+ class: "tags-section mn-b-medium"
79
+ };
80
+ const _hoisted_39 = { class: "flex gap-thin flex-wrap" };
81
+ const _hoisted_40 = {
82
+ key: 2,
83
+ class: "description-section bg-light pd-medium radius-medium mn-b-medium"
84
+ };
85
+ const _hoisted_41 = { class: "t-transp" };
86
+ const _hoisted_42 = {
87
+ key: 3,
88
+ class: "lyrics-section bg-light pd-medium radius-medium"
89
+ };
90
+ const _hoisted_43 = { class: "t-transp t-small" };
91
+ const _hoisted_44 = {
92
+ key: 3,
93
+ class: "related-section mn-t-big"
31
94
  };
95
+ const _hoisted_45 = { class: "bg-light radius-medium o-hidden" };
32
96
  const _sfc_main = {
33
97
  __name: "Track",
34
- setup(__props) {
98
+ emits: ["page-loading", "page-loaded"],
99
+ setup(__props, { emit: __emit }) {
35
100
  const route = useRoute();
36
- useRouter();
37
- const isLoading = ref(true);
38
- ref(false);
39
- ref(false);
40
- ref(false);
101
+ const router = useRouter();
102
+ const emits = __emit;
103
+ const hasLoaded = ref(false);
104
+ const showDropdown = ref(false);
105
+ const showAddToPlaylistModal = ref(false);
106
+ const isFavorite = ref(false);
107
+ const isFollowingArtist = ref(false);
108
+ state.currentTrack = null;
109
+ state.relatedTracks = [];
41
110
  const track = computed(() => state.currentTrack);
42
- const relatedTracks = computed(() => state.relatedTracks);
43
- computed(() => {
111
+ const relatedTracks = computed(() => state.relatedTracks || []);
112
+ const isOwner = computed(() => {
44
113
  return track.value?.owner?.target === state$1.user?._id;
45
114
  });
115
+ const formatDuration = (seconds) => {
116
+ if (!seconds) return "0:00";
117
+ const h = Math.floor(seconds / 3600);
118
+ const m = Math.floor(seconds % 3600 / 60);
119
+ const s = Math.floor(seconds % 60);
120
+ if (h > 0) {
121
+ return `${h}:${m.toString().padStart(2, "0")}:${s.toString().padStart(2, "0")}`;
122
+ }
123
+ return `${m}:${s.toString().padStart(2, "0")}`;
124
+ };
125
+ const formatDate = (dateString) => {
126
+ if (!dateString) return "Unknown";
127
+ return new Date(dateString).toLocaleDateString("en-US", {
128
+ year: "numeric",
129
+ month: "long",
130
+ day: "numeric"
131
+ });
132
+ };
133
+ const formatNumber = (num) => {
134
+ if (!num) return "0";
135
+ if (num >= 1e6) {
136
+ return (num / 1e6).toFixed(1) + "M";
137
+ } else if (num >= 1e3) {
138
+ return (num / 1e3).toFixed(1) + "K";
139
+ }
140
+ return num.toString();
141
+ };
142
+ const playTrack = () => {
143
+ if (track.value) {
144
+ actions$1.setQueue([track.value]);
145
+ }
146
+ };
147
+ const toggleFavorite = () => {
148
+ isFavorite.value = !isFavorite.value;
149
+ };
150
+ const toggleFollowArtist = () => {
151
+ isFollowingArtist.value = !isFollowingArtist.value;
152
+ };
153
+ const addToQueue = () => {
154
+ if (track.value) {
155
+ actions$1.addToQueue(track.value);
156
+ }
157
+ };
158
+ const editTrack = () => {
159
+ router.push({ name: "track-edit", params: { url: track.value.url } });
160
+ };
161
+ const deleteTrack = async () => {
162
+ if (confirm("Are you sure you want to delete this track?")) {
163
+ try {
164
+ await actions.deleteTrack(track.value._id);
165
+ router.push({ name: "music-library" });
166
+ } catch (error) {
167
+ console.error("Failed to delete track:", error);
168
+ }
169
+ }
170
+ };
171
+ const copyLink = () => {
172
+ navigator.clipboard.writeText(window.location.href);
173
+ showDropdown.value = false;
174
+ };
46
175
  const fetchTrackData = async () => {
47
- isLoading.value = true;
48
176
  try {
49
177
  await actions.fetchTrackByUrl(route.params.url);
50
178
  await actions.fetchRelatedTracks(route.params.url);
51
179
  } catch (error) {
52
180
  console.error("Error loading track:", error);
53
- } finally {
54
- isLoading.value = false;
55
181
  }
56
182
  };
57
- onMounted(fetchTrackData);
58
- watch(() => route.params.url, fetchTrackData);
183
+ onMounted(async () => {
184
+ emits("page-loading");
185
+ await fetchTrackData();
186
+ hasLoaded.value = true;
187
+ emits("page-loaded");
188
+ });
59
189
  return (_ctx, _cache) => {
190
+ const _component_router_link = resolveComponent("router-link");
60
191
  return openBlock(), createElementBlock("div", _hoisted_1, [
61
- isLoading.value ? (openBlock(), createElementBlock("div", _hoisted_2, [
192
+ _ctx.isLoading ? (openBlock(), createElementBlock("div", _hoisted_2, [
62
193
  createVNode(Loader)
63
- ])) : !track.value ? (openBlock(), createElementBlock("div", _hoisted_3, _cache[0] || (_cache[0] = [
194
+ ])) : createCommentVNode("", true),
195
+ hasLoaded.value && !track.value ? (openBlock(), createElementBlock("div", _hoisted_3, _cache[3] || (_cache[3] = [
64
196
  createElementVNode("h2", { class: "" }, "Track not found", -1),
65
- createElementVNode("p", { class: "t-grey t-medium" }, "The track you're looking for doesn't exist or has been removed.", -1)
66
- ]))) : (openBlock(), createElementBlock("div", _hoisted_4, [
67
- track.value.lyrics ? (openBlock(), createElementBlock("div", _hoisted_5, [
68
- _cache[1] || (_cache[1] = createElementVNode("h2", { class: "mn-b-small" }, "Lyrics", -1)),
69
- createElementVNode("pre", _hoisted_6, toDisplayString(track.value.lyrics), 1)
70
- ])) : createCommentVNode("", true),
71
- relatedTracks.value.length ? (openBlock(), createElementBlock("section", _hoisted_7, [
72
- _cache[2] || (_cache[2] = createElementVNode("h2", { class: "mn-b-small" }, "Related Tracks", -1)),
73
- createVNode(_sfc_main$1, {
74
- store: {
75
- read: () => _ctx.Promise.resolve(relatedTracks.value.value),
76
- state: { isLoading: false }
77
- },
78
- external: true,
79
- items: relatedTracks.value,
80
- states: {
81
- empty: {
82
- title: "No related tracks",
83
- description: "Check back later for recommendations",
84
- class: "pd-medium bg-dark-transp-10 radius-medium"
85
- }
86
- },
87
- class: "gap-thin"
88
- }, {
89
- default: withCtx(({ items }) => [
90
- (openBlock(true), createElementBlock(Fragment, null, renderList(items, (relatedTrack) => {
91
- return openBlock(), createBlock(TrackCard, {
197
+ createElementVNode("p", { class: "t-transp t-medium" }, "The track you're looking for doesn't exist or has been removed.", -1)
198
+ ]))) : createCommentVNode("", true),
199
+ track.value ? (openBlock(), createElementBlock("div", _hoisted_4, [
200
+ createElementVNode("div", _hoisted_5, [
201
+ createElementVNode("div", _hoisted_6, [
202
+ createVNode(Media, {
203
+ url: track.value.coverUrl || track.value.album && track.value.album.coverUrl || "/logo/logo-placeholder.jpg",
204
+ alt: track.value.title,
205
+ class: "aspect-1x1 w-100 radius-medium o-hidden"
206
+ }, null, 8, ["url", "alt"])
207
+ ]),
208
+ createElementVNode("div", _hoisted_7, [
209
+ createElementVNode("div", _hoisted_8, [
210
+ createElementVNode("div", _hoisted_9, toDisplayString(formatNumber(track.value.playCount)), 1),
211
+ _cache[4] || (_cache[4] = createElementVNode("div", { class: "t-small t-transp t-uppercase" }, "Plays", -1))
212
+ ]),
213
+ createElementVNode("div", _hoisted_10, [
214
+ createElementVNode("div", _hoisted_11, toDisplayString(formatNumber(track.value.views)), 1),
215
+ _cache[5] || (_cache[5] = createElementVNode("div", { class: "t-small t-transp t-uppercase" }, "Views", -1))
216
+ ])
217
+ ])
218
+ ]),
219
+ createElementVNode("div", _hoisted_12, [
220
+ createElementVNode("div", _hoisted_13, [
221
+ _cache[6] || (_cache[6] = createElementVNode("span", { class: "badge bg-primary-transp-20 t-primary pd-thin-big radius-small t-small t-uppercase" }, "Single", -1)),
222
+ track.value.isExplicit ? (openBlock(), createElementBlock("span", _hoisted_14, "Explicit")) : createCommentVNode("", true)
223
+ ]),
224
+ createElementVNode("h1", _hoisted_15, toDisplayString(track.value.title), 1),
225
+ createElementVNode("div", _hoisted_16, [
226
+ createVNode(_sfc_main$1, {
227
+ onClick: playTrack,
228
+ color: "primary",
229
+ size: "medium",
230
+ class: "flex-1 flex-center gap-thin"
231
+ }, {
232
+ default: withCtx(() => [
233
+ createVNode(_sfc_main$2, { class: "w-1r h-1r" }),
234
+ _cache[7] || (_cache[7] = createTextVNode(" Play "))
235
+ ]),
236
+ _: 1
237
+ }),
238
+ createVNode(_sfc_main$1, {
239
+ onClick: toggleFavorite,
240
+ color: isFavorite.value ? "danger" : "transp",
241
+ size: "medium",
242
+ class: "w-3r h-3r radius-full"
243
+ }, {
244
+ default: withCtx(() => [
245
+ createVNode(_sfc_main$3, {
246
+ class: "w-1-25r h-1-25r",
247
+ fill: isFavorite.value
248
+ }, null, 8, ["fill"])
249
+ ]),
250
+ _: 1
251
+ }, 8, ["color"]),
252
+ createVNode(_sfc_main$1, {
253
+ onClick: addToQueue,
254
+ color: "transp",
255
+ size: "medium",
256
+ class: "w-3r h-3r radius-full"
257
+ }, {
258
+ default: withCtx(() => [
259
+ createVNode(_sfc_main$4, { class: "w-1-25r h-1-25r" })
260
+ ]),
261
+ _: 1
262
+ }),
263
+ createVNode(_sfc_main$5, {
264
+ modelValue: showDropdown.value,
265
+ "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => showDropdown.value = $event),
266
+ class: "relative"
267
+ }, {
268
+ trigger: withCtx(() => [
269
+ createVNode(_sfc_main$1, {
270
+ color: "transp",
271
+ size: "medium",
272
+ class: "w-3r h-3r radius-full"
273
+ }, {
274
+ default: withCtx(() => [
275
+ createVNode(_sfc_main$6, { class: "w-1-25r h-1-25r" })
276
+ ]),
277
+ _: 1
278
+ })
279
+ ]),
280
+ default: withCtx(() => [
281
+ createElementVNode("div", _hoisted_17, [
282
+ createVNode(_sfc_main$1, {
283
+ onClick: _cache[0] || (_cache[0] = ($event) => showAddToPlaylistModal.value = true),
284
+ color: "transp",
285
+ size: "small",
286
+ class: "w-100 justify-start"
287
+ }, {
288
+ default: withCtx(() => _cache[8] || (_cache[8] = [
289
+ createTextVNode(" Add to Playlist ")
290
+ ])),
291
+ _: 1
292
+ }),
293
+ createVNode(_sfc_main$1, {
294
+ onClick: copyLink,
295
+ color: "transp",
296
+ size: "small",
297
+ class: "w-100 justify-start"
298
+ }, {
299
+ default: withCtx(() => _cache[9] || (_cache[9] = [
300
+ createTextVNode(" Copy Link ")
301
+ ])),
302
+ _: 1
303
+ }),
304
+ isOwner.value ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [
305
+ _cache[12] || (_cache[12] = createElementVNode("hr", { class: "mn-v-thin border-dark-transp-10" }, null, -1)),
306
+ createVNode(_sfc_main$1, {
307
+ onClick: editTrack,
308
+ color: "transp",
309
+ size: "small",
310
+ class: "w-100 justify-start"
311
+ }, {
312
+ default: withCtx(() => _cache[10] || (_cache[10] = [
313
+ createTextVNode(" Edit Track ")
314
+ ])),
315
+ _: 1
316
+ }),
317
+ createVNode(_sfc_main$1, {
318
+ onClick: deleteTrack,
319
+ color: "danger",
320
+ size: "small",
321
+ class: "w-100 justify-start"
322
+ }, {
323
+ default: withCtx(() => _cache[11] || (_cache[11] = [
324
+ createTextVNode(" Delete Track ")
325
+ ])),
326
+ _: 1
327
+ })
328
+ ], 64)) : createCommentVNode("", true)
329
+ ])
330
+ ]),
331
+ _: 1
332
+ }, 8, ["modelValue"])
333
+ ]),
334
+ createElementVNode("div", _hoisted_18, [
335
+ createVNode(_component_router_link, {
336
+ to: `/artist/${track.value.artist.url}`,
337
+ class: "flex items-center gap-medium flex-1 hover-opacity"
338
+ }, {
339
+ default: withCtx(() => [
340
+ createElementVNode("div", _hoisted_19, [
341
+ track.value.artist.photoUrl ? (openBlock(), createBlock(Media, {
342
+ key: 0,
343
+ src: track.value.artist.photoUrl,
344
+ alt: track.value.artist.name,
345
+ class: "w-4r h-4r radius-full object-cover"
346
+ }, null, 8, ["src", "alt"])) : (openBlock(), createElementBlock("div", _hoisted_20, toDisplayString(track.value.artist.name.charAt(0)), 1))
347
+ ]),
348
+ createElementVNode("div", null, [
349
+ createElementVNode("div", _hoisted_21, [
350
+ createElementVNode("span", _hoisted_22, toDisplayString(track.value.artist.name), 1),
351
+ track.value.artist.isVerified ? (openBlock(), createBlock(_sfc_main$7, {
352
+ key: 0,
353
+ class: "w-1r h-1r t-primary"
354
+ })) : createCommentVNode("", true)
355
+ ]),
356
+ _cache[13] || (_cache[13] = createElementVNode("span", { class: "t-small t-transp" }, "Artist", -1))
357
+ ])
358
+ ]),
359
+ _: 1
360
+ }, 8, ["to"]),
361
+ !isOwner.value ? (openBlock(), createBlock(_sfc_main$1, {
362
+ key: 0,
363
+ onClick: toggleFollowArtist,
364
+ color: isFollowingArtist.value ? "primary" : "transp",
365
+ size: "small"
366
+ }, {
367
+ default: withCtx(() => [
368
+ createTextVNode(toDisplayString(isFollowingArtist.value ? "Following" : "Follow"), 1)
369
+ ]),
370
+ _: 1
371
+ }, 8, ["color"])) : createCommentVNode("", true)
372
+ ]),
373
+ createElementVNode("div", _hoisted_23, [
374
+ createElementVNode("div", _hoisted_24, [
375
+ createElementVNode("div", _hoisted_25, [
376
+ createVNode(IconClock, { class: "w-1-5r h-1-5r t-primary" })
377
+ ]),
378
+ createElementVNode("div", null, [
379
+ _cache[14] || (_cache[14] = createElementVNode("div", { class: "t-small t-transp t-uppercase" }, "Duration", -1)),
380
+ createElementVNode("div", _hoisted_26, toDisplayString(formatDuration(track.value.duration)), 1)
381
+ ])
382
+ ]),
383
+ createElementVNode("div", _hoisted_27, [
384
+ createElementVNode("div", _hoisted_28, [
385
+ createVNode(_sfc_main$8, { class: "w-1-5r h-1-5r t-primary" })
386
+ ]),
387
+ createElementVNode("div", null, [
388
+ _cache[15] || (_cache[15] = createElementVNode("div", { class: "t-small t-transp t-uppercase" }, "Released", -1)),
389
+ createElementVNode("div", _hoisted_29, toDisplayString(formatDate(track.value.releaseDate)), 1)
390
+ ])
391
+ ]),
392
+ createElementVNode("div", _hoisted_30, [
393
+ createElementVNode("div", _hoisted_31, [
394
+ createVNode(_sfc_main$7, { class: "w-1-5r h-1-5r t-success" })
395
+ ]),
396
+ createElementVNode("div", null, [
397
+ _cache[16] || (_cache[16] = createElementVNode("div", { class: "t-small t-transp t-uppercase" }, "Status", -1)),
398
+ createElementVNode("div", _hoisted_32, toDisplayString(track.value.status), 1)
399
+ ])
400
+ ]),
401
+ createElementVNode("div", _hoisted_33, [
402
+ createElementVNode("div", _hoisted_34, [
403
+ createVNode(_sfc_main$9, { class: "w-1-5r h-1-5r t-primary" })
404
+ ]),
405
+ createElementVNode("div", null, [
406
+ _cache[17] || (_cache[17] = createElementVNode("div", { class: "t-small t-transp t-uppercase" }, "Visibility", -1)),
407
+ createElementVNode("div", _hoisted_35, toDisplayString(track.value.isPublic ? "Public" : "Private"), 1)
408
+ ])
409
+ ])
410
+ ]),
411
+ track.value.album ? (openBlock(), createElementBlock("div", _hoisted_36, [
412
+ _cache[18] || (_cache[18] = createElementVNode("div", { class: "t-small t-transp t-uppercase mn-b-thin" }, "From Album", -1)),
413
+ createVNode(_component_router_link, {
414
+ to: `/album/${track.value.album.url}`,
415
+ class: "flex items-center gap-medium hover-opacity"
416
+ }, {
417
+ default: withCtx(() => [
418
+ track.value.album.coverUrl ? (openBlock(), createBlock(Media, {
419
+ key: 0,
420
+ src: track.value.album.coverUrl,
421
+ alt: track.value.album.title,
422
+ class: "w-3r h-3r radius-small object-cover"
423
+ }, null, 8, ["src", "alt"])) : createCommentVNode("", true),
424
+ createElementVNode("span", _hoisted_37, toDisplayString(track.value.album.title), 1)
425
+ ]),
426
+ _: 1
427
+ }, 8, ["to"])
428
+ ])) : createCommentVNode("", true),
429
+ track.value.genre && track.value.genre.length || track.value.tags && track.value.tags.length ? (openBlock(), createElementBlock("div", _hoisted_38, [
430
+ _cache[19] || (_cache[19] = createElementVNode("h3", { class: "t-medium mn-b-small" }, "Genres & Tags", -1)),
431
+ createElementVNode("div", _hoisted_39, [
432
+ (openBlock(true), createElementBlock(Fragment, null, renderList(track.value.genre, (genre) => {
433
+ return openBlock(), createElementBlock("span", {
434
+ key: genre,
435
+ class: "tag bg-primary-transp-20 t-primary pd-thin-big radius-small t-small hover-bg-primary-transp-30 cursor-pointer"
436
+ }, toDisplayString(genre), 1);
437
+ }), 128)),
438
+ (openBlock(true), createElementBlock(Fragment, null, renderList(track.value.tags, (tag) => {
439
+ return openBlock(), createElementBlock("span", {
440
+ key: tag,
441
+ class: "tag bg-light t-transp pd-thin-big radius-small t-small hover-bg-light cursor-pointer"
442
+ }, " #" + toDisplayString(tag), 1);
443
+ }), 128))
444
+ ])
445
+ ])) : createCommentVNode("", true),
446
+ track.value.description ? (openBlock(), createElementBlock("div", _hoisted_40, [
447
+ _cache[20] || (_cache[20] = createElementVNode("h3", { class: "t-medium mn-b-small" }, "About", -1)),
448
+ createElementVNode("p", _hoisted_41, toDisplayString(track.value.description), 1)
449
+ ])) : createCommentVNode("", true),
450
+ track.value.lyrics ? (openBlock(), createElementBlock("div", _hoisted_42, [
451
+ _cache[21] || (_cache[21] = createElementVNode("h3", { class: "t-medium mn-b-small" }, "Lyrics", -1)),
452
+ createElementVNode("pre", _hoisted_43, toDisplayString(track.value.lyrics), 1)
453
+ ])) : createCommentVNode("", true)
454
+ ])
455
+ ])) : createCommentVNode("", true),
456
+ track.value && relatedTracks.value && relatedTracks.value.length ? (openBlock(), createElementBlock("section", _hoisted_44, [
457
+ _cache[22] || (_cache[22] = createElementVNode("h2", { class: "h2 mn-b-medium" }, "Related Tracks", -1)),
458
+ createVNode(_sfc_main$a, {
459
+ store: {
460
+ read: () => new _ctx.Promise((resolve) => resolve(relatedTracks.value || [])),
461
+ state: { isLoading: false }
462
+ },
463
+ external: true,
464
+ items: relatedTracks.value,
465
+ states: {
466
+ empty: {
467
+ title: "No related tracks",
468
+ description: "Check back later for recommendations",
469
+ class: "pd-medium bg-light radius-medium"
470
+ }
471
+ },
472
+ class: "grid cols-2 cols-m-3 cols-l-4 gap-medium"
473
+ }, {
474
+ default: withCtx(({ items }) => [
475
+ createElementVNode("div", _hoisted_45, [
476
+ (openBlock(true), createElementBlock(Fragment, null, renderList(items, (relatedTrack, index) => {
477
+ return openBlock(), createBlock(_sfc_main$b, {
92
478
  key: relatedTrack._id,
93
479
  track: relatedTrack,
480
+ index,
94
481
  showAlbum: true,
95
- showCover: true,
96
- class: "w-100 bg-dark-transp-10 radius-medium"
97
- }, null, 8, ["track"]);
482
+ showCover: true
483
+ }, null, 8, ["track", "index"]);
98
484
  }), 128))
99
- ]),
100
- _: 1
101
- }, 8, ["store", "items"])
102
- ])) : createCommentVNode("", true)
103
- ]))
485
+ ])
486
+ ]),
487
+ _: 1
488
+ }, 8, ["store", "items"])
489
+ ])) : createCommentVNode("", true),
490
+ showAddToPlaylistModal.value ? (openBlock(), createBlock(_sfc_main$c, {
491
+ key: 4,
492
+ onClosePopup: _cache[2] || (_cache[2] = ($event) => showAddToPlaylistModal.value = false),
493
+ class: "bg-dark pd-medium w-m-25r radius-medium"
494
+ }, {
495
+ default: withCtx(() => _cache[23] || (_cache[23] = [
496
+ createElementVNode("h3", { class: "h3 mn-b-medium" }, "Add to Playlist", -1),
497
+ createElementVNode("p", { class: "t-transp" }, "Playlist selector coming soon...", -1)
498
+ ])),
499
+ _: 1
500
+ })) : createCommentVNode("", true)
104
501
  ]);
105
502
  };
106
503
  }
@@ -1 +1 @@
1
- {"version":3,"file":"Track.vue.js","sources":["../../../../../../../src/modules/music/components/pages/Track.vue"],"sourcesContent":["<!-- components/pages/Track.vue -->\n<template>\n <div class=\"track-page\">\n <!-- Loading -->\n <div v-if=\"isLoading\" class=\"w-100 h-25r flex-center flex\">\n <Loader />\n </div>\n\n <!-- Not Found -->\n <div v-else-if=\"!track\" class=\"t-center pd-big\">\n <h2 class=\"\">Track not found</h2>\n <p class=\"t-grey t-medium\">The track you're looking for doesn't exist or has been removed.</p>\n </div>\n\n <!-- Track Content -->\n <div v-else>\n <!-- ... [HEADER + ACTIONS as you posted] -->\n\n <!-- Track Lyrics -->\n <div v-if=\"track.lyrics\" class=\"track-lyrics mn-b-medium pd-medium bg-dark-transp-10 radius-medium\">\n <h2 class=\" mn-b-small\">Lyrics</h2>\n <pre class=\"t-grey\">{{ track.lyrics }}</pre>\n </div>\n\n <!-- Related Tracks -->\n <section v-if=\"relatedTracks.length\" class=\"related-tracks mn-b-medium\">\n <h2 class=\" mn-b-small\">Related Tracks</h2>\n <Feed\n :store=\"{\n read: () => Promise.resolve(relatedTracks.value),\n state: { isLoading: false }\n }\"\n :external=\"true\"\n :items=\"relatedTracks\"\n :states=\"{\n empty: {\n title: 'No related tracks',\n description: 'Check back later for recommendations',\n class: 'pd-medium bg-dark-transp-10 radius-medium'\n }\n }\"\n class=\"gap-thin\"\n >\n <template #default=\"{ items }\">\n <TrackCard\n v-for=\"relatedTrack in items\"\n :key=\"relatedTrack._id\"\n :track=\"relatedTrack\"\n :showAlbum=\"true\"\n :showCover=\"true\"\n class=\"w-100 bg-dark-transp-10 radius-medium\"\n />\n </template>\n </Feed>\n </section>\n\n <!-- Add to Playlist Modal -->\n <!-- <Popup \n v-if=\"showAddToPlaylistModal\" \n @close-popup=\"showAddToPlaylistModal = false\" \n class=\"bg-dark pd-small w-m-25r radius-medium \"\n >\n <h3 class=\"mn-b-medium\">Add to Playlist</h3>\n <PlaylistSelector \n :trackId=\"track._id\" \n @added=\"showAddToPlaylistModal = false\"\n />\n </Popup> -->\n </div>\n </div>\n</template>\n\n<script setup>\nimport { ref, computed, onMounted, watch } from 'vue';\nimport { useRoute, useRouter } from 'vue-router';\nimport Button from '@martyrs/src/components/Button/Button.vue';\nimport Loader from '@martyrs/src/components/Loader/Loader.vue';\nimport Media from '@martyrs/src/components/Media/Media.vue';\nimport Dropdown from '@martyrs/src/components/Dropdown/Dropdown.vue';\nimport Popup from '@martyrs/src/components/Popup/Popup.vue';\nimport IconPlay from '@martyrs/src/modules/icons/navigation/IconPlay.vue';\nimport IconLike from '@martyrs/src/modules/icons/navigation/IconLike.vue';\nimport IconEllipsis from '@martyrs/src/modules/icons/navigation/IconEllipsis.vue';\nimport Feed from '@martyrs/src/components/Feed/Feed.vue';\nimport TrackCard from '../cards/TrackCard.vue';\n// import PlaylistSelector from '../forms/PlaylistSelector.vue';\n\nimport { state as tracksState, actions as tracksActions } from '../../store/tracks.js';\nimport { actions as playerActions } from '../../store/player.js';\nimport { state as authState } from '@martyrs/src/modules/auth/views/store/auth.js';\n\nconst route = useRoute();\nconst router = useRouter();\n\nconst isLoading = ref(true);\nconst showDropdown = ref(false);\nconst showAddToPlaylistModal = ref(false);\nconst isFavorite = ref(false);\n\nconst track = computed(() => tracksState.currentTrack);\nconst relatedTracks = computed(() => tracksState.relatedTracks);\n\nconst isOwner = computed(() => {\n return track.value?.owner?.target === authState.user?._id;\n});\n\nconst getArtistName = (track) => {\n if (!track || !track.artist) return 'Unknown';\n return typeof track.artist === 'object' ? track.artist.name : 'Unknown';\n};\n\nconst formatReleaseYear = (date) => {\n return date ? new Date(date).getFullYear() : 'Unknown';\n};\n\nconst playTrack = () => {\n if (track.value) {\n playerActions.setQueue([track.value]);\n }\n};\n\nconst toggleFavorite = () => {\n isFavorite.value = !isFavorite.value;\n // You can implement actual saving here\n};\n\nconst addToQueue = () => {\n if (track.value) {\n playerActions.addToQueue(track.value);\n }\n};\n\nconst editTrack = () => {\n router.push({ name: 'track-edit', params: { url: track.value.url } });\n};\n\nconst deleteTrack = async () => {\n try {\n await tracksActions.deleteTrack(track.value._id);\n router.push({ name: 'music-library' });\n } catch (error) {\n console.error('Failed to delete track:', error);\n }\n};\n\nconst copyLink = () => {\n navigator.clipboard.writeText(window.location.href);\n showDropdown.value = false;\n};\n\nconst fetchTrackData = async () => {\n isLoading.value = true;\n try {\n await tracksActions.fetchTrackByUrl(route.params.url);\n await tracksActions.fetchRelatedTracks(route.params.url);\n } catch (error) {\n console.error('Error loading track:', error);\n } finally {\n isLoading.value = false;\n }\n};\n\nonMounted(fetchTrackData);\nwatch(() => route.params.url, fetchTrackData);\n</script>\n"],"names":["tracksState","authState","tracksActions"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2FA,UAAM,QAAQ,SAAQ;AACP,cAAS;AAExB,UAAM,YAAY,IAAI,IAAI;AACL,QAAI,KAAK;AACC,QAAI,KAAK;AACrB,QAAI,KAAK;AAE5B,UAAM,QAAQ,SAAS,MAAMA,MAAY,YAAY;AACrD,UAAM,gBAAgB,SAAS,MAAMA,MAAY,aAAa;AAE9C,aAAS,MAAM;AAC7B,aAAO,MAAM,OAAO,OAAO,WAAWC,QAAU,MAAM;AAAA,IACxD,CAAC;AA8CD,UAAM,iBAAiB,YAAY;AACjC,gBAAU,QAAQ;AAClB,UAAI;AACF,cAAMC,QAAc,gBAAgB,MAAM,OAAO,GAAG;AACpD,cAAMA,QAAc,mBAAmB,MAAM,OAAO,GAAG;AAAA,MACzD,SAAS,OAAO;AACd,gBAAQ,MAAM,wBAAwB,KAAK;AAAA,MAC7C,UAAC;AACC,kBAAU,QAAQ;AAAA,MACpB;AAAA,IACF;AAEA,cAAU,cAAc;AACxB,UAAM,MAAM,MAAM,OAAO,KAAK,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"Track.vue.js","sources":["../../../../../../../src/modules/music/components/pages/Track.vue"],"sourcesContent":["<!-- components/pages/Track.vue -->\n<template>\n <div class=\"track-page pd-small\">\n <!-- Loading -->\n <div v-if=\"isLoading\" class=\"w-100 h-25r flex-center flex\">\n <Loader />\n </div>\n\n <!-- Not Found -->\n <div v-if=\"hasLoaded && !track\" class=\"t-center pd-big\">\n <h2 class=\"\">Track not found</h2>\n <p class=\"t-transp t-medium\">The track you're looking for doesn't exist or has been removed.</p>\n </div>\n\n <!-- Track Content -->\n <div v-if=\"track\" class=\"track-content cols-2-fit-content mobile:cols-1 gap-big\">\n <!-- Left Column - Cover & Stats -->\n <div class=\"pos-sticky pos-t-0 mobile:pos-relative track-cover-section\">\n <!-- Cover with Play Overlay -->\n <div class=\"cover-container relative mn-b-medium radius-big overflow-hidden shadow-big\">\n <Media \n :url=\"track.coverUrl || (track.album && track.album.coverUrl) || '/logo/logo-placeholder.jpg'\" \n :alt=\"track.title\"\n class=\"aspect-1x1 w-100 radius-medium o-hidden\"\n />\n <!-- <div class=\"cover-overlay absolute inset-0 bg-black-transp-40 flex-center opacity-0 hover-opacity-100 transition\">\n <Button\n @click=\"playTrack\"\n color=\"white\"\n size=\"big\"\n class=\"w-5r h-5r radius-full shadow-big hover-scale-110\"\n >\n <IconPlay class=\"w-2r h-2r\" />\n </Button>\n </div> -->\n </div>\n\n \n\n <!-- Quick Stats -->\n <div class=\"stats-grid grid cols-2 gap-small\">\n <div class=\"stat-card bg-light pd-medium radius-medium t-center\">\n <div class=\" mn-b-thin\">{{ formatNumber(track.playCount) }}</div>\n <div class=\"t-small t-transp t-uppercase\">Plays</div>\n </div>\n <div class=\"stat-card bg-light pd-medium radius-medium t-center\">\n <div class=\" mn-b-thin\">{{ formatNumber(track.views) }}</div>\n <div class=\"t-small t-transp t-uppercase\">Views</div>\n </div>\n </div>\n </div>\n\n <!-- Right Column - Track Details -->\n <div class=\"track-details-section\">\n <!-- Track Type Badge -->\n <div class=\"flex items-center gap-small mn-b-small\">\n <span class=\"badge bg-primary-transp-20 t-primary pd-thin-big radius-small t-small t-uppercase\">Single</span>\n <span v-if=\"track.isExplicit\" class=\"badge bg-danger-transp-20 t-danger pd-thin-big radius-small t-small\">Explicit</span>\n </div>\n\n <!-- Track Title -->\n <h1 class=\"h1 mn-b-medium\">{{ track.title }}</h1>\n <!-- Action Buttons -->\n <div class=\"flex gap-small mn-b-medium\">\n <Button\n @click=\"playTrack\"\n color=\"primary\"\n size=\"medium\"\n class=\"flex-1 flex-center gap-thin\"\n >\n <IconPlay class=\"w-1r h-1r\" />\n Play\n </Button>\n \n <Button\n @click=\"toggleFavorite\"\n :color=\"isFavorite ? 'danger' : 'transp'\"\n size=\"medium\"\n class=\"w-3r h-3r radius-full\"\n >\n <IconLike class=\"w-1-25r h-1-25r\" :fill=\"isFavorite\" />\n </Button>\n \n <Button\n @click=\"addToQueue\"\n color=\"transp\"\n size=\"medium\"\n class=\"w-3r h-3r radius-full\"\n >\n <IconAdd class=\"w-1-25r h-1-25r\" />\n </Button>\n \n <Dropdown v-model=\"showDropdown\" class=\"relative\">\n <template #trigger>\n <Button color=\"transp\" size=\"medium\" class=\"w-3r h-3r radius-full\">\n <IconEllipsis class=\"w-1-25r h-1-25r\" />\n </Button>\n </template>\n <template #default>\n <div class=\"dropdown-menu bg-dark pd-small radius-medium shadow-big mn-t-thin\">\n <Button @click=\"showAddToPlaylistModal = true\" color=\"transp\" size=\"small\" class=\"w-100 justify-start\">\n Add to Playlist\n </Button>\n <Button @click=\"copyLink\" color=\"transp\" size=\"small\" class=\"w-100 justify-start\">\n Copy Link\n </Button>\n <template v-if=\"isOwner\">\n <hr class=\"mn-v-thin border-dark-transp-10\" />\n <Button @click=\"editTrack\" color=\"transp\" size=\"small\" class=\"w-100 justify-start\">\n Edit Track\n </Button>\n <Button @click=\"deleteTrack\" color=\"danger\" size=\"small\" class=\"w-100 justify-start\">\n Delete Track\n </Button>\n </template>\n </div>\n </template>\n </Dropdown>\n </div>\n\n <!-- Artist Card -->\n <div class=\"artist-card bg-light pd-medium radius-medium flex items-center gap-medium mn-b-big\">\n <router-link \n :to=\"`/artist/${track.artist.url}`\"\n class=\"flex items-center gap-medium flex-1 hover-opacity\"\n >\n <div class=\"artist-avatar\">\n <Media \n v-if=\"track.artist.photoUrl\"\n :src=\"track.artist.photoUrl\"\n :alt=\"track.artist.name\"\n class=\"w-4r h-4r radius-full object-cover\"\n />\n <div v-else class=\"w-4r h-4r radius-full bg-primary flex-center \">\n {{ track.artist.name.charAt(0) }}\n </div>\n </div>\n <div>\n <div class=\"flex items-center gap-thin\">\n <span class=\"t-large \">{{ track.artist.name }}</span>\n <IconVerified v-if=\"track.artist.isVerified\" class=\"w-1r h-1r t-primary\" />\n </div>\n <span class=\"t-small t-transp\">Artist</span>\n </div>\n </router-link>\n <Button \n v-if=\"!isOwner\"\n @click=\"toggleFollowArtist\"\n :color=\"isFollowingArtist ? 'primary' : 'transp'\"\n size=\"small\"\n >\n {{ isFollowingArtist ? 'Following' : 'Follow' }}\n </Button>\n </div>\n\n\n\n <!-- Metadata Cards -->\n <div class=\"metadata-grid grid cols-2 gap-small mn-b-big\">\n <!-- Duration -->\n <div class=\"metadata-card bg-light pd-medium radius-medium flex items-center gap-medium\">\n <div class=\"icon-wrapper bg-primary-transp-20 w-3r h-3r radius-small flex-center\">\n <IconClock class=\"w-1-5r h-1-5r t-primary\" />\n </div>\n <div>\n <div class=\"t-small t-transp t-uppercase\">Duration</div>\n <div class=\"t-medium \">{{ formatDuration(track.duration) }}</div>\n </div>\n </div>\n\n <!-- Release Date -->\n <div class=\"metadata-card bg-light pd-medium radius-medium flex items-center gap-medium\">\n <div class=\"icon-wrapper bg-primary-transp-20 w-3r h-3r radius-small flex-center\">\n <IconCalendar class=\"w-1-5r h-1-5r t-primary\" />\n </div>\n <div>\n <div class=\"t-small t-transp t-uppercase\">Released</div>\n <div class=\"t-medium \">{{ formatDate(track.releaseDate) }}</div>\n </div>\n </div>\n\n <!-- Status -->\n <div class=\"metadata-card bg-light pd-medium radius-medium flex items-center gap-medium\">\n <div class=\"icon-wrapper bg-success-transp-20 w-3r h-3r radius-small flex-center\">\n <IconCheck class=\"w-1-5r h-1-5r t-success\" />\n </div>\n <div>\n <div class=\"t-small t-transp t-uppercase\">Status</div>\n <div class=\"t-medium t-success\">{{ track.status }}</div>\n </div>\n </div>\n\n <!-- Visibility -->\n <div class=\"metadata-card bg-light pd-medium radius-medium flex items-center gap-medium\">\n <div class=\"icon-wrapper bg-primary-transp-20 w-3r h-3r radius-small flex-center\">\n <IconEye class=\"w-1-5r h-1-5r t-primary\" />\n </div>\n <div>\n <div class=\"t-small t-transp t-uppercase\">Visibility</div>\n <div class=\"t-medium \">{{ track.isPublic ? 'Public' : 'Private' }}</div>\n </div>\n </div>\n </div>\n\n <!-- Album Info -->\n <div v-if=\"track.album\" class=\"album-card bg-light pd-medium radius-medium mn-b-medium\">\n <div class=\"t-small t-transp t-uppercase mn-b-thin\">From Album</div>\n <router-link \n :to=\"`/album/${track.album.url}`\"\n class=\"flex items-center gap-medium hover-opacity\"\n >\n <Media \n v-if=\"track.album.coverUrl\"\n :src=\"track.album.coverUrl\"\n :alt=\"track.album.title\"\n class=\"w-3r h-3r radius-small object-cover\"\n />\n <span class=\"t-medium \">{{ track.album.title }}</span>\n </router-link>\n </div>\n\n <!-- Genres & Tags -->\n <div v-if=\"(track.genre && track.genre.length) || (track.tags && track.tags.length)\" class=\"tags-section mn-b-medium\">\n <h3 class=\"t-medium mn-b-small\">Genres & Tags</h3>\n <div class=\"flex gap-thin flex-wrap\">\n <span \n v-for=\"genre in track.genre\" \n :key=\"genre\"\n class=\"tag bg-primary-transp-20 t-primary pd-thin-big radius-small t-small hover-bg-primary-transp-30 cursor-pointer\"\n >\n {{ genre }}\n </span>\n <span \n v-for=\"tag in track.tags\" \n :key=\"tag\"\n class=\"tag bg-light t-transp pd-thin-big radius-small t-small hover-bg-light cursor-pointer\"\n >\n #{{ tag }}\n </span>\n </div>\n </div>\n\n <!-- Description -->\n <div v-if=\"track.description\" class=\"description-section bg-light pd-medium radius-medium mn-b-medium\">\n <h3 class=\"t-medium mn-b-small\">About</h3>\n <p class=\"t-transp\">{{ track.description }}</p>\n </div>\n\n <!-- Lyrics -->\n <div v-if=\"track.lyrics\" class=\"lyrics-section bg-light pd-medium radius-medium\">\n <h3 class=\"t-medium mn-b-small\">Lyrics</h3>\n <pre class=\"t-transp t-small\">{{ track.lyrics }}</pre>\n </div>\n </div>\n </div>\n\n <!-- Related Tracks -->\n <section v-if=\"track && relatedTracks && relatedTracks.length\" class=\"related-section mn-t-big\">\n <h2 class=\"h2 mn-b-medium\">Related Tracks</h2>\n <Feed\n :store=\"{\n read: () => new Promise(resolve => resolve(relatedTracks || [])),\n state: { isLoading: false }\n }\"\n :external=\"true\"\n :items=\"relatedTracks\"\n :states=\"{\n empty: {\n title: 'No related tracks',\n description: 'Check back later for recommendations',\n class: 'pd-medium bg-light radius-medium'\n }\n }\"\n class=\"grid cols-2 cols-m-3 cols-l-4 gap-medium\"\n >\n <template #default=\"{ items }\">\n <div class=\"bg-light radius-medium o-hidden\">\n <TrackListCard\n v-for=\"(relatedTrack, index) in items\"\n :key=\"relatedTrack._id\"\n :track=\"relatedTrack\"\n :index=\"index\"\n :showAlbum=\"true\"\n :showCover=\"true\"\n />\n </div>\n </template>\n </Feed>\n </section>\n\n <!-- Add to Playlist Modal -->\n <Popup \n v-if=\"showAddToPlaylistModal\" \n @close-popup=\"showAddToPlaylistModal = false\" \n class=\"bg-dark pd-medium w-m-25r radius-medium\"\n >\n <h3 class=\"h3 mn-b-medium\">Add to Playlist</h3>\n <!-- <PlaylistSelector \n :trackId=\"track._id\" \n @added=\"showAddToPlaylistModal = false\"\n /> -->\n <p class=\"t-transp\">Playlist selector coming soon...</p>\n </Popup>\n </div>\n</template>\n\n<script setup>\nimport { ref, computed, onMounted, watch } from 'vue';\nimport { useRoute, useRouter } from 'vue-router';\nimport Button from '@martyrs/src/components/Button/Button.vue';\nimport Loader from '@martyrs/src/components/Loader/Loader.vue';\nimport Media from '@martyrs/src/components/Media/Media.vue';\nimport Dropdown from '@martyrs/src/components/Dropdown/Dropdown.vue';\nimport Popup from '@martyrs/src/components/Popup/Popup.vue';\nimport Feed from '@martyrs/src/components/Feed/Feed.vue';\n\n// Icons\nimport IconPlay from '@martyrs/src/modules/icons/navigation/IconPlay.vue';\nimport IconLike from '@martyrs/src/modules/icons/navigation/IconLike.vue';\nimport IconEllipsis from '@martyrs/src/modules/icons/navigation/IconEllipsis.vue';\nimport IconAdd from '@martyrs/src/modules/icons/navigation/IconAdd.vue';\nimport IconClock from '@martyrs/src/modules/icons/entities/IconTime.vue';\nimport IconCalendar from '@martyrs/src/modules/icons/entities/IconCalendar.vue';\nimport IconCheck from '@martyrs/src/modules/icons/navigation/IconCheckmark.vue';\nimport IconEye from '@martyrs/src/modules/icons/actions/IconShow.vue';\nimport IconVerified from '@martyrs/src/modules/icons/navigation/IconCheckmark.vue';\n\n// Components\nimport TrackListCard from '../cards/TrackListCard.vue';\n// import PlaylistSelector from '../forms/PlaylistSelector.vue';\n\n// Store\nimport { state as tracksState, actions as tracksActions } from '../../store/tracks.js';\nimport { actions as playerActions } from '../../store/player.js';\nimport { state as authState } from '@martyrs/src/modules/auth/views/store/auth.js';\n\nconst route = useRoute();\nconst router = useRouter();\n\n// Emits\nconst emits = defineEmits(['page-loading', 'page-loaded']);\n\n// State\nconst hasLoaded = ref(false);\nconst showDropdown = ref(false);\nconst showAddToPlaylistModal = ref(false);\nconst isFavorite = ref(false);\nconst isFollowingArtist = ref(false);\n\n// Clear state\ntracksState.currentTrack = null;\ntracksState.relatedTracks = [];\n\n// Computed\nconst track = computed(() => tracksState.currentTrack);\nconst relatedTracks = computed(() => tracksState.relatedTracks || []);\n\nconst isOwner = computed(() => {\n return track.value?.owner?.target === authState.user?._id;\n});\n\n// Format helpers\nconst formatDuration = (seconds) => {\n if (!seconds) return '0:00';\n const h = Math.floor(seconds / 3600);\n const m = Math.floor((seconds % 3600) / 60);\n const s = Math.floor(seconds % 60);\n \n if (h > 0) {\n return `${h}:${m.toString().padStart(2, '0')}:${s.toString().padStart(2, '0')}`;\n }\n return `${m}:${s.toString().padStart(2, '0')}`;\n};\n\nconst formatDate = (dateString) => {\n if (!dateString) return 'Unknown';\n return new Date(dateString).toLocaleDateString('en-US', {\n year: 'numeric',\n month: 'long',\n day: 'numeric'\n });\n};\n\nconst formatNumber = (num) => {\n if (!num) return '0';\n if (num >= 1000000) {\n return (num / 1000000).toFixed(1) + 'M';\n } else if (num >= 1000) {\n return (num / 1000).toFixed(1) + 'K';\n }\n return num.toString();\n};\n\n// Actions\nconst playTrack = () => {\n if (track.value) {\n playerActions.setQueue([track.value]);\n }\n};\n\nconst toggleFavorite = () => {\n isFavorite.value = !isFavorite.value;\n // TODO: Implement actual saving\n};\n\nconst toggleFollowArtist = () => {\n isFollowingArtist.value = !isFollowingArtist.value;\n // TODO: Implement actual following\n};\n\nconst addToQueue = () => {\n if (track.value) {\n playerActions.addToQueue(track.value);\n }\n};\n\nconst editTrack = () => {\n router.push({ name: 'track-edit', params: { url: track.value.url } });\n};\n\nconst deleteTrack = async () => {\n if (confirm('Are you sure you want to delete this track?')) {\n try {\n await tracksActions.deleteTrack(track.value._id);\n router.push({ name: 'music-library' });\n } catch (error) {\n console.error('Failed to delete track:', error);\n }\n }\n};\n\nconst copyLink = () => {\n navigator.clipboard.writeText(window.location.href);\n showDropdown.value = false;\n};\n\n// Data fetching\nconst fetchTrackData = async () => {\n try {\n await tracksActions.fetchTrackByUrl(route.params.url);\n await tracksActions.fetchRelatedTracks(route.params.url);\n } catch (error) {\n console.error('Error loading track:', error);\n }\n};\n\n// Lifecycle\nonMounted(async () => {\n emits('page-loading');\n \n await fetchTrackData();\n \n hasLoaded.value = true;\n emits('page-loaded');\n});\n</script>\n\n<style scoped>\n</style>"],"names":["tracksState","authState","playerActions","tracksActions"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgVA,UAAM,QAAQ,SAAQ;AACtB,UAAM,SAAS,UAAS;AAGxB,UAAM,QAAQ;AAGd,UAAM,YAAY,IAAI,KAAK;AAC3B,UAAM,eAAe,IAAI,KAAK;AAC9B,UAAM,yBAAyB,IAAI,KAAK;AACxC,UAAM,aAAa,IAAI,KAAK;AAC5B,UAAM,oBAAoB,IAAI,KAAK;AAGnCA,UAAY,eAAe;AAC3BA,UAAY,gBAAgB,CAAA;AAG5B,UAAM,QAAQ,SAAS,MAAMA,MAAY,YAAY;AACrD,UAAM,gBAAgB,SAAS,MAAMA,MAAY,iBAAiB,CAAA,CAAE;AAEpE,UAAM,UAAU,SAAS,MAAM;AAC7B,aAAO,MAAM,OAAO,OAAO,WAAWC,QAAU,MAAM;AAAA,IACxD,CAAC;AAGD,UAAM,iBAAiB,CAAC,YAAY;AAClC,UAAI,CAAC,QAAS,QAAO;AACrB,YAAM,IAAI,KAAK,MAAM,UAAU,IAAI;AACnC,YAAM,IAAI,KAAK,MAAO,UAAU,OAAQ,EAAE;AAC1C,YAAM,IAAI,KAAK,MAAM,UAAU,EAAE;AAEjC,UAAI,IAAI,GAAG;AACT,eAAO,GAAG,CAAC,IAAI,EAAE,SAAQ,EAAG,SAAS,GAAG,GAAG,CAAC,IAAI,EAAE,SAAQ,EAAG,SAAS,GAAG,GAAG,CAAC;AAAA,MAC/E;AACA,aAAO,GAAG,CAAC,IAAI,EAAE,SAAQ,EAAG,SAAS,GAAG,GAAG,CAAC;AAAA,IAC9C;AAEA,UAAM,aAAa,CAAC,eAAe;AACjC,UAAI,CAAC,WAAY,QAAO;AACxB,aAAO,IAAI,KAAK,UAAU,EAAE,mBAAmB,SAAS;AAAA,QACtD,MAAM;AAAA,QACN,OAAO;AAAA,QACP,KAAK;AAAA,MACT,CAAG;AAAA,IACH;AAEA,UAAM,eAAe,CAAC,QAAQ;AAC5B,UAAI,CAAC,IAAK,QAAO;AACjB,UAAI,OAAO,KAAS;AAClB,gBAAQ,MAAM,KAAS,QAAQ,CAAC,IAAI;AAAA,MACtC,WAAW,OAAO,KAAM;AACtB,gBAAQ,MAAM,KAAM,QAAQ,CAAC,IAAI;AAAA,MACnC;AACA,aAAO,IAAI,SAAQ;AAAA,IACrB;AAGA,UAAM,YAAY,MAAM;AACtB,UAAI,MAAM,OAAO;AACfC,kBAAc,SAAS,CAAC,MAAM,KAAK,CAAC;AAAA,MACtC;AAAA,IACF;AAEA,UAAM,iBAAiB,MAAM;AAC3B,iBAAW,QAAQ,CAAC,WAAW;AAAA,IAEjC;AAEA,UAAM,qBAAqB,MAAM;AAC/B,wBAAkB,QAAQ,CAAC,kBAAkB;AAAA,IAE/C;AAEA,UAAM,aAAa,MAAM;AACvB,UAAI,MAAM,OAAO;AACfA,kBAAc,WAAW,MAAM,KAAK;AAAA,MACtC;AAAA,IACF;AAEA,UAAM,YAAY,MAAM;AACtB,aAAO,KAAK,EAAE,MAAM,cAAc,QAAQ,EAAE,KAAK,MAAM,MAAM,IAAG,EAAE,CAAE;AAAA,IACtE;AAEA,UAAM,cAAc,YAAY;AAC9B,UAAI,QAAQ,6CAA6C,GAAG;AAC1D,YAAI;AACF,gBAAMC,QAAc,YAAY,MAAM,MAAM,GAAG;AAC/C,iBAAO,KAAK,EAAE,MAAM,gBAAe,CAAE;AAAA,QACvC,SAAS,OAAO;AACd,kBAAQ,MAAM,2BAA2B,KAAK;AAAA,QAChD;AAAA,MACF;AAAA,IACF;AAEA,UAAM,WAAW,MAAM;AACrB,gBAAU,UAAU,UAAU,OAAO,SAAS,IAAI;AAClD,mBAAa,QAAQ;AAAA,IACvB;AAGA,UAAM,iBAAiB,YAAY;AACjC,UAAI;AACF,cAAMA,QAAc,gBAAgB,MAAM,OAAO,GAAG;AACpD,cAAMA,QAAc,mBAAmB,MAAM,OAAO,GAAG;AAAA,MACzD,SAAS,OAAO;AACd,gBAAQ,MAAM,wBAAwB,KAAK;AAAA,MAC7C;AAAA,IACF;AAGA,cAAU,YAAY;AACpB,YAAM,cAAc;AAEpB,YAAM,eAAc;AAEpB,gBAAU,QAAQ;AAClB,YAAM,aAAa;AAAA,IACrB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}