@ozdao/martyrs 0.2.470 → 0.2.472

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 (284) hide show
  1. package/dist/{Media-CR0V1zvB.js → Media-DW8RLbfM.js} +1 -1
  2. package/dist/{Media-C4Ges_Sd.mjs → Media-y_TX6us_.mjs} +1 -1
  3. package/dist/_virtual/index.cjs +1 -1
  4. package/dist/_virtual/index.js +1 -1
  5. package/dist/auth.server.js +1 -1
  6. package/dist/auth.server.mjs +1 -1
  7. package/dist/chats.server.js +1 -1
  8. package/dist/chats.server.mjs +1 -1
  9. package/dist/community.server.js +1 -1
  10. package/dist/community.server.mjs +1 -1
  11. package/dist/events.server.js +1 -1
  12. package/dist/events.server.mjs +1 -1
  13. package/dist/files.server.js +1 -1
  14. package/dist/files.server.mjs +1 -1
  15. package/dist/gallery.server.js +1 -1
  16. package/dist/gallery.server.mjs +1 -1
  17. package/dist/{index-DQqZReAr.js → index-CVXl1rB5.js} +0 -1
  18. package/dist/{index-DICZTQ-1.mjs → index-Df8vtZx7.mjs} +0 -1
  19. package/dist/{main-CsZAG5Wz.js → main-CCfQH-Dd.js} +2 -2
  20. package/dist/{main-CTcal9qN.mjs → main-CgmHzhq5.mjs} +74 -74
  21. package/dist/{node_modules/.pnpm/@vue_server-renderer@3.5.13_vue@3.5.13_typescript@5.8.3_ → martyrs}/node_modules/@vue/server-renderer/dist/server-renderer.esm-bundler.cjs +1 -1
  22. package/dist/martyrs/node_modules/@vue/server-renderer/dist/server-renderer.esm-bundler.cjs.map +1 -0
  23. package/dist/{node_modules/.pnpm/@vue_server-renderer@3.5.13_vue@3.5.13_typescript@5.8.3_ → martyrs}/node_modules/@vue/server-renderer/dist/server-renderer.esm-bundler.js +1 -1
  24. package/dist/martyrs/node_modules/@vue/server-renderer/dist/server-renderer.esm-bundler.js.map +1 -0
  25. package/dist/martyrs/node_modules/@vue/shared/dist/shared.esm-bundler.cjs.map +1 -0
  26. package/dist/martyrs/node_modules/@vue/shared/dist/shared.esm-bundler.js.map +1 -0
  27. package/dist/martyrs/node_modules/uuid/dist/esm-browser/regex.cjs +5 -0
  28. package/dist/martyrs/node_modules/uuid/dist/esm-browser/regex.cjs.map +1 -0
  29. package/dist/martyrs/node_modules/uuid/dist/esm-browser/regex.js +5 -0
  30. package/dist/martyrs/node_modules/uuid/dist/esm-browser/regex.js.map +1 -0
  31. package/dist/{node_modules/.pnpm/uuid@11.1.0 → martyrs}/node_modules/uuid/dist/esm-browser/rng.cjs +4 -4
  32. package/dist/martyrs/node_modules/uuid/dist/esm-browser/rng.cjs.map +1 -0
  33. package/dist/martyrs/node_modules/uuid/dist/esm-browser/rng.js +15 -0
  34. package/dist/martyrs/node_modules/uuid/dist/esm-browser/rng.js.map +1 -0
  35. package/dist/martyrs/node_modules/uuid/dist/esm-browser/stringify.cjs +17 -0
  36. package/dist/martyrs/node_modules/uuid/dist/esm-browser/stringify.cjs.map +1 -0
  37. package/dist/martyrs/node_modules/uuid/dist/esm-browser/stringify.js +17 -0
  38. package/dist/martyrs/node_modules/uuid/dist/esm-browser/stringify.js.map +1 -0
  39. package/dist/martyrs/node_modules/uuid/dist/esm-browser/v4.cjs +13 -0
  40. package/dist/martyrs/node_modules/uuid/dist/esm-browser/v4.cjs.map +1 -0
  41. package/dist/martyrs/node_modules/uuid/dist/esm-browser/v4.js +13 -0
  42. package/dist/martyrs/node_modules/uuid/dist/esm-browser/v4.js.map +1 -0
  43. package/dist/martyrs/node_modules/uuid/dist/esm-browser/validate.cjs +8 -0
  44. package/dist/martyrs/node_modules/uuid/dist/esm-browser/validate.cjs.map +1 -0
  45. package/dist/martyrs/node_modules/uuid/dist/esm-browser/validate.js +8 -0
  46. package/dist/martyrs/node_modules/uuid/dist/esm-browser/validate.js.map +1 -0
  47. package/dist/martyrs/src/components/Feed/Feed.vue.cjs +2 -2
  48. package/dist/martyrs/src/components/Feed/Feed.vue.cjs.map +1 -1
  49. package/dist/martyrs/src/components/Feed/Feed.vue.js +2 -2
  50. package/dist/martyrs/src/components/Feed/Feed.vue.js.map +1 -1
  51. package/dist/martyrs/src/components/Menu/{Menu.vue.cjs → Menu.vue2.cjs} +2 -2
  52. package/dist/martyrs/src/components/Menu/Menu.vue2.cjs.map +1 -0
  53. package/dist/martyrs/src/components/Menu/{Menu.vue.js → Menu.vue2.js} +2 -2
  54. package/dist/martyrs/src/components/Menu/Menu.vue2.js.map +1 -0
  55. package/dist/martyrs/src/components/Skeleton/Skeleton.vue.cjs +5 -5
  56. package/dist/martyrs/src/components/Skeleton/Skeleton.vue.cjs.map +1 -1
  57. package/dist/martyrs/src/components/Skeleton/Skeleton.vue.js +5 -5
  58. package/dist/martyrs/src/components/Skeleton/Skeleton.vue.js.map +1 -1
  59. package/dist/martyrs/src/components/Tab/{Tab.vue2.cjs → Tab.vue.cjs} +2 -2
  60. package/dist/martyrs/src/components/Tab/{Tab.vue2.js.map → Tab.vue.cjs.map} +1 -1
  61. package/dist/martyrs/src/components/Tab/{Tab.vue2.js → Tab.vue.js} +2 -2
  62. package/dist/martyrs/src/components/Tab/Tab.vue.js.map +1 -0
  63. package/dist/martyrs/src/components/Tree/Tree.vue.cjs +3 -1
  64. package/dist/martyrs/src/components/Tree/Tree.vue.cjs.map +1 -1
  65. package/dist/martyrs/src/components/Tree/Tree.vue.js +3 -1
  66. package/dist/martyrs/src/components/Tree/Tree.vue.js.map +1 -1
  67. package/dist/martyrs/src/modules/auth/views/components/layouts/Auth.vue.cjs +1 -1
  68. package/dist/martyrs/src/modules/auth/views/components/layouts/Auth.vue.js +1 -1
  69. package/dist/martyrs/src/modules/auth/views/components/pages/EnterPassword.vue.cjs +1 -1
  70. package/dist/martyrs/src/modules/auth/views/components/pages/EnterPassword.vue.js +1 -1
  71. package/dist/martyrs/src/modules/auth/views/components/pages/Invite.vue.cjs +1 -1
  72. package/dist/martyrs/src/modules/auth/views/components/pages/Invite.vue.js +1 -1
  73. package/dist/martyrs/src/modules/auth/views/components/pages/Profile.vue.cjs +1 -1
  74. package/dist/martyrs/src/modules/auth/views/components/pages/Profile.vue.js +1 -1
  75. package/dist/martyrs/src/modules/auth/views/components/pages/ProfileBlogposts.vue.cjs +1 -1
  76. package/dist/martyrs/src/modules/auth/views/components/pages/ProfileBlogposts.vue.js +1 -1
  77. package/dist/martyrs/src/modules/auth/views/components/pages/ProfileEdit.vue.cjs +1 -1
  78. package/dist/martyrs/src/modules/auth/views/components/pages/ProfileEdit.vue.js +1 -1
  79. package/dist/martyrs/src/modules/auth/views/components/pages/ResetPassword.vue.cjs +1 -1
  80. package/dist/martyrs/src/modules/auth/views/components/pages/ResetPassword.vue.js +1 -1
  81. package/dist/martyrs/src/modules/auth/views/components/pages/SignIn.vue.cjs +1 -1
  82. package/dist/martyrs/src/modules/auth/views/components/pages/SignIn.vue.js +1 -1
  83. package/dist/martyrs/src/modules/auth/views/components/pages/SignUp.vue.cjs +1 -1
  84. package/dist/martyrs/src/modules/auth/views/components/pages/SignUp.vue.js +1 -1
  85. package/dist/martyrs/src/modules/auth/views/store/auth.cjs +1 -0
  86. package/dist/martyrs/src/modules/auth/views/store/auth.cjs.map +1 -1
  87. package/dist/martyrs/src/modules/auth/views/store/auth.js +1 -0
  88. package/dist/martyrs/src/modules/auth/views/store/auth.js.map +1 -1
  89. package/dist/martyrs/src/modules/constructor/components/sections/Constructor.vue.cjs +1 -1
  90. package/dist/martyrs/src/modules/constructor/components/sections/Constructor.vue.js +1 -1
  91. package/dist/martyrs/src/modules/events/components/pages/EventsBackoffice.vue.cjs +1 -1
  92. package/dist/martyrs/src/modules/events/components/pages/EventsBackoffice.vue.js +1 -1
  93. package/dist/martyrs/src/modules/globals/views/classes/globals.store.cjs +107 -21
  94. package/dist/martyrs/src/modules/globals/views/classes/globals.store.cjs.map +1 -1
  95. package/dist/martyrs/src/modules/globals/views/classes/globals.store.js +107 -21
  96. package/dist/martyrs/src/modules/globals/views/classes/globals.store.js.map +1 -1
  97. package/dist/martyrs/src/modules/globals/views/components/partials/Navigation.vue.cjs +10 -14
  98. package/dist/martyrs/src/modules/globals/views/components/partials/Navigation.vue.cjs.map +1 -1
  99. package/dist/martyrs/src/modules/globals/views/components/partials/Navigation.vue.js +12 -16
  100. package/dist/martyrs/src/modules/globals/views/components/partials/Navigation.vue.js.map +1 -1
  101. package/dist/martyrs/src/modules/globals/views/components/sections/SectionPageTitle.vue.cjs +1 -1
  102. package/dist/martyrs/src/modules/globals/views/components/sections/SectionPageTitle.vue.js +1 -1
  103. package/dist/martyrs/src/modules/globals/views/utils/vue-app-renderer.cjs +7 -13
  104. package/dist/martyrs/src/modules/globals/views/utils/vue-app-renderer.cjs.map +1 -1
  105. package/dist/martyrs/src/modules/globals/views/utils/vue-app-renderer.js +7 -13
  106. package/dist/martyrs/src/modules/globals/views/utils/vue-app-renderer.js.map +1 -1
  107. package/dist/martyrs/src/modules/orders/components/pages/OrderCreate.vue.cjs +6 -7
  108. package/dist/martyrs/src/modules/orders/components/pages/OrderCreate.vue.cjs.map +1 -1
  109. package/dist/martyrs/src/modules/orders/components/pages/OrderCreate.vue.js +7 -8
  110. package/dist/martyrs/src/modules/orders/components/pages/OrderCreate.vue.js.map +1 -1
  111. package/dist/martyrs/src/modules/orders/components/pages/OrderCreateBackoffice.vue.cjs +1 -1
  112. package/dist/martyrs/src/modules/orders/components/pages/OrderCreateBackoffice.vue.js +1 -1
  113. package/dist/martyrs/src/modules/orders/components/pages/Orders.vue.cjs +1 -1
  114. package/dist/martyrs/src/modules/orders/components/pages/Orders.vue.js +1 -1
  115. package/dist/martyrs/src/modules/organizations/components/pages/DepartmentEdit.vue.cjs +1 -1
  116. package/dist/martyrs/src/modules/organizations/components/pages/DepartmentEdit.vue.js +1 -1
  117. package/dist/martyrs/src/modules/organizations/components/pages/Members.vue.cjs +2 -2
  118. package/dist/martyrs/src/modules/organizations/components/pages/Members.vue.js +2 -2
  119. package/dist/martyrs/src/modules/organizations/components/pages/Organization.vue.cjs +2 -2
  120. package/dist/martyrs/src/modules/organizations/components/pages/Organization.vue.js +2 -2
  121. package/dist/martyrs/src/modules/organizations/components/pages/OrganizationBackoffice.vue.cjs +1 -1
  122. package/dist/martyrs/src/modules/organizations/components/pages/OrganizationBackoffice.vue.js +1 -1
  123. package/dist/martyrs/src/modules/organizations/components/pages/OrganizationEdit.vue.cjs +1 -1
  124. package/dist/martyrs/src/modules/organizations/components/pages/OrganizationEdit.vue.js +1 -1
  125. package/dist/martyrs/src/modules/organizations/components/pages/Organizations.vue.cjs +1 -1
  126. package/dist/martyrs/src/modules/organizations/components/pages/Organizations.vue.js +1 -1
  127. package/dist/martyrs/src/modules/organizations/components/sections/Organizations.vue.cjs +1 -1
  128. package/dist/martyrs/src/modules/organizations/components/sections/Organizations.vue.js +1 -1
  129. package/dist/martyrs/src/modules/products/components/blocks/CardCategory.vue.cjs +11 -5
  130. package/dist/martyrs/src/modules/products/components/blocks/CardCategory.vue.cjs.map +1 -1
  131. package/dist/martyrs/src/modules/products/components/blocks/CardCategory.vue.js +12 -6
  132. package/dist/martyrs/src/modules/products/components/blocks/CardCategory.vue.js.map +1 -1
  133. package/dist/martyrs/src/modules/products/components/pages/Categories.vue.cjs +34 -13
  134. package/dist/martyrs/src/modules/products/components/pages/Categories.vue.cjs.map +1 -1
  135. package/dist/martyrs/src/modules/products/components/pages/Categories.vue.js +35 -14
  136. package/dist/martyrs/src/modules/products/components/pages/Categories.vue.js.map +1 -1
  137. package/dist/martyrs/src/modules/products/components/pages/CategoryEdit.vue.cjs +20 -9
  138. package/dist/martyrs/src/modules/products/components/pages/CategoryEdit.vue.cjs.map +1 -1
  139. package/dist/martyrs/src/modules/products/components/pages/CategoryEdit.vue.js +21 -10
  140. package/dist/martyrs/src/modules/products/components/pages/CategoryEdit.vue.js.map +1 -1
  141. package/dist/martyrs/src/modules/products/components/pages/Leftovers.vue.cjs +1 -1
  142. package/dist/martyrs/src/modules/products/components/pages/Leftovers.vue.js +1 -1
  143. package/dist/martyrs/src/modules/products/components/pages/Product.vue.cjs +1 -1
  144. package/dist/martyrs/src/modules/products/components/pages/Product.vue.js +1 -1
  145. package/dist/martyrs/src/modules/products/components/pages/ProductEdit.vue.cjs +2 -1
  146. package/dist/martyrs/src/modules/products/components/pages/ProductEdit.vue.cjs.map +1 -1
  147. package/dist/martyrs/src/modules/products/components/pages/ProductEdit.vue.js +2 -1
  148. package/dist/martyrs/src/modules/products/components/pages/ProductEdit.vue.js.map +1 -1
  149. package/dist/martyrs/src/modules/products/components/pages/Products.vue.cjs +1 -1
  150. package/dist/martyrs/src/modules/products/components/pages/Products.vue.js +1 -1
  151. package/dist/martyrs/src/modules/products/components/sections/SectionProduct.vue.cjs +1 -1
  152. package/dist/martyrs/src/modules/products/components/sections/SectionProduct.vue.js +1 -1
  153. package/dist/martyrs/src/modules/rents/views/components/pages/GanttChart.vue.cjs +1 -1
  154. package/dist/martyrs/src/modules/rents/views/components/pages/GanttChart.vue.js +1 -1
  155. package/dist/martyrs/src/modules/rents/views/components/pages/Rents.vue.cjs +1 -1
  156. package/dist/martyrs/src/modules/rents/views/components/pages/Rents.vue.js +1 -1
  157. package/dist/martyrs/src/modules/spots/components/pages/SpotEdit.vue.cjs +1 -1
  158. package/dist/martyrs/src/modules/spots/components/pages/SpotEdit.vue.js +1 -1
  159. package/dist/martyrs.cjs.js +1 -1
  160. package/dist/martyrs.css +1 -1
  161. package/dist/martyrs.es.js +1 -1
  162. package/dist/notifications.server.js +35 -2
  163. package/dist/notifications.server.mjs +35 -2
  164. package/dist/orders.server.js +3 -3
  165. package/dist/orders.server.mjs +3 -3
  166. package/dist/organizations.server.js +1 -1
  167. package/dist/organizations.server.mjs +1 -1
  168. package/dist/products.server.js +78 -53
  169. package/dist/products.server.mjs +78 -53
  170. package/dist/rents.server.js +1 -1
  171. package/dist/rents.server.mjs +1 -1
  172. package/dist/style.css +37 -38
  173. package/dist/wallet.server.js +1 -1
  174. package/dist/wallet.server.mjs +1 -1
  175. package/package.json +2 -1
  176. package/src/components/Feed/Feed.vue +2 -7
  177. package/src/components/Skeleton/Skeleton.vue +4 -5
  178. package/src/components/Tree/Tree.vue +5 -2
  179. package/src/modules/auth/controllers/middlewares/authJwt.js +1 -1
  180. package/src/modules/auth/views/store/auth.js +2 -1
  181. package/src/modules/globals/controllers/classes/globals.crud.js +2 -2
  182. package/src/modules/globals/views/classes/globals.store.js +119 -31
  183. package/src/modules/globals/views/components/partials/Navigation.vue +11 -10
  184. package/src/modules/globals/views/utils/vue-app-renderer.js +7 -16
  185. package/src/modules/icons/entities/IconMusic.vue +14 -0
  186. package/src/modules/icons/navigation/IconCheck.vue +31 -0
  187. package/src/modules/icons/navigation/IconHeart.vue +26 -0
  188. package/src/modules/icons/navigation/IconPause.vue +31 -0
  189. package/src/modules/icons/navigation/IconPlay.vue +17 -0
  190. package/src/modules/icons/navigation/IconRefresh.vue +31 -0
  191. package/src/modules/icons/navigation/IconShuffle.vue +31 -0
  192. package/src/modules/icons/navigation/IconVolume.vue +31 -0
  193. package/src/modules/music/components/SidebarMusic.vue +156 -0
  194. package/src/modules/music/components/cards/AlbumCard.vue +107 -0
  195. package/src/modules/music/components/cards/ArtistCard.vue +37 -0
  196. package/src/modules/music/components/cards/PlaylistCard.vue +100 -0
  197. package/src/modules/music/components/cards/TrackCard.vue +86 -0
  198. package/src/modules/music/components/forms/PlaylistForm.vue +156 -0
  199. package/src/modules/music/components/forms/SearchForm.vue +82 -0
  200. package/src/modules/music/components/forms/UploadForm.vue +313 -0
  201. package/src/modules/music/components/layouts/MusicLayout.vue +137 -0
  202. package/src/modules/music/components/lists/AlbumList.vue +25 -0
  203. package/src/modules/music/components/lists/ArtistList.vue +25 -0
  204. package/src/modules/music/components/lists/PlaylistList.vue +25 -0
  205. package/src/modules/music/components/lists/TrackList.vue +175 -0
  206. package/src/modules/music/components/pages/AlbumDetail.vue +265 -0
  207. package/src/modules/music/components/pages/ArtistDetail.vue +247 -0
  208. package/src/modules/music/components/pages/MusicHome.vue +177 -0
  209. package/src/modules/music/components/pages/MusicLibrary.vue +192 -0
  210. package/src/modules/music/components/pages/MusicUpload.vue +44 -0
  211. package/src/modules/music/components/pages/PlaylistDetail.vue +504 -0
  212. package/src/modules/music/components/pages/SearchResults.vue +397 -0
  213. package/src/modules/music/components/pages/TrackDetail.vue +143 -0
  214. package/src/modules/music/components/player/MusicPlayer.vue +202 -0
  215. package/src/modules/music/components/player/TrackProgress.vue +110 -0
  216. package/src/modules/music/components/player/VolumeControl.vue +98 -0
  217. package/src/modules/music/controllers/album.controller.js +98 -0
  218. package/src/modules/music/controllers/artist.controller.js +111 -0
  219. package/src/modules/music/controllers/genre.controller.js +71 -0
  220. package/src/modules/music/controllers/music.controller.js +174 -0
  221. package/src/modules/music/controllers/playlist.controller.js +182 -0
  222. package/src/modules/music/controllers/search.controller.js +103 -0
  223. package/src/modules/music/controllers/stream.controller.js +106 -0
  224. package/src/modules/music/models/album.model.js +61 -0
  225. package/src/modules/music/models/artist.model.js +67 -0
  226. package/src/modules/music/models/genre.model.js +42 -0
  227. package/src/modules/music/models/play-history.model.js +51 -0
  228. package/src/modules/music/models/playlist.model.js +69 -0
  229. package/src/modules/music/models/track.model.js +94 -0
  230. package/src/modules/music/music.client.js +186 -0
  231. package/src/modules/music/music.server.js +114 -0
  232. package/src/modules/music/policies/music.policies.js +84 -0
  233. package/src/modules/music/router/music.js +77 -0
  234. package/src/modules/music/routes/album.routes.js +62 -0
  235. package/src/modules/music/routes/artist.routes.js +67 -0
  236. package/src/modules/music/routes/genre.routes.js +60 -0
  237. package/src/modules/music/routes/music.routes.js +145 -0
  238. package/src/modules/music/routes/playlist.routes.js +99 -0
  239. package/src/modules/music/routes/search.routes.js +10 -0
  240. package/src/modules/music/routes/stream.routes.js +38 -0
  241. package/src/modules/music/store/albums.js +200 -0
  242. package/src/modules/music/store/artists.js +180 -0
  243. package/src/modules/music/store/player.js +397 -0
  244. package/src/modules/music/store/playlists.js +211 -0
  245. package/src/modules/music/store/search.js +126 -0
  246. package/src/modules/music/store/tracks.js +230 -0
  247. package/src/modules/music/websocket/streaming.handler.js +151 -0
  248. package/src/modules/notifications/controllers/notifications.controller.js +44 -1
  249. package/src/modules/notifications/notifications.server.js +0 -1
  250. package/src/modules/notifications/routes/notifications.routes.js +3 -0
  251. package/src/modules/orders/components/pages/OrderCreate.vue +0 -2
  252. package/src/modules/products/components/blocks/CardCategory.vue +5 -4
  253. package/src/modules/products/components/pages/Categories.vue +38 -20
  254. package/src/modules/products/components/pages/CategoryEdit.vue +16 -7
  255. package/src/modules/products/components/pages/ProductEdit.vue +1 -0
  256. package/src/modules/products/controllers/categories.controller.js +155 -103
  257. package/dist/martyrs/src/components/Menu/Menu.vue.cjs.map +0 -1
  258. package/dist/martyrs/src/components/Menu/Menu.vue.js.map +0 -1
  259. package/dist/martyrs/src/components/Tab/Tab.vue2.cjs.map +0 -1
  260. package/dist/node_modules/.pnpm/@vue_server-renderer@3.5.13_vue@3.5.13_typescript@5.8.3_/node_modules/@vue/server-renderer/dist/server-renderer.esm-bundler.cjs.map +0 -1
  261. package/dist/node_modules/.pnpm/@vue_server-renderer@3.5.13_vue@3.5.13_typescript@5.8.3_/node_modules/@vue/server-renderer/dist/server-renderer.esm-bundler.js.map +0 -1
  262. package/dist/node_modules/.pnpm/@vue_shared@3.5.13/node_modules/@vue/shared/dist/shared.esm-bundler.cjs.map +0 -1
  263. package/dist/node_modules/.pnpm/@vue_shared@3.5.13/node_modules/@vue/shared/dist/shared.esm-bundler.js.map +0 -1
  264. package/dist/node_modules/.pnpm/uuid@11.1.0/node_modules/uuid/dist/esm-browser/native.cjs +0 -6
  265. package/dist/node_modules/.pnpm/uuid@11.1.0/node_modules/uuid/dist/esm-browser/native.cjs.map +0 -1
  266. package/dist/node_modules/.pnpm/uuid@11.1.0/node_modules/uuid/dist/esm-browser/native.js +0 -6
  267. package/dist/node_modules/.pnpm/uuid@11.1.0/node_modules/uuid/dist/esm-browser/native.js.map +0 -1
  268. package/dist/node_modules/.pnpm/uuid@11.1.0/node_modules/uuid/dist/esm-browser/rng.cjs.map +0 -1
  269. package/dist/node_modules/.pnpm/uuid@11.1.0/node_modules/uuid/dist/esm-browser/rng.js +0 -15
  270. package/dist/node_modules/.pnpm/uuid@11.1.0/node_modules/uuid/dist/esm-browser/rng.js.map +0 -1
  271. package/dist/node_modules/.pnpm/uuid@11.1.0/node_modules/uuid/dist/esm-browser/stringify.cjs +0 -11
  272. package/dist/node_modules/.pnpm/uuid@11.1.0/node_modules/uuid/dist/esm-browser/stringify.cjs.map +0 -1
  273. package/dist/node_modules/.pnpm/uuid@11.1.0/node_modules/uuid/dist/esm-browser/stringify.js +0 -11
  274. package/dist/node_modules/.pnpm/uuid@11.1.0/node_modules/uuid/dist/esm-browser/stringify.js.map +0 -1
  275. package/dist/node_modules/.pnpm/uuid@11.1.0/node_modules/uuid/dist/esm-browser/v4.cjs +0 -21
  276. package/dist/node_modules/.pnpm/uuid@11.1.0/node_modules/uuid/dist/esm-browser/v4.cjs.map +0 -1
  277. package/dist/node_modules/.pnpm/uuid@11.1.0/node_modules/uuid/dist/esm-browser/v4.js +0 -21
  278. package/dist/node_modules/.pnpm/uuid@11.1.0/node_modules/uuid/dist/esm-browser/v4.js.map +0 -1
  279. /package/dist/{node_modules/.pnpm/@vue_shared@3.5.13 → martyrs}/node_modules/@vue/shared/dist/shared.esm-bundler.cjs +0 -0
  280. /package/dist/{node_modules/.pnpm/@vue_shared@3.5.13 → martyrs}/node_modules/@vue/shared/dist/shared.esm-bundler.js +0 -0
  281. /package/dist/{node_modules → martyrs/node_modules}/fast-deep-equal/index.cjs +0 -0
  282. /package/dist/{node_modules → martyrs/node_modules}/fast-deep-equal/index.cjs.map +0 -0
  283. /package/dist/{node_modules → martyrs/node_modules}/fast-deep-equal/index.js +0 -0
  284. /package/dist/{node_modules → martyrs/node_modules}/fast-deep-equal/index.js.map +0 -0
@@ -0,0 +1,175 @@
1
+ <!-- components/lists/TrackList.vue (continued) -->
2
+ <template>
3
+ <div class="track-list w-100">
4
+ <div
5
+ v-if="showHeader"
6
+ class="track-list-header pd-small br-b br-solid br-dark-transp-20 t-grey flex-v-center flex"
7
+ >
8
+ <div class="track-number w-3r t-center">#</div>
9
+ <div class="track-title flex-child-1">TITLE</div>
10
+ <div v-if="showAlbum" class="track-album w-15r mobile:w-0 mobile:hidden">ALBUM</div>
11
+ <div class="track-duration w-5r t-right">DURATION</div>
12
+ </div>
13
+
14
+ <div class="track-list-body">
15
+ <div
16
+ v-for="(track, index) in tracks"
17
+ :key="track._id"
18
+ class="track-item pd-small hover-bg-dark-transp-25 flex-v-center flex cursor-pointer"
19
+ :class="{'bg-dark-transp-25': isPlaying(track)}"
20
+ @click="playTrack(track)"
21
+ @dblclick="playTrack(track, true)"
22
+ @mouseenter="hoveredIndex = index"
23
+ @mouseleave="hoveredIndex = -1"
24
+ >
25
+ <div class="track-number w-3r t-center pos-relative">
26
+ <span v-if="!isPlaying(track) && hoveredIndex !== index" class="t-grey">{{ index + 1 }}</span>
27
+ <Button
28
+ v-else-if="!isPlaying(track) && hoveredIndex === index"
29
+ @click.stop="playTrack(track)"
30
+ class="bg-transparent border-none pd-zero"
31
+ :showLoader="false"
32
+ :showSucces="false"
33
+ >
34
+ <IconPlay class="i-small" fill="rgb(var(--white))"/>
35
+ </Button>
36
+ <Button
37
+ v-else
38
+ @click.stop="pauseTrack()"
39
+ class="bg-transparent border-none pd-zero"
40
+ :showLoader="false"
41
+ :showSucces="false"
42
+ >
43
+ <IconPause class="i-small" fill="rgb(var(--main))"/>
44
+ </Button>
45
+ </div>
46
+
47
+ <div class="track-title flex-child-1 flex flex-v-center">
48
+ <div v-if="showCover" class="track-cover mn-r-small">
49
+ <Media
50
+ :url="track.coverUrl || (track.album && track.album.coverUrl) || '/assets/placeholder-track.jpg'"
51
+ class="w-3r h-3r object-fit-cover radius-small"
52
+ />
53
+ </div>
54
+
55
+ <div class="track-info">
56
+ <div class="track-name t-white" :class="{'t-main': isPlaying(track)}">{{ track.title }}</div>
57
+ <div class="track-artist t-grey t-small">
58
+ <router-link
59
+ v-if="track.artist && track.artist._id"
60
+ :to="{ name: 'artist-detail', params: { url: track.artist.url } }"
61
+ class="t-grey hover-t-white"
62
+ @click.stop
63
+ >
64
+ {{ getArtistName(track) }}
65
+ </router-link>
66
+ <span v-else>{{ getArtistName(track) }}</span>
67
+ </div>
68
+ </div>
69
+ </div>
70
+
71
+ <div v-if="showAlbum" class="track-album w-15r mobile:w-0 mobile:hidden t-grey t-truncate">
72
+ <router-link
73
+ v-if="track.album && track.album._id"
74
+ :to="{ name: 'album-detail', params: { url: track.album.url } }"
75
+ class="t-grey hover-t-white"
76
+ @click.stop
77
+ >
78
+ {{ track.album.title }}
79
+ </router-link>
80
+ <span v-else>{{ track.album?.title || 'Single' }}</span>
81
+ </div>
82
+
83
+ <div class="track-duration w-5r t-right t-grey">{{ formatDuration(track.duration) }}</div>
84
+ </div>
85
+ </div>
86
+ </div>
87
+ </template>
88
+
89
+ <script setup>
90
+ import { ref, computed } from 'vue';
91
+ import Media from '@martyrs/src/components/Media/Media.vue';
92
+ import Button from '@martyrs/src/components/Button/Button.vue';
93
+ import IconPlay from '@martyrs/src/modules/icons/navigation/IconPlay.vue';
94
+ import IconPause from '@martyrs/src/modules/icons/navigation/IconPause.vue';
95
+
96
+ // Import player store
97
+ import { state as playerState, actions as playerActions } from '../../store/player.js';
98
+
99
+ const props = defineProps({
100
+ tracks: {
101
+ type: Array,
102
+ required: true
103
+ },
104
+ showHeader: {
105
+ type: Boolean,
106
+ default: true
107
+ },
108
+ showAlbum: {
109
+ type: Boolean,
110
+ default: false
111
+ },
112
+ showCover: {
113
+ type: Boolean,
114
+ default: false
115
+ },
116
+ showIndex: {
117
+ type: Boolean,
118
+ default: true
119
+ }
120
+ });
121
+
122
+ // State
123
+ const hoveredIndex = ref(-1);
124
+
125
+ // Computed
126
+ const currentTrack = computed(() => playerState.currentTrack);
127
+
128
+ // Methods
129
+ const isPlaying = (track) => {
130
+ return currentTrack.value && currentTrack.value._id === track._id && isPlaying.value;
131
+ };
132
+
133
+ const isHovering = (index) => {
134
+ return hoveredIndex.value === index;
135
+ };
136
+
137
+ const playTrack = (track, addToQueue = false) => {
138
+ if (addToQueue) {
139
+ playerActions.addToQueue(track);
140
+ } else {
141
+ // Find track index to set queue properly
142
+ const trackIndex = props.tracks.findIndex(t => t._id === track._id);
143
+ playerActions.setQueue([...props.tracks], trackIndex);
144
+ }
145
+ };
146
+
147
+ const pauseTrack = () => {
148
+ playerActions.togglePlay();
149
+ };
150
+
151
+ const getArtistName = (track) => {
152
+ if (track.artist) {
153
+ if (typeof track.artist === 'object') {
154
+ return track.artist.name || 'Unknown Artist';
155
+ }
156
+ return track.artist;
157
+ }
158
+ return 'Unknown Artist';
159
+ };
160
+
161
+ const formatDuration = (seconds) => {
162
+ if (!seconds) return '0:00';
163
+
164
+ const minutes = Math.floor(seconds / 60);
165
+ const remainingSeconds = Math.floor(seconds % 60);
166
+
167
+ return `${minutes}:${remainingSeconds.toString().padStart(2, '0')}`;
168
+ };
169
+ </script>
170
+
171
+ <style scoped>
172
+ .track-item {
173
+ transition: background-color 0.2s ease;
174
+ }
175
+ </style>
@@ -0,0 +1,265 @@
1
+ <!-- components/pages/AlbumDetail.vue -->
2
+ <template>
3
+ <div class="album-detail-page">
4
+ <div v-if="isLoading" class="w-100 h-25r flex-center flex">
5
+ <Loader />
6
+ </div>
7
+
8
+ <div v-else-if="!album" class="t-center pd-big">
9
+ <h2 class="t-white">Album not found</h2>
10
+ <p class="t-grey t-medium">The album you're looking for doesn't exist or has been removed.</p>
11
+ </div>
12
+
13
+ <div v-else>
14
+ <!-- Album Header -->
15
+ <div class="album-header mn-b-medium flex flex-v-center gap-medium">
16
+ <div class="album-cover">
17
+ <Media
18
+ :url="album.coverUrl || '/assets/placeholder-album.jpg'"
19
+ class="w-15r h-15r object-fit-cover shadow-lg radius-small"
20
+ />
21
+ </div>
22
+
23
+ <div class="album-info">
24
+ <div class="t-small t-uppercase t-white">Album</div>
25
+ <h1 class="t-white">{{ album.title }}</h1>
26
+
27
+ <div class="album-meta mn-t-small flex flex-v-center">
28
+ <router-link
29
+ v-if="album.artist && album.artist._id"
30
+ :to="{ name: 'artist-detail', params: { url: album.artist.url } }"
31
+ class="t-white t-medium hover-t-main"
32
+ >
33
+ {{ getArtistName(album) }}
34
+ </router-link>
35
+ <span v-else class="t-white t-medium">{{ getArtistName(album) }}</span>
36
+
37
+ <span class="t-grey mn-l-small mn-r-small">•</span>
38
+
39
+ <span class="t-grey">{{ formatReleaseYear(album.releaseDate) }}</span>
40
+
41
+ <span class="t-grey mn-l-small mn-r-small">•</span>
42
+
43
+ <span class="t-grey">{{ albumTracks.length }} {{ albumTracks.length === 1 ? 'song' : 'songs' }}</span>
44
+ </div>
45
+ </div>
46
+ </div>
47
+
48
+ <!-- Album Actions -->
49
+ <div class="album-actions mn-b-medium flex flex-v-center gap-small">
50
+ <Button
51
+ @click="playAlbum"
52
+ class="play-button bg-main radius-round pd-small flex-v-center flex gap-small hover-scale-1"
53
+ :showLoader="false"
54
+ :showSucces="false"
55
+ >
56
+ <IconPlay class="i-small" fill="rgb(var(--black))"/>
57
+ <span class="t-black t-medium">Play</span>
58
+ </Button>
59
+
60
+ <Button
61
+ @click="toggleFavorite"
62
+ class="bg-transparent border-none pd-zero"
63
+ :showLoader="false"
64
+ :showSucces="false"
65
+ >
66
+ <IconHeart class="i-medium" :fill="isFavorite ? 'rgb(var(--main))' : 'rgb(var(--white))'"/>
67
+ </Button>
68
+
69
+ <Dropdown class="pos-relative">
70
+ <Button
71
+ @click="showDropdown = !showDropdown"
72
+ class="bg-transparent border-none pd-zero"
73
+ :showLoader="false"
74
+ :showSucces="false"
75
+ >
76
+ <IconEllipsis class="i-medium" fill="rgb(var(--white))"/>
77
+ </Button>
78
+
79
+ <template #content>
80
+ <ul v-if="showDropdown" class="pd-small bg-dark radius-small pos-absolute pos-t-100 pos-r-0 z-index-3 w-max-15r mn-t-thin">
81
+ <li class="mn-b-thin">
82
+ <Button
83
+ @click="addToQueue"
84
+ class="bg-transparent border-none pd-thin t-white w-100 t-left hover-bg-dark radius-small"
85
+ :showLoader="false"
86
+ :showSucces="false"
87
+ >
88
+ <span>Add to Queue</span>
89
+ </Button>
90
+ </li>
91
+ <li>
92
+ <Button
93
+ @click="copyLink"
94
+ class="bg-transparent border-none pd-thin t-white w-100 t-left hover-bg-dark radius-small"
95
+ :showLoader="false"
96
+ :showSucces="false"
97
+ >
98
+ <span>Copy Link</span>
99
+ </Button>
100
+ </li>
101
+ </ul>
102
+ </template>
103
+ </Dropdown>
104
+ </div>
105
+
106
+ <!-- Album Tracks -->
107
+ <div class="album-tracks">
108
+ <TrackList
109
+ :tracks="albumTracks"
110
+ :showAlbum="false"
111
+ :showCover="false"
112
+ class="bg-dark-transp-10 radius-medium o-hidden"
113
+ />
114
+ </div>
115
+
116
+ <!-- Album Info -->
117
+ <div v-if="album.description" class="album-description mn-t-medium pd-medium bg-dark-transp-10 radius-medium">
118
+ <h3 class="t-white mn-b-small">About</h3>
119
+ <p class="t-grey">{{ album.description }}</p>
120
+ </div>
121
+
122
+ <!-- More from this artist if available -->
123
+ <div v-if="moreFromArtist.length > 0" class="more-from-artist mn-t-medium">
124
+ <div class="flex-between flex mn-b-small">
125
+ <h2 class="t-white">More by {{ getArtistName(album) }}</h2>
126
+ <router-link
127
+ v-if="album.artist && album.artist._id"
128
+ :to="{ name: 'artist-detail', params: { url: album.artist.url } }"
129
+ class="t-main t-small hover-opacity"
130
+ >
131
+ See all
132
+ </router-link>
133
+ </div>
134
+
135
+ <div class="albums-grid cols-5 mobile:cols-2 gap-small">
136
+ <div v-for="relatedAlbum in moreFromArtist" :key="relatedAlbum._id">
137
+ <AlbumCard :album="relatedAlbum" />
138
+ </div>
139
+ </div>
140
+ </div>
141
+ </div>
142
+ </div>
143
+ </template>
144
+
145
+ <script setup>
146
+ import { ref, computed, onMounted, watch } from 'vue';
147
+ import { useRoute, useRouter } from 'vue-router';
148
+ import TrackList from '../lists/TrackList.vue';
149
+ import AlbumCard from '../cards/AlbumCard.vue';
150
+ import Button from '@martyrs/src/components/Button/Button.vue';
151
+ import Loader from '@martyrs/src/components/Loader/Loader.vue';
152
+ import Media from '@martyrs/src/components/Media/Media.vue';
153
+ import Dropdown from '@martyrs/src/components/Dropdown/Dropdown.vue';
154
+
155
+ // Import icons
156
+ import IconPlay from '@martyrs/src/modules/icons/navigation/IconPlay.vue';
157
+ import IconHeart from '@martyrs/src/modules/icons/navigation/IconHeart.vue';
158
+ import IconEllipsis from '@martyrs/src/modules/icons/navigation/IconEllipsis.vue';
159
+
160
+ // Import store modules
161
+ import { state as albumsState, actions as albumsActions } from '../../store/albums.js';
162
+ import { actions as playerActions } from '../../store/player.js';
163
+
164
+ const route = useRoute();
165
+ const router = useRouter();
166
+
167
+ // State
168
+ const isLoading = ref(true);
169
+ const isFavorite = ref(false);
170
+ const showDropdown = ref(false);
171
+ const moreFromArtist = ref([]);
172
+
173
+ // Computed properties
174
+ const album = computed(() => albumsState.currentAlbum);
175
+ const albumTracks = computed(() => albumsState.currentAlbumTracks);
176
+
177
+ // Methods
178
+ const getArtistName = (albumItem) => {
179
+ if (!albumItem) return 'Unknown Artist';
180
+
181
+ if (albumItem.artist) {
182
+ if (typeof albumItem.artist === 'object') {
183
+ return albumItem.artist.name || 'Unknown Artist';
184
+ }
185
+ return albumItem.artist;
186
+ }
187
+ return 'Unknown Artist';
188
+ };
189
+
190
+ const formatReleaseYear = (dateString) => {
191
+ if (!dateString) return '';
192
+ return new Date(dateString).getFullYear();
193
+ };
194
+
195
+ const playAlbum = () => {
196
+ if (albumTracks.value && albumTracks.value.length > 0) {
197
+ playerActions.setQueue(albumTracks.value);
198
+ }
199
+ };
200
+
201
+ const toggleFavorite = () => {
202
+ isFavorite.value = !isFavorite.value;
203
+ // Implement favorite album logic here
204
+ };
205
+
206
+ const addToQueue = () => {
207
+ if (albumTracks.value && albumTracks.value.length > 0) {
208
+ // Add all tracks to queue
209
+ albumTracks.value.forEach(track => {
210
+ playerActions.addToQueue(track);
211
+ });
212
+
213
+ showDropdown.value = false;
214
+ }
215
+ };
216
+
217
+ const copyLink = () => {
218
+ const url = window.location.href;
219
+ navigator.clipboard.writeText(url).then(() => {
220
+ // Could show a success notification here
221
+ showDropdown.value = false;
222
+ });
223
+ };
224
+
225
+ const fetchAlbumData = async () => {
226
+ isLoading.value = true;
227
+
228
+ try {
229
+ // Fetch album data
230
+ await albumsActions.fetchAlbumByUrl(route.params.url);
231
+
232
+ // If artist is available, fetch more albums from the same artist
233
+ if (album.value?.artist?._id) {
234
+ const artistAlbums = await albumsActions.fetchAlbums({
235
+ artist: album.value.artist._id,
236
+ status: 'published',
237
+ isPublic: true,
238
+ limit: 5
239
+ });
240
+
241
+ // Filter out the current album
242
+ moreFromArtist.value = artistAlbums.filter(a => a._id !== album.value._id);
243
+ }
244
+ } catch (error) {
245
+ console.error('Error fetching album data:', error);
246
+ } finally {
247
+ isLoading.value = false;
248
+ }
249
+ };
250
+
251
+ // Fetch data when component mounts or URL changes
252
+ onMounted(fetchAlbumData);
253
+
254
+ watch(() => route.params.url, (newUrl) => {
255
+ if (newUrl) {
256
+ fetchAlbumData();
257
+ }
258
+ });
259
+ </script>
260
+
261
+ <style scoped>
262
+ .album-cover {
263
+ box-shadow: 0 4px 60px rgba(0, 0, 0, 0.5);
264
+ }
265
+ </style>
@@ -0,0 +1,247 @@
1
+ <!-- components/pages/ArtistDetail.vue -->
2
+ <template>
3
+ <div class="artist-detail-page">
4
+ <div v-if="isLoading" class="w-100 h-25r flex-center flex">
5
+ <Loader />
6
+ </div>
7
+
8
+ <div v-else-if="!artist" class="t-center pd-big">
9
+ <h2 class="t-white">Artist not found</h2>
10
+ <p class="t-grey t-medium">The artist you're looking for doesn't exist or has been removed.</p>
11
+ </div>
12
+
13
+ <div v-else>
14
+ <!-- Artist Header with Background -->
15
+ <div class="artist-hero pos-relative mn-b-medium pd-medium">
16
+ <div class="artist-cover pos-absolute pos-t-0 pos-l-0 w-100 h-100" v-if="artist.coverUrl">
17
+ <Media
18
+ :url="artist.coverUrl"
19
+ class="w-100 h-100 object-fit-cover"
20
+ />
21
+ <div class="overlay pos-absolute pos-t-0 pos-l-0 w-100 h-100"></div>
22
+ </div>
23
+
24
+ <div class="artist-header z-index-1 pos-relative flex flex-v-center gap-medium">
25
+ <div class="artist-photo">
26
+ <Media
27
+ :url="artist.photoUrl || '/assets/placeholder-artist.jpg'"
28
+ class="w-15r h-15r object-fit-cover radius-round shadow-lg"
29
+ />
30
+ </div>
31
+
32
+ <div class="artist-info">
33
+ <div v-if="artist.isVerified" class="verified-badge t-small t-uppercase t-main mn-b-small">
34
+ <IconVerified class="i-small mn-r-thin" fill="rgb(var(--main))"/>
35
+ Verified Artist
36
+ </div>
37
+ <h1 class="t-white">{{ artist.name }}</h1>
38
+
39
+ <div class="artist-stats mn-t-small t-grey">
40
+ {{ formatFollowersCount(artist.popularity || 0) }} followers
41
+ </div>
42
+ </div>
43
+ </div>
44
+ </div>
45
+
46
+ <!-- Artist Actions -->
47
+ <div class="artist-actions mn-b-medium flex flex-v-center gap-small">
48
+ <Button
49
+ @click="playArtistTracks"
50
+ class="play-button bg-main radius-round pd-small flex-v-center flex gap-small hover-scale-1"
51
+ :showLoader="false"
52
+ :showSucces="false"
53
+ >
54
+ <IconPlay class="i-small" fill="rgb(var(--black))"/>
55
+ <span class="t-black t-medium">Play</span>
56
+ </Button>
57
+
58
+ <Button
59
+ @click="toggleFollow"
60
+ class="follow-button pd-small radius-extra"
61
+ :class="isFollowing ? 'bg-dark-transp-25 t-white br-solid br-white-transp-25' : 'bg-dark-transp-25 t-white'"
62
+ :showLoader="false"
63
+ :showSucces="false"
64
+ >
65
+ {{ isFollowing ? 'Following' : 'Follow' }}
66
+ </Button>
67
+
68
+ <Dropdown class="pos-relative">
69
+ <Button
70
+ @click="showDropdown = !showDropdown"
71
+ class="bg-transparent border-none pd-zero"
72
+ :showLoader="false"
73
+ :showSucces="false"
74
+ >
75
+ <IconEllipsis class="i-medium" fill="rgb(var(--white))"/>
76
+ </Button>
77
+
78
+ <template #content>
79
+ <ul v-if="showDropdown" class="pd-small bg-dark radius-small pos-absolute pos-t-100 pos-r-0 z-index-3 w-max-15r mn-t-thin">
80
+ <li>
81
+ <Button
82
+ @click="copyLink"
83
+ class="bg-transparent border-none pd-thin t-white w-100 t-left hover-bg-dark radius-small"
84
+ :showLoader="false"
85
+ :showSucces="false"
86
+ >
87
+ <span>Copy Link</span>
88
+ </Button>
89
+ </li>
90
+ </ul>
91
+ </template>
92
+ </Dropdown>
93
+ </div>
94
+
95
+ <!-- Popular Tracks -->
96
+ <section class="artist-popular-tracks mn-b-medium">
97
+ <h2 class="t-white mn-b-small">Popular</h2>
98
+
99
+ <TrackList
100
+ :tracks="discography.singles.slice(0, 5)"
101
+ :showAlbum="true"
102
+ :showCover="true"
103
+ class="bg-dark-transp-10 radius-medium o-hidden"
104
+ />
105
+ </section>
106
+
107
+ <!-- Discography - Albums -->
108
+ <section v-if="discography.albums.length > 0" class="artist-albums mn-b-medium">
109
+ <div class="flex-between flex mn-b-small">
110
+ <h2 class="t-white">Albums</h2>
111
+ </div>
112
+
113
+ <AlbumList :albums="discography.albums" />
114
+ </section>
115
+
116
+ <!-- Singles and EPs -->
117
+ <section v-if="discography.singles.length > 5" class="artist-singles mn-b-medium">
118
+ <div class="flex-between flex mn-b-small">
119
+ <h2 class="t-white">Singles and EPs</h2>
120
+ </div>
121
+
122
+ <div class="singles-grid cols-5 mobile:cols-2 gap-small">
123
+ <div v-for="track in discography.singles.slice(5)" :key="track._id">
124
+ <TrackCard :track="track" />
125
+ </div>
126
+ </div>
127
+ </section>
128
+
129
+ <!-- Artist Bio -->
130
+ <section v-if="artist.bio" class="artist-bio mn-b-medium pd-medium bg-dark-transp-10 radius-medium">
131
+ <h2 class="t-white mn-b-small">About</h2>
132
+ <p class="t-grey">{{ artist.bio }}</p>
133
+ </section>
134
+
135
+ <!-- Related Artists -->
136
+ <section v-if="relatedArtists.length > 0" class="related-artists">
137
+ <h2 class="t-white mn-b-small">Fans Also Like</h2>
138
+
139
+ <ArtistList :artists="relatedArtists" />
140
+ </section>
141
+ </div>
142
+ </div>
143
+ </template>
144
+
145
+ <script setup>
146
+ import { ref, computed, onMounted, watch } from 'vue';
147
+ import { useRoute, useRouter } from 'vue-router';
148
+ import TrackList from '../lists/TrackList.vue';
149
+ import TrackCard from '../cards/TrackCard.vue';
150
+ import AlbumList from '../lists/AlbumList.vue';
151
+ import ArtistList from '../lists/ArtistList.vue';
152
+ import Button from '@martyrs/src/components/Button/Button.vue';
153
+ import Loader from '@martyrs/src/components/Loader/Loader.vue';
154
+ import Media from '@martyrs/src/components/Media/Media.vue';
155
+ import Dropdown from '@martyrs/src/components/Dropdown/Dropdown.vue';
156
+
157
+ // Import icons
158
+ import IconPlay from '@martyrs/src/modules/icons/navigation/IconPlay.vue';
159
+ import IconEllipsis from '@martyrs/src/modules/icons/navigation/IconEllipsis.vue';
160
+ import IconVerified from '@martyrs/src/modules/icons/navigation/IconCheck.vue';
161
+
162
+ // Import store modules
163
+ import { state as artistsState, actions as artistsActions } from '../../store/artists.js';
164
+ import { actions as playerActions } from '../../store/player.js';
165
+
166
+ const route = useRoute();
167
+ const router = useRouter();
168
+
169
+ // State
170
+ const isLoading = ref(true);
171
+ const isFollowing = ref(false);
172
+ const showDropdown = ref(false);
173
+
174
+ // Computed properties
175
+ const artist = computed(() => artistsState.currentArtist);
176
+ const discography = computed(() => artistsState.discography);
177
+ const relatedArtists = computed(() => artistsState.relatedArtists);
178
+
179
+ // Methods
180
+ const formatFollowersCount = (count) => {
181
+ if (count >= 1000000) {
182
+ return `${(count / 1000000).toFixed(1)}M`;
183
+ } else if (count >= 1000) {
184
+ return `${(count / 1000).toFixed(1)}K`;
185
+ }
186
+ return count.toString();
187
+ };
188
+
189
+ const playArtistTracks = () => {
190
+ const tracks = [
191
+ ...discography.value.singles,
192
+ ...discography.value.albums.reduce((acc, album) => {
193
+ // In a real app, you'd first load the album tracks here
194
+ return acc;
195
+ }, [])
196
+ ];
197
+
198
+ if (tracks.length > 0) {
199
+ playerActions.setQueue(tracks);
200
+ }
201
+ };
202
+
203
+ const toggleFollow = () => {
204
+ isFollowing.value = !isFollowing.value;
205
+ // Implement follow artist logic here
206
+ };
207
+
208
+ const copyLink = () => {
209
+ const url = window.location.href;
210
+ navigator.clipboard.writeText(url).then(() => {
211
+ // Could show a success notification here
212
+ showDropdown.value = false;
213
+ });
214
+ };
215
+
216
+ const fetchArtistData = async () => {
217
+ isLoading.value = true;
218
+
219
+ try {
220
+ // Fetch artist data
221
+ await artistsActions.fetchArtistByUrl(route.params.url);
222
+ } catch (error) {
223
+ console.error('Error fetching artist data:', error);
224
+ } finally {
225
+ isLoading.value = false;
226
+ }
227
+ };
228
+
229
+ // Fetch data when component mounts or URL changes
230
+ onMounted(fetchArtistData);
231
+
232
+ watch(() => route.params.url, (newUrl) => {
233
+ if (newUrl) {
234
+ fetchArtistData();
235
+ }
236
+ });
237
+ </script>
238
+
239
+ <style scoped>
240
+ .artist-hero {
241
+ min-height: 20rem;
242
+ }
243
+
244
+ .overlay {
245
+ background: linear-gradient(transparent 0%, rgba(0, 0, 0, 0.8) 100%);
246
+ }
247
+ </style>