@fluid-app/portal-sdk 0.1.287 → 0.1.288

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 (344) hide show
  1. package/dist/{ShareablesScreen-CQZBq1Hl.cjs → ShareablesScreen-BT3H1Omb.cjs} +982 -543
  2. package/dist/ShareablesScreen-BT3H1Omb.cjs.map +1 -0
  3. package/dist/{ShareablesScreen-DYOIQwK-.mjs → ShareablesScreen-BrsJQqia.mjs} +982 -543
  4. package/dist/ShareablesScreen-BrsJQqia.mjs.map +1 -0
  5. package/dist/{ShareablesScreen-CPvylNL7.mjs → ShareablesScreen-IU9JBJzD.mjs} +2 -1
  6. package/dist/{ShareablesScreen-ljPcmGLg.cjs → ShareablesScreen-RxdJqjda.cjs} +2 -1
  7. package/dist/{ShopScreen-CZ9j_KkC.mjs → ShopScreen-BLo9zSmm.mjs} +1 -1
  8. package/dist/{ShopScreen-DjpBctSs.cjs → ShopScreen-BgiNBkIk.cjs} +21 -21
  9. package/dist/{ShopScreen-DjpBctSs.cjs.map → ShopScreen-BgiNBkIk.cjs.map} +1 -1
  10. package/dist/{ShopScreen-BpA6aD2v.mjs → ShopScreen-Bjo-5mdC.mjs} +21 -21
  11. package/dist/{ShopScreen-BpA6aD2v.mjs.map → ShopScreen-Bjo-5mdC.mjs.map} +1 -1
  12. package/dist/{ShopScreen-DcHCZmzi.cjs → ShopScreen-BzaTY9cV.cjs} +1 -1
  13. package/dist/{SubscriptionsScreen-GYGrW5-O.cjs → SubscriptionsScreen-5IsYJnvc.cjs} +21 -21
  14. package/dist/{SubscriptionsScreen-GYGrW5-O.cjs.map → SubscriptionsScreen-5IsYJnvc.cjs.map} +1 -1
  15. package/dist/{SubscriptionsScreen-C63ieyKx.mjs → SubscriptionsScreen-B9_Cmmrc.mjs} +21 -21
  16. package/dist/{SubscriptionsScreen-C63ieyKx.mjs.map → SubscriptionsScreen-B9_Cmmrc.mjs.map} +1 -1
  17. package/dist/{SubscriptionsScreen-D9m0xJuk.cjs → SubscriptionsScreen-BpiWZf9J.cjs} +1 -1
  18. package/dist/{de-D6Lv3YWx.mjs → de-B2xuRzqB.mjs} +1 -1
  19. package/dist/de-B2xuRzqB.mjs.map +1 -0
  20. package/dist/{de-BSkuBbT5.mjs → de-BMzN6pvJ.mjs} +1 -1
  21. package/dist/de-BMzN6pvJ.mjs.map +1 -0
  22. package/dist/{de-DaHmuCCC.cjs → de-CA1BpazO.cjs} +1 -1
  23. package/dist/de-CA1BpazO.cjs.map +1 -0
  24. package/dist/{de-DVlH5v7j.cjs → de-CQojBku3.cjs} +1 -1
  25. package/dist/de-CQojBku3.cjs.map +1 -0
  26. package/dist/de-d5sXuDlc.cjs +12 -0
  27. package/dist/de-d5sXuDlc.cjs.map +1 -0
  28. package/dist/de-ndSZ5ykY.mjs +6 -0
  29. package/dist/de-ndSZ5ykY.mjs.map +1 -0
  30. package/dist/el-3T5wNvmF.cjs +12 -0
  31. package/dist/el-3T5wNvmF.cjs.map +1 -0
  32. package/dist/{el-BbF6kVcS.cjs → el-BVROkdqG.cjs} +1 -1
  33. package/dist/el-BVROkdqG.cjs.map +1 -0
  34. package/dist/{el-CAyQKFtf.cjs → el-C1QZdoK1.cjs} +1 -1
  35. package/dist/el-C1QZdoK1.cjs.map +1 -0
  36. package/dist/{el-gB8Hq3fO.mjs → el-CT5RY-mx.mjs} +1 -1
  37. package/dist/el-CT5RY-mx.mjs.map +1 -0
  38. package/dist/{el-X6FQJ94p.mjs → el-CWq1GFO2.mjs} +1 -1
  39. package/dist/el-CWq1GFO2.mjs.map +1 -0
  40. package/dist/el-epEJkauy.mjs +6 -0
  41. package/dist/el-epEJkauy.mjs.map +1 -0
  42. package/dist/{es-CE1vcNIk.cjs → es-C2uchKja.cjs} +1 -1
  43. package/dist/es-C2uchKja.cjs.map +1 -0
  44. package/dist/{es-6BbLrKR8.mjs → es-C2zfJQck.mjs} +1 -1
  45. package/dist/es-C2zfJQck.mjs.map +1 -0
  46. package/dist/es-CWW1uLK3.mjs +6 -0
  47. package/dist/es-CWW1uLK3.mjs.map +1 -0
  48. package/dist/{es-BRduk0CI.cjs → es-CyPr-juY.cjs} +1 -1
  49. package/dist/es-CyPr-juY.cjs.map +1 -0
  50. package/dist/es-DYAui4cM.cjs +12 -0
  51. package/dist/es-DYAui4cM.cjs.map +1 -0
  52. package/dist/{es-DWWQRCG6.mjs → es-DjcSUa7j.mjs} +1 -1
  53. package/dist/es-DjcSUa7j.mjs.map +1 -0
  54. package/dist/{fr-JI0AJpi4.mjs → fr-BiJrmc6t.mjs} +1 -1
  55. package/dist/fr-BiJrmc6t.mjs.map +1 -0
  56. package/dist/{fr-DsRxIPGX.cjs → fr-BzVQUMC0.cjs} +1 -1
  57. package/dist/fr-BzVQUMC0.cjs.map +1 -0
  58. package/dist/{fr-fn45Htrq.cjs → fr-C-2Pj7D2.cjs} +1 -1
  59. package/dist/fr-C-2Pj7D2.cjs.map +1 -0
  60. package/dist/fr-CT47eWK_.mjs +6 -0
  61. package/dist/fr-CT47eWK_.mjs.map +1 -0
  62. package/dist/fr-DYML7Hb_.cjs +12 -0
  63. package/dist/fr-DYML7Hb_.cjs.map +1 -0
  64. package/dist/{fr-cuw-6rMw.mjs → fr-jXtwm66y.mjs} +1 -1
  65. package/dist/fr-jXtwm66y.mjs.map +1 -0
  66. package/dist/{he-BrmBdbqF.cjs → he-BNgtWUzu.cjs} +1 -1
  67. package/dist/he-BNgtWUzu.cjs.map +1 -0
  68. package/dist/{he-Bo038PQk.cjs → he-CBny3yj_.cjs} +1 -1
  69. package/dist/he-CBny3yj_.cjs.map +1 -0
  70. package/dist/he-Cu_YCy1f.cjs +12 -0
  71. package/dist/he-Cu_YCy1f.cjs.map +1 -0
  72. package/dist/{he-alv3r1UX.mjs → he-D-R8pe0L.mjs} +1 -1
  73. package/dist/he-D-R8pe0L.mjs.map +1 -0
  74. package/dist/he-gcmGB1-C.mjs +6 -0
  75. package/dist/he-gcmGB1-C.mjs.map +1 -0
  76. package/dist/{he-BkfYmB1i.mjs → he-z0iIyfGu.mjs} +1 -1
  77. package/dist/he-z0iIyfGu.mjs.map +1 -0
  78. package/dist/{hu-CnNC2Pbr.mjs → hu-BLBHZrAu.mjs} +1 -1
  79. package/dist/hu-BLBHZrAu.mjs.map +1 -0
  80. package/dist/{hu-CWg9eTQi.cjs → hu-BR0rOtJC.cjs} +1 -1
  81. package/dist/hu-BR0rOtJC.cjs.map +1 -0
  82. package/dist/{hu-Bac0NMFc.cjs → hu-BTBlTUaQ.cjs} +1 -1
  83. package/dist/hu-BTBlTUaQ.cjs.map +1 -0
  84. package/dist/hu-Czc1FPg9.cjs +12 -0
  85. package/dist/hu-Czc1FPg9.cjs.map +1 -0
  86. package/dist/{hu-uNLuVt0n.mjs → hu-D4fy_GxO.mjs} +1 -1
  87. package/dist/hu-D4fy_GxO.mjs.map +1 -0
  88. package/dist/hu-pswRdooT.mjs +6 -0
  89. package/dist/hu-pswRdooT.mjs.map +1 -0
  90. package/dist/{id-CxB-SzNc.cjs → id-52itow18.cjs} +1 -1
  91. package/dist/id-52itow18.cjs.map +1 -0
  92. package/dist/{id-QB01f2eJ.mjs → id-Bbvk8MDA.mjs} +1 -1
  93. package/dist/id-Bbvk8MDA.mjs.map +1 -0
  94. package/dist/{id-DcYvttVc.cjs → id-BxQgqmXd.cjs} +1 -1
  95. package/dist/id-BxQgqmXd.cjs.map +1 -0
  96. package/dist/{id-DyMHy3kg.mjs → id-DGh6JGZ5.mjs} +1 -1
  97. package/dist/id-DGh6JGZ5.mjs.map +1 -0
  98. package/dist/id-Dhws7LdN.mjs +6 -0
  99. package/dist/id-Dhws7LdN.mjs.map +1 -0
  100. package/dist/id-Vw9DQ3V1.cjs +12 -0
  101. package/dist/id-Vw9DQ3V1.cjs.map +1 -0
  102. package/dist/index.cjs +9 -9
  103. package/dist/index.d.cts.map +1 -1
  104. package/dist/index.d.mts.map +1 -1
  105. package/dist/index.mjs +9 -9
  106. package/dist/{it-DZodgnbb.cjs → it-CbZjaErj.cjs} +1 -1
  107. package/dist/it-CbZjaErj.cjs.map +1 -0
  108. package/dist/{it-bICkLWhn.mjs → it-CfLSq25e.mjs} +1 -1
  109. package/dist/it-CfLSq25e.mjs.map +1 -0
  110. package/dist/it-CpnrX6Qu.cjs +12 -0
  111. package/dist/it-CpnrX6Qu.cjs.map +1 -0
  112. package/dist/{it-DVaUm43V.mjs → it-ELWZ1sxy.mjs} +1 -1
  113. package/dist/it-ELWZ1sxy.mjs.map +1 -0
  114. package/dist/{it-BEH3ds1H.cjs → it-L0NVZqjU.cjs} +1 -1
  115. package/dist/it-L0NVZqjU.cjs.map +1 -0
  116. package/dist/it-dsOgAn3r.mjs +6 -0
  117. package/dist/it-dsOgAn3r.mjs.map +1 -0
  118. package/dist/{ja-DScRnwnk.cjs → ja-BaU2QXo2.cjs} +1 -1
  119. package/dist/ja-BaU2QXo2.cjs.map +1 -0
  120. package/dist/ja-BqySbP-W.mjs +6 -0
  121. package/dist/ja-BqySbP-W.mjs.map +1 -0
  122. package/dist/{ja-D18mnnKW.mjs → ja-C1QZfTGN.mjs} +1 -1
  123. package/dist/ja-C1QZfTGN.mjs.map +1 -0
  124. package/dist/{ja-DJwp44R3.cjs → ja-D5fpLCDT.cjs} +1 -1
  125. package/dist/ja-D5fpLCDT.cjs.map +1 -0
  126. package/dist/ja-JVcCjBJ9.cjs +12 -0
  127. package/dist/ja-JVcCjBJ9.cjs.map +1 -0
  128. package/dist/{ja-RoxMTtpa.mjs → ja-kM5CUvdg.mjs} +1 -1
  129. package/dist/ja-kM5CUvdg.mjs.map +1 -0
  130. package/dist/{ko-H2-0hunm.mjs → ko-BX4GXxaa.mjs} +1 -1
  131. package/dist/ko-BX4GXxaa.mjs.map +1 -0
  132. package/dist/ko-Cdb4MyCC.mjs +6 -0
  133. package/dist/ko-Cdb4MyCC.mjs.map +1 -0
  134. package/dist/{ko-tQ7eTEXA.mjs → ko-D2TLG_3_.mjs} +1 -1
  135. package/dist/ko-D2TLG_3_.mjs.map +1 -0
  136. package/dist/{ko-C1JrZ8Zc.cjs → ko-D64no-WM.cjs} +1 -1
  137. package/dist/ko-D64no-WM.cjs.map +1 -0
  138. package/dist/ko-WIfVodYY.cjs +12 -0
  139. package/dist/ko-WIfVodYY.cjs.map +1 -0
  140. package/dist/{ko-pdYT9YP0.cjs → ko-vQjiRfrX.cjs} +1 -1
  141. package/dist/ko-vQjiRfrX.cjs.map +1 -0
  142. package/dist/nl-C5U5y6gr.cjs +12 -0
  143. package/dist/nl-C5U5y6gr.cjs.map +1 -0
  144. package/dist/{nl-Bv4B_LAE.cjs → nl-C8T6RqHI.cjs} +1 -1
  145. package/dist/nl-C8T6RqHI.cjs.map +1 -0
  146. package/dist/nl-D0dcnS-5.mjs +6 -0
  147. package/dist/nl-D0dcnS-5.mjs.map +1 -0
  148. package/dist/{nl-BpHcFzEh.cjs → nl-DRxCBp_v.cjs} +1 -1
  149. package/dist/nl-DRxCBp_v.cjs.map +1 -0
  150. package/dist/{nl-DluEm_YD.mjs → nl-Dww7O0AO.mjs} +1 -1
  151. package/dist/nl-Dww7O0AO.mjs.map +1 -0
  152. package/dist/{nl-C4QRmvLS.mjs → nl-mL8uL7cu.mjs} +1 -1
  153. package/dist/nl-mL8uL7cu.mjs.map +1 -0
  154. package/dist/{pl-CD6XB8Yb.cjs → pl-AsC20yM9.cjs} +1 -1
  155. package/dist/pl-AsC20yM9.cjs.map +1 -0
  156. package/dist/{pl-BMYfuJP2.mjs → pl-Beb7Fiam.mjs} +1 -1
  157. package/dist/pl-Beb7Fiam.mjs.map +1 -0
  158. package/dist/pl-COP9NGch.mjs +6 -0
  159. package/dist/pl-COP9NGch.mjs.map +1 -0
  160. package/dist/pl-DJKAFKNJ.cjs +12 -0
  161. package/dist/pl-DJKAFKNJ.cjs.map +1 -0
  162. package/dist/{pl-D0UcIjco.cjs → pl-DpVEpGL0.cjs} +1 -1
  163. package/dist/pl-DpVEpGL0.cjs.map +1 -0
  164. package/dist/{pl-DCEQYzdi.mjs → pl-PV9rlOz1.mjs} +1 -1
  165. package/dist/pl-PV9rlOz1.mjs.map +1 -0
  166. package/dist/{pt-CdlP3ZEw.mjs → pt-B4hr_uJO.mjs} +1 -1
  167. package/dist/pt-B4hr_uJO.mjs.map +1 -0
  168. package/dist/{pt-DS-bjz4a.cjs → pt-BBFH5zDu.cjs} +1 -1
  169. package/dist/pt-BBFH5zDu.cjs.map +1 -0
  170. package/dist/{pt-DcZKpc5z.mjs → pt-BC56DXTY.mjs} +1 -1
  171. package/dist/pt-BC56DXTY.mjs.map +1 -0
  172. package/dist/pt-CSvh02ed.mjs +6 -0
  173. package/dist/pt-CSvh02ed.mjs.map +1 -0
  174. package/dist/{pt-C8mqwNHS.cjs → pt-CifIYahI.cjs} +1 -1
  175. package/dist/pt-CifIYahI.cjs.map +1 -0
  176. package/dist/pt-CpQN7iPy.cjs +12 -0
  177. package/dist/pt-CpQN7iPy.cjs.map +1 -0
  178. package/dist/{ro-kawLYFcb.cjs → ro-B6ExafZC.cjs} +1 -1
  179. package/dist/ro-B6ExafZC.cjs.map +1 -0
  180. package/dist/ro-CGOwHLvs.cjs +12 -0
  181. package/dist/ro-CGOwHLvs.cjs.map +1 -0
  182. package/dist/{ro-Bb7f9dpa.mjs → ro-CJJKGRs9.mjs} +1 -1
  183. package/dist/ro-CJJKGRs9.mjs.map +1 -0
  184. package/dist/ro-D2WH48l8.mjs +6 -0
  185. package/dist/ro-D2WH48l8.mjs.map +1 -0
  186. package/dist/{ro-Cl2KkquO.cjs → ro-DS3mARiW.cjs} +1 -1
  187. package/dist/ro-DS3mARiW.cjs.map +1 -0
  188. package/dist/{ro-nRdCzIy6.mjs → ro-DhGoI55Z.mjs} +1 -1
  189. package/dist/ro-DhGoI55Z.mjs.map +1 -0
  190. package/dist/ru-BCP_P-Kw.mjs +6 -0
  191. package/dist/ru-BCP_P-Kw.mjs.map +1 -0
  192. package/dist/{ru-SD9I_vbQ.mjs → ru-BymfL4lY.mjs} +1 -1
  193. package/dist/ru-BymfL4lY.mjs.map +1 -0
  194. package/dist/{ru-DhVdR84E.cjs → ru-CKfstS2M.cjs} +1 -1
  195. package/dist/ru-CKfstS2M.cjs.map +1 -0
  196. package/dist/ru-CW4wBDfy.cjs +12 -0
  197. package/dist/ru-CW4wBDfy.cjs.map +1 -0
  198. package/dist/{ru-C8vlzdV2.mjs → ru-DHNcAvHk.mjs} +1 -1
  199. package/dist/ru-DHNcAvHk.mjs.map +1 -0
  200. package/dist/{ru-DkGCoTib.cjs → ru-fz-F75f4.cjs} +1 -1
  201. package/dist/ru-fz-F75f4.cjs.map +1 -0
  202. package/dist/{th-BwrX1HXy.cjs → th-BVg0Jjgr.cjs} +1 -1
  203. package/dist/th-BVg0Jjgr.cjs.map +1 -0
  204. package/dist/{th-DzMSJQnA.cjs → th-BYXBW0X2.cjs} +1 -1
  205. package/dist/th-BYXBW0X2.cjs.map +1 -0
  206. package/dist/th-C7VrhPP5.cjs +12 -0
  207. package/dist/th-C7VrhPP5.cjs.map +1 -0
  208. package/dist/th-CZxqRIHs.mjs +6 -0
  209. package/dist/th-CZxqRIHs.mjs.map +1 -0
  210. package/dist/{th-DeiGkH2A.mjs → th-cad5Cap4.mjs} +1 -1
  211. package/dist/th-cad5Cap4.mjs.map +1 -0
  212. package/dist/{th-Q32fruvI.mjs → th-ge5FSv6T.mjs} +1 -1
  213. package/dist/th-ge5FSv6T.mjs.map +1 -0
  214. package/dist/{tl-DcgEPkew.mjs → tl-B888TBzV.mjs} +1 -1
  215. package/dist/tl-B888TBzV.mjs.map +1 -0
  216. package/dist/tl-CATDGPeB.cjs +12 -0
  217. package/dist/tl-CATDGPeB.cjs.map +1 -0
  218. package/dist/{tl-BrFPZytT.cjs → tl-CKjLSF_S.cjs} +1 -1
  219. package/dist/tl-CKjLSF_S.cjs.map +1 -0
  220. package/dist/tl-DCKUBvuV.mjs +6 -0
  221. package/dist/tl-DCKUBvuV.mjs.map +1 -0
  222. package/dist/{tl-Rc9FUVPE.mjs → tl-icpkJ5RY.mjs} +1 -1
  223. package/dist/tl-icpkJ5RY.mjs.map +1 -0
  224. package/dist/{tl-DKc258LE.cjs → tl-lZlSu-sM.cjs} +1 -1
  225. package/dist/tl-lZlSu-sM.cjs.map +1 -0
  226. package/dist/{tr-BSLMOkiM.mjs → tr-B96yy4BZ.mjs} +1 -1
  227. package/dist/tr-B96yy4BZ.mjs.map +1 -0
  228. package/dist/tr-Bsdv5dWu.cjs +12 -0
  229. package/dist/tr-Bsdv5dWu.cjs.map +1 -0
  230. package/dist/tr-COlHtN47.mjs +6 -0
  231. package/dist/tr-COlHtN47.mjs.map +1 -0
  232. package/dist/{tr--9yVKl_5.cjs → tr-CifdAA_w.cjs} +1 -1
  233. package/dist/tr-CifdAA_w.cjs.map +1 -0
  234. package/dist/{tr-YozY7m25.cjs → tr-DMnXKPnI.cjs} +1 -1
  235. package/dist/tr-DMnXKPnI.cjs.map +1 -0
  236. package/dist/{tr-BGaeZdYg.mjs → tr-QaTfqnit.mjs} +1 -1
  237. package/dist/tr-QaTfqnit.mjs.map +1 -0
  238. package/dist/{zh_CN-D1Ms29s8.mjs → zh_CN-BJnhvkc0.mjs} +1 -1
  239. package/dist/zh_CN-BJnhvkc0.mjs.map +1 -0
  240. package/dist/{zh_CN-CsMqRjiQ.mjs → zh_CN-BT8zi4ct.mjs} +1 -1
  241. package/dist/zh_CN-BT8zi4ct.mjs.map +1 -0
  242. package/dist/{zh_CN-E0kXVRxC.cjs → zh_CN-BWIy2qoV.cjs} +1 -1
  243. package/dist/zh_CN-BWIy2qoV.cjs.map +1 -0
  244. package/dist/{zh_CN-CbVSbwQS.cjs → zh_CN-BrkBDK-m.cjs} +1 -1
  245. package/dist/zh_CN-BrkBDK-m.cjs.map +1 -0
  246. package/dist/zh_CN-Bzo7sqbA.cjs +12 -0
  247. package/dist/zh_CN-Bzo7sqbA.cjs.map +1 -0
  248. package/dist/zh_CN-oOeDsP-B.mjs +6 -0
  249. package/dist/zh_CN-oOeDsP-B.mjs.map +1 -0
  250. package/dist/{zh_TW-xI_SNVQ3.mjs → zh_TW-Bz5_kUpI.mjs} +1 -1
  251. package/dist/zh_TW-Bz5_kUpI.mjs.map +1 -0
  252. package/dist/zh_TW-D-xI7JBs.mjs +6 -0
  253. package/dist/zh_TW-D-xI7JBs.mjs.map +1 -0
  254. package/dist/{zh_TW-BnIFVRFE.cjs → zh_TW-D86GUR9C.cjs} +1 -1
  255. package/dist/zh_TW-D86GUR9C.cjs.map +1 -0
  256. package/dist/zh_TW-DQdWK1u9.cjs +12 -0
  257. package/dist/zh_TW-DQdWK1u9.cjs.map +1 -0
  258. package/dist/{zh_TW-CqIYX4Jc.cjs → zh_TW-DzFlj-kU.cjs} +1 -1
  259. package/dist/zh_TW-DzFlj-kU.cjs.map +1 -0
  260. package/dist/{zh_TW-BmouVjK8.mjs → zh_TW-idE0Evam.mjs} +1 -1
  261. package/dist/zh_TW-idE0Evam.mjs.map +1 -0
  262. package/package.json +15 -15
  263. package/dist/ShareablesScreen-CQZBq1Hl.cjs.map +0 -1
  264. package/dist/ShareablesScreen-DYOIQwK-.mjs.map +0 -1
  265. package/dist/de-BSkuBbT5.mjs.map +0 -1
  266. package/dist/de-D6Lv3YWx.mjs.map +0 -1
  267. package/dist/de-DVlH5v7j.cjs.map +0 -1
  268. package/dist/de-DaHmuCCC.cjs.map +0 -1
  269. package/dist/el-BbF6kVcS.cjs.map +0 -1
  270. package/dist/el-CAyQKFtf.cjs.map +0 -1
  271. package/dist/el-X6FQJ94p.mjs.map +0 -1
  272. package/dist/el-gB8Hq3fO.mjs.map +0 -1
  273. package/dist/es-6BbLrKR8.mjs.map +0 -1
  274. package/dist/es-BRduk0CI.cjs.map +0 -1
  275. package/dist/es-CE1vcNIk.cjs.map +0 -1
  276. package/dist/es-DWWQRCG6.mjs.map +0 -1
  277. package/dist/fr-DsRxIPGX.cjs.map +0 -1
  278. package/dist/fr-JI0AJpi4.mjs.map +0 -1
  279. package/dist/fr-cuw-6rMw.mjs.map +0 -1
  280. package/dist/fr-fn45Htrq.cjs.map +0 -1
  281. package/dist/he-BkfYmB1i.mjs.map +0 -1
  282. package/dist/he-Bo038PQk.cjs.map +0 -1
  283. package/dist/he-BrmBdbqF.cjs.map +0 -1
  284. package/dist/he-alv3r1UX.mjs.map +0 -1
  285. package/dist/hu-Bac0NMFc.cjs.map +0 -1
  286. package/dist/hu-CWg9eTQi.cjs.map +0 -1
  287. package/dist/hu-CnNC2Pbr.mjs.map +0 -1
  288. package/dist/hu-uNLuVt0n.mjs.map +0 -1
  289. package/dist/id-CxB-SzNc.cjs.map +0 -1
  290. package/dist/id-DcYvttVc.cjs.map +0 -1
  291. package/dist/id-DyMHy3kg.mjs.map +0 -1
  292. package/dist/id-QB01f2eJ.mjs.map +0 -1
  293. package/dist/it-BEH3ds1H.cjs.map +0 -1
  294. package/dist/it-DVaUm43V.mjs.map +0 -1
  295. package/dist/it-DZodgnbb.cjs.map +0 -1
  296. package/dist/it-bICkLWhn.mjs.map +0 -1
  297. package/dist/ja-D18mnnKW.mjs.map +0 -1
  298. package/dist/ja-DJwp44R3.cjs.map +0 -1
  299. package/dist/ja-DScRnwnk.cjs.map +0 -1
  300. package/dist/ja-RoxMTtpa.mjs.map +0 -1
  301. package/dist/ko-C1JrZ8Zc.cjs.map +0 -1
  302. package/dist/ko-H2-0hunm.mjs.map +0 -1
  303. package/dist/ko-pdYT9YP0.cjs.map +0 -1
  304. package/dist/ko-tQ7eTEXA.mjs.map +0 -1
  305. package/dist/nl-BpHcFzEh.cjs.map +0 -1
  306. package/dist/nl-Bv4B_LAE.cjs.map +0 -1
  307. package/dist/nl-C4QRmvLS.mjs.map +0 -1
  308. package/dist/nl-DluEm_YD.mjs.map +0 -1
  309. package/dist/pl-BMYfuJP2.mjs.map +0 -1
  310. package/dist/pl-CD6XB8Yb.cjs.map +0 -1
  311. package/dist/pl-D0UcIjco.cjs.map +0 -1
  312. package/dist/pl-DCEQYzdi.mjs.map +0 -1
  313. package/dist/pt-C8mqwNHS.cjs.map +0 -1
  314. package/dist/pt-CdlP3ZEw.mjs.map +0 -1
  315. package/dist/pt-DS-bjz4a.cjs.map +0 -1
  316. package/dist/pt-DcZKpc5z.mjs.map +0 -1
  317. package/dist/ro-Bb7f9dpa.mjs.map +0 -1
  318. package/dist/ro-Cl2KkquO.cjs.map +0 -1
  319. package/dist/ro-kawLYFcb.cjs.map +0 -1
  320. package/dist/ro-nRdCzIy6.mjs.map +0 -1
  321. package/dist/ru-C8vlzdV2.mjs.map +0 -1
  322. package/dist/ru-DhVdR84E.cjs.map +0 -1
  323. package/dist/ru-DkGCoTib.cjs.map +0 -1
  324. package/dist/ru-SD9I_vbQ.mjs.map +0 -1
  325. package/dist/th-BwrX1HXy.cjs.map +0 -1
  326. package/dist/th-DeiGkH2A.mjs.map +0 -1
  327. package/dist/th-DzMSJQnA.cjs.map +0 -1
  328. package/dist/th-Q32fruvI.mjs.map +0 -1
  329. package/dist/tl-BrFPZytT.cjs.map +0 -1
  330. package/dist/tl-DKc258LE.cjs.map +0 -1
  331. package/dist/tl-DcgEPkew.mjs.map +0 -1
  332. package/dist/tl-Rc9FUVPE.mjs.map +0 -1
  333. package/dist/tr--9yVKl_5.cjs.map +0 -1
  334. package/dist/tr-BGaeZdYg.mjs.map +0 -1
  335. package/dist/tr-BSLMOkiM.mjs.map +0 -1
  336. package/dist/tr-YozY7m25.cjs.map +0 -1
  337. package/dist/zh_CN-CbVSbwQS.cjs.map +0 -1
  338. package/dist/zh_CN-CsMqRjiQ.mjs.map +0 -1
  339. package/dist/zh_CN-D1Ms29s8.mjs.map +0 -1
  340. package/dist/zh_CN-E0kXVRxC.cjs.map +0 -1
  341. package/dist/zh_TW-BmouVjK8.mjs.map +0 -1
  342. package/dist/zh_TW-BnIFVRFE.cjs.map +0 -1
  343. package/dist/zh_TW-CqIYX4Jc.cjs.map +0 -1
  344. package/dist/zh_TW-xI_SNVQ3.mjs.map +0 -1
@@ -2,6 +2,7 @@ const require_chunk = require("./chunk-9hOWP6kD.cjs");
2
2
  const require_portal_tenant = require("./portal_tenant-DG4gKXnu.cjs");
3
3
  const require_portal_tenant_content = require("./portal_tenant_content-C1R1xxDP.cjs");
4
4
  const require_PortalTenantClientProvider = require("./PortalTenantClientProvider-CVv-4rQ9.cjs");
5
+ const require_static_dict_adapter = require("./static-dict-adapter-D1ErNskC.cjs");
5
6
  const require_src = require("./src-B0ut9PTw.cjs");
6
7
  const require_ScreenHeaderContext = require("./ScreenHeaderContext-CsfhnuJk.cjs");
7
8
  const require_use_store = require("./use-store-DvtLtZ3f.cjs");
@@ -488,11 +489,18 @@ async function getProduct(client, id, options) {
488
489
  });
489
490
  }
490
491
  //#endregion
492
+ //#region ../../shareables/core/src/translation-api-context.ts
493
+ const { Provider: ShareablesProvider, useTranslation } = require_static_dict_adapter.createTranslationContext("Shareables");
494
+ const ShareablesTranslationProvider = ShareablesProvider;
495
+ const useShareablesTranslation = useTranslation;
496
+ //#endregion
491
497
  //#region ../../shareables/ui/src/components/MediaShare/ShareItemCard.tsx
492
498
  const DEFAULT_IMAGE$6 = "https://assets.fluid.app/fluid-admin/images/we-commerce/we-commerce.png";
493
- function ShareItemCard({ title, imageUrl, href, badge, isVideo = false, subtitle = "Click to find shareable assets" }) {
499
+ function ShareItemCard({ title, imageUrl, href, badge, isVideo = false, subtitle }) {
494
500
  const { navigate } = useShareablesUI();
495
501
  const renderImage = useRenderImage();
502
+ const { t } = useShareablesTranslation();
503
+ const resolvedSubtitle = subtitle ?? t("share_click_to_find_assets");
496
504
  function handleClick() {
497
505
  navigate(href);
498
506
  }
@@ -534,10 +542,10 @@ function ShareItemCard({ title, imageUrl, href, badge, isVideo = false, subtitle
534
542
  className: "px-2 pt-2 pb-4",
535
543
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
536
544
  className: "text-foreground line-clamp-2 text-sm leading-tight font-bold",
537
- children: title || "Untitled"
545
+ children: title || t("common_untitled")
538
546
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
539
547
  className: "text-muted-foreground mt-1 text-xs",
540
- children: subtitle
548
+ children: resolvedSubtitle
541
549
  })]
542
550
  })]
543
551
  });
@@ -552,13 +560,14 @@ function getProductImageUrl(product) {
552
560
  return product.image_url ?? null;
553
561
  }
554
562
  function ShareProductCard({ product, mediaCount }) {
563
+ const { t } = useShareablesTranslation();
555
564
  const imageUrl = getProductImageUrl(product);
556
565
  const isVideo = product.kind === "video" && !!product.video_url;
557
566
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ShareItemCard, {
558
567
  title: product.title,
559
568
  imageUrl,
560
569
  href: `product/${product.id}`,
561
- badge: !isVideo && mediaCount != null ? { text: `${mediaCount} assets` } : void 0,
570
+ badge: !isVideo && mediaCount != null ? { text: t("products_asset_count", { count: String(mediaCount) }) } : void 0,
562
571
  isVideo
563
572
  });
564
573
  }
@@ -582,7 +591,9 @@ const SHAREABLE_GRID_CLASS = "grid grid-cols-1 gap-8 sm:grid-cols-2 md:grid-cols
582
591
  * `filters` and `children`. This component does NOT own data fetching or
583
592
  * any state — callers pass in the derived flags.
584
593
  */
585
- function ShareableListLayout({ filters, children, isLoading, error, errorMessage = "Failed to load. Please try again.", isEmpty, emptyMessage, footer, loadingFilterShape = "search", sentinelRef }) {
594
+ function ShareableListLayout({ filters, children, isLoading, error, errorMessage, isEmpty, emptyMessage, footer, loadingFilterShape = "search", sentinelRef }) {
595
+ const { t } = useShareablesTranslation();
596
+ const resolvedErrorMessage = errorMessage ?? t("common_load_error_default");
586
597
  if (isLoading) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
587
598
  className: "space-y-6 px-4 py-4 md:px-10 md:py-6",
588
599
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
@@ -608,7 +619,7 @@ function ShareableListLayout({ filters, children, isLoading, error, errorMessage
608
619
  className: "flex flex-col items-center justify-center py-16",
609
620
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
610
621
  className: "text-destructive text-sm",
611
- children: errorMessage
622
+ children: resolvedErrorMessage
612
623
  })
613
624
  });
614
625
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
@@ -644,6 +655,7 @@ const SHAREABLE_LIST_CLASS = "divide-border divide-y rounded-lg border";
644
655
  * button. Hover styling applies to the entire row container.
645
656
  */
646
657
  function ShareableListRow({ imageUrl, imageAlt, title, subtitle, onClick, leading, trailing }) {
658
+ const { t } = useShareablesTranslation();
647
659
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
648
660
  className: "hover:bg-muted flex items-center gap-3 px-4 py-3 transition-colors",
649
661
  children: [
@@ -663,7 +675,7 @@ function ShareableListRow({ imageUrl, imageAlt, title, subtitle, onClick, leadin
663
675
  className: "min-w-0 flex-1",
664
676
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
665
677
  className: "text-foreground truncate text-sm font-medium",
666
- children: title || "Untitled"
678
+ children: title || t("common_untitled")
667
679
  }), subtitle != null && subtitle !== false && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
668
680
  className: "text-muted-foreground flex items-center gap-1.5 text-xs",
669
681
  children: subtitle
@@ -681,16 +693,17 @@ function ShareableListRow({ imageUrl, imageAlt, title, subtitle, onClick, leadin
681
693
  * listing screen. Stateless — callers own the `viewMode` state.
682
694
  */
683
695
  function ViewModeToggle({ value, onChange }) {
696
+ const { t } = useShareablesTranslation();
684
697
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
685
698
  className: "border-input bg-muted flex items-center rounded-lg border p-0.5",
686
699
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ToggleButton, {
687
700
  active: value === "list",
688
- label: "List view",
701
+ label: t("common_list_view"),
689
702
  onClick: () => onChange("list"),
690
703
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.List, { className: "h-4 w-4" })
691
704
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ToggleButton, {
692
705
  active: value === "grid",
693
- label: "Grid view",
706
+ label: t("common_grid_view"),
694
707
  onClick: () => onChange("grid"),
695
708
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.LayoutGrid, { className: "h-4 w-4" })
696
709
  })]
@@ -741,35 +754,36 @@ function useInfiniteListSentinel({ hasNextPage, isFetchingNextPage, fetchNextPag
741
754
  //#endregion
742
755
  //#region ../../shareables/ui/src/components/screens/ProductsScreen.tsx
743
756
  const PAGE_SIZE$6 = 24;
744
- const SORT_OPTIONS$1 = [
745
- {
746
- label: "Newest",
747
- value: "created_at_desc"
748
- },
749
- {
750
- label: "Oldest",
751
- value: "created_at_asc"
752
- },
753
- {
754
- label: "Title A–Z",
755
- value: "title_asc"
756
- },
757
- {
758
- label: "Title Z–A",
759
- value: "title_desc"
760
- },
761
- {
762
- label: "Price: Low to High",
763
- value: "price_asc"
764
- },
765
- {
766
- label: "Price: High to Low",
767
- value: "price_desc"
768
- }
769
- ];
770
757
  function ProductsScreen({ countryCode, fetchProducts: fetchPortalProducts, onNavigate }) {
771
758
  const client = useShareablesClient();
772
759
  const { navigate } = useShareablesUI();
760
+ const { t } = useShareablesTranslation();
761
+ const SORT_OPTIONS = (0, react.useMemo)(() => [
762
+ {
763
+ label: t("sort_newest"),
764
+ value: "created_at_desc"
765
+ },
766
+ {
767
+ label: t("sort_oldest"),
768
+ value: "created_at_asc"
769
+ },
770
+ {
771
+ label: t("sort_title_asc"),
772
+ value: "title_asc"
773
+ },
774
+ {
775
+ label: t("sort_title_desc"),
776
+ value: "title_desc"
777
+ },
778
+ {
779
+ label: t("sort_price_asc"),
780
+ value: "price_asc"
781
+ },
782
+ {
783
+ label: t("sort_price_desc"),
784
+ value: "price_desc"
785
+ }
786
+ ], [t]);
773
787
  const [searchTerm, setSearchTerm] = (0, react.useState)("");
774
788
  const [debouncedSearch, setDebouncedSearch] = (0, react.useState)("");
775
789
  const [sortValue, setSortValue] = (0, react.useState)("created_at_desc");
@@ -848,18 +862,18 @@ function ProductsScreen({ countryCode, fetchProducts: fetchPortalProducts, onNav
848
862
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "border-primary h-6 w-6 animate-spin rounded-full border-2 border-t-transparent" })
849
863
  }), error && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
850
864
  className: "bg-destructive/10 text-destructive rounded-lg px-3 py-2",
851
- children: "Failed to load products. Please try again."
865
+ children: t("products_load_error")
852
866
  })] });
853
867
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_ScreenHeaderContext.ScreenHeaderBreadcrumbs, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Breadcrumb, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.BreadcrumbList, {
854
868
  className: "text-lg",
855
869
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.BreadcrumbItem, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.BreadcrumbPage, {
856
870
  className: "font-semibold",
857
- children: "Products"
871
+ children: t("products_breadcrumb")
858
872
  }) })
859
873
  }) }) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ShareableListLayout, {
860
874
  isLoading,
861
875
  isEmpty: !error && products.length === 0 && !isFetchingNextPage && !hasNextPage,
862
- emptyMessage: debouncedSearch ? "No products match your search." : "No products available.",
876
+ emptyMessage: debouncedSearch ? t("products_search_no_results") : t("products_empty_default"),
863
877
  filters: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
864
878
  className: "flex items-center justify-end gap-2",
865
879
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
@@ -867,8 +881,8 @@ function ProductsScreen({ countryCode, fetchProducts: fetchPortalProducts, onNav
867
881
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_PortalProductsApiProvider.SearchSort, {
868
882
  searchValue: searchTerm,
869
883
  onSearchChange: setSearchTerm,
870
- placeholder: "Search products...",
871
- sortOptions: SORT_OPTIONS$1,
884
+ placeholder: t("products_search_placeholder"),
885
+ sortOptions: SORT_OPTIONS,
872
886
  sortValue,
873
887
  onSortChange: setSortValue
874
888
  })
@@ -895,7 +909,7 @@ function ProductsScreen({ countryCode, fetchProducts: fetchPortalProducts, onNav
895
909
  children: products.map((product) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ShareableListRow, {
896
910
  imageUrl: product.image_url,
897
911
  title: product.title,
898
- subtitle: product.media_count != null ? `${product.media_count} assets` : void 0,
912
+ subtitle: product.media_count != null ? t("products_asset_count", { count: String(product.media_count) }) : void 0,
899
913
  onClick: () => navigate(`product/${product.id}`)
900
914
  }, product.id))
901
915
  })
@@ -956,7 +970,9 @@ function SharePageImageDisplay({ displayImage, displayTitle, displayVideo, isVid
956
970
  }
957
971
  //#endregion
958
972
  //#region ../../shareables/ui/src/components/QrCodeDisplay.tsx
959
- function QrCodeDisplay({ url, alt = "QR Code", size = "md", className = "" }) {
973
+ function QrCodeDisplay({ url, alt, size = "md", className = "" }) {
974
+ const { t } = useShareablesTranslation();
975
+ const resolvedAlt = alt ?? t("share_qr_code_default_alt");
960
976
  const qrCodeUrl = (0, react.useMemo)(() => url ? `https://api.qrserver.com/v1/create-qr-code/?size=200x200&data=${encodeURIComponent(url)}` : "", [url]);
961
977
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
962
978
  className: `flex ${{
@@ -966,13 +982,13 @@ function QrCodeDisplay({ url, alt = "QR Code", size = "md", className = "" }) {
966
982
  }[size]} items-center justify-center overflow-hidden rounded-xl border border-gray-200 bg-white shadow-sm ${className}`,
967
983
  children: qrCodeUrl ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
968
984
  src: qrCodeUrl,
969
- alt,
985
+ alt: resolvedAlt,
970
986
  className: "h-full w-full object-cover",
971
987
  loading: "lazy",
972
988
  onError: (e) => {
973
989
  e.currentTarget.style.display = "none";
974
990
  const parent = e.currentTarget.parentElement;
975
- if (parent) parent.title = "QR code failed to load";
991
+ if (parent) parent.title = t("share_qr_code_load_error");
976
992
  }
977
993
  }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
978
994
  className: "flex items-center justify-center text-gray-400",
@@ -1031,16 +1047,17 @@ function XTwitterIcon(props) {
1031
1047
  //#region ../../shareables/ui/src/components/SharePage/ShareLinkSection.tsx
1032
1048
  function ShareLinkSection({ shareLink, loading, displayTitle, isVideo, relateableId, relateableType }) {
1033
1049
  const { showToast, onMySiteShare } = useShareablesUI();
1050
+ const { t } = useShareablesTranslation();
1034
1051
  const handleCopyLink = async () => {
1035
1052
  if (shareLink) try {
1036
1053
  await navigator.clipboard.writeText(shareLink);
1037
1054
  showToast({
1038
- title: "Share link copied to clipboard!",
1055
+ title: t("share_link_copied"),
1039
1056
  type: "success"
1040
1057
  });
1041
1058
  } catch (error) {
1042
1059
  showToast({
1043
- title: "Failed to copy link to clipboard",
1060
+ title: t("share_link_copy_error"),
1044
1061
  type: "error",
1045
1062
  error
1046
1063
  });
@@ -1049,7 +1066,7 @@ function ShareLinkSection({ shareLink, loading, displayTitle, isVideo, relateabl
1049
1066
  const handlePlatformShare = async (platform) => {
1050
1067
  if (!shareLink) {
1051
1068
  showToast({
1052
- title: "Share link not available yet. Please wait...",
1069
+ title: t("share_link_not_available"),
1053
1070
  type: "error"
1054
1071
  });
1055
1072
  return;
@@ -1057,7 +1074,10 @@ function ShareLinkSection({ shareLink, loading, displayTitle, isVideo, relateabl
1057
1074
  await handleSocialShare(platform.toLowerCase(), {
1058
1075
  url: shareLink,
1059
1076
  title: displayTitle,
1060
- description: `Check out this ${isVideo ? "video" : "image"}: ${displayTitle}`
1077
+ description: t("share_social_description", {
1078
+ type: isVideo ? "video" : "image",
1079
+ title: displayTitle
1080
+ })
1061
1081
  }, (message) => showToast({
1062
1082
  title: message,
1063
1083
  type: "success"
@@ -1069,7 +1089,7 @@ function ShareLinkSection({ shareLink, loading, displayTitle, isVideo, relateabl
1069
1089
  const handleMySiteShareClick = async () => {
1070
1090
  if (!shareLink) {
1071
1091
  showToast({
1072
- title: "Share link not available yet. Please wait...",
1092
+ title: t("share_link_not_available"),
1073
1093
  type: "error"
1074
1094
  });
1075
1095
  return;
@@ -1081,12 +1101,12 @@ function ShareLinkSection({ shareLink, loading, displayTitle, isVideo, relateabl
1081
1101
  relateable_type: relateableType
1082
1102
  });
1083
1103
  showToast({
1084
- title: "Shared to MySite",
1104
+ title: t("share_mysite_success"),
1085
1105
  type: "success"
1086
1106
  });
1087
1107
  } catch (error) {
1088
1108
  showToast({
1089
- title: "Failed to share to MySite",
1109
+ title: t("share_mysite_error"),
1090
1110
  type: "error",
1091
1111
  error
1092
1112
  });
@@ -1116,7 +1136,7 @@ function ShareLinkSection({ shareLink, loading, displayTitle, isVideo, relateabl
1116
1136
  className: "flex items-center gap-3",
1117
1137
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
1118
1138
  className: "text-foreground shrink-0 text-sm font-semibold",
1119
- children: "Share Your Unique Link"
1139
+ children: t("share_unique_link_heading")
1120
1140
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "bg-foreground h-px flex-1" })]
1121
1141
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1122
1142
  className: "flex items-start gap-4",
@@ -1124,7 +1144,7 @@ function ShareLinkSection({ shareLink, loading, displayTitle, isVideo, relateabl
1124
1144
  className: "bg-muted shrink-0 rounded-md p-2",
1125
1145
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(QrCodeDisplay, {
1126
1146
  url: shareLink,
1127
- alt: "QR Code for share link",
1147
+ alt: t("share_qr_code_alt"),
1128
1148
  size: "sm",
1129
1149
  className: "h-[75px] w-[75px] rounded-none! border-none"
1130
1150
  })
@@ -1137,14 +1157,14 @@ function ShareLinkSection({ shareLink, loading, displayTitle, isVideo, relateabl
1137
1157
  variant: "secondary",
1138
1158
  size: "sm",
1139
1159
  className: "border-foreground bg-background text-foreground hover:bg-muted h-8 rounded-md border px-3 text-xs font-semibold transition-colors",
1140
- children: "MySite"
1160
+ children: t("share_mysite_button")
1141
1161
  }), isMobileDevice() ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.DropdownMenu, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.DropdownMenuTrigger, {
1142
1162
  asChild: true,
1143
1163
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.Button, {
1144
1164
  variant: "secondary",
1145
1165
  size: "sm",
1146
1166
  className: "border-foreground bg-background text-foreground hover:bg-muted h-8 rounded-md border px-3 text-xs font-semibold transition-colors",
1147
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Menu, { className: "mr-1 h-3 w-3" }), "Share"]
1167
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Menu, { className: "mr-1 h-3 w-3" }), t("share_button")]
1148
1168
  })
1149
1169
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.DropdownMenuContent, {
1150
1170
  className: "w-48",
@@ -1165,7 +1185,7 @@ function ShareLinkSection({ shareLink, loading, displayTitle, isVideo, relateabl
1165
1185
  style: { background: "linear-gradient(81.27deg, #E5F7FF 0.95%, #FFDBF5 34.5%, #FFE0CF 60.44%, #EDFFFB 75.06%, #FFDBF5 99.76%)" },
1166
1186
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1167
1187
  className: "flex-1 truncate text-sm text-[#344054]",
1168
- children: shareLink || (loading ? "Generating link..." : "Loading...")
1188
+ children: shareLink || (loading ? t("share_generating_link") : t("common_loading"))
1169
1189
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Button, {
1170
1190
  onClick: handleCopyLink,
1171
1191
  variant: "ghost",
@@ -1196,6 +1216,7 @@ async function downloadFile(url, filename) {
1196
1216
  //#region ../../shareables/ui/src/components/SharePage/AssetActions.tsx
1197
1217
  function AssetActions({ downloadUrl, displayTitle, shareLink, shareLinkLoading, isVideo, relateableId, relateableType }) {
1198
1218
  const { onFileDownload } = useShareablesUI();
1219
+ const { t } = useShareablesTranslation();
1199
1220
  const [isDownloading, setIsDownloading] = (0, react.useState)(false);
1200
1221
  const handleDownload = (0, react.useCallback)(async () => {
1201
1222
  if (!downloadUrl || isDownloading) return;
@@ -1223,7 +1244,7 @@ function AssetActions({ downloadUrl, displayTitle, shareLink, shareLinkLoading,
1223
1244
  className: "bg-foreground text-background hover:bg-foreground/70 flex h-10 w-full items-center justify-between rounded-lg px-4 transition-all",
1224
1245
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1225
1246
  className: "text-sm font-medium",
1226
- children: "Download Asset"
1247
+ children: t("share_download_asset")
1227
1248
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Download, { className: "h-4 w-4" })]
1228
1249
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ShareLinkSection, {
1229
1250
  shareLink,
@@ -1237,25 +1258,21 @@ function AssetActions({ downloadUrl, displayTitle, shareLink, shareLinkLoading,
1237
1258
  //#endregion
1238
1259
  //#region ../../shareables/ui/src/components/ShareablesModal/MarketingAssetsGrid.tsx
1239
1260
  const PLACEHOLDER_IMAGE = "https://assets.fluid.app/fluid-admin/images/placeholder.png";
1240
- const FILTER_TABS = [
1241
- "All",
1242
- "Images",
1243
- "Videos"
1244
- ];
1245
1261
  const FilterTabs = react.default.memo(function FilterTabs({ tabs, activeTab, onTabChange }) {
1246
1262
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1247
1263
  className: "mb-3 flex gap-2",
1248
1264
  children: tabs.map((tab) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Button, {
1249
- onClick: () => onTabChange(tab),
1265
+ onClick: () => onTabChange(tab.id),
1250
1266
  variant: "secondary",
1251
1267
  size: "sm",
1252
- className: `inline-flex items-center gap-x-1.5 rounded-sm border-none px-2 py-1 text-xs font-medium capitalize shadow-none! transition-colors ${activeTab === tab ? "bg-primary text-primary-foreground ring-primary hover:bg-primary hover:text-primary-foreground hover:ring-primary" : "bg-muted text-foreground hover:bg-primary hover:text-primary-foreground hover:ring-primary"}`,
1253
- children: tab
1254
- }, tab))
1268
+ className: `inline-flex items-center gap-x-1.5 rounded-sm border-none px-2 py-1 text-xs font-medium capitalize shadow-none! transition-colors ${activeTab === tab.id ? "bg-primary text-primary-foreground ring-primary hover:bg-primary hover:text-primary-foreground hover:ring-primary" : "bg-muted text-foreground hover:bg-primary hover:text-primary-foreground hover:ring-primary"}`,
1269
+ children: tab.label
1270
+ }, tab.id))
1255
1271
  });
1256
1272
  });
1257
1273
  const MediaCard = react.default.memo(function MediaCard({ mediaItem, onClick }) {
1258
1274
  const renderImage = useRenderImage();
1275
+ const { t } = useShareablesTranslation();
1259
1276
  const isVideo = mediaItem.kind === "video";
1260
1277
  const isImage = mediaItem.kind === "image";
1261
1278
  const MediaIcon = isVideo ? lucide_react.Play : isImage ? lucide_react.FileImage : lucide_react.Image;
@@ -1266,7 +1283,7 @@ const MediaCard = react.default.memo(function MediaCard({ mediaItem, onClick })
1266
1283
  className: "bg-background relative aspect-[3/4] w-full overflow-hidden rounded-lg",
1267
1284
  children: [renderImage({
1268
1285
  src: mediaItem.image_url || PLACEHOLDER_IMAGE,
1269
- alt: mediaItem.title || "Media",
1286
+ alt: mediaItem.title || t("media_type_default"),
1270
1287
  fill: true,
1271
1288
  className: "object-cover"
1272
1289
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
@@ -1278,25 +1295,28 @@ const MediaCard = react.default.memo(function MediaCard({ mediaItem, onClick })
1278
1295
  })]
1279
1296
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
1280
1297
  className: "text-foreground line-clamp-2 px-1 text-[15px] leading-[1.4] font-semibold",
1281
- children: mediaItem.title || "Untitled"
1298
+ children: mediaItem.title || t("common_untitled")
1282
1299
  })]
1283
1300
  });
1284
1301
  });
1285
- const LoadingState = react.default.memo(function LoadingState({ message = "Loading media..." }) {
1302
+ const LoadingState = react.default.memo(function LoadingState({ message }) {
1303
+ const { t } = useShareablesTranslation();
1304
+ const resolvedMessage = message ?? t("share_loading_media");
1286
1305
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1287
1306
  className: "flex flex-col items-center justify-center gap-3 py-12",
1288
1307
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Spinner, { className: "size-8" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1289
1308
  className: "text-muted-foreground text-sm",
1290
- children: message
1309
+ children: resolvedMessage
1291
1310
  })]
1292
1311
  });
1293
1312
  });
1294
- const ErrorState = react.default.memo(function ErrorState({ message = "Failed to load media" }) {
1313
+ const ErrorState = react.default.memo(function ErrorState({ message }) {
1314
+ const { t } = useShareablesTranslation();
1295
1315
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1296
1316
  className: "flex items-center justify-center",
1297
1317
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1298
1318
  className: "text-sm text-red-500",
1299
- children: message
1319
+ children: message ?? t("share_media_load_error")
1300
1320
  })
1301
1321
  });
1302
1322
  });
@@ -1319,29 +1339,30 @@ const EmptyState = react.default.memo(function EmptyState({ message, icon, descr
1319
1339
  });
1320
1340
  });
1321
1341
  const AnalyticsPlaceholder = react.default.memo(function AnalyticsPlaceholder() {
1342
+ const { t } = useShareablesTranslation();
1322
1343
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1323
1344
  className: "flex flex-1 items-center justify-center",
1324
1345
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1325
1346
  className: "text-center",
1326
1347
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1327
1348
  className: "mb-1 text-sm text-gray-500",
1328
- children: "Analytics Coming Soon"
1349
+ children: t("share_analytics_coming_soon")
1329
1350
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1330
1351
  className: "text-xs text-gray-400",
1331
- children: "View engagement metrics and performance data"
1352
+ children: t("share_analytics_description")
1332
1353
  })]
1333
1354
  })
1334
1355
  });
1335
1356
  });
1336
- const RELATEABLE_TYPE_LABELS = {
1337
- Product: "product",
1338
- Medium: "media",
1339
- EnrollmentPack: "enrollment pack",
1340
- MySite: "site",
1341
- Library: "library"
1342
- };
1343
1357
  const NoAssetsState = react.default.memo(function NoAssetsState({ relateable_type }) {
1344
- const label = RELATEABLE_TYPE_LABELS[relateable_type] ?? "item";
1358
+ const { t } = useShareablesTranslation();
1359
+ const label = (0, react.useMemo)(() => ({
1360
+ Product: t("share_type_product"),
1361
+ Medium: t("share_type_media"),
1362
+ EnrollmentPack: t("share_type_enrollment_pack"),
1363
+ MySite: t("share_type_site"),
1364
+ Library: t("share_type_library")
1365
+ }), [t])[relateable_type] ?? "item";
1345
1366
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1346
1367
  className: "flex flex-1 items-center justify-center px-6",
1347
1368
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
@@ -1353,21 +1374,32 @@ const NoAssetsState = react.default.memo(function NoAssetsState({ relateable_typ
1353
1374
  }),
1354
1375
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1355
1376
  className: "mb-1 text-sm text-gray-500",
1356
- children: "No Marketing Assets"
1377
+ children: t("share_no_marketing_assets")
1357
1378
  }),
1358
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1379
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1359
1380
  className: "text-xs text-gray-400",
1360
- children: [
1361
- "This ",
1362
- label,
1363
- " does not have any associated media"
1364
- ]
1381
+ children: t("share_no_associated_media", { label })
1365
1382
  })
1366
1383
  ]
1367
1384
  })
1368
1385
  });
1369
1386
  });
1370
1387
  function MarketingAssetsGrid({ isLoading, error, activeTab, onTabChange, mediaItems, onMediaItemClick, showEmptyState = false, activeMainTab = "Related Sharables", relateable_type }) {
1388
+ const { t } = useShareablesTranslation();
1389
+ const FILTER_TABS = (0, react.useMemo)(() => [
1390
+ {
1391
+ id: "all",
1392
+ label: t("common_all")
1393
+ },
1394
+ {
1395
+ id: "images",
1396
+ label: t("media_filter_images")
1397
+ },
1398
+ {
1399
+ id: "videos",
1400
+ label: t("media_filter_videos")
1401
+ }
1402
+ ], [t]);
1371
1403
  const handleMediaItemClick = (0, react.useCallback)((mediaItem) => {
1372
1404
  onMediaItemClick(mediaItem);
1373
1405
  }, [onMediaItemClick]);
@@ -1376,13 +1408,9 @@ function MarketingAssetsGrid({ isLoading, error, activeTab, onTabChange, mediaIt
1376
1408
  if (activeMainTab === "Analytics" && relateable_type === "Medium") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AnalyticsPlaceholder, {});
1377
1409
  if (activeMainTab === "Related Sharables") return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1378
1410
  className: "mb-4 px-4 pt-4",
1379
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("h2", {
1411
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h2", {
1380
1412
  className: "text-foreground text-[15px] leading-[1.4] font-semibold",
1381
- children: [
1382
- "Related Sharables (",
1383
- mediaItems.length,
1384
- ")"
1385
- ]
1413
+ children: t("share_related_sharables_count", { count: String(mediaItems.length) })
1386
1414
  })
1387
1415
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1388
1416
  className: "px-4 pb-4",
@@ -1401,7 +1429,7 @@ function MarketingAssetsGrid({ isLoading, error, activeTab, onTabChange, mediaIt
1401
1429
  onClick: handleMediaItemClick
1402
1430
  }, mediaItem.id))
1403
1431
  }),
1404
- !isLoading && !error && mediaItems.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(EmptyState, { message: `No ${activeTab.toLowerCase()} found` })
1432
+ !isLoading && !error && mediaItems.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(EmptyState, { message: t("share_no_tab_items_found", { tab: (FILTER_TABS.find((tab) => tab.id === activeTab)?.label ?? activeTab).toLowerCase() }) })
1405
1433
  ]
1406
1434
  })] });
1407
1435
  return null;
@@ -1428,7 +1456,9 @@ var MarketingAssetsGrid_default = react.default.memo(MarketingAssetsGrid);
1428
1456
  * NOT touch the shell header. Dialogs (delete confirmation, etc.) belong to
1429
1457
  * the caller and should be rendered as siblings to this component.
1430
1458
  */
1431
- function ShareableDetailLayout({ isLoading, notFound, notFoundMessage = "Not found or failed to load.", title, description, image, actions, meta, children, containerHeightClass = "md:h-[calc(100vh-140px)]" }) {
1459
+ function ShareableDetailLayout({ isLoading, notFound, notFoundMessage, title, description, image, actions, meta, children, containerHeightClass = "md:h-[calc(100vh-140px)]" }) {
1460
+ const { t } = useShareablesTranslation();
1461
+ const resolvedNotFoundMessage = notFoundMessage ?? t("common_not_found_default");
1432
1462
  if (isLoading) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1433
1463
  className: "flex items-center justify-center py-16",
1434
1464
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Spinner, { className: "size-8" })
@@ -1437,7 +1467,7 @@ function ShareableDetailLayout({ isLoading, notFound, notFoundMessage = "Not fou
1437
1467
  className: "flex flex-col items-center justify-center py-16",
1438
1468
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1439
1469
  className: "text-destructive text-sm",
1440
- children: notFoundMessage
1470
+ children: resolvedNotFoundMessage
1441
1471
  })
1442
1472
  });
1443
1473
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
@@ -1471,6 +1501,7 @@ function ShareableDetailLayout({ isLoading, notFound, notFoundMessage = "Not fou
1471
1501
  * (e.g. mediaItem.description.body) — tags are stripped internally.
1472
1502
  */
1473
1503
  function ShareableDescription({ html, threshold = 150 }) {
1504
+ const { t } = useShareablesTranslation();
1474
1505
  const [isExpanded, setIsExpanded] = (0, react.useState)(false);
1475
1506
  const stripped = stripTags(html ?? "");
1476
1507
  if (!stripped) return null;
@@ -1485,7 +1516,7 @@ function ShareableDescription({ html, threshold = 150 }) {
1485
1516
  variant: "ghost",
1486
1517
  size: "sm",
1487
1518
  className: "text-foreground hover:text-foreground/80 mt-1 h-auto p-0 text-xs font-normal underline",
1488
- children: isExpanded ? "Read less" : "Read more"
1519
+ children: isExpanded ? t("common_read_less") : t("common_read_more")
1489
1520
  })]
1490
1521
  });
1491
1522
  }
@@ -1495,7 +1526,8 @@ function ProductDetailScreen({ productId, countryCode, fetchProduct: fetchPortal
1495
1526
  const api = useShareablesApi();
1496
1527
  const client = useShareablesClient();
1497
1528
  const { navigate } = useShareablesUI();
1498
- const [activeTab, setActiveTab] = (0, react.useState)("All");
1529
+ const { t } = useShareablesTranslation();
1530
+ const [activeTab, setActiveTab] = (0, react.useState)("all");
1499
1531
  const { data: portalProductResponse, isLoading: isLoadingPortalProduct } = (0, _tanstack_react_query.useQuery)({
1500
1532
  queryKey: [
1501
1533
  "portal-products",
@@ -1545,9 +1577,9 @@ function ProductDetailScreen({ productId, countryCode, fetchProduct: fetchPortal
1545
1577
  }
1546
1578
  })();
1547
1579
  const filteredMediaItems = (productMediaResponse?.media ?? []).filter((item) => {
1548
- if (activeTab === "All") return true;
1549
- if (activeTab === "Images") return item.kind === "image";
1550
- if (activeTab === "Videos") return item.kind === "video";
1580
+ if (activeTab === "all") return true;
1581
+ if (activeTab === "images") return item.kind === "image";
1582
+ if (activeTab === "videos") return item.kind === "video";
1551
1583
  return true;
1552
1584
  }).map((item) => ({
1553
1585
  id: item.id,
@@ -1570,18 +1602,18 @@ function ProductDetailScreen({ productId, countryCode, fetchProduct: fetchPortal
1570
1602
  e.preventDefault();
1571
1603
  (onBack ?? (() => navigate("products")))();
1572
1604
  },
1573
- children: "Products"
1605
+ children: t("products_breadcrumb")
1574
1606
  }) }),
1575
1607
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.BreadcrumbSeparator, {}),
1576
1608
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.BreadcrumbItem, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.BreadcrumbPage, {
1577
1609
  className: "font-semibold",
1578
- children: displayTitle || "Product"
1610
+ children: displayTitle || t("products_breadcrumb_fallback")
1579
1611
  }) })
1580
1612
  ]
1581
1613
  }) }) }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(ShareableDetailLayout, {
1582
1614
  isLoading: isLoadingProduct,
1583
1615
  notFound: !product,
1584
- notFoundMessage: "Product not found or failed to load.",
1616
+ notFoundMessage: t("products_not_found"),
1585
1617
  title: displayTitle,
1586
1618
  description: displayDescription,
1587
1619
  image: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
@@ -1595,11 +1627,11 @@ function ProductDetailScreen({ productId, countryCode, fetchProduct: fetchPortal
1595
1627
  }),
1596
1628
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1597
1629
  className: "mb-1 text-sm text-gray-500",
1598
- children: "No Product Image"
1630
+ children: t("products_no_image")
1599
1631
  }),
1600
1632
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1601
1633
  className: "text-xs text-gray-400",
1602
- children: "This product does not have any associated media"
1634
+ children: t("products_no_media")
1603
1635
  })
1604
1636
  ]
1605
1637
  }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SharePageImageDisplay, {
@@ -1614,7 +1646,7 @@ function ProductDetailScreen({ productId, countryCode, fetchProduct: fetchPortal
1614
1646
  children: [
1615
1647
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1616
1648
  className: "font-semibold",
1617
- children: "Price"
1649
+ children: t("products_price_label")
1618
1650
  }),
1619
1651
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "|" }),
1620
1652
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
@@ -1650,29 +1682,36 @@ function ProductDetailScreen({ productId, countryCode, fetchProduct: fetchPortal
1650
1682
  }
1651
1683
  //#endregion
1652
1684
  //#region ../../shareables/ui/src/components/OwnerFilterTabs.tsx
1653
- function getFilteredEmptyMessage({ searchTerm, ownerFilter, hasOtherFilters = false, entityName = "items", defaultMessage = "Nothing available at the moment." }) {
1685
+ function getFilteredEmptyMessage({ searchTerm, ownerFilter, hasOtherFilters = false, entityName = "items", defaultMessage = "Nothing available at the moment.", messages }) {
1654
1686
  const isFiltered = ownerFilter !== "all" || hasOtherFilters;
1687
+ if (messages) {
1688
+ if (searchTerm && isFiltered) return messages.filterSearchNoResults;
1689
+ if (searchTerm) return messages.searchNoResults;
1690
+ if (isFiltered) return messages.filterNoResults;
1691
+ return defaultMessage;
1692
+ }
1655
1693
  if (searchTerm && isFiltered) return `No ${entityName} match "${searchTerm}" with the current filters. Try a different search term or switch to "All".`;
1656
1694
  if (searchTerm) return `No ${entityName} match "${searchTerm}". Try a different search term.`;
1657
1695
  if (isFiltered) return `No matching ${entityName} for the current filters.`;
1658
1696
  return defaultMessage;
1659
1697
  }
1660
- function OwnerFilterTabs({ value, onValueChange, myLabel = "Mine" }) {
1698
+ function OwnerFilterTabs({ value, onValueChange, myLabel }) {
1699
+ const { t } = useShareablesTranslation();
1661
1700
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Tabs, {
1662
1701
  value,
1663
1702
  onValueChange: (v) => onValueChange(v),
1664
1703
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.TabsList, { children: [
1665
1704
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.TabsTrigger, {
1666
1705
  value: "all",
1667
- children: "All"
1706
+ children: t("common_all")
1668
1707
  }),
1669
1708
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.TabsTrigger, {
1670
1709
  value: "mine",
1671
- children: myLabel
1710
+ children: myLabel ?? t("common_mine")
1672
1711
  }),
1673
1712
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.TabsTrigger, {
1674
1713
  value: "company",
1675
- children: "Company"
1714
+ children: t("common_company")
1676
1715
  })
1677
1716
  ] })
1678
1717
  });
@@ -1680,17 +1719,18 @@ function OwnerFilterTabs({ value, onValueChange, myLabel = "Mine" }) {
1680
1719
  //#endregion
1681
1720
  //#region ../../shareables/ui/src/components/screens/MediaListingScreen.tsx
1682
1721
  const PAGE_SIZE$5 = 24;
1683
- function getMediaKindLabel(kind) {
1722
+ function getMediaKindLabel(kind, labels) {
1684
1723
  switch (kind) {
1685
- case "video": return "Video";
1686
- case "pdf": return "PDF";
1687
- default: return "Image";
1724
+ case "video": return labels.video;
1725
+ case "pdf": return labels.pdf;
1726
+ default: return labels.image;
1688
1727
  }
1689
1728
  }
1690
1729
  /** Three-dot dropdown attached to each media row/card — currently just
1691
1730
  * exposes "Delete", but kept as its own component so future actions
1692
1731
  * (Duplicate, Archive, etc.) slot in cleanly. */
1693
1732
  function MediaRowActionsMenu({ onDelete }) {
1733
+ const { t } = useShareablesTranslation();
1694
1734
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.DropdownMenu, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.DropdownMenuTrigger, {
1695
1735
  asChild: true,
1696
1736
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Button, {
@@ -1700,7 +1740,7 @@ function MediaRowActionsMenu({ onDelete }) {
1700
1740
  onClick: (e) => {
1701
1741
  e.stopPropagation();
1702
1742
  },
1703
- "aria-label": "Media actions",
1743
+ "aria-label": t("media_actions_aria"),
1704
1744
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.MoreVertical, { className: "h-4 w-4" })
1705
1745
  })
1706
1746
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.DropdownMenuContent, {
@@ -1709,11 +1749,12 @@ function MediaRowActionsMenu({ onDelete }) {
1709
1749
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.DropdownMenuItem, {
1710
1750
  onClick: onDelete,
1711
1751
  className: "text-destructive focus:text-destructive",
1712
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Trash2, { className: "mr-2 h-4 w-4" }), "Delete"]
1752
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Trash2, { className: "mr-2 h-4 w-4" }), t("common_delete")]
1713
1753
  })
1714
1754
  })] });
1715
1755
  }
1716
1756
  function MediaListingScreen(_props) {
1757
+ const { t } = useShareablesTranslation();
1717
1758
  const api = useShareablesApi();
1718
1759
  const repContext = useRepContext();
1719
1760
  const queryClient = (0, _tanstack_react_query.useQueryClient)();
@@ -1735,7 +1776,7 @@ function MediaListingScreen(_props) {
1735
1776
  mutationFn: (id) => api.media.deleteMedia(id),
1736
1777
  onSuccess: () => {
1737
1778
  showToast({
1738
- title: "Media deleted",
1779
+ title: t("media_delete_success"),
1739
1780
  type: "success"
1740
1781
  });
1741
1782
  queryClient.invalidateQueries({ queryKey: shareablesKeys.media.all });
@@ -1743,7 +1784,7 @@ function MediaListingScreen(_props) {
1743
1784
  },
1744
1785
  onError: (error) => {
1745
1786
  showToast({
1746
- title: `Failed to delete: ${error.message}`,
1787
+ title: t("media_delete_error", { message: error.message }),
1747
1788
  type: "error",
1748
1789
  error
1749
1790
  });
@@ -1787,7 +1828,7 @@ function MediaListingScreen(_props) {
1787
1828
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(OwnerFilterTabs, {
1788
1829
  value: ownerFilter,
1789
1830
  onValueChange: setOwnerFilter,
1790
- myLabel: "My Media"
1831
+ myLabel: t("media_my_media_tab")
1791
1832
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1792
1833
  className: "ml-auto flex items-center gap-2",
1793
1834
  children: [
@@ -1796,18 +1837,18 @@ function MediaListingScreen(_props) {
1796
1837
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_PortalProductsApiProvider.SearchSort, {
1797
1838
  searchValue: searchTerm,
1798
1839
  onSearchChange: setSearchTerm,
1799
- placeholder: "Search media...",
1840
+ placeholder: t("media_search_placeholder"),
1800
1841
  sortOptions: [
1801
1842
  {
1802
- label: "Newest",
1843
+ label: t("sort_newest"),
1803
1844
  value: "newest"
1804
1845
  },
1805
1846
  {
1806
- label: "Name (A-Z)",
1847
+ label: t("sort_name_asc"),
1807
1848
  value: "title_asc"
1808
1849
  },
1809
1850
  {
1810
- label: "Name (Z-A)",
1851
+ label: t("sort_name_desc"),
1811
1852
  value: "title_desc"
1812
1853
  }
1813
1854
  ],
@@ -1819,29 +1860,29 @@ function MediaListingScreen(_props) {
1819
1860
  asChild: true,
1820
1861
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.Button, {
1821
1862
  variant: "outline",
1822
- "aria-label": `Filter: ${kindFilter === "all" ? "All types" : kindFilter}`,
1863
+ "aria-label": `Filter: ${kindFilter === "all" ? t("media_filter_all_types") : kindFilter}`,
1823
1864
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Filter, { className: "size-4" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1824
1865
  className: "hidden sm:inline",
1825
- children: kindFilter === "all" ? "All types" : kindFilter === "image" ? "Images" : kindFilter === "video" ? "Videos" : "PDFs"
1866
+ children: kindFilter === "all" ? t("media_filter_all_types") : kindFilter === "image" ? t("media_filter_images") : kindFilter === "video" ? t("media_filter_videos") : t("media_filter_pdfs")
1826
1867
  })]
1827
1868
  })
1828
1869
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.DropdownMenuContent, {
1829
1870
  align: "end",
1830
1871
  children: [
1831
1872
  {
1832
- label: "All types",
1873
+ label: t("media_filter_all_types"),
1833
1874
  value: "all"
1834
1875
  },
1835
1876
  {
1836
- label: "Images",
1877
+ label: t("media_filter_images"),
1837
1878
  value: "image"
1838
1879
  },
1839
1880
  {
1840
- label: "Videos",
1881
+ label: t("media_filter_videos"),
1841
1882
  value: "video"
1842
1883
  },
1843
1884
  {
1844
- label: "PDFs",
1885
+ label: t("media_filter_pdfs"),
1845
1886
  value: "pdf"
1846
1887
  }
1847
1888
  ].map((opt) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.DropdownMenuItem, {
@@ -1864,19 +1905,19 @@ function MediaListingScreen(_props) {
1864
1905
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "border-primary h-6 w-6 animate-spin rounded-full border-2 border-t-transparent" })
1865
1906
  }), error && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
1866
1907
  className: "bg-destructive/10 text-destructive rounded-lg px-3 py-2",
1867
- children: ["Error: ", error.message]
1908
+ children: [t("common_error_prefix"), error.message]
1868
1909
  })] });
1869
1910
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
1870
1911
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_ScreenHeaderContext.ScreenHeaderActions, { children: readOnly ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.Button, {
1871
1912
  onClick: () => navigate("media/new"),
1872
1913
  size: "sm",
1873
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Plus, { className: "mr-1 h-4 w-4" }), "Add Media"]
1914
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Plus, { className: "mr-1 h-4 w-4" }), t("media_add_button")]
1874
1915
  }) }),
1875
1916
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_ScreenHeaderContext.ScreenHeaderBreadcrumbs, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Breadcrumb, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.BreadcrumbList, {
1876
1917
  className: "text-lg",
1877
1918
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.BreadcrumbItem, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.BreadcrumbPage, {
1878
1919
  className: "font-semibold",
1879
- children: "Media"
1920
+ children: t("media_breadcrumb")
1880
1921
  }) })
1881
1922
  }) }) }),
1882
1923
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ShareableListLayout, {
@@ -1887,7 +1928,18 @@ function MediaListingScreen(_props) {
1887
1928
  ownerFilter,
1888
1929
  hasOtherFilters: kindFilter !== "all",
1889
1930
  entityName: "media",
1890
- defaultMessage: "No media available."
1931
+ defaultMessage: t("media_empty_default"),
1932
+ messages: {
1933
+ filterSearchNoResults: t("common_filter_search_no_results", {
1934
+ entityName: "media",
1935
+ searchTerm: debouncedSearch
1936
+ }),
1937
+ searchNoResults: t("common_search_no_results", {
1938
+ entityName: "media",
1939
+ searchTerm: debouncedSearch
1940
+ }),
1941
+ filterNoResults: t("common_filter_no_results", { entityName: "media" })
1942
+ }
1891
1943
  }),
1892
1944
  filters: filterBar,
1893
1945
  footer,
@@ -1903,14 +1955,22 @@ function MediaListingScreen(_props) {
1903
1955
  title: item.title ?? "",
1904
1956
  imageUrl: item.image_url,
1905
1957
  href: `media/${item.id}`,
1906
- badge: { text: getMediaKindLabel(item.kind) },
1958
+ badge: { text: getMediaKindLabel(item.kind, {
1959
+ video: t("media_type_video"),
1960
+ pdf: t("media_type_pdf"),
1961
+ image: t("media_type_image")
1962
+ }) },
1907
1963
  isVideo: item.kind === "video",
1908
1964
  subtitle: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1909
1965
  className: "flex items-center gap-1.5",
1910
- children: [getMediaKindLabel(item.kind), item.owner_type === "user" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Badge, {
1966
+ children: [getMediaKindLabel(item.kind, {
1967
+ video: t("media_type_video"),
1968
+ pdf: t("media_type_pdf"),
1969
+ image: t("media_type_image")
1970
+ }), item.owner_type === "user" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Badge, {
1911
1971
  variant: "secondary",
1912
1972
  className: "px-1.5 py-0 text-[10px] leading-4",
1913
- children: "My Media"
1973
+ children: t("media_my_media_badge")
1914
1974
  })]
1915
1975
  })
1916
1976
  }), canEdit && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
@@ -1926,8 +1986,12 @@ function MediaListingScreen(_props) {
1926
1986
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ShareableListRow, {
1927
1987
  imageUrl: item.image_url,
1928
1988
  imageAlt: item.title ?? "",
1929
- title: item.title ?? "Untitled",
1930
- subtitle: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [getMediaKindLabel(item.kind), item.owner_type === "user" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Badge, {
1989
+ title: item.title ?? t("common_untitled"),
1990
+ subtitle: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [getMediaKindLabel(item.kind, {
1991
+ video: t("media_type_video"),
1992
+ pdf: t("media_type_pdf"),
1993
+ image: t("media_type_image")
1994
+ }), item.owner_type === "user" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Badge, {
1931
1995
  variant: "secondary",
1932
1996
  className: "px-1.5 py-0 text-[10px] leading-4",
1933
1997
  children: "My Media"
@@ -1941,9 +2005,9 @@ function MediaListingScreen(_props) {
1941
2005
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.AlertDialog, {
1942
2006
  open: pendingDeleteId !== null,
1943
2007
  onOpenChange: (open) => !open && setPendingDeleteId(null),
1944
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.AlertDialogContent, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.AlertDialogHeader, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.AlertDialogTitle, { children: "Delete this media?" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.AlertDialogDescription, { children: "This removes the item from your media library. Shared links that point to it will stop working." })] }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.AlertDialogFooter, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.AlertDialogCancel, {
2008
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.AlertDialogContent, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.AlertDialogHeader, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.AlertDialogTitle, { children: t("media_delete_confirm_title") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.AlertDialogDescription, { children: t("media_delete_confirm_description") })] }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.AlertDialogFooter, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.AlertDialogCancel, {
1945
2009
  disabled: isDeleting,
1946
- children: "Cancel"
2010
+ children: t("common_cancel")
1947
2011
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.AlertDialogAction, {
1948
2012
  onClick: (e) => {
1949
2013
  e.preventDefault();
@@ -1951,7 +2015,7 @@ function MediaListingScreen(_props) {
1951
2015
  },
1952
2016
  disabled: isDeleting,
1953
2017
  className: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
1954
- children: isDeleting ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Spinner, { className: "size-4" }) : "Delete"
2018
+ children: isDeleting ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Spinner, { className: "size-4" }) : t("common_delete")
1955
2019
  })] })] })
1956
2020
  })
1957
2021
  ] });
@@ -1974,6 +2038,7 @@ function resolvePrice(product) {
1974
2038
  }
1975
2039
  function TaggedProductsList({ products, onProductClick }) {
1976
2040
  const renderImage = useRenderImage();
2041
+ const { t } = useShareablesTranslation();
1977
2042
  const handleProductClick = (productId, e) => {
1978
2043
  e.stopPropagation();
1979
2044
  if (productId == null) return;
@@ -1985,7 +2050,7 @@ function TaggedProductsList({ products, onProductClick }) {
1985
2050
  className: "mb-4 px-4",
1986
2051
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h2", {
1987
2052
  className: "text-foreground text-[15px] leading-[1.4] font-semibold",
1988
- children: "Tagged Products (0)"
2053
+ children: t("share_tagged_products_count", { count: "0" })
1989
2054
  })
1990
2055
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1991
2056
  className: "flex flex-1 items-center justify-center px-6 py-12",
@@ -1998,11 +2063,11 @@ function TaggedProductsList({ products, onProductClick }) {
1998
2063
  }),
1999
2064
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2000
2065
  className: "text-foreground mb-1 text-sm",
2001
- children: "No Tagged Products"
2066
+ children: t("share_no_tagged_products")
2002
2067
  }),
2003
2068
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2004
2069
  className: "text-muted-foreground text-xs",
2005
- children: "No products are tagged in this playlist"
2070
+ children: t("share_no_tagged_products_description")
2006
2071
  })
2007
2072
  ]
2008
2073
  })
@@ -2012,13 +2077,9 @@ function TaggedProductsList({ products, onProductClick }) {
2012
2077
  className: "mb-6",
2013
2078
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2014
2079
  className: "mb-4 px-4",
2015
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("h2", {
2080
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h2", {
2016
2081
  className: "text-foreground text-[15px] leading-[1.4] font-semibold",
2017
- children: [
2018
- "Tagged Products (",
2019
- products.length,
2020
- ")"
2021
- ]
2082
+ children: t("share_tagged_products_count", { count: String(products.length) })
2022
2083
  })
2023
2084
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2024
2085
  className: "px-4",
@@ -2026,7 +2087,7 @@ function TaggedProductsList({ products, onProductClick }) {
2026
2087
  className: "scrollbar-none flex gap-4 overflow-x-auto pb-2",
2027
2088
  children: products.map((product, index) => {
2028
2089
  const imageUrl = product.images?.[0]?.image_url || product.image_url || product.compressed_image_url || DEFAULT_IMAGE$5;
2029
- const title = product.title || "Untitled";
2090
+ const title = product.title || t("common_untitled");
2030
2091
  const displayPrice = resolvePrice(product);
2031
2092
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
2032
2093
  onClick: (e) => handleProductClick(product.id, e),
@@ -2060,15 +2121,16 @@ function TaggedProductsList({ products, onProductClick }) {
2060
2121
  }
2061
2122
  //#endregion
2062
2123
  //#region ../../shareables/ui/src/components/screens/MediaDetailScreen.tsx
2063
- function getBadgeLabel(kind) {
2124
+ function getBadgeLabel(kind, labels) {
2064
2125
  switch (kind) {
2065
- case "video": return "Video";
2066
- case "image": return "Image";
2067
- case "pdf": return "PDF";
2068
- default: return "Media";
2126
+ case "video": return labels.video;
2127
+ case "image": return labels.image;
2128
+ case "pdf": return labels.pdf;
2129
+ default: return labels.default;
2069
2130
  }
2070
2131
  }
2071
2132
  function MediaDetailScreen({ mediaId, onNavigate, onBack }) {
2133
+ const { t } = useShareablesTranslation();
2072
2134
  const api = useShareablesApi();
2073
2135
  const repContext = useRepContext();
2074
2136
  const { navigate, readOnly, mediaProductsApi } = useShareablesUI();
@@ -2095,7 +2157,12 @@ function MediaDetailScreen({ mediaId, onNavigate, onBack }) {
2095
2157
  const displayImage = mediaItem?.image_url || "";
2096
2158
  const displayVideo = mediaItem?.video_url || "";
2097
2159
  const isVideo = mediaItem?.kind === "video" && !!displayVideo;
2098
- const badgeLabel = getBadgeLabel(mediaItem?.kind ?? null);
2160
+ const badgeLabel = getBadgeLabel(mediaItem?.kind ?? null, {
2161
+ video: t("media_type_video"),
2162
+ image: t("media_type_image"),
2163
+ pdf: t("media_type_pdf"),
2164
+ default: t("media_type_default")
2165
+ });
2099
2166
  const rawDescription = mediaItem?.description?.body || mediaItem?.stripped || "";
2100
2167
  const downloadUrl = isVideo ? displayVideo : mediaItem?.pdf_url || displayImage;
2101
2168
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
@@ -2108,12 +2175,12 @@ function MediaDetailScreen({ mediaId, onNavigate, onBack }) {
2108
2175
  e.preventDefault();
2109
2176
  (onBack ?? (() => navigate("media")))();
2110
2177
  },
2111
- children: "Media"
2178
+ children: t("media_breadcrumb")
2112
2179
  }) }),
2113
2180
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.BreadcrumbSeparator, {}),
2114
2181
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.BreadcrumbItem, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.BreadcrumbPage, {
2115
2182
  className: "block max-w-[60vw] truncate align-bottom font-semibold md:max-w-[60ch]",
2116
- children: displayTitle || "Media"
2183
+ children: displayTitle || t("media_breadcrumb")
2117
2184
  }) })
2118
2185
  ]
2119
2186
  }) }) }),
@@ -2122,12 +2189,12 @@ function MediaDetailScreen({ mediaId, onNavigate, onBack }) {
2122
2189
  variant: "outline",
2123
2190
  onClick: () => navigate(`media/${mediaId}/edit`),
2124
2191
  className: "flex items-center gap-1.5",
2125
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Pencil, { className: "h-3.5 w-3.5" }), "Edit"]
2192
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Pencil, { className: "h-3.5 w-3.5" }), t("common_edit")]
2126
2193
  }) }),
2127
2194
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ShareableDetailLayout, {
2128
2195
  isLoading,
2129
2196
  notFound: !mediaItem,
2130
- notFoundMessage: "Media not found or failed to load.",
2197
+ notFoundMessage: t("media_not_found"),
2131
2198
  title: displayTitle,
2132
2199
  description: rawDescription,
2133
2200
  containerHeightClass: "md:h-[calc(95vh-140px)]",
@@ -7625,7 +7692,8 @@ function useThumbnailMeta(src) {
7625
7692
  }
7626
7693
  //#endregion
7627
7694
  //#region ../../shareables/ui/src/components/playlists/RichTextEditor.tsx
7628
- function RichTextEditor({ value, onChange, placeholder = "Start writing...", className, editorClassName }) {
7695
+ function RichTextEditor({ value, onChange, placeholder, className, editorClassName }) {
7696
+ const { t } = useShareablesTranslation();
7629
7697
  const editor = require_dist$3.useEditor({
7630
7698
  extensions: [
7631
7699
  require_dist$3.StarterKit.configure({
@@ -7638,7 +7706,7 @@ function RichTextEditor({ value, onChange, placeholder = "Start writing...", cla
7638
7706
  keepAttributes: false
7639
7707
  }
7640
7708
  }),
7641
- require_dist$3.Placeholder.configure({ placeholder }),
7709
+ require_dist$3.Placeholder.configure({ placeholder: placeholder ?? t("common_start_writing_placeholder") }),
7642
7710
  require_dist$4.TextAlign.configure({
7643
7711
  types: ["paragraph"],
7644
7712
  alignments: [
@@ -7674,7 +7742,7 @@ function RichTextEditor({ value, onChange, placeholder = "Start writing...", cla
7674
7742
  onClick: () => editor?.chain().focus().toggleBold().run(),
7675
7743
  disabled: !editor?.can().chain().focus().toggleBold().run(),
7676
7744
  className: require_src.cn(buttonBase, "font-bold", editor?.isActive("bold") ? buttonActive : buttonInactive),
7677
- title: "Bold",
7745
+ title: t("editor_bold"),
7678
7746
  children: "B"
7679
7747
  }),
7680
7748
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
@@ -7682,7 +7750,7 @@ function RichTextEditor({ value, onChange, placeholder = "Start writing...", cla
7682
7750
  onClick: () => editor?.chain().focus().toggleItalic().run(),
7683
7751
  disabled: !editor?.can().chain().focus().toggleItalic().run(),
7684
7752
  className: require_src.cn(buttonBase, "italic", editor?.isActive("italic") ? buttonActive : buttonInactive),
7685
- title: "Italic",
7753
+ title: t("editor_italic"),
7686
7754
  children: "I"
7687
7755
  }),
7688
7756
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
@@ -7690,7 +7758,7 @@ function RichTextEditor({ value, onChange, placeholder = "Start writing...", cla
7690
7758
  onClick: () => editor?.chain().focus().toggleUnderline().run(),
7691
7759
  disabled: !editor?.can().chain().focus().toggleUnderline().run(),
7692
7760
  className: require_src.cn(buttonBase, "underline", editor?.isActive("underline") ? buttonActive : buttonInactive),
7693
- title: "Underline",
7761
+ title: t("editor_underline"),
7694
7762
  children: "U"
7695
7763
  }),
7696
7764
  separator,
@@ -7698,28 +7766,28 @@ function RichTextEditor({ value, onChange, placeholder = "Start writing...", cla
7698
7766
  type: "button",
7699
7767
  onClick: () => editor?.chain().focus().setTextAlign("left").run(),
7700
7768
  className: require_src.cn(buttonBase, editor?.isActive({ textAlign: "left" }) ? buttonActive : buttonInactive),
7701
- title: "Align left",
7769
+ title: t("editor_align_left"),
7702
7770
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.AlignLeft, { className: "h-3.5 w-3.5" })
7703
7771
  }),
7704
7772
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
7705
7773
  type: "button",
7706
7774
  onClick: () => editor?.chain().focus().setTextAlign("center").run(),
7707
7775
  className: require_src.cn(buttonBase, editor?.isActive({ textAlign: "center" }) ? buttonActive : buttonInactive),
7708
- title: "Align center",
7776
+ title: t("editor_align_center"),
7709
7777
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.AlignCenter, { className: "h-3.5 w-3.5" })
7710
7778
  }),
7711
7779
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
7712
7780
  type: "button",
7713
7781
  onClick: () => editor?.chain().focus().setTextAlign("right").run(),
7714
7782
  className: require_src.cn(buttonBase, editor?.isActive({ textAlign: "right" }) ? buttonActive : buttonInactive),
7715
- title: "Align right",
7783
+ title: t("editor_align_right"),
7716
7784
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.AlignRight, { className: "h-3.5 w-3.5" })
7717
7785
  }),
7718
7786
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
7719
7787
  type: "button",
7720
7788
  onClick: () => editor?.chain().focus().setTextAlign("justify").run(),
7721
7789
  className: require_src.cn(buttonBase, editor?.isActive({ textAlign: "justify" }) ? buttonActive : buttonInactive),
7722
- title: "Justify",
7790
+ title: t("editor_justify"),
7723
7791
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.AlignJustify, { className: "h-3.5 w-3.5" })
7724
7792
  }),
7725
7793
  separator,
@@ -7727,14 +7795,14 @@ function RichTextEditor({ value, onChange, placeholder = "Start writing...", cla
7727
7795
  type: "button",
7728
7796
  onClick: () => editor?.chain().focus().toggleBulletList().run(),
7729
7797
  className: require_src.cn(buttonBase, editor?.isActive("bulletList") ? buttonActive : buttonInactive),
7730
- title: "Bullet list",
7798
+ title: t("editor_bullet_list"),
7731
7799
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.List, { className: "h-3.5 w-3.5" })
7732
7800
  }),
7733
7801
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
7734
7802
  type: "button",
7735
7803
  onClick: () => editor?.chain().focus().toggleOrderedList().run(),
7736
7804
  className: require_src.cn(buttonBase, editor?.isActive("orderedList") ? buttonActive : buttonInactive),
7737
- title: "Ordered list",
7805
+ title: t("editor_ordered_list"),
7738
7806
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ListOrdered, { className: "h-3.5 w-3.5" })
7739
7807
  })
7740
7808
  ]
@@ -7779,10 +7847,11 @@ function RichTextEditor({ value, onChange, placeholder = "Start writing...", cla
7779
7847
  //#region ../../shareables/ui/src/components/media/MediaProductTagging.tsx
7780
7848
  const PAGE_SIZE$3 = 25;
7781
7849
  function ProductImage({ imageUrl, name }) {
7850
+ const { t } = useShareablesTranslation();
7782
7851
  const [errored, setErrored] = (0, react.useState)(false);
7783
7852
  if (imageUrl && imageUrl.length > 0 && !errored) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
7784
7853
  src: imageUrl,
7785
- alt: name ?? "Product",
7854
+ alt: name ?? t("common_product"),
7786
7855
  width: 40,
7787
7856
  height: 40,
7788
7857
  className: "h-10 w-10 shrink-0 rounded object-cover",
@@ -7794,6 +7863,7 @@ function ProductImage({ imageUrl, name }) {
7794
7863
  });
7795
7864
  }
7796
7865
  function MediaProductTagging({ products, onAddProduct, onRemoveProduct, onSearchProducts, disabled = false, maxProducts = 100 }) {
7866
+ const { t } = useShareablesTranslation();
7797
7867
  const { showToast } = useShareablesUI();
7798
7868
  const [isModalOpen, setIsModalOpen] = (0, react.useState)(false);
7799
7869
  const [query, setQuery] = (0, react.useState)("");
@@ -7818,7 +7888,7 @@ function MediaProductTagging({ products, onAddProduct, onRemoveProduct, onSearch
7818
7888
  setSearchResults([]);
7819
7889
  setNextCursor(null);
7820
7890
  showToast({
7821
- title: "Failed to load products. Please try again.",
7891
+ title: t("products_load_error"),
7822
7892
  type: "error",
7823
7893
  error
7824
7894
  });
@@ -7839,7 +7909,7 @@ function MediaProductTagging({ products, onAddProduct, onRemoveProduct, onSearch
7839
7909
  } catch (error) {
7840
7910
  setNextCursor(null);
7841
7911
  showToast({
7842
- title: "Failed to load more products.",
7912
+ title: t("products_load_more_error"),
7843
7913
  type: "error",
7844
7914
  error
7845
7915
  });
@@ -7898,7 +7968,7 @@ function MediaProductTagging({ products, onAddProduct, onRemoveProduct, onSearch
7898
7968
  runSearch(query);
7899
7969
  } catch (error) {
7900
7970
  showToast({
7901
- title: "Failed to add product. Please try again.",
7971
+ title: t("products_add_error"),
7902
7972
  type: "error",
7903
7973
  error
7904
7974
  });
@@ -7912,7 +7982,7 @@ function MediaProductTagging({ products, onAddProduct, onRemoveProduct, onSearch
7912
7982
  await onRemoveProduct(productId);
7913
7983
  } catch (error) {
7914
7984
  showToast({
7915
- title: "Failed to remove product. Please try again.",
7985
+ title: t("products_remove_error"),
7916
7986
  type: "error",
7917
7987
  error
7918
7988
  });
@@ -7925,7 +7995,7 @@ function MediaProductTagging({ products, onAddProduct, onRemoveProduct, onSearch
7925
7995
  children: [
7926
7996
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
7927
7997
  className: "text-foreground mb-4 text-base font-semibold",
7928
- children: "Tagged Products"
7998
+ children: t("media_tagged_products_heading")
7929
7999
  }),
7930
8000
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
7931
8001
  className: "space-y-3",
@@ -7933,39 +8003,37 @@ function MediaProductTagging({ products, onAddProduct, onRemoveProduct, onSearch
7933
8003
  className: "rounded-lg border border-dashed border-gray-200 p-4 text-center",
7934
8004
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
7935
8005
  className: "mb-3 text-sm text-gray-500",
7936
- children: "No products tagged yet."
8006
+ children: t("media_no_products_tagged")
7937
8007
  }), !disabled && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.Button, {
7938
8008
  type: "button",
7939
8009
  onClick: handleOpenModal,
7940
8010
  size: "sm",
7941
8011
  className: "gap-1.5",
7942
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Plus, { className: "h-3 w-3" }), "Add Product"]
8012
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Plus, { className: "h-3 w-3" }), t("media_add_product_button")]
7943
8013
  })]
7944
8014
  }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7945
8015
  className: "relative space-y-4",
7946
8016
  children: [
7947
8017
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7948
8018
  className: "flex items-center justify-between",
7949
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
8019
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
7950
8020
  className: "text-xs text-gray-500",
7951
- children: [
7952
- products.length,
7953
- " of ",
7954
- maxProducts,
7955
- " products selected"
7956
- ]
8021
+ children: t("media_products_selected_count", {
8022
+ current: String(products.length),
8023
+ max: String(maxProducts)
8024
+ })
7957
8025
  }), !disabled && !isAtMaxLimit && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.Button, {
7958
8026
  type: "button",
7959
8027
  onClick: handleOpenModal,
7960
8028
  variant: "outline",
7961
8029
  size: "sm",
7962
8030
  className: "gap-1.5 text-xs",
7963
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Plus, { className: "h-3 w-3" }), "Add Products"]
8031
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Plus, { className: "h-3 w-3" }), t("media_add_products_button")]
7964
8032
  })]
7965
8033
  }),
7966
8034
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
7967
8035
  className: "text-xs text-gray-500",
7968
- children: "Products will only display in available countries."
8036
+ children: t("media_products_country_note")
7969
8037
  }),
7970
8038
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
7971
8039
  className: "max-h-96 space-y-2 overflow-y-auto pb-2",
@@ -7978,10 +8046,10 @@ function MediaProductTagging({ products, onAddProduct, onRemoveProduct, onSearch
7978
8046
  name: product.name
7979
8047
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
7980
8048
  className: "text-sm font-medium text-gray-900",
7981
- children: product.name ?? `Product #${product.id}`
8049
+ children: product.name ?? t("media_product_fallback_name", { id: String(product.id) })
7982
8050
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
7983
8051
  className: "text-xs text-gray-500",
7984
- children: product.price ? `$${product.price}` : "N/A"
8052
+ children: product.price ? `$${product.price}` : t("common_na")
7985
8053
  })] })]
7986
8054
  }), !disabled && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Button, {
7987
8055
  type: "button",
@@ -7990,17 +8058,13 @@ function MediaProductTagging({ products, onAddProduct, onRemoveProduct, onSearch
7990
8058
  onClick: () => void handleRemove(product.id),
7991
8059
  disabled: removingId === product.id,
7992
8060
  className: "text-xs text-red-600 hover:bg-red-50 hover:text-red-700",
7993
- children: removingId === product.id ? "Removing..." : "Remove"
8061
+ children: removingId === product.id ? t("common_removing") : t("common_remove")
7994
8062
  })]
7995
8063
  }, product.id))
7996
8064
  }),
7997
- isAtMaxLimit && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
8065
+ isAtMaxLimit && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
7998
8066
  className: "py-2 text-center text-xs text-gray-500",
7999
- children: [
8000
- "Maximum ",
8001
- maxProducts,
8002
- " products reached"
8003
- ]
8067
+ children: t("media_max_products_reached", { max: String(maxProducts) })
8004
8068
  })
8005
8069
  ]
8006
8070
  })
@@ -8011,31 +8075,24 @@ function MediaProductTagging({ products, onAddProduct, onRemoveProduct, onSearch
8011
8075
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.DialogContent, {
8012
8076
  className: "max-w-2xl",
8013
8077
  children: [
8014
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.DialogHeader, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.DialogTitle, { children: ["Select Products to Tag", /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
8078
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.DialogHeader, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.DialogTitle, { children: [t("media_select_products_title"), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
8015
8079
  className: "ml-2 text-sm font-normal text-gray-500",
8016
- children: [
8017
- "(",
8018
- products.length,
8019
- "/",
8020
- maxProducts,
8021
- " selected)"
8022
- ]
8080
+ children: t("media_products_selected_ratio", {
8081
+ current: String(products.length),
8082
+ max: String(maxProducts)
8083
+ })
8023
8084
  })] }) }),
8024
8085
  isAtMaxLimit && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
8025
8086
  className: "rounded-md border border-yellow-200 bg-yellow-50 p-3",
8026
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
8087
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
8027
8088
  className: "text-sm text-yellow-800",
8028
- children: [
8029
- "You have reached the maximum limit of ",
8030
- maxProducts,
8031
- " products."
8032
- ]
8089
+ children: t("media_max_products_warning", { max: String(maxProducts) })
8033
8090
  })
8034
8091
  }),
8035
8092
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8036
8093
  className: "relative",
8037
8094
  children: [searching ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Spinner, { className: "absolute top-1/2 left-3 size-4 -translate-y-1/2" }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Search, { className: "absolute top-1/2 left-3 size-4 -translate-y-1/2 text-gray-400" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Input, {
8038
- placeholder: "Search products...",
8095
+ placeholder: t("products_search_placeholder"),
8039
8096
  value: query,
8040
8097
  onChange: (e) => setQuery(e.target.value),
8041
8098
  className: "pl-10",
@@ -8050,7 +8107,7 @@ function MediaProductTagging({ products, onAddProduct, onRemoveProduct, onSearch
8050
8107
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Spinner, { className: "size-5" })
8051
8108
  }) : searchResults.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
8052
8109
  className: "py-8 text-center text-sm text-gray-500",
8053
- children: query.length > 0 ? "No products found matching your search." : "Start typing to search for products."
8110
+ children: query.length > 0 ? t("products_search_no_results") : t("products_search_start_typing")
8054
8111
  }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8055
8112
  className: "space-y-2 px-1",
8056
8113
  children: [searchResults.map((result) => {
@@ -8065,7 +8122,7 @@ function MediaProductTagging({ products, onAddProduct, onRemoveProduct, onSearch
8065
8122
  name: result.name
8066
8123
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
8067
8124
  className: `text-sm font-medium ${canAdd ? "text-gray-900" : "text-gray-500"}`,
8068
- children: result.name ?? `Product #${result.id}`
8125
+ children: result.name ?? t("media_product_fallback_name", { id: String(result.id) })
8069
8126
  }), result.price && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
8070
8127
  className: "text-xs text-gray-500",
8071
8128
  children: ["$", result.price]
@@ -8079,7 +8136,7 @@ function MediaProductTagging({ products, onAddProduct, onRemoveProduct, onSearch
8079
8136
  },
8080
8137
  disabled: !canAdd || addingId === result.id,
8081
8138
  className: isTagged ? "text-green-600" : "",
8082
- children: addingId === result.id ? "Adding..." : isTagged ? "Added" : canAdd ? "Add" : "Limit reached"
8139
+ children: addingId === result.id ? t("common_adding") : isTagged ? t("common_added") : canAdd ? t("common_add") : t("media_limit_reached")
8083
8140
  })]
8084
8141
  }, result.id);
8085
8142
  }), nextCursor !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
@@ -8095,7 +8152,7 @@ function MediaProductTagging({ products, onAddProduct, onRemoveProduct, onSearch
8095
8152
  type: "button",
8096
8153
  variant: "outline",
8097
8154
  onClick: () => setIsModalOpen(false),
8098
- children: "Done"
8155
+ children: t("common_done")
8099
8156
  })
8100
8157
  })
8101
8158
  ]
@@ -8106,29 +8163,30 @@ function MediaProductTagging({ products, onAddProduct, onRemoveProduct, onSearch
8106
8163
  }
8107
8164
  //#endregion
8108
8165
  //#region ../../shareables/ui/src/components/media/CtaModal.tsx
8109
- const CTA_TYPES = [
8110
- {
8111
- value: "link",
8112
- label: "Page",
8113
- icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Globe, { className: "h-3.5 w-3.5 text-gray-500" })
8114
- },
8115
- {
8116
- value: "cart",
8117
- label: "Cart",
8118
- icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ShoppingCart, { className: "h-3.5 w-3.5 text-gray-500" })
8119
- },
8120
- {
8121
- value: "email",
8122
- label: "Email",
8123
- icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Mail, { className: "h-3.5 w-3.5 text-gray-500" })
8124
- },
8125
- {
8126
- value: "phone",
8127
- label: "Phone",
8128
- icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Phone, { className: "h-3.5 w-3.5 text-gray-500" })
8129
- }
8130
- ];
8131
8166
  function CtaModal({ open, onOpenChange, ctaEnabled, ctaType, ctaButtonText, ctaUrl, onDone }) {
8167
+ const { t } = useShareablesTranslation();
8168
+ const CTA_TYPES = (0, react.useMemo)(() => [
8169
+ {
8170
+ value: "link",
8171
+ label: t("cta_type_page"),
8172
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Globe, { className: "h-3.5 w-3.5 text-gray-500" })
8173
+ },
8174
+ {
8175
+ value: "cart",
8176
+ label: t("cta_type_cart"),
8177
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ShoppingCart, { className: "h-3.5 w-3.5 text-gray-500" })
8178
+ },
8179
+ {
8180
+ value: "email",
8181
+ label: t("cta_type_email"),
8182
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Mail, { className: "h-3.5 w-3.5 text-gray-500" })
8183
+ },
8184
+ {
8185
+ value: "phone",
8186
+ label: t("cta_type_phone"),
8187
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Phone, { className: "h-3.5 w-3.5 text-gray-500" })
8188
+ }
8189
+ ], [t]);
8132
8190
  const [enabled, setEnabled] = (0, react.useState)(ctaEnabled);
8133
8191
  const [type, setType] = (0, react.useState)(ctaType || "link");
8134
8192
  const [buttonText, setButtonText] = (0, react.useState)(ctaButtonText);
@@ -8137,7 +8195,7 @@ function CtaModal({ open, onOpenChange, ctaEnabled, ctaType, ctaButtonText, ctaU
8137
8195
  if (open) {
8138
8196
  setEnabled(ctaEnabled);
8139
8197
  setType(ctaType || "link");
8140
- setButtonText(ctaButtonText || "Learn More");
8198
+ setButtonText(ctaButtonText || t("cta_default_button_text"));
8141
8199
  setUrl(ctaUrl);
8142
8200
  }
8143
8201
  }, [
@@ -8149,7 +8207,7 @@ function CtaModal({ open, onOpenChange, ctaEnabled, ctaType, ctaButtonText, ctaU
8149
8207
  ]);
8150
8208
  const handleEnable = (checked) => {
8151
8209
  setEnabled(checked);
8152
- if (checked && !buttonText) setButtonText("Learn More");
8210
+ if (checked && !buttonText) setButtonText(t("cta_default_button_text"));
8153
8211
  };
8154
8212
  const handleCancel = () => {
8155
8213
  onOpenChange(false);
@@ -8170,10 +8228,10 @@ function CtaModal({ open, onOpenChange, ctaEnabled, ctaType, ctaButtonText, ctaU
8170
8228
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.DialogContent, {
8171
8229
  className: "max-w-lg",
8172
8230
  children: [
8173
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.DialogHeader, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.DialogTitle, { children: "CTA Button" }) }),
8231
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.DialogHeader, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.DialogTitle, { children: t("cta_dialog_title") }) }),
8174
8232
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
8175
8233
  className: "mt-1 text-sm text-gray-500",
8176
- children: "Configure the call-to-action button that appears with your media."
8234
+ children: t("cta_dialog_description")
8177
8235
  }),
8178
8236
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8179
8237
  className: "space-y-5",
@@ -8182,7 +8240,7 @@ function CtaModal({ open, onOpenChange, ctaEnabled, ctaType, ctaButtonText, ctaU
8182
8240
  className: "flex items-center justify-between border-b border-gray-200 pb-4",
8183
8241
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
8184
8242
  className: "text-sm font-medium text-gray-700",
8185
- children: "Enable call-to-action button"
8243
+ children: t("cta_enable_toggle_label")
8186
8244
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Switch, {
8187
8245
  checked: enabled,
8188
8246
  onCheckedChange: handleEnable
@@ -8194,21 +8252,21 @@ function CtaModal({ open, onOpenChange, ctaEnabled, ctaType, ctaButtonText, ctaU
8194
8252
  className: "flex flex-col gap-1.5",
8195
8253
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Label, {
8196
8254
  className: fieldsDisabled ? "text-gray-400" : "text-gray-700",
8197
- children: "Action Type"
8255
+ children: t("cta_action_type_label")
8198
8256
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.Select, {
8199
8257
  value: type,
8200
8258
  onValueChange: (v) => setType(v),
8201
8259
  disabled: fieldsDisabled,
8202
8260
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.SelectTrigger, {
8203
8261
  className: `w-full ${fieldsDisabled ? "opacity-50" : ""}`,
8204
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.SelectValue, { placeholder: "Select type" })
8205
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.SelectContent, { children: CTA_TYPES.map((t) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.SelectItem, {
8206
- value: t.value,
8262
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.SelectValue, { placeholder: t("cta_type_placeholder") })
8263
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.SelectContent, { children: CTA_TYPES.map((ctaOption) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.SelectItem, {
8264
+ value: ctaOption.value,
8207
8265
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
8208
8266
  className: "flex items-center gap-2",
8209
- children: [t.icon, t.label]
8267
+ children: [ctaOption.icon, ctaOption.label]
8210
8268
  })
8211
- }, t.value)) })]
8269
+ }, ctaOption.value)) })]
8212
8270
  })]
8213
8271
  }), type !== "cart" ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8214
8272
  className: "flex flex-col gap-1.5",
@@ -8216,12 +8274,12 @@ function CtaModal({ open, onOpenChange, ctaEnabled, ctaType, ctaButtonText, ctaU
8216
8274
  className: "flex items-center gap-1.5",
8217
8275
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Label, {
8218
8276
  className: fieldsDisabled ? "text-gray-400" : "text-gray-700",
8219
- children: "Button Label"
8277
+ children: t("cta_button_label")
8220
8278
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.HelpCircle, { className: "h-3.5 w-3.5 text-gray-400" })]
8221
8279
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Input, {
8222
8280
  value: buttonText,
8223
8281
  onChange: (e) => setButtonText(e.target.value),
8224
- placeholder: "Learn More",
8282
+ placeholder: t("cta_default_button_text"),
8225
8283
  disabled: fieldsDisabled,
8226
8284
  className: fieldsDisabled ? "opacity-50" : ""
8227
8285
  })]
@@ -8233,12 +8291,12 @@ function CtaModal({ open, onOpenChange, ctaEnabled, ctaType, ctaButtonText, ctaU
8233
8291
  className: "flex items-center gap-1.5",
8234
8292
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Label, {
8235
8293
  className: fieldsDisabled ? "text-gray-400" : "text-gray-700",
8236
- children: "URL"
8294
+ children: t("cta_url_label")
8237
8295
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.HelpCircle, { className: "h-3.5 w-3.5 text-gray-400" })]
8238
8296
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Input, {
8239
8297
  value: url,
8240
8298
  onChange: (e) => setUrl(e.target.value),
8241
- placeholder: "https://example.com",
8299
+ placeholder: t("cta_url_placeholder"),
8242
8300
  type: "url",
8243
8301
  disabled: fieldsDisabled,
8244
8302
  className: fieldsDisabled ? "opacity-50" : ""
@@ -8251,10 +8309,10 @@ function CtaModal({ open, onOpenChange, ctaEnabled, ctaType, ctaButtonText, ctaU
8251
8309
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Button, {
8252
8310
  variant: "outline",
8253
8311
  onClick: handleCancel,
8254
- children: "Cancel"
8312
+ children: t("common_cancel")
8255
8313
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Button, {
8256
8314
  onClick: handleDone,
8257
- children: "Done"
8315
+ children: t("common_done")
8258
8316
  })]
8259
8317
  })
8260
8318
  ]
@@ -8267,6 +8325,7 @@ function formatTime(seconds) {
8267
8325
  return `${Math.floor(seconds / 60)}:${Math.floor(seconds % 60).toString().padStart(2, "0")}`;
8268
8326
  }
8269
8327
  function VideoThumbnailSelector({ videoUrl, thumbnailUrl, onThumbnailCaptured, onThumbnailSelected, disabled = false }) {
8328
+ const { t } = useShareablesTranslation();
8270
8329
  const { showToast } = useShareablesUI();
8271
8330
  const [frameSelectorOpen, setFrameSelectorOpen] = (0, react.useState)(false);
8272
8331
  const [isPlaying, setIsPlaying] = (0, react.useState)(false);
@@ -8325,20 +8384,24 @@ function VideoThumbnailSelector({ videoUrl, thumbnailUrl, onThumbnailCaptured, o
8325
8384
  onThumbnailCaptured(blob);
8326
8385
  setFrameSelectorOpen(false);
8327
8386
  } else showToast({
8328
- title: "Couldn't capture the video frame. Please try again.",
8387
+ title: t("media_frame_capture_error"),
8329
8388
  type: "error"
8330
8389
  });
8331
8390
  setCapturing(false);
8332
8391
  }, "image/jpeg", .92);
8333
8392
  } catch (error) {
8334
8393
  showToast({
8335
- title: "Couldn't capture the video frame. Please try again.",
8394
+ title: t("media_frame_capture_error"),
8336
8395
  type: "error",
8337
8396
  error
8338
8397
  });
8339
8398
  setCapturing(false);
8340
8399
  }
8341
- }, [onThumbnailCaptured, showToast]);
8400
+ }, [
8401
+ onThumbnailCaptured,
8402
+ showToast,
8403
+ t
8404
+ ]);
8342
8405
  const handleOpenDialog = (0, react.useCallback)(() => {
8343
8406
  setIsPlaying(false);
8344
8407
  setCurrentTime(0);
@@ -8351,7 +8414,7 @@ function VideoThumbnailSelector({ videoUrl, thumbnailUrl, onThumbnailCaptured, o
8351
8414
  className: "space-y-3",
8352
8415
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
8353
8416
  className: "text-foreground mb-1.5 block text-sm font-medium",
8354
- children: "Thumbnail"
8417
+ children: t("media_thumbnail_label")
8355
8418
  }), thumbnailUrl ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8356
8419
  className: "flex items-start gap-4",
8357
8420
  children: [imgLoadError ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
@@ -8359,7 +8422,7 @@ function VideoThumbnailSelector({ videoUrl, thumbnailUrl, onThumbnailCaptured, o
8359
8422
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ImageIcon, { className: "text-muted-foreground h-8 w-8" })
8360
8423
  }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
8361
8424
  src: thumbnailUrl,
8362
- alt: "Video thumbnail",
8425
+ alt: t("media_video_thumbnail_alt"),
8363
8426
  className: "w-48 shrink-0 rounded-md border object-contain",
8364
8427
  onLoad: handleImgLoad,
8365
8428
  onError: handleImgError
@@ -8390,13 +8453,13 @@ function VideoThumbnailSelector({ videoUrl, thumbnailUrl, onThumbnailCaptured, o
8390
8453
  size: "sm",
8391
8454
  onClick: handleOpenDialog,
8392
8455
  className: "gap-1.5",
8393
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Camera, { className: "h-3.5 w-3.5" }), "Select from video frame"]
8456
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Camera, { className: "h-3.5 w-3.5" }), t("media_select_from_video_frame")]
8394
8457
  }), onThumbnailSelected && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.Button, {
8395
8458
  variant: "outline",
8396
8459
  size: "sm",
8397
8460
  onClick: onThumbnailSelected,
8398
8461
  className: "gap-1.5",
8399
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ImageIcon, { className: "h-3.5 w-3.5" }), "Select New Image"]
8462
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ImageIcon, { className: "h-3.5 w-3.5" }), t("media_select_new_image")]
8400
8463
  })]
8401
8464
  })
8402
8465
  ]
@@ -8410,7 +8473,7 @@ function VideoThumbnailSelector({ videoUrl, thumbnailUrl, onThumbnailCaptured, o
8410
8473
  className: "min-w-0 flex-1",
8411
8474
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
8412
8475
  className: "text-muted-foreground text-sm",
8413
- children: "No thumbnail set"
8476
+ children: t("media_no_thumbnail")
8414
8477
  }), !disabled && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
8415
8478
  className: "mt-2",
8416
8479
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.Button, {
@@ -8418,7 +8481,7 @@ function VideoThumbnailSelector({ videoUrl, thumbnailUrl, onThumbnailCaptured, o
8418
8481
  size: "sm",
8419
8482
  onClick: handleOpenDialog,
8420
8483
  className: "gap-1.5",
8421
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Camera, { className: "h-3.5 w-3.5" }), "Select Video Frame"]
8484
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Camera, { className: "h-3.5 w-3.5" }), t("media_select_video_frame")]
8422
8485
  })
8423
8486
  })]
8424
8487
  })]
@@ -8428,7 +8491,7 @@ function VideoThumbnailSelector({ videoUrl, thumbnailUrl, onThumbnailCaptured, o
8428
8491
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.DialogContent, {
8429
8492
  className: "max-w-2xl",
8430
8493
  children: [
8431
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.DialogHeader, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.DialogTitle, { children: "Select Video Frame" }) }),
8494
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.DialogHeader, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.DialogTitle, { children: t("media_select_video_frame") }) }),
8432
8495
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8433
8496
  className: "space-y-4",
8434
8497
  children: [
@@ -8480,7 +8543,7 @@ function VideoThumbnailSelector({ videoUrl, thumbnailUrl, onThumbnailCaptured, o
8480
8543
  onClick: handleCapture,
8481
8544
  disabled: !isMetadataLoaded || capturing,
8482
8545
  className: "w-full gap-2",
8483
- children: [capturing ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Spinner, { className: "size-4" }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Camera, { className: "h-4 w-4" }), "Capture Frame"]
8546
+ children: [capturing ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Spinner, { className: "size-4" }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Camera, { className: "h-4 w-4" }), t("media_capture_frame")]
8484
8547
  })
8485
8548
  ]
8486
8549
  }),
@@ -8528,6 +8591,7 @@ function buildEditState(mediaItem) {
8528
8591
  };
8529
8592
  }
8530
8593
  function ThumbnailWithMeta({ src, onReplace }) {
8594
+ const { t } = useShareablesTranslation();
8531
8595
  const { meta, fileName, handleLoad, handleError, loadError } = useThumbnailMeta(src);
8532
8596
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8533
8597
  className: "flex items-start gap-4",
@@ -8536,7 +8600,7 @@ function ThumbnailWithMeta({ src, onReplace }) {
8536
8600
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ImageIcon, { className: "text-muted-foreground h-8 w-8" })
8537
8601
  }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
8538
8602
  src,
8539
- alt: "Thumbnail",
8603
+ alt: t("media_thumbnail_alt"),
8540
8604
  className: "w-48 shrink-0 rounded-md border object-contain",
8541
8605
  onLoad: handleLoad,
8542
8606
  onError: handleError
@@ -8567,7 +8631,7 @@ function ThumbnailWithMeta({ src, onReplace }) {
8567
8631
  size: "sm",
8568
8632
  onClick: onReplace,
8569
8633
  className: "gap-1.5",
8570
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ImageIcon, { className: "h-3.5 w-3.5" }), "Select New Image"]
8634
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ImageIcon, { className: "h-3.5 w-3.5" }), t("media_select_new_image")]
8571
8635
  })
8572
8636
  })
8573
8637
  ]
@@ -8575,6 +8639,7 @@ function ThumbnailWithMeta({ src, onReplace }) {
8575
8639
  });
8576
8640
  }
8577
8641
  function CurrentMediaPreview({ mediaItem, pendingFileUrl, pendingKind }) {
8642
+ const { t } = useShareablesTranslation();
8578
8643
  const effectiveKind = pendingKind ?? mediaItem.content_format ?? mediaItem.kind;
8579
8644
  const effectiveVideoUrl = pendingKind === "video" ? pendingFileUrl : mediaItem.video_url;
8580
8645
  const effectiveImageUrl = pendingKind === "image" ? pendingFileUrl : pendingKind ? null : mediaItem.image_url;
@@ -8611,11 +8676,12 @@ function CurrentMediaPreview({ mediaItem, pendingFileUrl, pendingKind }) {
8611
8676
  className: "border-border text-muted-foreground flex h-40 w-full flex-col items-center justify-center gap-2 rounded-lg border",
8612
8677
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ImageIcon, { className: "h-6 w-6" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
8613
8678
  className: "text-sm",
8614
- children: "No media available"
8679
+ children: t("media_no_media_available")
8615
8680
  })]
8616
8681
  });
8617
8682
  }
8618
8683
  function MediaEditScreen({ mediaId, onNavigate: _onNavigate, onBack }) {
8684
+ const { t } = useShareablesTranslation();
8619
8685
  const api = useShareablesApi();
8620
8686
  const repContext = useRepContext();
8621
8687
  const queryClient = (0, _tanstack_react_query.useQueryClient)();
@@ -8694,13 +8760,13 @@ function MediaEditScreen({ mediaId, onNavigate: _onNavigate, onBack }) {
8694
8760
  setPendingMediaFile(null);
8695
8761
  setPendingThumbnail(null);
8696
8762
  showToast({
8697
- title: "Media saved successfully",
8763
+ title: t("media_save_success"),
8698
8764
  type: "success"
8699
8765
  });
8700
8766
  },
8701
8767
  onError: (error) => {
8702
8768
  showToast({
8703
- title: `Failed to save: ${error.message}`,
8769
+ title: t("media_save_error", { message: error.message }),
8704
8770
  type: "error",
8705
8771
  error
8706
8772
  });
@@ -8710,14 +8776,14 @@ function MediaEditScreen({ mediaId, onNavigate: _onNavigate, onBack }) {
8710
8776
  mutationFn: () => api.media.deleteMedia(Number(mediaId)),
8711
8777
  onSuccess: () => {
8712
8778
  showToast({
8713
- title: "Media deleted",
8779
+ title: t("media_delete_success"),
8714
8780
  type: "success"
8715
8781
  });
8716
8782
  navigate("media");
8717
8783
  },
8718
8784
  onError: (error) => {
8719
8785
  showToast({
8720
- title: `Failed to delete: ${error.message}`,
8786
+ title: t("media_delete_error", { message: error.message }),
8721
8787
  type: "error",
8722
8788
  error
8723
8789
  });
@@ -8760,7 +8826,7 @@ function MediaEditScreen({ mediaId, onNavigate: _onNavigate, onBack }) {
8760
8826
  className: "flex flex-col items-center justify-center py-16",
8761
8827
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
8762
8828
  className: "text-destructive text-sm",
8763
- children: "Media not found or failed to load."
8829
+ children: t("media_not_found")
8764
8830
  })
8765
8831
  });
8766
8832
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
@@ -8773,7 +8839,7 @@ function MediaEditScreen({ mediaId, onNavigate: _onNavigate, onBack }) {
8773
8839
  e.preventDefault();
8774
8840
  (onBack ?? (() => navigate("media")))();
8775
8841
  },
8776
- children: "Media"
8842
+ children: t("media_breadcrumb")
8777
8843
  }) }),
8778
8844
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.BreadcrumbSeparator, {}),
8779
8845
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.BreadcrumbItem, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.BreadcrumbLink, {
@@ -8783,12 +8849,12 @@ function MediaEditScreen({ mediaId, onNavigate: _onNavigate, onBack }) {
8783
8849
  navigate(`media/${mediaId}`);
8784
8850
  },
8785
8851
  className: "block max-w-[40vw] truncate align-bottom md:max-w-[60ch]",
8786
- children: displayTitle || "Media"
8852
+ children: displayTitle || t("media_breadcrumb")
8787
8853
  }) }),
8788
8854
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.BreadcrumbSeparator, {}),
8789
8855
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.BreadcrumbItem, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.BreadcrumbPage, {
8790
8856
  className: "font-semibold",
8791
- children: "Edit"
8857
+ children: t("common_edit")
8792
8858
  }) })
8793
8859
  ]
8794
8860
  }) }) }),
@@ -8807,13 +8873,13 @@ function MediaEditScreen({ mediaId, onNavigate: _onNavigate, onBack }) {
8807
8873
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.DropdownMenuItem, {
8808
8874
  onClick: () => setIsDeleteOpen(true),
8809
8875
  className: "text-destructive focus:text-destructive",
8810
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Trash2, { className: "mr-2 h-4 w-4" }), "Delete"]
8876
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Trash2, { className: "mr-2 h-4 w-4" }), t("common_delete")]
8811
8877
  })
8812
8878
  })] }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Button, {
8813
8879
  onClick: handleSave,
8814
8880
  disabled: !isDirty || isSaving,
8815
8881
  size: "sm",
8816
- children: isSaving ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Spinner, { className: "size-4" }) : "Save"
8882
+ children: isSaving ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Spinner, { className: "size-4" }) : t("common_save")
8817
8883
  })]
8818
8884
  }) }),
8819
8885
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
@@ -8823,7 +8889,7 @@ function MediaEditScreen({ mediaId, onNavigate: _onNavigate, onBack }) {
8823
8889
  className: "mx-auto flex w-full max-w-5xl items-center gap-3",
8824
8890
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h1", {
8825
8891
  className: "text-foreground text-xl font-semibold break-words",
8826
- children: editState.title || displayTitle || "Media"
8892
+ children: editState.title || displayTitle || t("media_heading")
8827
8893
  })
8828
8894
  }),
8829
8895
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
@@ -8838,20 +8904,20 @@ function MediaEditScreen({ mediaId, onNavigate: _onNavigate, onBack }) {
8838
8904
  className: "mb-4 flex flex-wrap items-center justify-between gap-2",
8839
8905
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
8840
8906
  className: "text-foreground text-base font-semibold",
8841
- children: "Media"
8907
+ children: t("media_heading")
8842
8908
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8843
8909
  className: "flex flex-wrap items-center gap-2",
8844
8910
  children: [!readOnly && filePickerContextValue && filePickerApi && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Button, {
8845
8911
  onClick: () => setIsPickerOpen(true),
8846
8912
  variant: "outline",
8847
8913
  size: "sm",
8848
- children: "Replace Media"
8914
+ children: t("media_replace_button")
8849
8915
  }), !readOnly && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.Button, {
8850
8916
  variant: "outline",
8851
8917
  size: "sm",
8852
8918
  onClick: () => setIsCtaModalOpen(true),
8853
8919
  className: editState.ctaEnabled ? "border-primary text-primary" : "",
8854
- children: ["CTA Button: ", editState.ctaEnabled ? "On" : "Off"]
8920
+ children: [t("media_cta_button_label"), editState.ctaEnabled ? t("common_on") : t("common_off")]
8855
8921
  })]
8856
8922
  })]
8857
8923
  }),
@@ -8874,7 +8940,7 @@ function MediaEditScreen({ mediaId, onNavigate: _onNavigate, onBack }) {
8874
8940
  onThumbnailCaptured: async (blob) => {
8875
8941
  if (!uploadThumbnail) {
8876
8942
  showToast({
8877
- title: "Thumbnail capture is not available in this context",
8943
+ title: t("media_thumbnail_capture_unavailable"),
8878
8944
  type: "error"
8879
8945
  });
8880
8946
  return;
@@ -8883,7 +8949,7 @@ function MediaEditScreen({ mediaId, onNavigate: _onNavigate, onBack }) {
8883
8949
  setPendingThumbnail(await uploadThumbnail(blob, `thumbnail-${mediaId}.jpg`));
8884
8950
  } catch (error) {
8885
8951
  showToast({
8886
- title: "Failed to upload thumbnail",
8952
+ title: t("media_thumbnail_upload_error"),
8887
8953
  type: "error",
8888
8954
  error
8889
8955
  });
@@ -8892,7 +8958,7 @@ function MediaEditScreen({ mediaId, onNavigate: _onNavigate, onBack }) {
8892
8958
  onThumbnailSelected: () => setIsThumbnailPickerOpen(true)
8893
8959
  }), pendingThumbnail && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
8894
8960
  className: "text-muted-foreground mt-1.5 text-xs",
8895
- children: "Pending — save to apply"
8961
+ children: t("media_pending_save")
8896
8962
  })]
8897
8963
  });
8898
8964
  if (effectiveKind === "pdf") {
@@ -8903,7 +8969,7 @@ function MediaEditScreen({ mediaId, onNavigate: _onNavigate, onBack }) {
8903
8969
  className: "space-y-3",
8904
8970
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
8905
8971
  className: "text-foreground mb-1.5 block text-sm font-medium",
8906
- children: "Thumbnail"
8972
+ children: t("media_thumbnail_label")
8907
8973
  }), currentThumbnail ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ThumbnailWithMeta, {
8908
8974
  src: currentThumbnail,
8909
8975
  onReplace: () => setIsThumbnailPickerOpen(true)
@@ -8916,19 +8982,19 @@ function MediaEditScreen({ mediaId, onNavigate: _onNavigate, onBack }) {
8916
8982
  className: "min-w-0 flex-1",
8917
8983
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
8918
8984
  className: "text-muted-foreground mb-2 text-sm",
8919
- children: "No thumbnail set"
8985
+ children: t("media_no_thumbnail")
8920
8986
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.Button, {
8921
8987
  variant: "outline",
8922
8988
  size: "sm",
8923
8989
  onClick: () => setIsThumbnailPickerOpen(true),
8924
8990
  className: "gap-1.5",
8925
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ImageIcon, { className: "h-3.5 w-3.5" }), "Select New Image"]
8991
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ImageIcon, { className: "h-3.5 w-3.5" }), t("media_select_new_image")]
8926
8992
  })]
8927
8993
  })]
8928
8994
  })]
8929
8995
  }), pendingThumbnail && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
8930
8996
  className: "text-muted-foreground mt-1.5 text-xs",
8931
- children: "Pending — save to apply"
8997
+ children: t("media_pending_save")
8932
8998
  })]
8933
8999
  });
8934
9000
  }
@@ -8940,17 +9006,21 @@ function MediaEditScreen({ mediaId, onNavigate: _onNavigate, onBack }) {
8940
9006
  className: "border-border bg-card rounded-lg border p-4 md:p-5",
8941
9007
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
8942
9008
  className: "text-foreground mb-4 text-base font-semibold",
8943
- children: "Media Details"
9009
+ children: t("media_details_heading")
8944
9010
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8945
9011
  className: "flex flex-col gap-4",
8946
9012
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8947
9013
  className: "flex flex-col gap-1.5",
8948
9014
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.Label, {
8949
9015
  htmlFor: "media-title",
8950
- children: ["Title ", /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
8951
- className: "text-destructive",
8952
- children: "*"
8953
- })]
9016
+ children: [
9017
+ t("common_title_label"),
9018
+ " ",
9019
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
9020
+ className: "text-destructive",
9021
+ children: "*"
9022
+ })
9023
+ ]
8954
9024
  }), readOnly ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
8955
9025
  className: "text-foreground text-sm",
8956
9026
  children: displayTitle
@@ -8961,11 +9031,11 @@ function MediaEditScreen({ mediaId, onNavigate: _onNavigate, onBack }) {
8961
9031
  ...s,
8962
9032
  title: e.target.value
8963
9033
  })),
8964
- placeholder: "Enter media title"
9034
+ placeholder: t("media_title_placeholder")
8965
9035
  })]
8966
9036
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8967
9037
  className: "flex flex-col gap-1.5",
8968
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Label, { children: "Description" }), readOnly ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
9038
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Label, { children: t("common_description_label") }), readOnly ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
8969
9039
  className: "text-foreground/70 text-sm leading-relaxed",
8970
9040
  children: stripTags(editState.description)
8971
9041
  }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RichTextEditor, {
@@ -8974,7 +9044,7 @@ function MediaEditScreen({ mediaId, onNavigate: _onNavigate, onBack }) {
8974
9044
  ...s,
8975
9045
  description: val
8976
9046
  })),
8977
- placeholder: "Start writing..."
9047
+ placeholder: t("common_start_writing_placeholder")
8978
9048
  })]
8979
9049
  })]
8980
9050
  })]
@@ -9023,12 +9093,12 @@ function MediaEditScreen({ mediaId, onNavigate: _onNavigate, onBack }) {
9023
9093
  className: "mb-4 flex items-center justify-between",
9024
9094
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
9025
9095
  className: "text-foreground text-base font-semibold",
9026
- children: "SEO And Link Sharing"
9096
+ children: t("seo_heading")
9027
9097
  }), !readOnly && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Button, {
9028
9098
  variant: "ghost",
9029
9099
  size: "sm",
9030
9100
  onClick: () => setSeoExpanded((prev) => !prev),
9031
- children: seoExpanded ? "Done" : "Edit"
9101
+ children: seoExpanded ? t("common_done") : t("common_edit")
9032
9102
  })]
9033
9103
  }),
9034
9104
  (() => {
@@ -9048,10 +9118,10 @@ function MediaEditScreen({ mediaId, onNavigate: _onNavigate, onBack }) {
9048
9118
  className: "min-w-0 flex-1",
9049
9119
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
9050
9120
  className: "text-foreground truncate text-xs font-medium",
9051
- children: editState.seoTitle || displayTitle || "Your page title"
9121
+ children: editState.seoTitle || displayTitle || t("seo_preview_title_fallback")
9052
9122
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
9053
9123
  className: "text-muted-foreground truncate text-xs",
9054
- children: mediaItem?.preview_link ?? mediaItem?.canonical_url ?? "yoursite.com/media/..."
9124
+ children: mediaItem?.preview_link ?? mediaItem?.canonical_url ?? t("seo_preview_url_fallback")
9055
9125
  })]
9056
9126
  })]
9057
9127
  }), editState.seoDescription && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
@@ -9067,7 +9137,7 @@ function MediaEditScreen({ mediaId, onNavigate: _onNavigate, onBack }) {
9067
9137
  className: "flex flex-col gap-1.5",
9068
9138
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Label, {
9069
9139
  htmlFor: "seo-title",
9070
- children: "SEO Title"
9140
+ children: t("seo_title_label")
9071
9141
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Input, {
9072
9142
  id: "seo-title",
9073
9143
  value: editState.seoTitle,
@@ -9075,14 +9145,14 @@ function MediaEditScreen({ mediaId, onNavigate: _onNavigate, onBack }) {
9075
9145
  ...s,
9076
9146
  seoTitle: e.target.value
9077
9147
  })),
9078
- placeholder: "Page title for search engines"
9148
+ placeholder: t("seo_title_placeholder")
9079
9149
  })]
9080
9150
  }),
9081
9151
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
9082
9152
  className: "flex flex-col gap-1.5",
9083
9153
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Label, {
9084
9154
  htmlFor: "seo-description",
9085
- children: "SEO Description"
9155
+ children: t("seo_description_label")
9086
9156
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Textarea, {
9087
9157
  id: "seo-description",
9088
9158
  value: editState.seoDescription,
@@ -9090,7 +9160,7 @@ function MediaEditScreen({ mediaId, onNavigate: _onNavigate, onBack }) {
9090
9160
  ...s,
9091
9161
  seoDescription: e.target.value
9092
9162
  })),
9093
- placeholder: "Description for search engines",
9163
+ placeholder: t("seo_description_placeholder"),
9094
9164
  rows: 3
9095
9165
  })]
9096
9166
  }),
@@ -9100,10 +9170,10 @@ function MediaEditScreen({ mediaId, onNavigate: _onNavigate, onBack }) {
9100
9170
  className: "flex flex-col gap-0.5",
9101
9171
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
9102
9172
  className: "text-foreground text-sm font-medium",
9103
- children: "Block Crawlers"
9173
+ children: t("seo_block_crawlers_label")
9104
9174
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
9105
9175
  className: "text-muted-foreground text-xs",
9106
- children: "Prevent search engines from indexing"
9176
+ children: t("seo_block_crawlers_description")
9107
9177
  })]
9108
9178
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Switch, {
9109
9179
  checked: editState.blockCrawler,
@@ -9111,7 +9181,7 @@ function MediaEditScreen({ mediaId, onNavigate: _onNavigate, onBack }) {
9111
9181
  ...s,
9112
9182
  blockCrawler: checked
9113
9183
  })),
9114
- "aria-label": "Block search engine crawlers"
9184
+ "aria-label": t("seo_block_crawlers_aria")
9115
9185
  })]
9116
9186
  })
9117
9187
  ]
@@ -9123,18 +9193,14 @@ function MediaEditScreen({ mediaId, onNavigate: _onNavigate, onBack }) {
9123
9193
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.AlertDialog, {
9124
9194
  open: isDeleteOpen,
9125
9195
  onOpenChange: setIsDeleteOpen,
9126
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.AlertDialogContent, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.AlertDialogHeader, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.AlertDialogTitle, { children: "Delete Media" }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.AlertDialogDescription, { children: [
9127
- "Are you sure you want to delete “",
9128
- displayTitle,
9129
- "”? This action cannot be undone."
9130
- ] })] }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.AlertDialogFooter, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.AlertDialogCancel, {
9196
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.AlertDialogContent, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.AlertDialogHeader, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.AlertDialogTitle, { children: t("media_delete_dialog_title") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.AlertDialogDescription, { children: t("media_delete_dialog_description", { title: mediaItem?.title ?? "" }) })] }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.AlertDialogFooter, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.AlertDialogCancel, {
9131
9197
  disabled: isDeleting,
9132
- children: "Cancel"
9198
+ children: t("common_cancel")
9133
9199
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.AlertDialogAction, {
9134
9200
  onClick: handleDelete,
9135
9201
  disabled: isDeleting,
9136
9202
  className: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
9137
- children: isDeleting ? "Deleting..." : "Delete"
9203
+ children: isDeleting ? t("common_deleting") : t("common_delete")
9138
9204
  })] })] })
9139
9205
  }),
9140
9206
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CtaModal, {
@@ -9208,6 +9274,7 @@ function deriveMediaType(mimeType) {
9208
9274
  return "image";
9209
9275
  }
9210
9276
  function FilePreview({ result, mediaType }) {
9277
+ const { t } = useShareablesTranslation();
9211
9278
  const thumbnailSrc = mediaType === "image" ? result.file_url : result.thumbnail_url;
9212
9279
  if (thumbnailSrc) {
9213
9280
  const Icon = mediaType === "video" ? lucide_react.Video : mediaType === "pdf" ? lucide_react.FileText : null;
@@ -9221,7 +9288,7 @@ function FilePreview({ result, mediaType }) {
9221
9288
  className: "absolute bottom-2 left-2 flex items-center gap-1.5 rounded-md bg-black/60 px-2 py-1 text-white",
9222
9289
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Icon, { className: "h-3.5 w-3.5" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
9223
9290
  className: "text-xs font-medium",
9224
- children: mediaType === "video" ? "Video" : "PDF"
9291
+ children: mediaType === "video" ? t("media_type_video") : t("media_type_pdf")
9225
9292
  })]
9226
9293
  })]
9227
9294
  });
@@ -9241,6 +9308,7 @@ function FilePreview({ result, mediaType }) {
9241
9308
  });
9242
9309
  }
9243
9310
  function MediaCreateScreen({ onNavigate, onBack }) {
9311
+ const { t } = useShareablesTranslation();
9244
9312
  const { navigate, showToast, filePickerApi } = useShareablesUI();
9245
9313
  const user = useShareablesUser();
9246
9314
  const [title, setTitle] = (0, react.useState)("");
@@ -9261,14 +9329,14 @@ function MediaCreateScreen({ onNavigate, onBack }) {
9261
9329
  const { mutate: createMedia, isPending: isCreating } = useCreateMediaMutation({
9262
9330
  onSuccess: (newMedia) => {
9263
9331
  showToast({
9264
- title: "Media created successfully",
9332
+ title: t("media_create_success"),
9265
9333
  type: "success"
9266
9334
  });
9267
9335
  onNavigate?.("media", String(newMedia.id));
9268
9336
  },
9269
9337
  onError: (error) => {
9270
9338
  showToast({
9271
- title: `Failed to create media: ${error.message}`,
9339
+ title: t("media_create_error", { message: error.message }),
9272
9340
  type: "error"
9273
9341
  });
9274
9342
  }
@@ -9276,14 +9344,14 @@ function MediaCreateScreen({ onNavigate, onBack }) {
9276
9344
  const handleSave = (0, react.useCallback)(() => {
9277
9345
  if (!title.trim()) {
9278
9346
  showToast({
9279
- title: "Title is required",
9347
+ title: t("media_title_required"),
9280
9348
  type: "warning"
9281
9349
  });
9282
9350
  return;
9283
9351
  }
9284
9352
  if (!selectedResult) {
9285
9353
  showToast({
9286
- title: "Please select a file",
9354
+ title: t("media_file_required"),
9287
9355
  type: "warning"
9288
9356
  });
9289
9357
  return;
@@ -9314,6 +9382,7 @@ function MediaCreateScreen({ onNavigate, onBack }) {
9314
9382
  }
9315
9383
  });
9316
9384
  }, [
9385
+ t,
9317
9386
  title,
9318
9387
  description,
9319
9388
  active,
@@ -9361,12 +9430,12 @@ function MediaCreateScreen({ onNavigate, onBack }) {
9361
9430
  e.preventDefault();
9362
9431
  (onBack ?? (() => navigate("media")))();
9363
9432
  },
9364
- children: "Media"
9433
+ children: t("media_breadcrumb")
9365
9434
  }) }),
9366
9435
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.BreadcrumbSeparator, {}),
9367
9436
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.BreadcrumbItem, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.BreadcrumbPage, {
9368
9437
  className: "font-semibold",
9369
- children: "New Media"
9438
+ children: t("media_create_breadcrumb")
9370
9439
  }) })
9371
9440
  ]
9372
9441
  }) }) }),
@@ -9374,7 +9443,7 @@ function MediaCreateScreen({ onNavigate, onBack }) {
9374
9443
  onClick: handleSave,
9375
9444
  disabled: isCreating,
9376
9445
  size: "sm",
9377
- children: isCreating ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Spinner, { className: "size-4" }) : "Save"
9446
+ children: isCreating ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Spinner, { className: "size-4" }) : t("common_save")
9378
9447
  }) }),
9379
9448
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
9380
9449
  className: "flex flex-col gap-4 px-4 py-4 md:px-10 md:py-6",
@@ -9383,7 +9452,7 @@ function MediaCreateScreen({ onNavigate, onBack }) {
9383
9452
  className: "mx-auto flex w-full max-w-5xl items-center gap-3",
9384
9453
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h1", {
9385
9454
  className: "text-foreground text-xl font-semibold",
9386
- children: title.trim() || "New Media"
9455
+ children: title.trim() || t("media_new_title")
9387
9456
  })
9388
9457
  }),
9389
9458
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
@@ -9396,7 +9465,7 @@ function MediaCreateScreen({ onNavigate, onBack }) {
9396
9465
  className: "mb-4 flex items-center justify-between",
9397
9466
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
9398
9467
  className: "text-foreground text-base font-semibold",
9399
- children: "Media"
9468
+ children: t("media_heading")
9400
9469
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
9401
9470
  className: "flex items-center gap-2",
9402
9471
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Button, {
@@ -9404,13 +9473,13 @@ function MediaCreateScreen({ onNavigate, onBack }) {
9404
9473
  variant: "outline",
9405
9474
  size: "sm",
9406
9475
  disabled: !filePickerApi,
9407
- children: "Select Media"
9476
+ children: t("media_select_button")
9408
9477
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.Button, {
9409
9478
  variant: "outline",
9410
9479
  size: "sm",
9411
9480
  onClick: () => setIsCtaModalOpen(true),
9412
9481
  className: ctaEnabled ? "border-primary text-primary" : "",
9413
- children: ["CTA Button: ", ctaEnabled ? "On" : "Off"]
9482
+ children: [t("media_cta_button_label"), ctaEnabled ? t("common_on") : t("common_off")]
9414
9483
  })]
9415
9484
  })]
9416
9485
  }), selectedResult && mediaType ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
@@ -9423,7 +9492,7 @@ function MediaCreateScreen({ onNavigate, onBack }) {
9423
9492
  variant: "outline",
9424
9493
  size: "sm",
9425
9494
  className: "w-fit",
9426
- children: "Replace"
9495
+ children: t("common_replace")
9427
9496
  })]
9428
9497
  }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
9429
9498
  type: "button",
@@ -9432,37 +9501,41 @@ function MediaCreateScreen({ onNavigate, onBack }) {
9432
9501
  className: "border-border text-muted-foreground hover:bg-muted/30 flex h-40 w-full flex-col items-center justify-center gap-2 rounded-lg border border-dashed transition-colors disabled:cursor-not-allowed disabled:opacity-50",
9433
9502
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Upload, { className: "h-6 w-6" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
9434
9503
  className: "text-sm",
9435
- children: "No media uploaded. Click to upload an image, video, or PDF."
9504
+ children: t("media_upload_placeholder")
9436
9505
  })]
9437
9506
  })]
9438
9507
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
9439
9508
  className: "border-border bg-card rounded-lg border p-5",
9440
9509
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
9441
9510
  className: "text-foreground mb-4 text-base font-semibold",
9442
- children: "Media Details"
9511
+ children: t("media_details_heading")
9443
9512
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
9444
9513
  className: "flex flex-col gap-4",
9445
9514
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
9446
9515
  className: "flex flex-col gap-1.5",
9447
9516
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.Label, {
9448
9517
  htmlFor: "media-title",
9449
- children: ["Title ", /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
9450
- className: "text-destructive",
9451
- children: "*"
9452
- })]
9518
+ children: [
9519
+ t("common_title_label"),
9520
+ " ",
9521
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
9522
+ className: "text-destructive",
9523
+ children: "*"
9524
+ })
9525
+ ]
9453
9526
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Input, {
9454
9527
  id: "media-title",
9455
9528
  value: title,
9456
9529
  onChange: (e) => setTitle(e.target.value),
9457
- placeholder: "Enter media title",
9530
+ placeholder: t("media_title_placeholder"),
9458
9531
  required: true
9459
9532
  })]
9460
9533
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
9461
9534
  className: "flex flex-col gap-1.5",
9462
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Label, { children: "Description" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RichTextEditor, {
9535
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Label, { children: t("common_description_label") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RichTextEditor, {
9463
9536
  value: description,
9464
9537
  onChange: setDescription,
9465
- placeholder: "Start writing..."
9538
+ placeholder: t("common_start_writing_placeholder")
9466
9539
  })]
9467
9540
  })]
9468
9541
  })]
@@ -9476,12 +9549,12 @@ function MediaCreateScreen({ onNavigate, onBack }) {
9476
9549
  className: "mb-4 flex items-center justify-between",
9477
9550
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
9478
9551
  className: "text-foreground text-base font-semibold",
9479
- children: "SEO And Link Sharing"
9552
+ children: t("seo_heading")
9480
9553
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Button, {
9481
9554
  variant: "ghost",
9482
9555
  size: "sm",
9483
9556
  onClick: () => setSeoExpanded((prev) => !prev),
9484
- children: seoExpanded ? "Done" : "Edit"
9557
+ children: seoExpanded ? t("common_done") : t("common_edit")
9485
9558
  })]
9486
9559
  }),
9487
9560
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
@@ -9495,10 +9568,10 @@ function MediaCreateScreen({ onNavigate, onBack }) {
9495
9568
  className: "min-w-0 flex-1",
9496
9569
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
9497
9570
  className: "text-foreground truncate text-xs font-medium",
9498
- children: seoTitle || "Your page title"
9571
+ children: seoTitle || t("seo_preview_title_fallback")
9499
9572
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
9500
9573
  className: "text-muted-foreground truncate text-xs",
9501
- children: "yoursite.com/media/..."
9574
+ children: t("seo_preview_url_fallback")
9502
9575
  })]
9503
9576
  })]
9504
9577
  }), seoDescription && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
@@ -9513,24 +9586,24 @@ function MediaCreateScreen({ onNavigate, onBack }) {
9513
9586
  className: "flex flex-col gap-1.5",
9514
9587
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Label, {
9515
9588
  htmlFor: "seo-title",
9516
- children: "SEO Title"
9589
+ children: t("seo_title_label")
9517
9590
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Input, {
9518
9591
  id: "seo-title",
9519
9592
  value: seoTitle,
9520
9593
  onChange: (e) => setSeoTitle(e.target.value),
9521
- placeholder: "Page title for search engines"
9594
+ placeholder: t("seo_title_placeholder")
9522
9595
  })]
9523
9596
  }),
9524
9597
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
9525
9598
  className: "flex flex-col gap-1.5",
9526
9599
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Label, {
9527
9600
  htmlFor: "seo-description",
9528
- children: "SEO Description"
9601
+ children: t("seo_description_label")
9529
9602
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Textarea, {
9530
9603
  id: "seo-description",
9531
9604
  value: seoDescription,
9532
9605
  onChange: (e) => setSeoDescription(e.target.value),
9533
- placeholder: "Description for search engines",
9606
+ placeholder: t("seo_description_placeholder"),
9534
9607
  rows: 3
9535
9608
  })]
9536
9609
  }),
@@ -9540,15 +9613,15 @@ function MediaCreateScreen({ onNavigate, onBack }) {
9540
9613
  className: "flex flex-col gap-0.5",
9541
9614
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
9542
9615
  className: "text-foreground text-sm font-medium",
9543
- children: "Block Crawlers"
9616
+ children: t("seo_block_crawlers_label")
9544
9617
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
9545
9618
  className: "text-muted-foreground text-xs",
9546
- children: "Prevent search engines from indexing"
9619
+ children: t("seo_block_crawlers_description")
9547
9620
  })]
9548
9621
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Switch, {
9549
9622
  checked: seoBlockCrawler,
9550
9623
  onCheckedChange: setSeoBlockCrawler,
9551
- "aria-label": "Block search engine crawlers"
9624
+ "aria-label": t("seo_block_crawlers_aria")
9552
9625
  })]
9553
9626
  })
9554
9627
  ]
@@ -9599,10 +9672,11 @@ function MediaCreateScreen({ onNavigate, onBack }) {
9599
9672
  const DEFAULT_IMAGE$4 = "https://assets.fluid.app/fluid-admin/images/we-commerce/we-commerce.png";
9600
9673
  function PlaylistCard({ title, imageUrl, href, itemCount, isFavorited = false, isSelectable = false, isSelected = false, canEdit = false, onSelectionChange, onToggleFavorite, onEdit, onDelete }) {
9601
9674
  const { navigate } = useShareablesUI();
9675
+ const { t } = useShareablesTranslation();
9602
9676
  const renderImage = useRenderImage();
9603
9677
  const [imgError, setImgError] = (0, react.useState)(false);
9604
9678
  const hasStack = itemCount > 1;
9605
- const badgeText = `${itemCount} ${itemCount === 1 ? "item" : "items"}`;
9679
+ const badgeText = itemCount === 1 ? t("playlist_item_count_one", { count: "1" }) : t("playlist_item_count_other", { count: String(itemCount) });
9606
9680
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
9607
9681
  type: "button",
9608
9682
  onClick: () => navigate(href),
@@ -9645,7 +9719,7 @@ function PlaylistCard({ title, imageUrl, href, itemCount, isFavorited = false, i
9645
9719
  type: "button",
9646
9720
  onClick: (e) => e.stopPropagation(),
9647
9721
  className: "bg-background/90 hover:bg-background flex h-8 w-8 items-center justify-center rounded-lg shadow-md backdrop-blur-sm transition-all",
9648
- "aria-label": "More options",
9722
+ "aria-label": t("common_more_options_aria"),
9649
9723
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.MoreVertical, { className: "text-foreground h-4 w-4" })
9650
9724
  })
9651
9725
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.DropdownMenuContent, {
@@ -9654,16 +9728,16 @@ function PlaylistCard({ title, imageUrl, href, itemCount, isFavorited = false, i
9654
9728
  children: [
9655
9729
  onToggleFavorite && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.DropdownMenuItem, {
9656
9730
  onClick: onToggleFavorite,
9657
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Heart, { className: require_src.cn("mr-2 h-4 w-4", isFavorited && "text-destructive fill-current") }), isFavorited ? "Unfavorite" : "Favorite"]
9731
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Heart, { className: require_src.cn("mr-2 h-4 w-4", isFavorited && "text-destructive fill-current") }), isFavorited ? t("common_unfavorite") : t("common_favorite")]
9658
9732
  }),
9659
9733
  canEdit && onEdit && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.DropdownMenuItem, {
9660
9734
  onClick: onEdit,
9661
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Pencil, { className: "mr-2 h-4 w-4" }), "Edit"]
9735
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Pencil, { className: "mr-2 h-4 w-4" }), t("common_edit")]
9662
9736
  }),
9663
9737
  canEdit && onDelete && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.DropdownMenuSeparator, {}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.DropdownMenuItem, {
9664
9738
  variant: "destructive",
9665
9739
  onClick: onDelete,
9666
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Trash2, { className: "mr-2 h-4 w-4" }), "Delete"]
9740
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Trash2, { className: "mr-2 h-4 w-4" }), t("common_delete")]
9667
9741
  })] })
9668
9742
  ]
9669
9743
  })] })
@@ -9676,7 +9750,7 @@ function PlaylistCard({ title, imageUrl, href, itemCount, isFavorited = false, i
9676
9750
  e.stopPropagation();
9677
9751
  onToggleFavorite();
9678
9752
  },
9679
- "aria-label": isFavorited ? "Unfavorite" : "Favorite",
9753
+ "aria-label": isFavorited ? t("common_unfavorite") : t("common_favorite"),
9680
9754
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Heart, { className: require_src.cn("h-6 w-6 drop-shadow-lg transition-all", isFavorited ? "fill-destructive text-destructive" : "text-[#ffffff]") })
9681
9755
  }),
9682
9756
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
@@ -9692,7 +9766,7 @@ function PlaylistCard({ title, imageUrl, href, itemCount, isFavorited = false, i
9692
9766
  className: "px-2 pt-2 pb-4",
9693
9767
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
9694
9768
  className: "text-foreground line-clamp-2 text-sm leading-tight font-bold",
9695
- children: title || "Untitled"
9769
+ children: title || t("common_untitled")
9696
9770
  })
9697
9771
  })]
9698
9772
  })]
@@ -9702,6 +9776,7 @@ function PlaylistCard({ title, imageUrl, href, itemCount, isFavorited = false, i
9702
9776
  //#endregion
9703
9777
  //#region ../../shareables/ui/src/components/playlists/BulkSelectionBar.tsx
9704
9778
  function BulkSelectionBar({ selectedCount, totalCount, onSelectAll, onClearSelection, onBulkFavorite }) {
9779
+ const { t } = useShareablesTranslation();
9705
9780
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
9706
9781
  className: "bg-foreground flex items-center justify-between rounded-lg px-4 py-3",
9707
9782
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
@@ -9710,10 +9785,10 @@ function BulkSelectionBar({ selectedCount, totalCount, onSelectAll, onClearSelec
9710
9785
  type: "button",
9711
9786
  onClick: onSelectAll,
9712
9787
  className: "text-background hover:text-background/80 text-sm font-medium",
9713
- children: selectedCount === totalCount ? "Deselect All" : "Select All"
9714
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
9788
+ children: selectedCount === totalCount ? t("common_deselect_all") : t("common_select_all")
9789
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
9715
9790
  className: "text-background/70 text-sm",
9716
- children: [selectedCount, " selected"]
9791
+ children: t("common_selected_count", { count: String(selectedCount) })
9717
9792
  })]
9718
9793
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
9719
9794
  className: "flex items-center gap-3",
@@ -9723,12 +9798,12 @@ function BulkSelectionBar({ selectedCount, totalCount, onSelectAll, onClearSelec
9723
9798
  variant: "secondary",
9724
9799
  size: "sm",
9725
9800
  className: "bg-background text-foreground hover:bg-background/90 rounded-md px-3 py-1.5 text-xs font-medium disabled:cursor-not-allowed disabled:opacity-50",
9726
- children: "Favorite"
9801
+ children: t("common_favorite")
9727
9802
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
9728
9803
  type: "button",
9729
9804
  onClick: onClearSelection,
9730
9805
  className: "text-background hover:text-background/80",
9731
- "aria-label": "Cancel selection",
9806
+ "aria-label": t("common_cancel_selection_aria"),
9732
9807
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.X, { className: "h-4 w-4" })
9733
9808
  })]
9734
9809
  })]
@@ -9740,6 +9815,7 @@ const PAGE_SIZE$2 = 12;
9740
9815
  const GRID_CLASS = "grid grid-cols-1 gap-8 sm:grid-cols-2 md:grid-cols-3 xl:grid-cols-4";
9741
9816
  function PlaylistsListingScreen(_props) {
9742
9817
  const api = useShareablesApi();
9818
+ const { t } = useShareablesTranslation();
9743
9819
  const { navigate, showToast, user, onToggleFavorite, onDeletePlaylist, readOnly } = useShareablesUI();
9744
9820
  const queryClient = (0, _tanstack_react_query.useQueryClient)();
9745
9821
  const [searchTerm, setSearchTerm] = (0, react.useState)("");
@@ -9842,13 +9918,13 @@ function PlaylistsListingScreen(_props) {
9842
9918
  onError: (_err, _playlistId, context) => {
9843
9919
  if (context?.previousData) queryClient.setQueryData(context.capturedKey, context.previousData);
9844
9920
  showToast({
9845
- title: "Failed to update favorite",
9921
+ title: t("playlist_favorite_error"),
9846
9922
  type: "error"
9847
9923
  });
9848
9924
  },
9849
9925
  onSuccess: (result) => {
9850
9926
  showToast({
9851
- title: result.is_favorited ? "Added to favorites" : "Removed from favorites",
9927
+ title: result.is_favorited ? t("playlist_favorite_added") : t("playlist_favorite_removed"),
9852
9928
  type: "success"
9853
9929
  });
9854
9930
  },
@@ -9875,14 +9951,14 @@ function PlaylistsListingScreen(_props) {
9875
9951
  onSuccess: () => {
9876
9952
  queryClient.invalidateQueries({ queryKey: shareablesKeys.playlists.all });
9877
9953
  showToast({
9878
- title: "Playlist deleted",
9954
+ title: t("playlist_delete_success"),
9879
9955
  type: "success"
9880
9956
  });
9881
9957
  setPendingDeleteId(null);
9882
9958
  },
9883
9959
  onError: (error) => {
9884
9960
  showToast({
9885
- title: "Failed to delete playlist",
9961
+ title: t("playlist_delete_error"),
9886
9962
  type: "error",
9887
9963
  error
9888
9964
  });
@@ -9892,6 +9968,24 @@ function PlaylistsListingScreen(_props) {
9892
9968
  const confirmDelete = (0, react.useCallback)(() => {
9893
9969
  if (pendingDeleteId != null) deletePlaylist(pendingDeleteId);
9894
9970
  }, [pendingDeleteId, deletePlaylist]);
9971
+ const sortOptions = (0, react.useMemo)(() => [
9972
+ {
9973
+ label: t("sort_name_asc"),
9974
+ value: "title"
9975
+ },
9976
+ {
9977
+ label: t("sort_name_desc"),
9978
+ value: "-title"
9979
+ },
9980
+ {
9981
+ label: t("sort_date_newest"),
9982
+ value: "-created_at"
9983
+ },
9984
+ {
9985
+ label: t("sort_date_oldest"),
9986
+ value: "created_at"
9987
+ }
9988
+ ], [t]);
9895
9989
  const filterBar = hasSelection ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BulkSelectionBar, {
9896
9990
  selectedCount: selectedIds.size,
9897
9991
  totalCount: filteredPlaylists.length,
@@ -9903,7 +9997,7 @@ function PlaylistsListingScreen(_props) {
9903
9997
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(OwnerFilterTabs, {
9904
9998
  value: ownerFilter,
9905
9999
  onValueChange: setOwnerFilter,
9906
- myLabel: "My Playlists"
10000
+ myLabel: t("playlist_my_playlists_tab")
9907
10001
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
9908
10002
  className: "ml-auto flex items-center gap-2",
9909
10003
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
@@ -9911,25 +10005,8 @@ function PlaylistsListingScreen(_props) {
9911
10005
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_PortalProductsApiProvider.SearchSort, {
9912
10006
  searchValue: searchTerm,
9913
10007
  onSearchChange: setSearchTerm,
9914
- placeholder: "Search playlists...",
9915
- sortOptions: [
9916
- {
9917
- label: "Name (A-Z)",
9918
- value: "title"
9919
- },
9920
- {
9921
- label: "Name (Z-A)",
9922
- value: "-title"
9923
- },
9924
- {
9925
- label: "Date Created (Newest)",
9926
- value: "-created_at"
9927
- },
9928
- {
9929
- label: "Date Created (Oldest)",
9930
- value: "created_at"
9931
- }
9932
- ],
10008
+ placeholder: t("playlist_search_placeholder"),
10009
+ sortOptions,
9933
10010
  sortValue,
9934
10011
  onSortChange: setSortValue
9935
10012
  })
@@ -9951,13 +10028,13 @@ function PlaylistsListingScreen(_props) {
9951
10028
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_ScreenHeaderContext.ScreenHeaderActions, { children: readOnly ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.Button, {
9952
10029
  onClick: () => navigate("playlists/new"),
9953
10030
  size: "sm",
9954
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Plus, { className: "mr-1 h-4 w-4" }), "Create Playlist"]
10031
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Plus, { className: "mr-1 h-4 w-4" }), t("playlist_create_button")]
9955
10032
  }) }),
9956
10033
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_ScreenHeaderContext.ScreenHeaderBreadcrumbs, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Breadcrumb, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.BreadcrumbList, {
9957
10034
  className: "text-lg",
9958
10035
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.BreadcrumbItem, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.BreadcrumbPage, {
9959
10036
  className: "font-semibold",
9960
- children: "Playlists"
10037
+ children: t("playlist_breadcrumb")
9961
10038
  }) })
9962
10039
  }) }) }),
9963
10040
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ShareableListLayout, {
@@ -9968,7 +10045,18 @@ function PlaylistsListingScreen(_props) {
9968
10045
  searchTerm,
9969
10046
  ownerFilter,
9970
10047
  entityName: "playlists",
9971
- defaultMessage: "There are no playlists available at the moment."
10048
+ defaultMessage: t("playlist_empty_default"),
10049
+ messages: {
10050
+ filterSearchNoResults: t("common_filter_search_no_results", {
10051
+ entityName: "playlists",
10052
+ searchTerm
10053
+ }),
10054
+ searchNoResults: t("common_search_no_results", {
10055
+ entityName: "playlists",
10056
+ searchTerm
10057
+ }),
10058
+ filterNoResults: t("common_filter_no_results", { entityName: "playlists" })
10059
+ }
9972
10060
  }),
9973
10061
  footer,
9974
10062
  sentinelRef: observerTarget,
@@ -9981,7 +10069,7 @@ function PlaylistsListingScreen(_props) {
9981
10069
  const itemCount = playlist.items_count ?? playlist.items?.length ?? 0;
9982
10070
  const canEdit = !readOnly && playlist.user_id === user?.id;
9983
10071
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PlaylistCard, {
9984
- title: playlist.title || "Untitled Playlist",
10072
+ title: playlist.title || t("playlist_untitled"),
9985
10073
  imageUrl,
9986
10074
  href: `playlists/${playlist.id}`,
9987
10075
  itemCount,
@@ -10003,29 +10091,25 @@ function PlaylistsListingScreen(_props) {
10003
10091
  const itemCount = playlist.items_count ?? playlist.items?.length ?? 0;
10004
10092
  const canEdit = !readOnly && playlist.user_id === user?.id;
10005
10093
  const isSelected = selectedIds.has(playlist.id);
10006
- const title = playlist.title || "Untitled Playlist";
10094
+ const title = playlist.title || t("playlist_untitled");
10007
10095
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ShareableListRow, {
10008
10096
  imageUrl,
10009
10097
  title,
10010
- subtitle: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.Badge, {
10098
+ subtitle: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Badge, {
10011
10099
  variant: "secondary",
10012
10100
  className: "px-1.5 py-0 text-[10px] leading-4",
10013
- children: [
10014
- itemCount,
10015
- " ",
10016
- itemCount === 1 ? "item" : "items"
10017
- ]
10101
+ children: itemCount === 1 ? t("playlist_item_count_one", { count: "1" }) : t("playlist_item_count_other", { count: String(itemCount) })
10018
10102
  }),
10019
10103
  onClick: () => navigate(`playlists/${playlist.id}`),
10020
10104
  leading: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Checkbox, {
10021
10105
  checked: isSelected,
10022
10106
  onCheckedChange: (checked) => handleToggleSelection(playlist.id, checked === true),
10023
- "aria-label": `Select ${title}`
10107
+ "aria-label": t("playlist_select_aria", { title })
10024
10108
  }),
10025
10109
  trailing: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [onToggleFavorite && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
10026
10110
  type: "button",
10027
10111
  onClick: () => handleFavorite(playlist.id),
10028
- "aria-label": playlist.is_favorited ? "Unfavorite" : "Favorite",
10112
+ "aria-label": playlist.is_favorited ? t("common_unfavorite") : t("common_favorite"),
10029
10113
  className: "hover:bg-muted-foreground/10 flex h-8 w-8 items-center justify-center rounded-md transition-colors",
10030
10114
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Heart, { className: require_src.cn("h-4 w-4 transition-colors", playlist.is_favorited ? "fill-destructive text-destructive" : "text-muted-foreground") })
10031
10115
  }), canEdit && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.DropdownMenu, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.DropdownMenuTrigger, {
@@ -10034,18 +10118,18 @@ function PlaylistsListingScreen(_props) {
10034
10118
  variant: "ghost",
10035
10119
  size: "sm",
10036
10120
  className: "h-8 w-8 p-0",
10037
- "aria-label": "Playlist actions",
10121
+ "aria-label": t("playlist_actions_aria"),
10038
10122
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.MoreVertical, { className: "h-4 w-4" })
10039
10123
  })
10040
10124
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.DropdownMenuContent, {
10041
10125
  align: "end",
10042
10126
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.DropdownMenuItem, {
10043
10127
  onClick: () => handleEdit(playlist.id),
10044
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Pencil, { className: "mr-2 h-4 w-4" }), "Edit"]
10128
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Pencil, { className: "mr-2 h-4 w-4" }), t("common_edit")]
10045
10129
  }), onDeletePlaylist && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.DropdownMenuSeparator, {}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.DropdownMenuItem, {
10046
10130
  variant: "destructive",
10047
10131
  onClick: () => setPendingDeleteId(playlist.id),
10048
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Trash2, { className: "mr-2 h-4 w-4" }), "Delete"]
10132
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Trash2, { className: "mr-2 h-4 w-4" }), t("common_delete")]
10049
10133
  })] })]
10050
10134
  })] })] })
10051
10135
  }, playlist.id);
@@ -10057,9 +10141,9 @@ function PlaylistsListingScreen(_props) {
10057
10141
  onOpenChange: (open) => {
10058
10142
  if (!open && !isDeleting) setPendingDeleteId(null);
10059
10143
  },
10060
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.AlertDialogContent, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.AlertDialogHeader, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.AlertDialogTitle, { children: "Delete this playlist?" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.AlertDialogDescription, { children: "This removes the playlist from your library. Shared links that point to it will stop working." })] }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.AlertDialogFooter, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.AlertDialogCancel, {
10144
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.AlertDialogContent, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.AlertDialogHeader, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.AlertDialogTitle, { children: t("playlist_delete_confirm_title") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.AlertDialogDescription, { children: t("playlist_delete_confirm_description") })] }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.AlertDialogFooter, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.AlertDialogCancel, {
10061
10145
  disabled: isDeleting,
10062
- children: "Cancel"
10146
+ children: t("common_cancel")
10063
10147
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.AlertDialogAction, {
10064
10148
  onClick: (e) => {
10065
10149
  e.preventDefault();
@@ -10067,7 +10151,7 @@ function PlaylistsListingScreen(_props) {
10067
10151
  },
10068
10152
  disabled: isDeleting,
10069
10153
  className: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
10070
- children: isDeleting ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Spinner, { className: "size-4" }) : "Delete"
10154
+ children: isDeleting ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Spinner, { className: "size-4" }) : t("common_delete")
10071
10155
  })] })] })
10072
10156
  })
10073
10157
  ] });
@@ -10082,13 +10166,13 @@ const NAVIGABLE_RELATEABLE_TYPES = new Set([
10082
10166
  //#endregion
10083
10167
  //#region ../../shareables/ui/src/components/SharePage/PlaylistItemsList.tsx
10084
10168
  const DEFAULT_IMAGE$3 = "https://assets.fluid.app/fluid-admin/images/we-commerce/we-commerce.png";
10085
- function getItemType(type, kind) {
10086
- if (type === "Product") return "Product";
10087
- if (type === "EnrollmentPack") return "Enrollment";
10088
- if (type === "Page") return "Page";
10089
- if (kind === "video") return "Video";
10090
- if (kind === "image") return "Image";
10091
- return "Media";
10169
+ function getItemType(type, kind, labels) {
10170
+ if (type === "Product") return labels.product;
10171
+ if (type === "EnrollmentPack") return labels.enrollment;
10172
+ if (type === "Page") return labels.page;
10173
+ if (kind === "video") return labels.video;
10174
+ if (kind === "image") return labels.image;
10175
+ return labels.media;
10092
10176
  }
10093
10177
  function formatVideoLength(seconds) {
10094
10178
  if (seconds == null) return null;
@@ -10106,6 +10190,7 @@ function getFileType(mediaFormat, imageUrl) {
10106
10190
  return null;
10107
10191
  }
10108
10192
  function PlaylistItemsList({ items, onSelectItem, selectedItemIndex = 0, onNavigateToItem }) {
10193
+ const { t } = useShareablesTranslation();
10109
10194
  const handleNavigateToItem = (itemId, type, e) => {
10110
10195
  e?.stopPropagation();
10111
10196
  onNavigateToItem?.(itemId, type);
@@ -10126,11 +10211,11 @@ function PlaylistItemsList({ items, onSelectItem, selectedItemIndex = 0, onNavig
10126
10211
  }),
10127
10212
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
10128
10213
  className: "mb-1 text-sm text-gray-500",
10129
- children: "No Items"
10214
+ children: t("playlist_no_items")
10130
10215
  }),
10131
10216
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
10132
10217
  className: "text-xs text-gray-400",
10133
- children: "This playlist doesn't have any items yet"
10218
+ children: t("playlist_no_items_description")
10134
10219
  })
10135
10220
  ]
10136
10221
  })
@@ -10140,11 +10225,18 @@ function PlaylistItemsList({ items, onSelectItem, selectedItemIndex = 0, onNavig
10140
10225
  children: items.map((item, index) => {
10141
10226
  const relateable = item.relateable;
10142
10227
  const imageUrl = item.image_url ?? relateable?.image_url ?? relateable?.compressed_image_url ?? DEFAULT_IMAGE$3;
10143
- const title = item.title ?? relateable?.title ?? "Untitled";
10228
+ const title = item.title ?? relateable?.title ?? t("common_untitled");
10144
10229
  const rawPrice = relateable?.display_price || relateable?.price;
10145
10230
  const price = rawPrice && parseFloat(rawPrice.replace(/[^0-9.-]/g, "")) > 0 ? rawPrice : null;
10146
10231
  const kind = item.kind ?? relateable?.kind;
10147
- const itemType = getItemType(item.relateable_type, kind);
10232
+ const itemType = getItemType(item.relateable_type, kind, {
10233
+ product: t("common_product"),
10234
+ enrollment: t("common_enrollment"),
10235
+ page: t("common_page"),
10236
+ video: t("media_type_video"),
10237
+ image: t("media_type_image"),
10238
+ media: t("media_type_default")
10239
+ });
10148
10240
  const isVideo = kind === "video";
10149
10241
  const isImage = kind === "image";
10150
10242
  const isProduct = item.relateable_type === "Product";
@@ -10191,7 +10283,7 @@ function PlaylistItemsList({ items, onSelectItem, selectedItemIndex = 0, onNavig
10191
10283
  }),
10192
10284
  isVideo && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
10193
10285
  className: "text-muted-foreground text-[13px] leading-[1.4] font-normal",
10194
- children: videoLength || "Video"
10286
+ children: videoLength || t("media_type_video")
10195
10287
  }),
10196
10288
  isImage && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
10197
10289
  className: "text-muted-foreground text-[13px] leading-[1.4] font-normal",
@@ -10214,13 +10306,9 @@ function PlaylistItemsList({ items, onSelectItem, selectedItemIndex = 0, onNavig
10214
10306
  className: "hide-scrollbar flex h-full flex-col",
10215
10307
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
10216
10308
  className: "mb-4 px-4 pt-4",
10217
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("h2", {
10309
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h2", {
10218
10310
  className: "text-foreground text-[15px] leading-[1.4] font-semibold",
10219
- children: [
10220
- "Items in playlist (",
10221
- items.length,
10222
- ")"
10223
- ]
10311
+ children: t("playlist_items_in_playlist_count", { count: String(items.length) })
10224
10312
  })
10225
10313
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
10226
10314
  className: "flex-1 overflow-y-auto px-4 pb-4",
@@ -10233,6 +10321,7 @@ function PlaylistItemsList({ items, onSelectItem, selectedItemIndex = 0, onNavig
10233
10321
  const DEFAULT_IMAGE$2 = "https://assets.fluid.app/fluid-admin/images/we-commerce/we-commerce.png";
10234
10322
  function PlaylistDetailScreen({ playlistId, onNavigate }) {
10235
10323
  const api = useShareablesApi();
10324
+ const { t } = useShareablesTranslation();
10236
10325
  const { navigate, user, readOnly } = useShareablesUI();
10237
10326
  const [selectedPlaylistItemIndex, setSelectedPlaylistItemIndex] = (0, react.useState)(0);
10238
10327
  const { data: playlistResponse, isLoading } = (0, _tanstack_react_query.useQuery)({
@@ -10258,7 +10347,7 @@ function PlaylistDetailScreen({ playlistId, onNavigate }) {
10258
10347
  variant: "outline",
10259
10348
  size: "sm",
10260
10349
  onClick: () => navigate(`playlists/${playlistId}/edit`),
10261
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Pencil, { className: "mr-1 h-3.5 w-3.5" }), "Edit"]
10350
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Pencil, { className: "mr-1 h-3.5 w-3.5" }), t("common_edit")]
10262
10351
  })
10263
10352
  }) : null }),
10264
10353
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_ScreenHeaderContext.ScreenHeaderBreadcrumbs, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Breadcrumb, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.BreadcrumbList, {
@@ -10270,19 +10359,19 @@ function PlaylistDetailScreen({ playlistId, onNavigate }) {
10270
10359
  e.preventDefault();
10271
10360
  navigate("playlists");
10272
10361
  },
10273
- children: "Playlists"
10362
+ children: t("playlist_breadcrumb")
10274
10363
  }) }),
10275
10364
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.BreadcrumbSeparator, {}),
10276
10365
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.BreadcrumbItem, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.BreadcrumbPage, {
10277
10366
  className: "block max-w-[60vw] truncate align-bottom font-semibold md:max-w-[60ch]",
10278
- children: displayTitle || "Playlist"
10367
+ children: displayTitle || t("playlist_breadcrumb_fallback")
10279
10368
  }) })
10280
10369
  ]
10281
10370
  }) }) }),
10282
10371
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(ShareableDetailLayout, {
10283
10372
  isLoading,
10284
10373
  notFound: !playlist,
10285
- notFoundMessage: "Playlist not found or failed to load.",
10374
+ notFoundMessage: t("playlist_not_found"),
10286
10375
  title: displayTitle,
10287
10376
  description: displayDescription,
10288
10377
  image: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
@@ -10292,7 +10381,7 @@ function PlaylistDetailScreen({ playlistId, onNavigate }) {
10292
10381
  displayTitle,
10293
10382
  displayVideo,
10294
10383
  isVideo,
10295
- badgeLabel: "Playlist"
10384
+ badgeLabel: t("playlist_badge_label")
10296
10385
  })
10297
10386
  }),
10298
10387
  actions: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AssetActions, {
@@ -10487,6 +10576,7 @@ function PlaylistItemsProvider({ children, initialItems = [] }) {
10487
10576
  //#endregion
10488
10577
  //#region ../../shareables/ui/src/components/playlists/form/PlaylistFormHeader.tsx
10489
10578
  function PlaylistFormHeader({ playlistId, isEditMode, onSubmit, isSaving }) {
10579
+ const { t } = useShareablesTranslation();
10490
10580
  const { form, isDirty: formIsDirty } = usePlaylistForm();
10491
10581
  const { isDirty: itemsIsDirty } = usePlaylistItems();
10492
10582
  const { onDeletePlaylist, showToast, navigate } = useShareablesUI();
@@ -10503,13 +10593,13 @@ function PlaylistFormHeader({ playlistId, isEditMode, onSubmit, isSaving }) {
10503
10593
  try {
10504
10594
  await onDeletePlaylist(Number(playlistId));
10505
10595
  showToast({
10506
- title: "Playlist deleted successfully",
10596
+ title: t("playlist_delete_success_full"),
10507
10597
  type: "success"
10508
10598
  });
10509
10599
  navigate("playlists");
10510
10600
  } catch (error) {
10511
10601
  showToast({
10512
- title: "Failed to delete playlist",
10602
+ title: t("playlist_delete_error"),
10513
10603
  type: "error",
10514
10604
  error
10515
10605
  });
@@ -10527,7 +10617,7 @@ function PlaylistFormHeader({ playlistId, isEditMode, onSubmit, isSaving }) {
10527
10617
  variant: "outline",
10528
10618
  size: "sm",
10529
10619
  className: "h-8 w-8 p-0",
10530
- "aria-label": "Playlist actions",
10620
+ "aria-label": t("playlist_actions_aria"),
10531
10621
  disabled: isMutating,
10532
10622
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.MoreVertical, { className: "h-4 w-4" })
10533
10623
  })
@@ -10536,7 +10626,7 @@ function PlaylistFormHeader({ playlistId, isEditMode, onSubmit, isSaving }) {
10536
10626
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.DropdownMenuItem, {
10537
10627
  onClick: () => setIsDeleteOpen(true),
10538
10628
  className: "text-destructive focus:text-destructive",
10539
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Trash2, { className: "mr-2 h-4 w-4" }), "Delete"]
10629
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Trash2, { className: "mr-2 h-4 w-4" }), t("common_delete")]
10540
10630
  })
10541
10631
  })] }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Button, {
10542
10632
  onClick: () => {
@@ -10544,7 +10634,7 @@ function PlaylistFormHeader({ playlistId, isEditMode, onSubmit, isSaving }) {
10544
10634
  },
10545
10635
  disabled: isMutating || !isDirty || !isFormValid,
10546
10636
  size: "sm",
10547
- children: isSaving ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Spinner, { className: "size-4" }) : "Save"
10637
+ children: isSaving ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Spinner, { className: "size-4" }) : t("common_save")
10548
10638
  })]
10549
10639
  }) }),
10550
10640
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_ScreenHeaderContext.ScreenHeaderBreadcrumbs, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Breadcrumb, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.BreadcrumbList, {
@@ -10556,12 +10646,12 @@ function PlaylistFormHeader({ playlistId, isEditMode, onSubmit, isSaving }) {
10556
10646
  e.preventDefault();
10557
10647
  navigate("playlists");
10558
10648
  },
10559
- children: "Playlists"
10649
+ children: t("playlist_breadcrumb")
10560
10650
  }) }),
10561
10651
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.BreadcrumbSeparator, {}),
10562
10652
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.BreadcrumbItem, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.BreadcrumbPage, {
10563
10653
  className: "font-semibold",
10564
- children: isEditMode ? "Edit Playlist" : "New Playlist"
10654
+ children: isEditMode ? t("playlist_edit_breadcrumb") : t("playlist_create_breadcrumb")
10565
10655
  }) })
10566
10656
  ]
10567
10657
  }) }) }),
@@ -10570,9 +10660,9 @@ function PlaylistFormHeader({ playlistId, isEditMode, onSubmit, isSaving }) {
10570
10660
  onOpenChange: (open) => {
10571
10661
  if (!open && !isDeleting) setIsDeleteOpen(false);
10572
10662
  },
10573
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.AlertDialogContent, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.AlertDialogHeader, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.AlertDialogTitle, { children: "Delete this playlist?" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.AlertDialogDescription, { children: "This removes the playlist from your library. Shared links that point to it will stop working." })] }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.AlertDialogFooter, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.AlertDialogCancel, {
10663
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.AlertDialogContent, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.AlertDialogHeader, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.AlertDialogTitle, { children: t("playlist_delete_confirm_title") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.AlertDialogDescription, { children: t("playlist_delete_confirm_description") })] }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.AlertDialogFooter, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.AlertDialogCancel, {
10574
10664
  disabled: isDeleting,
10575
- children: "Cancel"
10665
+ children: t("common_cancel")
10576
10666
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.AlertDialogAction, {
10577
10667
  onClick: (e) => {
10578
10668
  e.preventDefault();
@@ -10580,7 +10670,7 @@ function PlaylistFormHeader({ playlistId, isEditMode, onSubmit, isSaving }) {
10580
10670
  },
10581
10671
  disabled: isDeleting,
10582
10672
  className: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
10583
- children: isDeleting ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Spinner, { className: "size-4" }) : "Delete"
10673
+ children: isDeleting ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Spinner, { className: "size-4" }) : t("common_delete")
10584
10674
  })] })] })
10585
10675
  })
10586
10676
  ] });
@@ -10588,6 +10678,7 @@ function PlaylistFormHeader({ playlistId, isEditMode, onSubmit, isSaving }) {
10588
10678
  //#endregion
10589
10679
  //#region ../../shareables/ui/src/components/playlists/form/PlaylistFormDetails.tsx
10590
10680
  function PlaylistFormDetails() {
10681
+ const { t } = useShareablesTranslation();
10591
10682
  const { form, updateField, validationErrors } = usePlaylistForm();
10592
10683
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
10593
10684
  className: "border-border bg-card w-full rounded-lg border p-4 shadow-xs",
@@ -10595,10 +10686,10 @@ function PlaylistFormDetails() {
10595
10686
  className: "space-y-6",
10596
10687
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h2", {
10597
10688
  className: "text-md text-foreground font-semibold",
10598
- children: "Playlist"
10689
+ children: t("playlist_form_heading")
10599
10690
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
10600
10691
  className: "text-muted-foreground text-sm",
10601
- children: "Name your playlist and add a short description."
10692
+ children: t("playlist_form_description")
10602
10693
  })] }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
10603
10694
  className: "space-y-4",
10604
10695
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
@@ -10606,11 +10697,11 @@ function PlaylistFormDetails() {
10606
10697
  children: [
10607
10698
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Label, {
10608
10699
  className: "text-foreground font-medium",
10609
- children: "Name *"
10700
+ children: t("playlist_name_label")
10610
10701
  }),
10611
10702
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Input, {
10612
10703
  name: "title",
10613
- placeholder: "Playlist name",
10704
+ placeholder: t("playlist_name_placeholder"),
10614
10705
  value: form.title,
10615
10706
  onChange: (e) => updateField("title", e.target.value),
10616
10707
  required: true,
@@ -10625,7 +10716,7 @@ function PlaylistFormDetails() {
10625
10716
  className: "flex flex-col gap-2",
10626
10717
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Label, {
10627
10718
  className: "text-foreground font-medium",
10628
- children: "Description"
10719
+ children: t("common_description_label")
10629
10720
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
10630
10721
  className: "border-border rounded-[6px] border shadow-xs",
10631
10722
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RichTextEditor, {
@@ -10633,7 +10724,7 @@ function PlaylistFormDetails() {
10633
10724
  onChange: (value) => updateField("description", value),
10634
10725
  className: "h-48 border-0",
10635
10726
  editorClassName: "h-36 overflow-auto",
10636
- placeholder: "Describe this playlist..."
10727
+ placeholder: t("playlist_description_placeholder")
10637
10728
  })
10638
10729
  })]
10639
10730
  })]
@@ -10678,18 +10769,18 @@ function typeBadgeIcon(relateableType, kind) {
10678
10769
  if (relateableType === "EnrollmentPack") return lucide_react.Package;
10679
10770
  return lucide_react.ShoppingBag;
10680
10771
  }
10681
- function getTypeDisplay(relateableType, relateableKind) {
10772
+ function getTypeDisplay(relateableType, relateableKind, t) {
10682
10773
  switch (relateableType) {
10683
- case "Product": return "Product";
10684
- case "EnrollmentPack": return "Enrollment Pack";
10774
+ case "Product": return t("common_product");
10775
+ case "EnrollmentPack": return t("common_enrollment_pack");
10685
10776
  case "Medium": {
10686
10777
  const kind = relateableKind?.toLowerCase() ?? "";
10687
- if (kind === "video" || kind.includes("video")) return "Video";
10688
- if (kind === "image" || kind.includes("image")) return "Image";
10689
- return relateableKind || "Media";
10778
+ if (kind === "video" || kind.includes("video")) return t("media_type_video");
10779
+ if (kind === "image" || kind.includes("image")) return t("media_type_image");
10780
+ return relateableKind || t("media_type_default");
10690
10781
  }
10691
- case "Page": return "Page";
10692
- default: return relateableType?.replace(/_/g, " ") || "Unknown";
10782
+ case "Page": return t("common_page");
10783
+ default: return relateableType?.replace(/_/g, " ") || t("common_unknown");
10693
10784
  }
10694
10785
  }
10695
10786
  function getItemIcon(relateableType) {
@@ -10702,6 +10793,7 @@ function getItemIcon(relateableType) {
10702
10793
  }
10703
10794
  }
10704
10795
  function SortableTable({ items, setItems, onDeleteItem, isDeletePending, enableReordering = true }) {
10796
+ const { t } = useShareablesTranslation();
10705
10797
  const sensors = (0, import_dist.useSensors)((0, import_dist.useSensor)(import_dist.PointerSensor), (0, import_dist.useSensor)(import_dist.KeyboardSensor, { coordinateGetter: import_dist$1.sortableKeyboardCoordinates }));
10706
10798
  const handleDragEnd = (event) => {
10707
10799
  const { active, over } = event;
@@ -10726,19 +10818,19 @@ function SortableTable({ items, setItems, onDeleteItem, isDeletePending, enableR
10726
10818
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("tr", { children: [
10727
10819
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
10728
10820
  className: "text-muted-foreground px-6 py-3 text-left text-xs font-medium tracking-wider uppercase",
10729
- children: "Order"
10821
+ children: t("playlist_table_order")
10730
10822
  }),
10731
10823
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
10732
10824
  className: "text-muted-foreground px-6 py-3 text-left text-xs font-medium tracking-wider uppercase",
10733
- children: "Item"
10825
+ children: t("playlist_table_item")
10734
10826
  }),
10735
10827
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
10736
10828
  className: "text-muted-foreground px-6 py-3 text-left text-xs font-medium tracking-wider uppercase",
10737
- children: "Type"
10829
+ children: t("playlist_table_type")
10738
10830
  }),
10739
10831
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
10740
10832
  className: "text-muted-foreground px-6 py-3 text-left text-xs font-medium tracking-wider uppercase",
10741
- children: "Actions"
10833
+ children: t("playlist_table_actions")
10742
10834
  })
10743
10835
  ] })
10744
10836
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("tbody", {
@@ -10775,7 +10867,7 @@ function SortableTable({ items, setItems, onDeleteItem, isDeletePending, enableR
10775
10867
  className: "min-w-0 flex-1",
10776
10868
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
10777
10869
  className: "text-foreground truncate text-sm font-medium",
10778
- children: row.title || "Untitled"
10870
+ children: row.title || t("common_untitled")
10779
10871
  })
10780
10872
  })]
10781
10873
  })
@@ -10784,7 +10876,7 @@ function SortableTable({ items, setItems, onDeleteItem, isDeletePending, enableR
10784
10876
  className: "px-6 py-4 whitespace-nowrap",
10785
10877
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
10786
10878
  className: "bg-muted text-foreground inline-flex items-center gap-1 rounded-full px-2 py-1 text-xs",
10787
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(typeBadgeIcon(row.relateable_type || "", row.kind || ""), { className: "h-3 w-3 shrink-0" }), getTypeDisplay(row.relateable_type || "", row.kind || "")] })
10879
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(typeBadgeIcon(row.relateable_type || "", row.kind || ""), { className: "h-3 w-3 shrink-0" }), getTypeDisplay(row.relateable_type || "", row.kind || "", t)] })
10788
10880
  })
10789
10881
  }),
10790
10882
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", {
@@ -10805,7 +10897,7 @@ function SortableTable({ items, setItems, onDeleteItem, isDeletePending, enableR
10805
10897
  onDeleteItem(typeof row.id === "number" ? row.id : parseInt(String(row.id).replace("item-", "")));
10806
10898
  },
10807
10899
  variant: "destructive",
10808
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Trash2, { className: "mr-2 h-4 w-4" }), "Delete Item"]
10900
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Trash2, { className: "mr-2 h-4 w-4" }), t("playlist_delete_item")]
10809
10901
  })
10810
10902
  })] })
10811
10903
  })
@@ -10881,23 +10973,27 @@ function computeOrderedItems(items) {
10881
10973
  });
10882
10974
  return result;
10883
10975
  }
10884
- const SECTIONS = {
10885
- primary: {
10886
- heading: "Playlist Items",
10887
- description: "Manage the media and pages in your playlist. At least one is required.",
10888
- allowedMethods: ["media", "pages"],
10889
- allowedRelateableTypes: PRIMARY_CONTENT_TYPES
10890
- },
10891
- tagged: {
10892
- heading: "Tagged Products",
10893
- description: "Manage the products and enrollments in your playlist. These items will show as recommended items in the cart.",
10894
- allowedMethods: ["products", "enrollment_packs"],
10895
- allowedRelateableTypes: TAGGED_CONTENT_TYPES
10896
- }
10897
- };
10976
+ function useSections(t) {
10977
+ return (0, react.useMemo)(() => ({
10978
+ primary: {
10979
+ heading: t("playlist_items_heading"),
10980
+ description: t("playlist_items_description"),
10981
+ allowedMethods: ["media", "pages"],
10982
+ allowedRelateableTypes: PRIMARY_CONTENT_TYPES
10983
+ },
10984
+ tagged: {
10985
+ heading: t("playlist_tagged_products_heading"),
10986
+ description: t("playlist_tagged_products_description"),
10987
+ allowedMethods: ["products", "enrollment_packs"],
10988
+ allowedRelateableTypes: TAGGED_CONTENT_TYPES
10989
+ }
10990
+ }), [t]);
10991
+ }
10898
10992
  function PlaylistItemsSection({ playlistId }) {
10993
+ const { t } = useShareablesTranslation();
10899
10994
  const { showToast, filePickerApi, pickerSources } = useShareablesUI();
10900
10995
  const api = useShareablesApi();
10996
+ const SECTIONS = useSections(t);
10901
10997
  const [openSection, setOpenSection] = (0, react.useState)(null);
10902
10998
  const { items: contextItems, updateItems, addItem, removeItem } = usePlaylistItems();
10903
10999
  const tableItems = contextItems;
@@ -10915,7 +11011,7 @@ function PlaylistItemsSection({ playlistId }) {
10915
11011
  }, [tableItems]);
10916
11012
  const addItemMutation = useAddItemToPlaylistMutation({ onError: (error) => {
10917
11013
  showToast({
10918
- title: "Failed to add item to playlist",
11014
+ title: t("playlist_add_item_error"),
10919
11015
  type: "error",
10920
11016
  error
10921
11017
  });
@@ -10923,13 +11019,13 @@ function PlaylistItemsSection({ playlistId }) {
10923
11019
  const removeItemMutation = useRemoveItemsFromPlaylistMutation({
10924
11020
  onSuccess: () => {
10925
11021
  showToast({
10926
- title: "Item removed from playlist successfully",
11022
+ title: t("playlist_remove_item_success"),
10927
11023
  type: "success"
10928
11024
  });
10929
11025
  },
10930
11026
  onError: (error) => {
10931
11027
  showToast({
10932
- title: "Failed to remove item from playlist",
11028
+ title: t("playlist_remove_item_error"),
10933
11029
  type: "error",
10934
11030
  error
10935
11031
  });
@@ -10966,7 +11062,7 @@ function PlaylistItemsSection({ playlistId }) {
10966
11062
  if (rollback) updateItems(rollback);
10967
11063
  reorderRollbackRef.current = null;
10968
11064
  showToast({
10969
- title: "Failed to save new item order",
11065
+ title: t("playlist_reorder_error"),
10970
11066
  type: "error",
10971
11067
  error
10972
11068
  });
@@ -10981,7 +11077,8 @@ function PlaylistItemsSection({ playlistId }) {
10981
11077
  playlistId,
10982
11078
  canPersistReorder,
10983
11079
  reorderItemsMutation.mutate,
10984
- showToast
11080
+ showToast,
11081
+ t
10985
11082
  ]);
10986
11083
  const handleDeleteItem = (itemId) => {
10987
11084
  removeItem(itemId);
@@ -10994,7 +11091,7 @@ function PlaylistItemsSection({ playlistId }) {
10994
11091
  setOpenSection(null);
10995
11092
  if (results.length === 0) {
10996
11093
  showToast({
10997
- title: "No items selected",
11094
+ title: t("playlist_no_items_selected"),
10998
11095
  type: "warning"
10999
11096
  });
11000
11097
  return;
@@ -11008,7 +11105,7 @@ function PlaylistItemsSection({ playlistId }) {
11008
11105
  const label = result.metadata?.file_name || `${relateableType} #${relateableId}`;
11009
11106
  if (tableItems.some((existing) => existing.relateable_type === relateableType && existing.relateable?.id === relateableId)) {
11010
11107
  showToast({
11011
- title: "This item is already in the playlist",
11108
+ title: t("playlist_item_already_exists"),
11012
11109
  type: "error"
11013
11110
  });
11014
11111
  continue;
@@ -11035,7 +11132,7 @@ function PlaylistItemsSection({ playlistId }) {
11035
11132
  }
11036
11133
  });
11037
11134
  showToast({
11038
- title: "Item added to playlist successfully",
11135
+ title: t("playlist_add_item_success"),
11039
11136
  type: "success"
11040
11137
  });
11041
11138
  } catch {}
@@ -11046,7 +11143,8 @@ function PlaylistItemsSection({ playlistId }) {
11046
11143
  playlistId,
11047
11144
  addItemMutation,
11048
11145
  addItem,
11049
- showToast
11146
+ showToast,
11147
+ t
11050
11148
  ]);
11051
11149
  const filePickerContextValue = (0, react.useMemo)(() => {
11052
11150
  if (!filePickerApi) return null;
@@ -11129,6 +11227,7 @@ function PlaylistItemsSection({ playlistId }) {
11129
11227
  });
11130
11228
  }
11131
11229
  function PlaylistItemsSubsection({ section, items, onAdd, onReorder, onDeleteItem, isPending, isDeletePending, disableAdd = false }) {
11230
+ const { t } = useShareablesTranslation();
11132
11231
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
11133
11232
  className: "border-border bg-card rounded-lg border p-4",
11134
11233
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
@@ -11153,7 +11252,7 @@ function PlaylistItemsSubsection({ section, items, onAdd, onReorder, onDeleteIte
11153
11252
  size: "sm",
11154
11253
  className: "flex min-w-25 items-center gap-2",
11155
11254
  onClick: onAdd,
11156
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Plus, { className: "h-4 w-4" }), "Add Item"]
11255
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Plus, { className: "h-4 w-4" }), t("playlist_add_item_button")]
11157
11256
  })
11158
11257
  })]
11159
11258
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SortableTable, {
@@ -11201,13 +11300,14 @@ function buildPlaylistUrl(options) {
11201
11300
  return "";
11202
11301
  }
11203
11302
  function PlaylistOpenGraphPreview({ playlist, playlistShareBaseUrl }) {
11303
+ const { t } = useShareablesTranslation();
11204
11304
  const { form } = usePlaylistForm();
11205
11305
  const { items } = usePlaylistItems();
11206
11306
  const seo = form.search_engine_optimizer;
11207
11307
  const firstContentItem = (0, react.useMemo)(() => getFirstOrderedContentItem(items), [items]);
11208
11308
  const firstItemImageUrl = (0, react.useMemo)(() => getImageFromRelateable(firstContentItem), [firstContentItem]);
11209
- const title = (seo?.title || form.title || "").trim() || "Playlist title";
11210
- const description = (seo?.description || "").trim() || stripHtml(form.description || "") || "Description shown when this playlist is shared on social platforms.";
11309
+ const title = (seo?.title || form.title || "").trim() || t("playlist_og_title_fallback");
11310
+ const description = (seo?.description || "").trim() || stripHtml(form.description || "") || t("playlist_og_description_fallback");
11211
11311
  const imageUrl = firstItemImageUrl || (seo?.image_url || "").trim() || (form.image_url || "").trim();
11212
11312
  const shareUrl = (0, react.useMemo)(() => buildPlaylistUrl({
11213
11313
  playlist,
@@ -11231,7 +11331,7 @@ function PlaylistOpenGraphPreview({ playlist, playlistShareBaseUrl }) {
11231
11331
  className: "border-border bg-card rounded-lg border p-4 shadow-xs",
11232
11332
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
11233
11333
  className: "text-foreground mb-2 text-sm font-semibold",
11234
- children: "Preview"
11334
+ children: t("playlist_preview_heading")
11235
11335
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
11236
11336
  className: "border-border bg-card overflow-hidden rounded-lg border",
11237
11337
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
@@ -11246,7 +11346,7 @@ function PlaylistOpenGraphPreview({ playlist, playlistShareBaseUrl }) {
11246
11346
  children: [
11247
11347
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
11248
11348
  className: "text-muted-foreground text-[11px] tracking-wide uppercase",
11249
- children: hostname || "your-site.com"
11349
+ children: hostname || t("common_site_hostname_fallback")
11250
11350
  }),
11251
11351
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
11252
11352
  className: "text-foreground line-clamp-2 text-base font-semibold",
@@ -11265,6 +11365,7 @@ function PlaylistOpenGraphPreview({ playlist, playlistShareBaseUrl }) {
11265
11365
  //#region ../../shareables/ui/src/components/screens/PlaylistCreateScreen.tsx
11266
11366
  function PlaylistFormContent({ playlistId, playlist, isEditMode, itemsToUse, onBack, hideHeader, renderHeaderSlot }) {
11267
11367
  const api = useShareablesApi();
11368
+ const { t } = useShareablesTranslation();
11268
11369
  const { showToast, navigate, user } = useShareablesUI();
11269
11370
  const { items: contextItems } = usePlaylistItems();
11270
11371
  const { form, updateField, validateForm } = usePlaylistForm();
@@ -11286,7 +11387,7 @@ function PlaylistFormContent({ playlistId, playlist, isEditMode, itemsToUse, onB
11286
11387
  const createMutation = useCreatePlaylistMutation({
11287
11388
  onSuccess: (createdPlaylist) => {
11288
11389
  showToast({
11289
- title: "Playlist created successfully",
11390
+ title: t("playlist_create_success"),
11290
11391
  type: "success"
11291
11392
  });
11292
11393
  const newId = createdPlaylist.playlist.id;
@@ -11294,7 +11395,7 @@ function PlaylistFormContent({ playlistId, playlist, isEditMode, itemsToUse, onB
11294
11395
  },
11295
11396
  onError: (error) => {
11296
11397
  showToast({
11297
- title: "Failed to create playlist",
11398
+ title: t("playlist_create_error"),
11298
11399
  type: "error",
11299
11400
  error
11300
11401
  });
@@ -11303,13 +11404,13 @@ function PlaylistFormContent({ playlistId, playlist, isEditMode, itemsToUse, onB
11303
11404
  const updateMutation = useUpdatePlaylistMutation({
11304
11405
  onSuccess: () => {
11305
11406
  showToast({
11306
- title: "Playlist updated successfully",
11407
+ title: t("playlist_update_success"),
11307
11408
  type: "success"
11308
11409
  });
11309
11410
  },
11310
11411
  onError: (error) => {
11311
11412
  showToast({
11312
- title: "Failed to update playlist",
11413
+ title: t("playlist_update_error"),
11313
11414
  type: "error",
11314
11415
  error
11315
11416
  });
@@ -11319,7 +11420,7 @@ function PlaylistFormContent({ playlistId, playlist, isEditMode, itemsToUse, onB
11319
11420
  const onSaveForm = (0, react.useCallback)(async () => {
11320
11421
  if (!validateForm()) {
11321
11422
  showToast({
11322
- title: "Please fill out all required fields",
11423
+ title: t("common_fill_required_fields"),
11323
11424
  type: "error"
11324
11425
  });
11325
11426
  return Promise.reject(/* @__PURE__ */ new Error("Validation failed"));
@@ -11374,7 +11475,7 @@ function PlaylistFormContent({ playlistId, playlist, isEditMode, itemsToUse, onB
11374
11475
  } catch (itemError) {
11375
11476
  console.error("Error adding items to playlist:", itemError);
11376
11477
  showToast({
11377
- title: "Playlist created but some items failed to add",
11478
+ title: t("playlist_create_items_partial_error"),
11378
11479
  type: "warning"
11379
11480
  });
11380
11481
  }
@@ -11389,7 +11490,8 @@ function PlaylistFormContent({ playlistId, playlist, isEditMode, itemsToUse, onB
11389
11490
  updateMutation,
11390
11491
  showToast,
11391
11492
  api,
11392
- user?.id
11493
+ user?.id,
11494
+ t
11393
11495
  ]);
11394
11496
  const isSaving = createMutation.isPending || updateMutation.isPending;
11395
11497
  const handleSubmit = async () => {
@@ -11404,7 +11506,7 @@ function PlaylistFormContent({ playlistId, playlist, isEditMode, itemsToUse, onB
11404
11506
  e.preventDefault();
11405
11507
  (onBack ?? (() => navigate("playlists")))();
11406
11508
  },
11407
- children: "Playlists"
11509
+ children: t("playlist_breadcrumb")
11408
11510
  }) }), isEditMode ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
11409
11511
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.BreadcrumbSeparator, {}),
11410
11512
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.BreadcrumbItem, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.BreadcrumbLink, {
@@ -11414,16 +11516,16 @@ function PlaylistFormContent({ playlistId, playlist, isEditMode, itemsToUse, onB
11414
11516
  navigate(`playlists/${playlistId}`);
11415
11517
  },
11416
11518
  className: "block max-w-[40vw] truncate align-bottom md:max-w-[60ch]",
11417
- children: playlistTitle || "Playlist"
11519
+ children: playlistTitle || t("playlist_breadcrumb_fallback")
11418
11520
  }) }),
11419
11521
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.BreadcrumbSeparator, {}),
11420
11522
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.BreadcrumbItem, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.BreadcrumbPage, {
11421
11523
  className: "font-semibold",
11422
- children: "Edit"
11524
+ children: t("common_edit")
11423
11525
  }) })
11424
11526
  ] }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.BreadcrumbSeparator, {}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.BreadcrumbItem, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.BreadcrumbPage, {
11425
11527
  className: "font-semibold",
11426
- children: "New Playlist"
11528
+ children: t("playlist_create_breadcrumb")
11427
11529
  }) })] })]
11428
11530
  }) }) }),
11429
11531
  renderHeaderSlot?.({
@@ -11491,16 +11593,17 @@ function PlaylistCreateScreen({ playlistId, onBack, hideHeader, renderHeaderSlot
11491
11593
  //#endregion
11492
11594
  //#region ../../shareables/ui/src/components/screens/FilesListingScreen.tsx
11493
11595
  const PAGE_SIZE$1 = 24;
11494
- function formatFileSize(bytes) {
11495
- if (bytes < 1024) return `${bytes} B`;
11496
- if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
11497
- if (bytes < 1024 * 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
11498
- return `${(bytes / (1024 * 1024 * 1024)).toFixed(1)} GB`;
11596
+ function formatFileSize(bytes, labels) {
11597
+ if (bytes < 1024) return `${bytes} ${labels.b}`;
11598
+ if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} ${labels.kb}`;
11599
+ if (bytes < 1024 * 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(1)} ${labels.mb}`;
11600
+ return `${(bytes / (1024 * 1024 * 1024)).toFixed(1)} ${labels.gb}`;
11499
11601
  }
11500
11602
  const DEFAULT_IMAGE$1 = "https://assets.fluid.app/fluid-admin/images/we-commerce/we-commerce.png";
11501
11603
  function FilesListingScreen({ onNavigate }) {
11502
11604
  const api = useShareablesApi();
11503
11605
  const renderImage = useRenderImage();
11606
+ const { t } = useShareablesTranslation();
11504
11607
  const [searchTerm, setSearchTerm] = (0, react.useState)("");
11505
11608
  const [debouncedSearch, setDebouncedSearch] = (0, react.useState)("");
11506
11609
  (0, react.useEffect)(() => {
@@ -11536,18 +11639,18 @@ function FilesListingScreen({ onNavigate }) {
11536
11639
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "border-primary h-6 w-6 animate-spin rounded-full border-2 border-t-transparent" })
11537
11640
  }), error && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
11538
11641
  className: "bg-destructive/10 text-destructive rounded-lg px-3 py-2",
11539
- children: "Failed to load files. Please try again."
11642
+ children: t("files_load_error")
11540
11643
  })] });
11541
11644
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_ScreenHeaderContext.ScreenHeaderBreadcrumbs, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Breadcrumb, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.BreadcrumbList, {
11542
11645
  className: "text-lg",
11543
11646
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.BreadcrumbItem, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.BreadcrumbPage, {
11544
11647
  className: "font-semibold",
11545
- children: "Files"
11648
+ children: t("files_breadcrumb")
11546
11649
  }) })
11547
11650
  }) }) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ShareableListLayout, {
11548
11651
  isLoading,
11549
11652
  isEmpty: !error && files.length === 0 && !isFetchingNextPage && !hasNextPage,
11550
- emptyMessage: debouncedSearch ? `No files match "${debouncedSearch}". Try a different search term.` : "No files available.",
11653
+ emptyMessage: debouncedSearch ? t("files_search_no_results", { search: debouncedSearch }) : t("files_empty_default"),
11551
11654
  filters: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
11552
11655
  className: "flex justify-end",
11553
11656
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
@@ -11555,7 +11658,7 @@ function FilesListingScreen({ onNavigate }) {
11555
11658
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_PortalProductsApiProvider.SearchSort, {
11556
11659
  searchValue: searchTerm,
11557
11660
  onSearchChange: setSearchTerm,
11558
- placeholder: "Search files..."
11661
+ placeholder: t("files_search_placeholder")
11559
11662
  })
11560
11663
  })
11561
11664
  }),
@@ -11582,7 +11685,7 @@ function FilesListingScreen({ onNavigate }) {
11582
11685
  children: [
11583
11686
  renderImage({
11584
11687
  src: file.preview_image_url || DEFAULT_IMAGE$1,
11585
- alt: file.filename || "Untitled File",
11688
+ alt: file.filename || t("files_untitled"),
11586
11689
  fill: true,
11587
11690
  className: "object-cover transition-transform group-hover:scale-105"
11588
11691
  }),
@@ -11596,17 +11699,22 @@ function FilesListingScreen({ onNavigate }) {
11596
11699
  !isVideo && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Badge, {
11597
11700
  className: "absolute top-2 right-2 shadow-lg",
11598
11701
  variant: "default",
11599
- children: formatFileSize(file.content_size)
11702
+ children: formatFileSize(file.content_size, {
11703
+ b: t("files_size_b"),
11704
+ kb: t("files_size_kb"),
11705
+ mb: t("files_size_mb"),
11706
+ gb: t("files_size_gb")
11707
+ })
11600
11708
  })
11601
11709
  ]
11602
11710
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
11603
11711
  className: "px-2 pt-2 pb-4",
11604
11712
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
11605
11713
  className: "text-foreground line-clamp-2 text-sm leading-tight font-bold",
11606
- children: file.filename || "Untitled File"
11714
+ children: file.filename || t("files_untitled")
11607
11715
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
11608
11716
  className: "text-muted-foreground mt-1 text-xs",
11609
- children: file.content_type || "File"
11717
+ children: file.content_type || t("files_type_default")
11610
11718
  })]
11611
11719
  })]
11612
11720
  }, file.id);
@@ -11624,6 +11732,7 @@ function toApiSort(value) {
11624
11732
  function PagesListingScreen({ onNavigate }) {
11625
11733
  const api = useShareablesApi();
11626
11734
  const renderImage = useRenderImage();
11735
+ const { t } = useShareablesTranslation();
11627
11736
  const [searchTerm, setSearchTerm] = (0, react.useState)("");
11628
11737
  const [debouncedSearch, setDebouncedSearch] = (0, react.useState)("");
11629
11738
  const [sortValue, setSortValue] = (0, react.useState)("newest");
@@ -11650,6 +11759,20 @@ function PagesListingScreen({ onNavigate }) {
11650
11759
  initialPageParam: void 0,
11651
11760
  placeholderData: _tanstack_react_query.keepPreviousData
11652
11761
  });
11762
+ const sortOptions = (0, react.useMemo)(() => [
11763
+ {
11764
+ label: t("sort_newest_first"),
11765
+ value: "newest"
11766
+ },
11767
+ {
11768
+ label: t("sort_title_asc"),
11769
+ value: "title_asc"
11770
+ },
11771
+ {
11772
+ label: t("sort_title_desc"),
11773
+ value: "title_desc"
11774
+ }
11775
+ ], [t]);
11653
11776
  const allPages = (0, react.useMemo)(() => data?.pages.flatMap((p) => p.pages) ?? [], [data?.pages]);
11654
11777
  (0, react.useEffect)(() => {
11655
11778
  const target = observerTarget.current;
@@ -11671,14 +11794,14 @@ function PagesListingScreen({ onNavigate }) {
11671
11794
  className: "text-lg",
11672
11795
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.BreadcrumbItem, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.BreadcrumbPage, {
11673
11796
  className: "font-semibold",
11674
- children: "Pages"
11797
+ children: t("pages_breadcrumb")
11675
11798
  }) })
11676
11799
  }) }) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ShareableListLayout, {
11677
11800
  isLoading,
11678
11801
  error,
11679
- errorMessage: "Failed to load pages. Please try again.",
11802
+ errorMessage: t("pages_load_error"),
11680
11803
  isEmpty: allPages.length === 0 && !isFetchingNextPage,
11681
- emptyMessage: debouncedSearch ? `No pages match "${debouncedSearch}". Try a different search term.` : "No pages available.",
11804
+ emptyMessage: debouncedSearch ? t("pages_search_no_results", { search: debouncedSearch }) : t("pages_empty_default"),
11682
11805
  filters: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
11683
11806
  className: "flex justify-end",
11684
11807
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
@@ -11686,21 +11809,8 @@ function PagesListingScreen({ onNavigate }) {
11686
11809
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_PortalProductsApiProvider.SearchSort, {
11687
11810
  searchValue: searchTerm,
11688
11811
  onSearchChange: setSearchTerm,
11689
- placeholder: "Search pages...",
11690
- sortOptions: [
11691
- {
11692
- label: "Newest first",
11693
- value: "newest"
11694
- },
11695
- {
11696
- label: "Title (A-Z)",
11697
- value: "title_asc"
11698
- },
11699
- {
11700
- label: "Title (Z-A)",
11701
- value: "title_desc"
11702
- }
11703
- ],
11812
+ placeholder: t("pages_search_placeholder"),
11813
+ sortOptions,
11704
11814
  sortValue,
11705
11815
  onSortChange: (v) => setSortValue(v)
11706
11816
  })
@@ -11714,7 +11824,7 @@ function PagesListingScreen({ onNavigate }) {
11714
11824
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
11715
11825
  className: SHAREABLE_GRID_CLASS,
11716
11826
  children: allPages.map((page) => {
11717
- const title = page.title || "Untitled Page";
11827
+ const title = page.title || t("pages_untitled");
11718
11828
  const openDetail = () => onNavigate?.("pages", String(page.id));
11719
11829
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.Card, {
11720
11830
  role: "button",
@@ -11737,7 +11847,7 @@ function PagesListingScreen({ onNavigate }) {
11737
11847
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Badge, {
11738
11848
  className: "absolute top-2 right-2 shadow-lg",
11739
11849
  variant: page.status === "published" ? "default" : "secondary",
11740
- children: page.status === "published" ? "Published" : "Unpublished"
11850
+ children: page.status === "published" ? t("pages_status_published") : t("pages_status_unpublished")
11741
11851
  })]
11742
11852
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
11743
11853
  className: "px-2 pt-2 pb-4",
@@ -11759,6 +11869,7 @@ function PagesListingScreen({ onNavigate }) {
11759
11869
  function PageDetailScreen({ pageId, onBack }) {
11760
11870
  const api = useShareablesApi();
11761
11871
  const { navigate } = useShareablesUI();
11872
+ const { t } = useShareablesTranslation();
11762
11873
  const { data: pageResponse, isLoading } = (0, _tanstack_react_query.useQuery)({
11763
11874
  queryKey: shareablesKeys.pages.detail(Number(pageId)),
11764
11875
  queryFn: () => api.pages.getPage(Number(pageId))
@@ -11780,18 +11891,18 @@ function PageDetailScreen({ pageId, onBack }) {
11780
11891
  e.preventDefault();
11781
11892
  (onBack ?? (() => navigate("pages")))();
11782
11893
  },
11783
- children: "Pages"
11894
+ children: t("pages_breadcrumb")
11784
11895
  }) }),
11785
11896
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.BreadcrumbSeparator, {}),
11786
11897
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.BreadcrumbItem, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.BreadcrumbPage, {
11787
11898
  className: "block max-w-[60vw] truncate align-bottom font-semibold md:max-w-[60ch]",
11788
- children: displayTitle || "Page"
11899
+ children: displayTitle || t("pages_breadcrumb_fallback")
11789
11900
  }) })
11790
11901
  ]
11791
11902
  }) }) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ShareableDetailLayout, {
11792
11903
  isLoading,
11793
11904
  notFound: !page && !isLoading,
11794
- notFoundMessage: "Page not found or failed to load.",
11905
+ notFoundMessage: t("pages_not_found"),
11795
11906
  title: displayTitle,
11796
11907
  description,
11797
11908
  containerHeightClass: "md:h-[calc(95vh-140px)]",
@@ -11801,13 +11912,13 @@ function PageDetailScreen({ pageId, onBack }) {
11801
11912
  displayImage,
11802
11913
  displayTitle,
11803
11914
  isVideo: false,
11804
- badgeLabel: "Page",
11915
+ badgeLabel: t("pages_badge_label"),
11805
11916
  rounded: true,
11806
11917
  showBadge: false
11807
11918
  }), page && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Badge, {
11808
11919
  variant: page.status === "published" ? "default" : "secondary",
11809
11920
  className: "bg-background/80 text-foreground absolute top-3 right-3 z-0 inline-flex h-8 items-center rounded-full px-3 text-xs font-medium shadow-md backdrop-blur-sm",
11810
- children: page.status === "published" ? "Published" : "Unpublished"
11921
+ children: page.status === "published" ? t("pages_status_published") : t("pages_status_unpublished")
11811
11922
  })]
11812
11923
  }),
11813
11924
  actions: page && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AssetActions, {
@@ -11885,6 +11996,334 @@ function ShareablesApp({ screen, detailId, action, onNavigate, onBack, countryCo
11885
11996
  return content;
11886
11997
  }
11887
11998
  //#endregion
11999
+ //#region ../../shareables/core/src/translation-adapter.ts
12000
+ const shareablesDomain = require_static_dict_adapter.createDomainTranslations({
12001
+ fallback: {
12002
+ common_save: "Save",
12003
+ common_cancel: "Cancel",
12004
+ common_delete: "Delete",
12005
+ common_deleting: "Deleting...",
12006
+ common_edit: "Edit",
12007
+ common_done: "Done",
12008
+ common_on: "On",
12009
+ common_off: "Off",
12010
+ common_replace: "Replace",
12011
+ common_remove: "Remove",
12012
+ common_removing: "Removing...",
12013
+ common_add: "Add",
12014
+ common_adding: "Adding...",
12015
+ common_added: "Added",
12016
+ common_untitled: "Untitled",
12017
+ common_loading: "Loading...",
12018
+ common_na: "N/A",
12019
+ common_all: "All",
12020
+ common_mine: "Mine",
12021
+ common_company: "Company",
12022
+ common_product: "Product",
12023
+ common_enrollment: "Enrollment",
12024
+ common_enrollment_pack: "Enrollment Pack",
12025
+ common_page: "Page",
12026
+ common_unknown: "Unknown",
12027
+ common_title_label: "Title",
12028
+ common_description_label: "Description",
12029
+ common_start_writing_placeholder: "Start writing...",
12030
+ common_read_more: "Read more",
12031
+ common_read_less: "Read less",
12032
+ common_not_found_default: "Not found or failed to load.",
12033
+ common_load_error_default: "Failed to load. Please try again.",
12034
+ common_error_prefix: "Error: ",
12035
+ common_fill_required_fields: "Please fill out all required fields",
12036
+ common_select_all: "Select All",
12037
+ common_deselect_all: "Deselect All",
12038
+ common_selected_count: "{{count}} selected",
12039
+ common_favorite: "Favorite",
12040
+ common_unfavorite: "Unfavorite",
12041
+ common_cancel_selection_aria: "Cancel selection",
12042
+ common_more_options_aria: "More options",
12043
+ common_list_view: "List view",
12044
+ common_grid_view: "Grid view",
12045
+ common_site_hostname_fallback: "your-site.com",
12046
+ sort_newest: "Newest",
12047
+ sort_oldest: "Oldest",
12048
+ sort_newest_first: "Newest first",
12049
+ sort_name_asc: "Name (A-Z)",
12050
+ sort_name_desc: "Name (Z-A)",
12051
+ sort_title_asc: "Title (A-Z)",
12052
+ sort_title_desc: "Title (Z-A)",
12053
+ sort_date_newest: "Date Created (Newest)",
12054
+ sort_date_oldest: "Date Created (Oldest)",
12055
+ sort_price_asc: "Price: Low to High",
12056
+ sort_price_desc: "Price: High to Low",
12057
+ media_breadcrumb: "Media",
12058
+ media_heading: "Media",
12059
+ media_new_title: "New Media",
12060
+ media_create_breadcrumb: "New Media",
12061
+ media_type_image: "Image",
12062
+ media_type_video: "Video",
12063
+ media_type_pdf: "PDF",
12064
+ media_type_default: "Media",
12065
+ media_create_success: "Media created successfully",
12066
+ media_create_error: "Failed to create media: {{message}}",
12067
+ media_save_success: "Media saved successfully",
12068
+ media_save_error: "Failed to save: {{message}}",
12069
+ media_delete_success: "Media deleted",
12070
+ media_delete_error: "Failed to delete: {{message}}",
12071
+ media_title_required: "Title is required",
12072
+ media_file_required: "Please select a file",
12073
+ media_not_found: "Media not found or failed to load.",
12074
+ media_select_button: "Select Media",
12075
+ media_replace_button: "Replace Media",
12076
+ media_add_button: "Add Media",
12077
+ media_upload_placeholder: "No media uploaded. Click to upload an image, video, or PDF.",
12078
+ media_details_heading: "Media Details",
12079
+ media_title_placeholder: "Enter media title",
12080
+ media_cta_button_label: "CTA Button: ",
12081
+ media_thumbnail_label: "Thumbnail",
12082
+ media_thumbnail_alt: "Thumbnail",
12083
+ media_video_thumbnail_alt: "Video thumbnail",
12084
+ media_no_thumbnail: "No thumbnail set",
12085
+ media_pending_save: "Pending — save to apply",
12086
+ media_select_new_image: "Select New Image",
12087
+ media_thumbnail_capture_unavailable: "Thumbnail capture is not available in this context",
12088
+ media_thumbnail_upload_error: "Failed to upload thumbnail",
12089
+ media_no_media_available: "No media available",
12090
+ media_actions_aria: "Media actions",
12091
+ media_my_media_tab: "My Media",
12092
+ media_my_media_badge: "My Media",
12093
+ media_search_placeholder: "Search media...",
12094
+ media_filter_all_types: "All types",
12095
+ media_filter_images: "Images",
12096
+ media_filter_videos: "Videos",
12097
+ media_filter_pdfs: "PDFs",
12098
+ media_empty_default: "No media available.",
12099
+ media_delete_dialog_title: "Delete Media",
12100
+ media_delete_dialog_description: "Are you sure you want to delete {{title}}? This action cannot be undone.",
12101
+ media_delete_confirm_title: "Delete this media?",
12102
+ media_delete_confirm_description: "This removes the item from your media library. Shared links that point to it will stop working.",
12103
+ media_frame_capture_error: "Couldn't capture the video frame. Please try again.",
12104
+ media_select_from_video_frame: "Select from video frame",
12105
+ media_select_video_frame: "Select Video Frame",
12106
+ media_select_video_frame_title: "Select Video Frame",
12107
+ media_capture_frame: "Capture Frame",
12108
+ media_tagged_products_heading: "Tagged Products",
12109
+ media_no_products_tagged: "No products tagged yet.",
12110
+ media_add_product_button: "Add Product",
12111
+ media_add_products_button: "Add Products",
12112
+ media_products_selected_count: "{{current}} of {{max}} products selected",
12113
+ media_products_country_note: "Products will only display in available countries.",
12114
+ media_product_fallback_name: "Product #{{id}}",
12115
+ media_max_products_reached: "Maximum {{max}} products reached",
12116
+ media_select_products_title: "Select Products to Tag",
12117
+ media_products_selected_ratio: "({{current}}/{{max}} selected)",
12118
+ media_max_products_warning: "You have reached the maximum limit of {{max}} products.",
12119
+ media_limit_reached: "Limit reached",
12120
+ cta_dialog_title: "CTA Button",
12121
+ cta_dialog_description: "Configure the call-to-action button that appears with your media.",
12122
+ cta_enable_toggle_label: "Enable call-to-action button",
12123
+ cta_action_type_label: "Action Type",
12124
+ cta_type_placeholder: "Select type",
12125
+ cta_type_page: "Page",
12126
+ cta_type_cart: "Cart",
12127
+ cta_type_email: "Email",
12128
+ cta_type_phone: "Phone",
12129
+ cta_button_label: "Button Label",
12130
+ cta_default_button_text: "Learn More",
12131
+ cta_url_label: "URL",
12132
+ cta_url_placeholder: "https://example.com",
12133
+ seo_heading: "SEO And Link Sharing",
12134
+ seo_title_label: "SEO Title",
12135
+ seo_title_placeholder: "Page title for search engines",
12136
+ seo_description_label: "SEO Description",
12137
+ seo_description_placeholder: "Description for search engines",
12138
+ seo_block_crawlers_label: "Block Crawlers",
12139
+ seo_block_crawlers_description: "Prevent search engines from indexing",
12140
+ seo_block_crawlers_aria: "Block search engine crawlers",
12141
+ seo_preview_title_fallback: "Your page title",
12142
+ seo_preview_url_fallback: "yoursite.com/media/...",
12143
+ playlist_breadcrumb: "Playlists",
12144
+ playlist_breadcrumb_fallback: "Playlist",
12145
+ playlist_create_breadcrumb: "New Playlist",
12146
+ playlist_edit_breadcrumb: "Edit Playlist",
12147
+ playlist_badge_label: "Playlist",
12148
+ playlist_create_success: "Playlist created successfully",
12149
+ playlist_create_error: "Failed to create playlist",
12150
+ playlist_update_success: "Playlist updated successfully",
12151
+ playlist_update_error: "Failed to update playlist",
12152
+ playlist_delete_success: "Playlist deleted",
12153
+ playlist_delete_success_full: "Playlist deleted successfully",
12154
+ playlist_delete_error: "Failed to delete playlist",
12155
+ playlist_not_found: "Playlist not found or failed to load.",
12156
+ playlist_create_items_partial_error: "Playlist created but some items failed to add",
12157
+ playlist_favorite_error: "Failed to update favorite",
12158
+ playlist_favorite_added: "Added to favorites",
12159
+ playlist_favorite_removed: "Removed from favorites",
12160
+ playlist_my_playlists_tab: "My Playlists",
12161
+ playlist_search_placeholder: "Search playlists...",
12162
+ playlist_create_button: "Create Playlist",
12163
+ playlist_empty_default: "There are no playlists available at the moment.",
12164
+ playlist_untitled: "Untitled Playlist",
12165
+ playlist_item_count_one: "{{count}} item",
12166
+ playlist_item_count_other: "{{count}} items",
12167
+ playlist_select_aria: "Select {{title}}",
12168
+ playlist_actions_aria: "Playlist actions",
12169
+ playlist_delete_confirm_title: "Delete this playlist?",
12170
+ playlist_delete_confirm_description: "This removes the playlist from your library. Shared links that point to it will stop working.",
12171
+ playlist_form_heading: "Playlist",
12172
+ playlist_form_description: "Name your playlist and add a short description.",
12173
+ playlist_name_label: "Name *",
12174
+ playlist_name_placeholder: "Playlist name",
12175
+ playlist_description_placeholder: "Describe this playlist...",
12176
+ playlist_items_heading: "Playlist Items",
12177
+ playlist_items_description: "Manage the media and pages in your playlist. At least one is required.",
12178
+ playlist_tagged_products_heading: "Tagged Products",
12179
+ playlist_tagged_products_description: "Manage the products and enrollments in your playlist. These items will show as recommended items in the cart.",
12180
+ playlist_add_item_button: "Add Item",
12181
+ playlist_add_item_success: "Item added to playlist successfully",
12182
+ playlist_add_item_error: "Failed to add item to playlist",
12183
+ playlist_remove_item_success: "Item removed from playlist successfully",
12184
+ playlist_remove_item_error: "Failed to remove item from playlist",
12185
+ playlist_reorder_error: "Failed to save new item order",
12186
+ playlist_no_items_selected: "No items selected",
12187
+ playlist_item_already_exists: "This item is already in the playlist",
12188
+ playlist_delete_item: "Delete Item",
12189
+ playlist_table_order: "Order",
12190
+ playlist_table_item: "Item",
12191
+ playlist_table_type: "Type",
12192
+ playlist_table_actions: "Actions",
12193
+ playlist_preview_heading: "Preview",
12194
+ playlist_og_title_fallback: "Playlist title",
12195
+ playlist_og_description_fallback: "Description shown when this playlist is shared on social platforms.",
12196
+ playlist_no_other_playlists: "No Other Playlists",
12197
+ playlist_no_other_playlists_description: "There are no other playlists available",
12198
+ playlist_view_link: "View playlist ->",
12199
+ playlist_other_playlists_tab: "Other Playlists",
12200
+ playlist_no_items: "No Items",
12201
+ playlist_no_items_description: "This playlist doesn't have any items yet",
12202
+ playlist_items_in_playlist_count: "Items in playlist ({{count}})",
12203
+ pages_breadcrumb: "Pages",
12204
+ pages_breadcrumb_fallback: "Page",
12205
+ pages_badge_label: "Page",
12206
+ pages_load_error: "Failed to load pages. Please try again.",
12207
+ pages_search_no_results: "No pages match \"{{search}}\". Try a different search term.",
12208
+ pages_empty_default: "No pages available.",
12209
+ pages_search_placeholder: "Search pages...",
12210
+ pages_untitled: "Untitled Page",
12211
+ pages_status_published: "Published",
12212
+ pages_status_unpublished: "Unpublished",
12213
+ pages_not_found: "Page not found or failed to load.",
12214
+ products_breadcrumb: "Products",
12215
+ products_breadcrumb_fallback: "Product",
12216
+ products_load_error: "Failed to load products. Please try again.",
12217
+ products_load_more_error: "Failed to load more products.",
12218
+ products_add_error: "Failed to add product. Please try again.",
12219
+ products_remove_error: "Failed to remove product. Please try again.",
12220
+ products_search_placeholder: "Search products...",
12221
+ products_search_no_results: "No products found matching your search.",
12222
+ products_search_start_typing: "Start typing to search for products.",
12223
+ products_empty_default: "No products available.",
12224
+ products_not_found: "Product not found or failed to load.",
12225
+ products_no_image: "No Product Image",
12226
+ products_no_media: "This product does not have any associated media",
12227
+ products_price_label: "Price",
12228
+ products_related_sharables: "Related Sharables",
12229
+ products_asset_count: "{{count}} assets",
12230
+ files_breadcrumb: "Files",
12231
+ files_load_error: "Failed to load files. Please try again.",
12232
+ files_search_no_results: "No files match \"{{search}}\". Try a different search term.",
12233
+ files_empty_default: "No files available.",
12234
+ files_search_placeholder: "Search files...",
12235
+ files_untitled: "Untitled File",
12236
+ files_type_default: "File",
12237
+ files_size_b: "B",
12238
+ files_size_kb: "KB",
12239
+ files_size_mb: "MB",
12240
+ files_size_gb: "GB",
12241
+ share_download_asset: "Download Asset",
12242
+ share_download_no_asset: "No downloadable asset available",
12243
+ share_link_copied: "Share link copied to clipboard!",
12244
+ share_link_copy_error: "Failed to copy link to clipboard",
12245
+ share_link_not_available: "Share link not available yet. Please wait...",
12246
+ share_social_description: "Check out this {{type}}: {{title}}",
12247
+ share_mysite_success: "Shared to MySite",
12248
+ share_mysite_error: "Failed to share to MySite",
12249
+ share_unique_link_heading: "Share Your Unique Link",
12250
+ share_qr_code_alt: "QR Code for share link",
12251
+ share_qr_code_default_alt: "QR Code",
12252
+ share_qr_code_load_error: "QR code failed to load",
12253
+ share_mysite_button: "MySite",
12254
+ share_mysite_preview_title: "MySite Preview",
12255
+ share_button: "Share",
12256
+ share_generating_link: "Generating link...",
12257
+ share_loading_media: "Loading media...",
12258
+ share_media_load_error: "Failed to load media",
12259
+ share_analytics_coming_soon: "Analytics Coming Soon",
12260
+ share_analytics_description: "View engagement metrics and performance data",
12261
+ share_type_product: "product",
12262
+ share_type_media: "media",
12263
+ share_type_enrollment_pack: "enrollment pack",
12264
+ share_type_site: "site",
12265
+ share_type_library: "library",
12266
+ share_no_marketing_assets: "No Marketing Assets",
12267
+ share_no_associated_media: "This {{label}} does not have any associated media",
12268
+ share_related_sharables_count: "Related Sharables ({{count}})",
12269
+ share_no_tab_items_found: "No {{tab}} found",
12270
+ share_no_items_to_display: "No items to display",
12271
+ share_click_to_find_assets: "Click to find shareable assets",
12272
+ share_click_to_share_video: "Click to share this video",
12273
+ share_click_to_share_asset: "Click to share this asset",
12274
+ share_no_tagged_products: "No Tagged Products",
12275
+ share_no_tagged_products_description: "No products are tagged in this playlist",
12276
+ share_tagged_products_count: "Tagged Products ({{count}})",
12277
+ common_filter_search_no_results: "No {{entityName}} match \"{{searchTerm}}\" with the current filters. Try a different search term or switch to \"All\".",
12278
+ common_search_no_results: "No {{entityName}} match \"{{searchTerm}}\". Try a different search term.",
12279
+ common_filter_no_results: "No matching {{entityName}} for the current filters.",
12280
+ editor_bold: "Bold",
12281
+ editor_italic: "Italic",
12282
+ editor_underline: "Underline",
12283
+ editor_align_left: "Align left",
12284
+ editor_align_center: "Align center",
12285
+ editor_align_right: "Align right",
12286
+ editor_justify: "Justify",
12287
+ editor_bullet_list: "Bullet list",
12288
+ editor_ordered_list: "Ordered list"
12289
+ },
12290
+ loaders: {
12291
+ de: () => Promise.resolve().then(() => require("./de-d5sXuDlc.cjs")).then((m) => m.default),
12292
+ el: () => Promise.resolve().then(() => require("./el-3T5wNvmF.cjs")).then((m) => m.default),
12293
+ es: () => Promise.resolve().then(() => require("./es-DYAui4cM.cjs")).then((m) => m.default),
12294
+ fr: () => Promise.resolve().then(() => require("./fr-DYML7Hb_.cjs")).then((m) => m.default),
12295
+ he: () => Promise.resolve().then(() => require("./he-Cu_YCy1f.cjs")).then((m) => m.default),
12296
+ hu: () => Promise.resolve().then(() => require("./hu-Czc1FPg9.cjs")).then((m) => m.default),
12297
+ id: () => Promise.resolve().then(() => require("./id-Vw9DQ3V1.cjs")).then((m) => m.default),
12298
+ it: () => Promise.resolve().then(() => require("./it-CpnrX6Qu.cjs")).then((m) => m.default),
12299
+ ja: () => Promise.resolve().then(() => require("./ja-JVcCjBJ9.cjs")).then((m) => m.default),
12300
+ ko: () => Promise.resolve().then(() => require("./ko-WIfVodYY.cjs")).then((m) => m.default),
12301
+ nl: () => Promise.resolve().then(() => require("./nl-C5U5y6gr.cjs")).then((m) => m.default),
12302
+ pl: () => Promise.resolve().then(() => require("./pl-DJKAFKNJ.cjs")).then((m) => m.default),
12303
+ pt: () => Promise.resolve().then(() => require("./pt-CpQN7iPy.cjs")).then((m) => m.default),
12304
+ ro: () => Promise.resolve().then(() => require("./ro-CGOwHLvs.cjs")).then((m) => m.default),
12305
+ ru: () => Promise.resolve().then(() => require("./ru-CW4wBDfy.cjs")).then((m) => m.default),
12306
+ th: () => Promise.resolve().then(() => require("./th-C7VrhPP5.cjs")).then((m) => m.default),
12307
+ tl: () => Promise.resolve().then(() => require("./tl-CATDGPeB.cjs")).then((m) => m.default),
12308
+ tr: () => Promise.resolve().then(() => require("./tr-Bsdv5dWu.cjs")).then((m) => m.default),
12309
+ zh_CN: () => Promise.resolve().then(() => require("./zh_CN-Bzo7sqbA.cjs")).then((m) => m.default),
12310
+ zh_TW: () => Promise.resolve().then(() => require("./zh_TW-DQdWK1u9.cjs")).then((m) => m.default)
12311
+ }
12312
+ });
12313
+ function createShareablesTranslationAdapter(locale, dict) {
12314
+ return require_static_dict_adapter.createStaticDictAdapter(locale, dict);
12315
+ }
12316
+ //#endregion
12317
+ //#region src/providers/ShareablesTranslationBridge.tsx
12318
+ function ShareablesTranslationBridge({ children }) {
12319
+ const { locale } = require_static_dict_adapter.useActiveLocale();
12320
+ const dict = require_static_dict_adapter.useDomainDict(shareablesDomain, locale);
12321
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ShareablesTranslationProvider, {
12322
+ value: (0, react.useMemo)(() => createShareablesTranslationAdapter(locale, dict), [locale, dict]),
12323
+ children
12324
+ });
12325
+ }
12326
+ //#endregion
11888
12327
  //#region ../../file-picker/api-client/src/api/url-proxy.ts
11889
12328
  const urlProxyResponseSchema = zod.z.object({
11890
12329
  data: zod.z.string(),
@@ -13283,7 +13722,7 @@ function ShareablesScreenContent() {
13283
13722
  detailId,
13284
13723
  screen
13285
13724
  ]);
13286
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ShareablesCoreProvider, {
13725
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ShareablesTranslationBridge, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ShareablesCoreProvider, {
13287
13726
  config: (0, react.useMemo)(() => ({
13288
13727
  user: account ? { id: account.id } : null,
13289
13728
  repContext: true
@@ -13429,7 +13868,7 @@ function ShareablesScreenContent() {
13429
13868
  onBack: handleBack
13430
13869
  })
13431
13870
  })
13432
- });
13871
+ }) });
13433
13872
  }
13434
13873
  const shareablesScreenPropertySchema = {
13435
13874
  widgetType: "ShareablesScreen",
@@ -13454,4 +13893,4 @@ Object.defineProperty(exports, "shareablesScreenPropertySchema", {
13454
13893
  }
13455
13894
  });
13456
13895
 
13457
- //# sourceMappingURL=ShareablesScreen-CQZBq1Hl.cjs.map
13896
+ //# sourceMappingURL=ShareablesScreen-BT3H1Omb.cjs.map