@mercurjs/vendor 2.0.0 → 2.0.1

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 (256) hide show
  1. package/dist/{[id]-S6EPH4OO.js → [id]-6WYSWXWC.js} +30 -28
  2. package/dist/{[id]-SJXBJLAT.js → [id]-CLZ7BUYL.js} +9 -8
  3. package/dist/{[id]-47FGVJYM.js → [id]-DCCF7277.js} +35 -33
  4. package/dist/{[id]-ARXBXGNZ.js → [id]-EJAHMOOE.js} +33 -31
  5. package/dist/{[id]-HD76VJ2P.js → [id]-ENTJSLN2.js} +16 -15
  6. package/dist/{[id]-XY3A3EMF.js → [id]-LZPT5Y55.js} +32 -31
  7. package/dist/{[id]-Z4P7XA4G.js → [id]-OGHRZ2VY.js} +232 -103
  8. package/dist/{[id]-FLIHBDAS.js → [id]-PHS2WYFX.js} +33 -31
  9. package/dist/{[id]-JF6CCBRE.js → [id]-T64V4G6T.js} +19 -18
  10. package/dist/{[id]-IWPWKLOH.js → [id]-TLZZ53G7.js} +13 -12
  11. package/dist/{[id]-6HM66I3E.js → [id]-UAOAQVEM.js} +48 -45
  12. package/dist/{[id]-Q6HILUAG.js → [id]-VKG2WEIR.js} +39 -37
  13. package/dist/{[id]-VTFOP3BF.js → [id]-WRA56ZMU.js} +5 -5
  14. package/dist/{[id]-MIV4U5UW.js → [id]-XRGNT7CY.js} +7 -7
  15. package/dist/{[location_id]-AWDD2VHW.js → [location_id]-7ZUB2TTU.js} +14 -14
  16. package/dist/{[province_id]-36QJ2FKC.js → [province_id]-XGA44S7P.js} +30 -29
  17. package/dist/add-7ZTE42IE.js +158 -0
  18. package/dist/{add-YUANWTIL.js → add-AKC7LTK3.js} +49 -46
  19. package/dist/{add-customer-groups-7SLONTS2.js → add-customer-groups-BRC3DKQ2.js} +29 -27
  20. package/dist/{add-products-ISR3DRPQ.js → add-products-ZSULNZVI.js} +31 -29
  21. package/dist/{add-promotions-FZRDYHYX.js → add-promotions-TNFVT5ST.js} +12 -11
  22. package/dist/{add-to-campaign-V6D7JKRS.js → add-to-campaign-HL6NGRR4.js} +6 -6
  23. package/dist/address-3DSJESKM.js +249 -0
  24. package/dist/{adjust-inventory-P7AB7VIB.js → adjust-inventory-H4EUP7J3.js} +4 -4
  25. package/dist/{allocate-items-QAS5PZLR.js → allocate-items-6OAKG25R.js} +8 -8
  26. package/dist/{areas-Y7VDWH7G.js → areas-JO6L3M7Y.js} +11 -10
  27. package/dist/{attributes-UEM2VJKV.js → attributes-WRZYJEYN.js} +5 -4
  28. package/dist/{breadcrumb-6NAAOPIY.js → breadcrumb-3Z7KZG62.js} +4 -4
  29. package/dist/{breadcrumb-5OTOCYNL.js → breadcrumb-5BXDYVRO.js} +4 -4
  30. package/dist/{breadcrumb-3QTVWXZB.js → breadcrumb-BS7Y5OKF.js} +5 -5
  31. package/dist/{breadcrumb-CIGKLKKS.js → breadcrumb-D3UDTWGE.js} +3 -3
  32. package/dist/breadcrumb-D6QNYOAO.js +45 -0
  33. package/dist/{breadcrumb-OVMEC5OZ.js → breadcrumb-F3BN5753.js} +3 -3
  34. package/dist/{breadcrumb-MOQ7GI3Z.js → breadcrumb-KQSFIXQ4.js} +3 -3
  35. package/dist/{breadcrumb-NCBGPQML.js → breadcrumb-M5Z5WA6I.js} +4 -4
  36. package/dist/{breadcrumb-EOYLR3IQ.js → breadcrumb-OIGGCB3L.js} +3 -3
  37. package/dist/{breadcrumb-LENACUAA.js → breadcrumb-UAUX7XCV.js} +3 -3
  38. package/dist/breadcrumb-UH7FAYU2.js +46 -0
  39. package/dist/{breadcrumb-ASB2YCNV.js → breadcrumb-Y5UW3I4C.js} +3 -3
  40. package/dist/{breadcrumb-WP34OXGQ.js → breadcrumb-YBBYFQYG.js} +3 -3
  41. package/dist/breadcrumb-ZMVHXCOX.js +32 -0
  42. package/dist/bulk-edit-C6WJKURW.js +244 -0
  43. package/dist/{campaigns-PMVKUFEA.js → campaigns-SF2YDBID.js} +9 -8
  44. package/dist/{categories-JARCKR7M.js → categories-WRDJAJ2Q.js} +9 -8
  45. package/dist/{chunk-HUZG6A3X.js → chunk-2POPPFAP.js} +3 -3
  46. package/dist/{chunk-S5GQ2SES.js → chunk-2SLAVXFY.js} +5 -5
  47. package/dist/{chunk-JVBLYMY2.js → chunk-32RYSB2V.js} +2 -2
  48. package/dist/{chunk-VHMGJUYN.js → chunk-3B34B2M2.js} +1 -1
  49. package/dist/{chunk-BI2WWFPS.js → chunk-3BZBEC3Y.js} +1 -1
  50. package/dist/{chunk-LMHJRE4A.js → chunk-3DXMZA7M.js} +2 -2
  51. package/dist/{chunk-Z2WPXJ6J.js → chunk-4DYUQ3G5.js} +2 -2
  52. package/dist/{chunk-HBQC3YQZ.js → chunk-573EQEW2.js} +1 -1
  53. package/dist/{chunk-FBZHM2QZ.js → chunk-5BONGICL.js} +5 -5
  54. package/dist/{chunk-ZZ7VKT2S.js → chunk-5IWBNPZX.js} +766 -204
  55. package/dist/{chunk-KHHY7EEM.js → chunk-6WY5X4PE.js} +5 -5
  56. package/dist/{chunk-CUO22GTM.js → chunk-7TIZP4YG.js} +1 -1
  57. package/dist/{chunk-52I65K53.js → chunk-7XC7ZRG7.js} +17 -129
  58. package/dist/{chunk-AONKZGWL.js → chunk-ASEVHHCT.js} +3 -3
  59. package/dist/{chunk-TG3TCIL6.js → chunk-AW4WN2EK.js} +6 -6
  60. package/dist/{chunk-DDEIH66R.js → chunk-B5326BWT.js} +4 -4
  61. package/dist/{chunk-O6PRBSFL.js → chunk-BI2AYXZQ.js} +50 -35
  62. package/dist/{chunk-HUNGNEPY.js → chunk-BOZJOOGW.js} +1 -1
  63. package/dist/{chunk-AIFLEWO2.js → chunk-BWGPN6XV.js} +1 -1
  64. package/dist/{chunk-5XOCUDS2.js → chunk-CUMY2VZ5.js} +1 -1
  65. package/dist/chunk-DLNNTQRY.js +217 -0
  66. package/dist/{chunk-B2RVONU7.js → chunk-DRAZNW7J.js} +4 -4
  67. package/dist/{chunk-CVVYQI5F.js → chunk-EBZ5VZEO.js} +1 -1
  68. package/dist/{chunk-ZPGWTLF2.js → chunk-EFIF2GCZ.js} +4 -4
  69. package/dist/{chunk-DHADGZJ5.js → chunk-F4OJN2F2.js} +40 -5
  70. package/dist/{chunk-PYQJ5N25.js → chunk-FEUCCLKR.js} +6 -6
  71. package/dist/{chunk-JKSPDM7I.js → chunk-FNG7ZA7N.js} +1 -1
  72. package/dist/{chunk-UXKKD4AD.js → chunk-FQTYHU6G.js} +5 -5
  73. package/dist/chunk-FX4V5JCF.js +37 -0
  74. package/dist/{chunk-ZFFA36DB.js → chunk-GCSQEJMD.js} +2 -2
  75. package/dist/{chunk-NANYVBFI.js → chunk-GJM5XI3E.js} +1 -1
  76. package/dist/{chunk-W6ZVQJYB.js → chunk-GYV6SKY7.js} +1 -1
  77. package/dist/chunk-I5K5USJM.js +330 -0
  78. package/dist/{chunk-J2XP7VRG.js → chunk-IBTTL6EJ.js} +4 -4
  79. package/dist/{chunk-3LPVUPZZ.js → chunk-IDYGSAHT.js} +1 -1
  80. package/dist/{chunk-DC2K6CFQ.js → chunk-IQWK723D.js} +1 -1
  81. package/dist/{chunk-PWZKFTJS.js → chunk-ITQW6CK2.js} +5 -5
  82. package/dist/{chunk-NWFWI4IE.js → chunk-JKKRKFCS.js} +55 -62
  83. package/dist/chunk-JQV7CXEC.js +37 -0
  84. package/dist/{chunk-RH2NI4BC.js → chunk-JRT2U4UI.js} +448 -101
  85. package/dist/{chunk-4FCZDRAE.js → chunk-JTCUWZ7D.js} +5 -5
  86. package/dist/chunk-LA6XSPQG.js +3723 -0
  87. package/dist/{chunk-JXP5YZ77.js → chunk-LHKHQAAY.js} +1 -1
  88. package/dist/{chunk-TTFCO5HU.js → chunk-LKA7QM6R.js} +7 -7
  89. package/dist/{chunk-FGCKXH45.js → chunk-LPOAVK6Y.js} +1 -0
  90. package/dist/{chunk-VGJTARSA.js → chunk-LRARA622.js} +2 -2
  91. package/dist/chunk-LRD242C7.js +40 -0
  92. package/dist/{chunk-PADOWAXM.js → chunk-LWJF63JW.js} +1 -1
  93. package/dist/{chunk-DYUTYBAQ.js → chunk-M6N4ISXL.js} +1 -1
  94. package/dist/{chunk-2F3H6ORE.js → chunk-MWQQVKRU.js} +1 -1
  95. package/dist/{chunk-JK5CK6SW.js → chunk-N2WKLVUX.js} +20 -3
  96. package/dist/{chunk-R65A4P4H.js → chunk-N335VHD3.js} +1 -1
  97. package/dist/chunk-NBMM2TZK.js +33 -0
  98. package/dist/{chunk-SI4ALL7W.js → chunk-NBPMNUKZ.js} +1 -1
  99. package/dist/{chunk-GDMNHL7E.js → chunk-NCABGI3E.js} +6 -6
  100. package/dist/chunk-NYRRRCJS.js +339 -0
  101. package/dist/{chunk-QJ7QW3SZ.js → chunk-O7E4KQAK.js} +6 -6
  102. package/dist/{chunk-NKB6WTBH.js → chunk-OWPZ3CIR.js} +5 -5
  103. package/dist/{chunk-RE7YXVFG.js → chunk-PCMNEUMV.js} +3 -3
  104. package/dist/{chunk-CFETU5BI.js → chunk-QHQWEERJ.js} +1 -36
  105. package/dist/{chunk-WHTS4G5K.js → chunk-QXUKJDZB.js} +1 -1
  106. package/dist/{chunk-Y224F4UU.js → chunk-RIN4CBRB.js} +0 -1
  107. package/dist/{chunk-LWVBKUUL.js → chunk-RL7SFZOF.js} +2 -2
  108. package/dist/{chunk-UYJ65N46.js → chunk-RLETOWCM.js} +5 -5
  109. package/dist/{chunk-DVPTD7LZ.js → chunk-RMBCBXWD.js} +1 -1
  110. package/dist/{chunk-A2BNIZ7D.js → chunk-RTAWYMQP.js} +1 -1
  111. package/dist/{chunk-VJTYMQVA.js → chunk-RUE5BPC2.js} +2 -2
  112. package/dist/{chunk-EOOK6473.js → chunk-RV5UTYBG.js} +15 -13
  113. package/dist/chunk-S2Q7PO7I.js +177 -0
  114. package/dist/{chunk-Y4VBOHAP.js → chunk-S7EKBD2C.js} +3 -3
  115. package/dist/{chunk-CELHWX5P.js → chunk-SDSEW72R.js} +5 -5
  116. package/dist/{chunk-4TBDDMFP.js → chunk-SGT6QYWH.js} +1 -1
  117. package/dist/chunk-STBCWNZQ.js +57 -0
  118. package/dist/{chunk-LZ7QV42C.js → chunk-SYNUA6LQ.js} +1 -1
  119. package/dist/{chunk-CTWSWZ4R.js → chunk-T7LEJIIM.js} +4 -4
  120. package/dist/{chunk-7EM7WET3.js → chunk-TZTKHOEK.js} +4 -4
  121. package/dist/chunk-UL4O5M4S.js +45 -0
  122. package/dist/{chunk-AW77UWCZ.js → chunk-VBRTC2VU.js} +13 -4
  123. package/dist/{chunk-VDWGP2U6.js → chunk-VV6IKGCN.js} +1 -1
  124. package/dist/{chunk-JKXAL7WR.js → chunk-VXMOPVRH.js} +2 -2
  125. package/dist/{chunk-RIILGKYR.js → chunk-VXWN37PT.js} +1 -1
  126. package/dist/{chunk-CDIZEXFJ.js → chunk-WQX4ASK4.js} +6 -4
  127. package/dist/{chunk-SOZMJA7V.js → chunk-X22KTLZ7.js} +1 -1
  128. package/dist/{chunk-SDA5NDMT.js → chunk-XZG2HZYW.js} +2 -2
  129. package/dist/{chunk-SECZTXSU.js → chunk-YQYRAD5C.js} +1 -1
  130. package/dist/{chunk-WPFTRRWV.js → chunk-ZEVYT6IX.js} +202 -6
  131. package/dist/chunk-ZWTCVOHQ.js +14 -0
  132. package/dist/{chunk-NX26QE2O.js → chunk-ZYOXKUKZ.js} +1 -1
  133. package/dist/chunk-ZZO3INVE.js +9631 -0
  134. package/dist/collections-2M4RFH4P.js +66 -0
  135. package/dist/{configuration-RNWBTRAH.js → configuration-O5GDANA7.js} +5 -5
  136. package/dist/{configuration-KWAL2QZ5.js → configuration-RHPIO2QT.js} +3 -3
  137. package/dist/{create-BEVGWF6U.js → create-2TUWGQ2D.js} +33 -32
  138. package/dist/{create-YPCVTXAK.js → create-33TRLASX.js} +4 -4
  139. package/dist/{create-BBFTIFI2.js → create-3WUTLUJO.js} +36 -33
  140. package/dist/create-6IRE6AMF.js +78 -0
  141. package/dist/{create-F5K53QPH.js → create-D4F457BD.js} +38 -36
  142. package/dist/{create-7UEEO5TM.js → create-D6EW3EWC.js} +3 -3
  143. package/dist/{create-EJM5C2XP.js → create-FFKQAZ5D.js} +6 -6
  144. package/dist/{create-ZU362U3B.js → create-GHM7OTCR.js} +3 -3
  145. package/dist/{create-VUKGQU4L.js → create-IFMEEHN4.js} +34 -32
  146. package/dist/{create-IE6MYOIY.js → create-IOUKWPE4.js} +11 -10
  147. package/dist/{create-XGF6DB5F.js → create-KGOMJUXR.js} +5 -4
  148. package/dist/{create-TFDUNJSI.js → create-KGYL7FBM.js} +3 -3
  149. package/dist/{create-UCU73IXX.js → create-OF2OZ7EI.js} +25 -23
  150. package/dist/{create-MKBBF2V3.js → create-Q6ITSYJM.js} +3 -3
  151. package/dist/{create-VEWS4QDP.js → create-QK2SSLZK.js} +48 -45
  152. package/dist/{create-NPSYO6PE.js → create-YITFTHMA.js} +37 -35
  153. package/dist/{customers-4QWR5UOL.js → customers-OXAD52MC.js} +10 -9
  154. package/dist/{edit-J3LD76JS.js → edit-4HZHLYI3.js} +6 -6
  155. package/dist/{edit-47I7VVNB.js → edit-5CJZRHAA.js} +3 -3
  156. package/dist/{edit-BYXHU3IG.js → edit-7GVP6SRA.js} +3 -3
  157. package/dist/{edit-J6WCPHDS.js → edit-7HTH2UJF.js} +5 -5
  158. package/dist/{edit-XU33IVZH.js → edit-ATXE6CM5.js} +3 -3
  159. package/dist/{edit-ZMINDMGM.js → edit-B5B3XKDM.js} +3 -3
  160. package/dist/{edit-DG3MY3ZH.js → edit-FC64DWB2.js} +5 -5
  161. package/dist/{edit-LOKLQGM2.js → edit-FNDDSSMT.js} +3 -3
  162. package/dist/{edit-S7B7VPM4.js → edit-J5SC7GHQ.js} +29 -28
  163. package/dist/{edit-7LQATDUD.js → edit-LRRJTHV2.js} +4 -4
  164. package/dist/{edit-BQLSTFTQ.js → edit-MYSWY6W4.js} +5 -5
  165. package/dist/edit-ONSN756P.js +237 -0
  166. package/dist/{edit-JZVEAKJU.js → edit-PIE7Y73J.js} +49 -46
  167. package/dist/{edit-CZVL3IVY.js → edit-QRJIWTU2.js} +30 -29
  168. package/dist/{edit-JAKXFAVP.js → edit-SGEECDCR.js} +25 -24
  169. package/dist/{edit-5BUGSOTL.js → edit-UAXMJAEI.js} +5 -4
  170. package/dist/edit-UQAQVEUI.js +353 -0
  171. package/dist/edit-Z7EZRPUP.js +362 -0
  172. package/dist/{edit-NHU3LJIH.js → edit-ZEIL7EQW.js} +23 -22
  173. package/dist/{edit-budget-Z5USV462.js → edit-budget-J27CSEZH.js} +3 -3
  174. package/dist/{edit-inventory-item-YFW2AFRD.js → edit-inventory-item-US77M2FF.js} +3 -3
  175. package/dist/{edit-inventory-item-attributes-IYAMJDTB.js → edit-inventory-item-attributes-QYNDTUHT.js} +5 -4
  176. package/dist/edit-stocks-and-prices-543AYFDJ.js +409 -0
  177. package/dist/{fulfillment-V3D4XU3R.js → fulfillment-5LNFBSBS.js} +26 -25
  178. package/dist/{fulfillment-providers-YYN3GVV7.js → fulfillment-providers-U7Z7QMOQ.js} +33 -31
  179. package/dist/{home-PP7YYCSB.js → home-I3OILW5Z.js} +2 -2
  180. package/dist/index.css +5127 -3
  181. package/dist/index.js +453 -215
  182. package/dist/{inventory-AIRQ2KNS.js → inventory-W6S2NIBI.js} +8 -7
  183. package/dist/invite-P6HTOEIV.js +301 -0
  184. package/dist/invite-SI2KIPWI.js +370 -0
  185. package/dist/{locations-SQKM7JWN.js → locations-7SQJ3O2F.js} +4 -4
  186. package/dist/login-QDS5UXKV.js +36 -0
  187. package/dist/{manage-locations-4PQS4QY7.js → manage-locations-R4T72DTA.js} +4 -4
  188. package/dist/{media-UR73M6X2.js → media-RDXCLPKQ.js} +7 -6
  189. package/dist/{metadata-REBVXJJF.js → metadata-7JKDCVYY.js} +26 -25
  190. package/dist/{metadata-DIJTVDF7.js → metadata-AWUKZ25V.js} +6 -6
  191. package/dist/{metadata-ZKG2TRYU.js → metadata-UKBRUFH2.js} +23 -22
  192. package/dist/{metadata-UBZXDIFG.js → metadata-W5XIPFVU.js} +26 -25
  193. package/dist/{metadata-OOM44E2U.js → metadata-X4UIPNL6.js} +26 -25
  194. package/dist/{metadata-OGVHZEKS.js → metadata-ZV5RYLKR.js} +23 -22
  195. package/dist/{no-match-BO2NNLCM.js → no-match-JLVLPCRH.js} +1 -1
  196. package/dist/onboarding-DLIBZRKE.js +873 -0
  197. package/dist/orders-IAL3JNPU.js +61 -0
  198. package/dist/organization-QCSXE52A.js +303 -0
  199. package/dist/{organize-5AIJPYS2.js → organize-5W5KNBM2.js} +5 -5
  200. package/dist/{organize-YXJVI74L.js → organize-U2LVYSOD.js} +5 -5
  201. package/dist/pages/index.d.ts +222 -49
  202. package/dist/pages/index.js +96 -93
  203. package/dist/payment-details-ATUYMVJX.js +234 -0
  204. package/dist/{payouts-3BY73LZ3.js → payouts-ZLX3KFQT.js} +9 -8
  205. package/dist/{price-lists-G256JJN7.js → price-lists-JX22K5EO.js} +10 -9
  206. package/dist/{prices-EW7KBY6R.js → prices-6NY4DELP.js} +14 -13
  207. package/dist/{pricing-SQNF3KGG.js → pricing-RBESFX5P.js} +33 -31
  208. package/dist/{product-tags-FR32HXFW.js → product-tags-W4BL6RWV.js} +43 -40
  209. package/dist/{product-types-WJPLJI7H.js → product-types-MBLFYJOA.js} +10 -9
  210. package/dist/{product-variant-detail-G5MBDTFL.js → product-variant-detail-KU5OCL7E.js} +270 -56
  211. package/dist/{product-variant-edit-PW7W5J5E.js → product-variant-edit-5FMMMH2W.js} +8 -7
  212. package/dist/{products-C4BF2X7D.js → products-3VVYJUH7.js} +31 -29
  213. package/dist/products-YYLVCOOY.js +93 -0
  214. package/dist/professional-details-6Y5K6GBL.js +167 -0
  215. package/dist/profile-Y4AATQES.js +171 -0
  216. package/dist/{promotions-INYBMACT.js → promotions-NBJTFP6N.js} +10 -9
  217. package/dist/register-ZLE6MNPF.js +223 -0
  218. package/dist/{reset-password-CPTU3KHW.js → reset-password-PLCDLFL4.js} +4 -4
  219. package/dist/{chunk-5NF4OTVV.js → return-reasons-64WZ5Z3Z.js} +46 -5
  220. package/dist/{sales-channels-6I3U4W4Z.js → sales-channels-UIDLFCX6.js} +10 -9
  221. package/dist/{sales-channels-SOACADV2.js → sales-channels-UWPEFKAO.js} +12 -11
  222. package/dist/{settings-MAXHH7EC.js → settings-5MNWE5CR.js} +53 -56
  223. package/dist/{shipping-profile-7FTHSPY2.js → shipping-profile-JJBIVZPM.js} +4 -4
  224. package/dist/shipping-profiles-O7XB2DTE.js +45 -0
  225. package/dist/{stock-LOO5SU5Q.js → stock-2CGEFBXO.js} +30 -30
  226. package/dist/{stock-4G4PELBV.js → stock-VJAAYYW5.js} +30 -31
  227. package/dist/store-ZBSMNWFT.js +568 -0
  228. package/dist/store-closure-43FK32AQ.js +172 -0
  229. package/dist/store-select-Q2HE572R.js +166 -0
  230. package/dist/{tax-regions-45JVTUP3.js → tax-regions-FPMGLITT.js} +8 -8
  231. package/dist/team-ZLZJJWIY.js +269 -0
  232. package/package.json +9 -6
  233. package/dist/additional-attributes-XUFDADGP.js +0 -219
  234. package/dist/breadcrumb-3RAESPC7.js +0 -31
  235. package/dist/breadcrumb-54IEJEAX.js +0 -45
  236. package/dist/breadcrumb-CFDJOGTA.js +0 -44
  237. package/dist/chunk-6EYGH3TB.js +0 -26
  238. package/dist/chunk-FPJLYWOU.js +0 -190
  239. package/dist/chunk-GTUR4HSV.js +0 -53
  240. package/dist/chunk-LODQAVDC.js +0 -179
  241. package/dist/chunk-NYK5PQIF.js +0 -2078
  242. package/dist/chunk-PKBMQBKP.js +0 -7
  243. package/dist/chunk-RNC4NFVK.js +0 -170
  244. package/dist/collections-2222I5MO.js +0 -63
  245. package/dist/create-R3SFYWAH.js +0 -69
  246. package/dist/edit-HBNCGMQO.js +0 -413
  247. package/dist/login-RDIRFQ7U.js +0 -35
  248. package/dist/orders-Q347PBOH.js +0 -59
  249. package/dist/organization-TDDI3HOH.js +0 -233
  250. package/dist/products-4WTWZIVH.js +0 -85
  251. package/dist/register-6WOPLDJK.js +0 -366
  252. package/dist/return-reasons-4V2KVSRI.js +0 -52
  253. package/dist/seller-44DTDU26.js +0 -36
  254. package/dist/shipping-profiles-3PYQLYFE.js +0 -43
  255. /package/dist/{chunk-XG4PTPRM.js → chunk-NXDFDEKP.js} +0 -0
  256. /package/dist/{chunk-S3PQKKNV.js → chunk-V74Y5NIV.js} +0 -0
@@ -0,0 +1,3723 @@
1
+ import {
2
+ useSalesChannelTableColumns,
3
+ useSalesChannelTableEmptyState,
4
+ useSalesChannelTableFilters,
5
+ useSalesChannelTableQuery
6
+ } from "./chunk-XZG2HZYW.js";
7
+ import {
8
+ CategoryCombobox
9
+ } from "./chunk-TZTKHOEK.js";
10
+ import {
11
+ useComboboxData
12
+ } from "./chunk-OVPAOBZB.js";
13
+ import {
14
+ UploadMediaFormItem
15
+ } from "./chunk-3BZBEC3Y.js";
16
+ import {
17
+ CountrySelect
18
+ } from "./chunk-V74Y5NIV.js";
19
+ import {
20
+ UserCreatedOptionsList
21
+ } from "./chunk-I5K5USJM.js";
22
+ import {
23
+ PRODUCT_CREATE_FORM_DEFAULTS,
24
+ ProductCreateSchema,
25
+ decorateVariantsWithDefaultValues
26
+ } from "./chunk-7XC7ZRG7.js";
27
+ import {
28
+ NumericInput
29
+ } from "./chunk-DLNNTQRY.js";
30
+ import {
31
+ SwitchBox
32
+ } from "./chunk-YVCBMOJG.js";
33
+ import {
34
+ Combobox
35
+ } from "./chunk-VBRTC2VU.js";
36
+ import {
37
+ TabbedForm,
38
+ TabbedFormContext,
39
+ useTabbedForm
40
+ } from "./chunk-LPOAVK6Y.js";
41
+ import {
42
+ DataGrid,
43
+ DataGridMediaCell,
44
+ createDataGridHelper,
45
+ createDataGridPriceColumns
46
+ } from "./chunk-5IWBNPZX.js";
47
+ import {
48
+ KeyboundForm
49
+ } from "./chunk-U2ZFCAPX.js";
50
+ import {
51
+ RouteFocusModal,
52
+ StackedFocusModal,
53
+ useRouteModal,
54
+ useStackedModal
55
+ } from "./chunk-3CK6OINO.js";
56
+ import {
57
+ Form
58
+ } from "./chunk-3QSRE5LS.js";
59
+ import {
60
+ DataTable
61
+ } from "./chunk-CUMY2VZ5.js";
62
+ import {
63
+ useStockLocations
64
+ } from "./chunk-NBPMNUKZ.js";
65
+ import {
66
+ usePricePreferences,
67
+ useRegions
68
+ } from "./chunk-UL4O5M4S.js";
69
+ import {
70
+ useStore
71
+ } from "./chunk-FX4V5JCF.js";
72
+ import {
73
+ ActionMenu
74
+ } from "./chunk-BDGZ4EQO.js";
75
+ import {
76
+ useSalesChannels
77
+ } from "./chunk-3B34B2M2.js";
78
+ import {
79
+ useCreateProduct
80
+ } from "./chunk-ZEVYT6IX.js";
81
+ import {
82
+ queryKeysFactory
83
+ } from "./chunk-ZA2KFUFR.js";
84
+ import {
85
+ fetchQuery,
86
+ sdk,
87
+ uploadFilesQuery
88
+ } from "./chunk-RIN4CBRB.js";
89
+
90
+ // src/pages/products/create/product-create-page.tsx
91
+ import { Children as Children4, useCallback as useCallback5, useRef as useRef5, useState as useState10 } from "react";
92
+ import { useTranslation as useTranslation16 } from "react-i18next";
93
+
94
+ // src/pages/products/create/product-create-form/product-create-form.tsx
95
+ import { useCallback as useCallback2, useEffect as useEffect5, useMemo as useMemo4, useRef as useRef3, useState as useState6 } from "react";
96
+ import { Button as Button4, ProgressTabs, toast } from "@medusajs/ui";
97
+ import { useForm, useWatch as useWatch3 } from "react-hook-form";
98
+ import { useTranslation as useTranslation12 } from "react-i18next";
99
+ import { z as z2 } from "zod";
100
+ import { zodResolver } from "@hookform/resolvers/zod";
101
+
102
+ // src/hooks/api/attributes.tsx
103
+ import {
104
+ useQuery
105
+ } from "@tanstack/react-query";
106
+ var ATTRIBUTES_QUERY_KEY = "attributes";
107
+ var attributesQueryKeys = queryKeysFactory(ATTRIBUTES_QUERY_KEY);
108
+ var useAttributes = (query, options) => {
109
+ const { data, ...rest } = useQuery({
110
+ queryFn: () => fetchQuery("/vendor/attributes", {
111
+ method: "GET",
112
+ query
113
+ }),
114
+ queryKey: attributesQueryKeys.list(query),
115
+ ...options
116
+ });
117
+ return { ...data, ...rest };
118
+ };
119
+
120
+ // src/pages/products/create/product-create-attributes-form/product-create-attributes-form.tsx
121
+ import { forwardRef as forwardRef2, useEffect as useEffect2, useImperativeHandle } from "react";
122
+ import { CircleInfoSolid } from "@medusajs/icons";
123
+ import { Button, Divider, Heading, Text as Text2, Tooltip } from "@medusajs/ui";
124
+ import { useFieldArray } from "react-hook-form";
125
+ import { useTranslation as useTranslation3 } from "react-i18next";
126
+
127
+ // src/pages/products/create/utils/attribute-validation.ts
128
+ import { z } from "zod";
129
+ var createAttributeValidationRules = (attributes, t) => {
130
+ const rules = {};
131
+ attributes.forEach((attr) => {
132
+ const fieldName = attr.handle;
133
+ const isRequired = attr.is_required;
134
+ if (isRequired) {
135
+ switch (attr.ui_component) {
136
+ case "select":
137
+ case "toggle":
138
+ rules[fieldName] = {
139
+ required: t("products.fields.attributes.validation.requiredSelect"),
140
+ validate: (value) => {
141
+ if (typeof value !== "string" || !value || value === "") {
142
+ return t("products.fields.attributes.validation.requiredSelect");
143
+ }
144
+ return true;
145
+ }
146
+ };
147
+ break;
148
+ case "text":
149
+ case "text_area":
150
+ case "color_picker":
151
+ rules[fieldName] = {
152
+ required: t("products.fields.attributes.validation.requiredEnter"),
153
+ validate: (value) => {
154
+ if (typeof value !== "string" || !value || value === "") {
155
+ return t("products.fields.attributes.validation.requiredEnter");
156
+ }
157
+ return true;
158
+ }
159
+ };
160
+ break;
161
+ case "multivalue":
162
+ rules[fieldName] = {
163
+ required: t("products.fields.attributes.validation.requiredSelectMultiple"),
164
+ validate: (value) => {
165
+ if (!Array.isArray(value) || value.length === 0) {
166
+ return t("products.fields.attributes.validation.requiredSelectMultiple");
167
+ }
168
+ return true;
169
+ }
170
+ };
171
+ break;
172
+ case "unit":
173
+ rules[fieldName] = {
174
+ required: t("products.fields.attributes.validation.requiredEnter"),
175
+ validate: (value) => {
176
+ if (value === void 0 || value === null || value === "") {
177
+ return t("products.fields.attributes.validation.requiredEnter");
178
+ }
179
+ return true;
180
+ }
181
+ };
182
+ break;
183
+ default:
184
+ rules[fieldName] = {
185
+ required: t("products.fields.attributes.validation.requiredEnter"),
186
+ validate: (value) => {
187
+ if (typeof value !== "string" || !value || value === "") {
188
+ return t("products.fields.attributes.validation.requiredEnter");
189
+ }
190
+ return true;
191
+ }
192
+ };
193
+ break;
194
+ }
195
+ }
196
+ });
197
+ return rules;
198
+ };
199
+
200
+ // src/pages/products/create/utils/process-attributes.ts
201
+ var processAttributes = (allAttributes, primaryCategoryId) => {
202
+ if (!allAttributes || allAttributes.length === 0) {
203
+ return {
204
+ required: {
205
+ categorySpecific: [],
206
+ global: [],
207
+ all: []
208
+ }
209
+ };
210
+ }
211
+ const globalAttributes = allAttributes.filter(
212
+ (attr) => !attr.product_categories || attr.product_categories.length === 0
213
+ );
214
+ const categorySpecificAttributes = allAttributes.filter(
215
+ (attr) => attr.product_categories && attr.product_categories.length > 0
216
+ );
217
+ const applicableCategoryAttributes = categorySpecificAttributes.filter(
218
+ (attr) => attr.product_categories?.some(
219
+ (cat) => cat.id === primaryCategoryId
220
+ )
221
+ );
222
+ const mapToFormField = (attr) => ({
223
+ key: attr.id,
224
+ id: attr.id,
225
+ name: attr.name,
226
+ handle: attr.handle || attr.id,
227
+ ui_component: attr.ui_component,
228
+ is_required: attr.is_required,
229
+ description: attr.description,
230
+ possible_values: attr.possible_values?.map((value) => ({
231
+ value: value.id,
232
+ label: value.value
233
+ })) || []
234
+ });
235
+ const requiredCategorySpecificFormFields = applicableCategoryAttributes.filter((attr) => attr.is_required).map(mapToFormField);
236
+ const requiredGlobalFormFields = globalAttributes.filter((attr) => attr.is_required).map(mapToFormField);
237
+ return {
238
+ required: {
239
+ categorySpecific: requiredCategorySpecificFormFields,
240
+ global: requiredGlobalFormFields,
241
+ all: [
242
+ ...requiredCategorySpecificFormFields,
243
+ ...requiredGlobalFormFields
244
+ ]
245
+ }
246
+ };
247
+ };
248
+
249
+ // src/pages/products/create/product-create-attributes-form/required-attributes-list.tsx
250
+ import { Select, Textarea } from "@medusajs/ui";
251
+ import { useTranslation as useTranslation2 } from "react-i18next";
252
+
253
+ // src/components/inputs/multi-select/multi-select.tsx
254
+ import { forwardRef, useEffect, useMemo, useRef, useState } from "react";
255
+ import { CheckMini, TrianglesMini, XMarkMini } from "@medusajs/icons";
256
+ import { Badge, Input, Text } from "@medusajs/ui";
257
+ import { useTranslation } from "react-i18next";
258
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
259
+ var MultiSelect = forwardRef(
260
+ ({
261
+ options,
262
+ value,
263
+ onChange,
264
+ onBlur,
265
+ name,
266
+ placeholder,
267
+ "aria-invalid": ariaInvalid = false,
268
+ disabled = false,
269
+ className = "",
270
+ showSearch = true
271
+ }, ref) => {
272
+ const { t } = useTranslation();
273
+ const [isOpen, setIsOpen] = useState(false);
274
+ const [searchValue, setSearchValue] = useState("");
275
+ const dropdownRef = useRef(null);
276
+ const triggerRef = useRef(null);
277
+ const badgesContainerRef = useRef(null);
278
+ const [visibleBadgesCount, setVisibleBadgesCount] = useState(0);
279
+ useEffect(() => {
280
+ const handleClickOutside = (event) => {
281
+ if (dropdownRef.current && !dropdownRef.current.contains(event.target) && triggerRef.current && !triggerRef.current.contains(event.target)) {
282
+ setIsOpen(false);
283
+ }
284
+ };
285
+ document.addEventListener("mousedown", handleClickOutside);
286
+ return () => {
287
+ document.removeEventListener("mousedown", handleClickOutside);
288
+ };
289
+ }, []);
290
+ const calculateVisibleBadges = () => {
291
+ if (!value || value.length === 0 || !badgesContainerRef.current) {
292
+ setVisibleBadgesCount(0);
293
+ return;
294
+ }
295
+ const container = badgesContainerRef.current;
296
+ const containerWidth = container.offsetWidth;
297
+ const padding = 24;
298
+ const gap = 8;
299
+ const availableWidth = containerWidth - padding;
300
+ const estimateBadgeWidth = (label) => {
301
+ const baseWidth = 32;
302
+ const charWidth = 8;
303
+ return baseWidth + label.length * charWidth;
304
+ };
305
+ let totalWidth = 0;
306
+ let count = 0;
307
+ for (let i = 0; i < value.length; i++) {
308
+ const option = options.find((opt) => opt.value === value[i]);
309
+ const optionLabel = option?.label || "Unknown";
310
+ const badgeWidth = estimateBadgeWidth(optionLabel) > 200 ? 235 : estimateBadgeWidth(optionLabel);
311
+ if (totalWidth + badgeWidth + (count > 0 ? gap : 0) <= availableWidth) {
312
+ totalWidth += badgeWidth + (count > 0 ? gap : 0);
313
+ count++;
314
+ } else {
315
+ break;
316
+ }
317
+ }
318
+ setVisibleBadgesCount(count);
319
+ };
320
+ useEffect(() => {
321
+ calculateVisibleBadges();
322
+ }, [value, options]);
323
+ useEffect(() => {
324
+ const resizeObserver = new ResizeObserver(() => {
325
+ calculateVisibleBadges();
326
+ });
327
+ if (badgesContainerRef.current) {
328
+ resizeObserver.observe(badgesContainerRef.current);
329
+ }
330
+ return () => {
331
+ resizeObserver.disconnect();
332
+ };
333
+ }, [value, options]);
334
+ const handleToggle = () => {
335
+ if (disabled) return;
336
+ setIsOpen((prev) => !prev);
337
+ if (!isOpen && showSearch) {
338
+ setSearchValue("");
339
+ }
340
+ };
341
+ const handleItemClick = (optionValue) => {
342
+ const currentValue = value || [];
343
+ const isSelected = currentValue.includes(optionValue);
344
+ if (isSelected) {
345
+ onChange(currentValue.filter((val) => val !== optionValue));
346
+ } else {
347
+ onChange([...currentValue, optionValue]);
348
+ }
349
+ };
350
+ const handleRemoveBadge = (optionValue, e) => {
351
+ e.stopPropagation();
352
+ const currentValue = value || [];
353
+ onChange(currentValue.filter((val) => val !== optionValue));
354
+ };
355
+ const filteredOptions = useMemo(() => {
356
+ if (!showSearch || !searchValue.trim()) {
357
+ return options;
358
+ }
359
+ return options.filter(
360
+ (option) => option.label.toLowerCase().includes(searchValue.toLowerCase())
361
+ );
362
+ }, [options, searchValue, showSearch]);
363
+ const handleSearchChange = (e) => {
364
+ setSearchValue(e.target.value);
365
+ };
366
+ const handleClearSearch = () => {
367
+ setSearchValue("");
368
+ };
369
+ return /* @__PURE__ */ jsxs("div", { ref, className: `relative ${className}`, children: [
370
+ /* @__PURE__ */ jsxs(
371
+ "div",
372
+ {
373
+ ref: triggerRef,
374
+ className: `relative flex h-8 w-full cursor-pointer items-center justify-between overflow-hidden rounded-md border bg-ui-bg-field text-ui-fg-base shadow-sm transition-colors duration-150 ease-in-out focus-within:ring-1 hover:bg-ui-bg-field-hover ${disabled ? "cursor-not-allowed bg-ui-bg-disabled opacity-50" : ariaInvalid ? "!shadow-borders-error" : "focus-within:ring-ui-ring-interactive border-ui-border-base focus-within:border-ui-border-interactive"}`,
375
+ onClick: handleToggle,
376
+ onBlur,
377
+ tabIndex: 0,
378
+ role: "combobox",
379
+ "aria-expanded": isOpen,
380
+ "aria-haspopup": "listbox",
381
+ "aria-invalid": ariaInvalid,
382
+ "aria-label": name,
383
+ children: [
384
+ /* @__PURE__ */ jsx(
385
+ "div",
386
+ {
387
+ ref: badgesContainerRef,
388
+ className: "flex min-w-0 flex-1 items-center gap-2 px-3 py-2",
389
+ children: value && value.length > 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
390
+ value.slice(0, visibleBadgesCount).map((optionValue) => {
391
+ const option = options.find(
392
+ (opt) => opt.value === optionValue
393
+ );
394
+ return /* @__PURE__ */ jsx(
395
+ "button",
396
+ {
397
+ type: "button",
398
+ onClick: (e) => handleRemoveBadge(optionValue, e),
399
+ className: "flex flex-shrink-0 items-center self-center",
400
+ disabled,
401
+ children: /* @__PURE__ */ jsxs(
402
+ Badge,
403
+ {
404
+ size: "2xsmall",
405
+ className: "w-fit bg-ui-bg-base p-0",
406
+ children: [
407
+ /* @__PURE__ */ jsx("span", { className: "max-w-[200px] truncate text-ellipsis border-r border-ui-border-base px-1.5", children: option?.label || "Unknown" }),
408
+ /* @__PURE__ */ jsx(XMarkMini, { className: "mr-0.5 !text-ui-fg-base" })
409
+ ]
410
+ }
411
+ )
412
+ },
413
+ optionValue
414
+ );
415
+ }),
416
+ value && value.length > visibleBadgesCount && /* @__PURE__ */ jsxs(
417
+ Badge,
418
+ {
419
+ size: "small",
420
+ className: "txt-compact-small-plus w-fit flex-shrink-0 border-none bg-transparent px-0 text-ui-fg-subtle",
421
+ children: [
422
+ "+",
423
+ value.length - visibleBadgesCount
424
+ ]
425
+ }
426
+ )
427
+ ] }) : /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-subtle", children: placeholder || t("general.selectValues") })
428
+ }
429
+ ),
430
+ /* @__PURE__ */ jsx("div", { className: "flex h-full items-center justify-center", children: /* @__PURE__ */ jsx("span", { className: "flex h-full w-8 items-center justify-center", children: /* @__PURE__ */ jsx(TrianglesMini, { className: "text-ui-fg-muted" }) }) })
431
+ ]
432
+ }
433
+ ),
434
+ isOpen && !disabled && /* @__PURE__ */ jsxs(
435
+ "div",
436
+ {
437
+ ref: dropdownRef,
438
+ className: "absolute z-10 mt-1 max-h-60 w-full overflow-hidden rounded-md border border-ui-border-base bg-ui-bg-base shadow-lg",
439
+ children: [
440
+ showSearch && /* @__PURE__ */ jsx("div", { className: "sticky top-0 z-10 border-b border-ui-border-base bg-ui-bg-base p-2", children: /* @__PURE__ */ jsxs("div", { className: "relative", children: [
441
+ /* @__PURE__ */ jsx(
442
+ Input,
443
+ {
444
+ value: searchValue,
445
+ onChange: handleSearchChange,
446
+ placeholder: t("general.searchOptions"),
447
+ className: "w-full bg-transparent pr-8 shadow-none focus:!shadow-none",
448
+ autoFocus: true
449
+ }
450
+ ),
451
+ searchValue && /* @__PURE__ */ jsx(
452
+ "button",
453
+ {
454
+ type: "button",
455
+ onClick: handleClearSearch,
456
+ className: "absolute right-2 top-1/2 -translate-y-1/2 rounded-md p-1 transition-colors hover:bg-ui-bg-base-hover",
457
+ "aria-label": "Clear search",
458
+ children: /* @__PURE__ */ jsx(XMarkMini, { className: "h-4 w-4 text-ui-fg-muted" })
459
+ }
460
+ )
461
+ ] }) }),
462
+ /* @__PURE__ */ jsx(
463
+ "div",
464
+ {
465
+ className: `${showSearch ? "max-h-48" : "max-h-60"} overflow-y-auto py-1`,
466
+ children: filteredOptions.length === 0 ? /* @__PURE__ */ jsx("div", { className: "txt-compact-small-plus p-3 text-ui-fg-subtle", children: showSearch && searchValue.trim() ? t("general.noOptionsFound") : t("general.noOptionsAvailable") }) : filteredOptions.map((option) => {
467
+ const currentValue = value || [];
468
+ const isSelected = currentValue.includes(option.value);
469
+ return /* @__PURE__ */ jsx(
470
+ "div",
471
+ {
472
+ className: "flex cursor-pointer items-center px-1 py-1 hover:bg-ui-bg-base-hover",
473
+ onClick: () => handleItemClick(option.value),
474
+ children: /* @__PURE__ */ jsxs("div", { className: "flex flex-1 items-center gap-x-2 rounded-md px-2", children: [
475
+ /* @__PURE__ */ jsx("div", { className: "flex size-5 shrink-0 items-center justify-center", children: isSelected && /* @__PURE__ */ jsx(CheckMini, {}) }),
476
+ /* @__PURE__ */ jsx(Text, { className: "truncate", children: option.label })
477
+ ] })
478
+ },
479
+ option.value
480
+ );
481
+ })
482
+ }
483
+ )
484
+ ]
485
+ }
486
+ )
487
+ ] });
488
+ }
489
+ );
490
+ MultiSelect.displayName = "MultiSelect";
491
+ var multi_select_default = MultiSelect;
492
+
493
+ // src/pages/products/create/product-create-attributes-form/required-attributes-list.tsx
494
+ import { Fragment as Fragment2, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
495
+ var RequiredAttributesList = ({
496
+ form,
497
+ fields,
498
+ validationRules
499
+ }) => {
500
+ const { t } = useTranslation2();
501
+ return /* @__PURE__ */ jsx2(Fragment2, { children: fields.map((field) => /* @__PURE__ */ jsxs2("div", { className: "flex flex-col gap-y-4", children: [
502
+ field.ui_component === "select" && /* @__PURE__ */ jsx2(
503
+ Form.Field,
504
+ {
505
+ control: form.control,
506
+ name: field.handle,
507
+ rules: validationRules[field.handle] || {},
508
+ render: ({ field: formField, fieldState }) => /* @__PURE__ */ jsxs2(Form.Item, { children: [
509
+ /* @__PURE__ */ jsx2(Form.Label, { optional: !field.is_required, children: field.name }),
510
+ field.description && /* @__PURE__ */ jsx2("p", { className: "txt-compact-small !my-1 text-ui-fg-subtle", children: field.description }),
511
+ /* @__PURE__ */ jsx2(Form.Control, { children: /* @__PURE__ */ jsx2(
512
+ Combobox,
513
+ {
514
+ ...formField,
515
+ options: field.possible_values,
516
+ "aria-invalid": !!fieldState.error
517
+ }
518
+ ) }),
519
+ /* @__PURE__ */ jsx2(Form.ErrorMessage, {})
520
+ ] })
521
+ }
522
+ ),
523
+ field.ui_component === "multivalue" && /* @__PURE__ */ jsxs2("div", { className: "flex flex-col gap-y-2", children: [
524
+ /* @__PURE__ */ jsx2(
525
+ Form.Field,
526
+ {
527
+ control: form.control,
528
+ name: field.handle,
529
+ rules: validationRules[field.handle] || {},
530
+ render: ({ field: formField, fieldState }) => /* @__PURE__ */ jsxs2(Form.Item, { children: [
531
+ /* @__PURE__ */ jsx2(Form.Label, { optional: !field.is_required, children: field.name }),
532
+ field.description && /* @__PURE__ */ jsx2("p", { className: "txt-compact-small mb-1 text-ui-fg-subtle", children: field.description }),
533
+ /* @__PURE__ */ jsx2(Form.Control, { children: /* @__PURE__ */ jsx2(
534
+ multi_select_default,
535
+ {
536
+ value: formField.value,
537
+ onChange: formField.onChange,
538
+ name: formField.name,
539
+ options: field.possible_values,
540
+ showSearch: true,
541
+ "aria-invalid": !!fieldState.error
542
+ }
543
+ ) }),
544
+ /* @__PURE__ */ jsx2(Form.ErrorMessage, {})
545
+ ] })
546
+ }
547
+ ),
548
+ /* @__PURE__ */ jsx2(
549
+ SwitchBox,
550
+ {
551
+ control: form.control,
552
+ name: `${field.handle}UseForVariants`,
553
+ label: t(
554
+ "products.fields.attributes.useForVariants.label"
555
+ ),
556
+ description: t(
557
+ "products.fields.attributes.useForVariants.description"
558
+ )
559
+ }
560
+ )
561
+ ] }),
562
+ field.ui_component === "text_area" && /* @__PURE__ */ jsx2(
563
+ Form.Field,
564
+ {
565
+ control: form.control,
566
+ name: field.handle,
567
+ rules: validationRules[field.handle] || {},
568
+ render: ({ field: formField, fieldState }) => /* @__PURE__ */ jsxs2(Form.Item, { children: [
569
+ /* @__PURE__ */ jsx2(Form.Label, { optional: !field.is_required, children: field.name }),
570
+ field.description && /* @__PURE__ */ jsx2("p", { className: "txt-compact-small !my-1 text-ui-fg-subtle", children: field.description }),
571
+ /* @__PURE__ */ jsx2(Form.Control, { children: /* @__PURE__ */ jsx2(
572
+ Textarea,
573
+ {
574
+ ...formField,
575
+ placeholder: t(
576
+ "products.fields.attributes.enterValuePlaceholder"
577
+ ),
578
+ "aria-invalid": !!fieldState.error
579
+ }
580
+ ) }),
581
+ /* @__PURE__ */ jsx2(Form.ErrorMessage, {})
582
+ ] })
583
+ }
584
+ ),
585
+ field.ui_component === "toggle" && /* @__PURE__ */ jsx2(
586
+ Form.Field,
587
+ {
588
+ control: form.control,
589
+ name: field.handle,
590
+ rules: validationRules[field.handle] || {},
591
+ render: ({ field: formField, fieldState }) => /* @__PURE__ */ jsxs2(Form.Item, { children: [
592
+ /* @__PURE__ */ jsx2(Form.Label, { optional: !field.is_required, children: field.name }),
593
+ field.description && /* @__PURE__ */ jsx2("p", { className: "txt-compact-small !my-1 text-ui-fg-subtle", children: field.description }),
594
+ /* @__PURE__ */ jsx2(Form.Control, { children: /* @__PURE__ */ jsxs2(
595
+ Select,
596
+ {
597
+ ...formField,
598
+ onValueChange: formField.onChange,
599
+ value: formField.value,
600
+ children: [
601
+ /* @__PURE__ */ jsx2(
602
+ Select.Trigger,
603
+ {
604
+ "aria-invalid": !!fieldState.error,
605
+ children: /* @__PURE__ */ jsx2(
606
+ Select.Value,
607
+ {
608
+ placeholder: t(
609
+ "products.fields.attributes.selectValuePlaceholder"
610
+ )
611
+ }
612
+ )
613
+ }
614
+ ),
615
+ /* @__PURE__ */ jsxs2(Select.Content, { children: [
616
+ /* @__PURE__ */ jsx2(Select.Item, { value: "true", children: t("general.true") }),
617
+ /* @__PURE__ */ jsx2(Select.Item, { value: "false", children: t("general.false") })
618
+ ] })
619
+ ]
620
+ }
621
+ ) }),
622
+ /* @__PURE__ */ jsx2(Form.ErrorMessage, {})
623
+ ] })
624
+ }
625
+ ),
626
+ field.ui_component === "unit" && /* @__PURE__ */ jsx2(
627
+ Form.Field,
628
+ {
629
+ control: form.control,
630
+ name: field.handle,
631
+ rules: validationRules[field.handle] || {},
632
+ render: ({ field: formField, fieldState }) => /* @__PURE__ */ jsxs2(Form.Item, { children: [
633
+ /* @__PURE__ */ jsx2(Form.Label, { optional: !field.is_required, children: field.name }),
634
+ field.description && /* @__PURE__ */ jsx2("p", { className: "txt-compact-small !my-1 text-ui-fg-subtle", children: field.description }),
635
+ /* @__PURE__ */ jsx2(Form.Control, { children: /* @__PURE__ */ jsx2(
636
+ NumericInput,
637
+ {
638
+ value: formField.value,
639
+ onChange: formField.onChange,
640
+ onBlur: formField.onBlur,
641
+ name: formField.name,
642
+ placeholder: t(
643
+ "products.fields.attributes.enterValuePlaceholder"
644
+ ),
645
+ "aria-invalid": !!fieldState.error,
646
+ hideControls: true
647
+ }
648
+ ) }),
649
+ /* @__PURE__ */ jsx2(Form.ErrorMessage, {})
650
+ ] })
651
+ }
652
+ )
653
+ ] }, field.id)) });
654
+ };
655
+
656
+ // src/pages/products/create/product-create-attributes-form/product-create-attributes-form.tsx
657
+ import { Fragment as Fragment3, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
658
+ var ProductCreateAttributesForm = forwardRef2(({ form }, ref) => {
659
+ const { t } = useTranslation3();
660
+ const primaryCategoryId = form.watch("categories")?.[0];
661
+ const options = useFieldArray({
662
+ control: form.control,
663
+ name: "options"
664
+ });
665
+ const { attributes: allAttributes, isLoading: allAttributesLoading } = useAttributes({
666
+ fields: "id,name,handle,description,ui_component,is_required,product_categories.*,possible_values.*"
667
+ });
668
+ const processedAttributes = processAttributes(
669
+ allAttributes,
670
+ primaryCategoryId
671
+ );
672
+ const requiredFormFields = processedAttributes.required.all;
673
+ const validationRules = createAttributeValidationRules(
674
+ requiredFormFields,
675
+ t
676
+ );
677
+ const validateAttributes = async () => {
678
+ const errors = {};
679
+ requiredFormFields.forEach((field) => {
680
+ if (field.is_required) {
681
+ const value = form.getValues(
682
+ field.handle
683
+ );
684
+ switch (field.ui_component) {
685
+ case "select":
686
+ case "toggle":
687
+ if (!value || value === "") {
688
+ errors[field.handle] = t(
689
+ "products.fields.attributes.validation.requiredSelect"
690
+ );
691
+ }
692
+ break;
693
+ case "text":
694
+ case "text_area":
695
+ if (!value || value === "") {
696
+ errors[field.handle] = t(
697
+ "products.fields.attributes.validation.requiredEnter"
698
+ );
699
+ }
700
+ break;
701
+ case "multivalue":
702
+ if (!value || !Array.isArray(value) || value.length === 0) {
703
+ errors[field.handle] = t(
704
+ "products.fields.attributes.validation.requiredSelectMultiple"
705
+ );
706
+ }
707
+ break;
708
+ case "unit":
709
+ if (value === void 0 || value === null || value === "") {
710
+ errors[field.handle] = t(
711
+ "products.fields.attributes.validation.requiredEnter"
712
+ );
713
+ }
714
+ break;
715
+ }
716
+ }
717
+ });
718
+ requiredFormFields.forEach((field) => {
719
+ if (field.is_required) {
720
+ form.clearErrors(
721
+ field.handle
722
+ );
723
+ }
724
+ });
725
+ Object.keys(errors).forEach((fieldName) => {
726
+ form.setError(fieldName, {
727
+ type: "required",
728
+ message: errors[fieldName]
729
+ });
730
+ });
731
+ const currentOptions = form.getValues("options") || [];
732
+ const optionsValid = currentOptions.length > 0 ? await form.trigger("options") : true;
733
+ return Object.keys(errors).length === 0 && optionsValid;
734
+ };
735
+ useImperativeHandle(
736
+ ref,
737
+ () => ({
738
+ validateAttributes,
739
+ requiredFormFields
740
+ }),
741
+ [validateAttributes, requiredFormFields, form, t]
742
+ );
743
+ useEffect2(() => {
744
+ const subscription = form.watch((values, { name }) => {
745
+ if (name && requiredFormFields.some((field) => field.handle === name)) {
746
+ const field = requiredFormFields.find(
747
+ (f) => f.handle === name
748
+ );
749
+ if (field && field.is_required) {
750
+ const value = values[name];
751
+ let isValid = false;
752
+ switch (field.ui_component) {
753
+ case "select":
754
+ case "toggle":
755
+ isValid = typeof value === "string" && value !== "";
756
+ break;
757
+ case "text":
758
+ case "text_area":
759
+ isValid = typeof value === "string" && value !== "";
760
+ break;
761
+ case "multivalue":
762
+ isValid = Array.isArray(value) && value.length > 0;
763
+ break;
764
+ case "unit":
765
+ isValid = value !== void 0 && value !== null && value !== "";
766
+ break;
767
+ default:
768
+ isValid = false;
769
+ break;
770
+ }
771
+ if (isValid) {
772
+ form.clearErrors(
773
+ name
774
+ );
775
+ }
776
+ }
777
+ }
778
+ });
779
+ return () => subscription.unsubscribe();
780
+ }, [form, requiredFormFields]);
781
+ const nonRequiredAttributes = allAttributes?.filter(
782
+ (attribute) => !attribute.is_required
783
+ );
784
+ const availableAttributes = nonRequiredAttributes?.filter(
785
+ (attribute) => !options.fields?.some(
786
+ (option) => option.attributeId === attribute.id
787
+ )
788
+ );
789
+ return /* @__PURE__ */ jsx3("div", { className: "flex flex-col items-center p-16", children: /* @__PURE__ */ jsxs3("div", { className: "flex w-full max-w-[720px] flex-col gap-y-8", children: [
790
+ /* @__PURE__ */ jsx3(Header, { options }),
791
+ /* @__PURE__ */ jsxs3("div", { className: "flex flex-col gap-y-8", children: [
792
+ /* @__PURE__ */ jsx3(
793
+ UserCreatedOptionsList,
794
+ {
795
+ form,
796
+ options,
797
+ availableAttributes,
798
+ allNonRequiredAttributes: nonRequiredAttributes,
799
+ allowCreate: true
800
+ }
801
+ ),
802
+ requiredFormFields.length === 0 ? /* @__PURE__ */ jsx3("div", { className: "py-8 text-center text-gray-500", children: allAttributesLoading ? "Loading attributes..." : null }) : /* @__PURE__ */ jsxs3(Fragment3, { children: [
803
+ /* @__PURE__ */ jsx3(Divider, { variant: "dashed" }),
804
+ /* @__PURE__ */ jsxs3("div", { className: "flex flex-col gap-y-2", children: [
805
+ /* @__PURE__ */ jsx3(Heading, { level: "h3", className: "text-ui-fg-base", children: t(
806
+ "products.create.attributes.requiredHeading"
807
+ ) }),
808
+ /* @__PURE__ */ jsx3(
809
+ Text2,
810
+ {
811
+ size: "small",
812
+ className: "text-ui-fg-subtle",
813
+ children: t(
814
+ "products.create.attributes.requiredDescription"
815
+ )
816
+ }
817
+ )
818
+ ] }),
819
+ /* @__PURE__ */ jsx3(
820
+ RequiredAttributesList,
821
+ {
822
+ form,
823
+ fields: requiredFormFields,
824
+ validationRules
825
+ }
826
+ )
827
+ ] })
828
+ ] })
829
+ ] }) });
830
+ });
831
+ ProductCreateAttributesForm.displayName = "ProductCreateAttributesForm";
832
+ var Header = ({ options }) => {
833
+ const { t } = useTranslation3();
834
+ return /* @__PURE__ */ jsx3("div", { className: "flex flex-col gap-y-2", children: /* @__PURE__ */ jsxs3("div", { className: "flex items-start justify-between", children: [
835
+ /* @__PURE__ */ jsxs3("div", { className: "flex flex-col gap-y-2", children: [
836
+ /* @__PURE__ */ jsx3(Heading, { level: "h1", className: "text-ui-fg-base", children: t("products.create.tabs.attributes") }),
837
+ /* @__PURE__ */ jsxs3("div", { className: "space-y-0.5", children: [
838
+ /* @__PURE__ */ jsx3(
839
+ Text2,
840
+ {
841
+ size: "small",
842
+ className: "max-w-[440px] text-ui-fg-subtle",
843
+ children: t("products.create.attributes.description")
844
+ }
845
+ ),
846
+ /* @__PURE__ */ jsxs3(
847
+ Text2,
848
+ {
849
+ size: "small",
850
+ className: "flex items-center gap-1 text-ui-fg-subtle",
851
+ children: [
852
+ t(
853
+ "products.create.attributes.learnMore.label"
854
+ ),
855
+ /* @__PURE__ */ jsx3(
856
+ Tooltip,
857
+ {
858
+ content: t(
859
+ "products.create.attributes.learnMore.content"
860
+ ),
861
+ children: /* @__PURE__ */ jsx3(CircleInfoSolid, {})
862
+ }
863
+ )
864
+ ]
865
+ }
866
+ )
867
+ ] })
868
+ ] }),
869
+ /* @__PURE__ */ jsxs3(
870
+ Button,
871
+ {
872
+ size: "small",
873
+ variant: "secondary",
874
+ type: "button",
875
+ className: "min-w-[100px]",
876
+ onClick: () => {
877
+ options.append(
878
+ {
879
+ title: "",
880
+ values: [],
881
+ metadata: { author: "vendor" },
882
+ useForVariants: true
883
+ },
884
+ {
885
+ shouldFocus: false
886
+ }
887
+ );
888
+ },
889
+ children: [
890
+ t("actions.add"),
891
+ " ",
892
+ t("products.create.attributes.buttonLabel")
893
+ ]
894
+ }
895
+ )
896
+ ] }) });
897
+ };
898
+
899
+ // src/pages/products/create/product-create-details-form/product-create-details-form.tsx
900
+ import { Heading as Heading2 } from "@medusajs/ui";
901
+ import { Children } from "react";
902
+ import { useTranslation as useTranslation6 } from "react-i18next";
903
+
904
+ // src/pages/products/create/product-create-details-form/components/product-create-details-general-section/product-create-general-section.tsx
905
+ import { Input as Input3, Textarea as Textarea2 } from "@medusajs/ui";
906
+ import { useTranslation as useTranslation4 } from "react-i18next";
907
+
908
+ // src/components/inputs/handle-input/handle-input.tsx
909
+ import { Input as Input2, Text as Text3 } from "@medusajs/ui";
910
+ import { forwardRef as forwardRef3 } from "react";
911
+ import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
912
+ var HandleInput = forwardRef3(
913
+ (props, ref) => {
914
+ return /* @__PURE__ */ jsxs4("div", { className: "relative", children: [
915
+ /* @__PURE__ */ jsx4("div", { className: "absolute inset-y-0 left-0 z-10 flex w-8 items-center justify-center border-r", children: /* @__PURE__ */ jsx4(
916
+ Text3,
917
+ {
918
+ className: "text-ui-fg-muted",
919
+ size: "small",
920
+ leading: "compact",
921
+ weight: "plus",
922
+ children: "/"
923
+ }
924
+ ) }),
925
+ /* @__PURE__ */ jsx4(Input2, { ref, ...props, className: "pl-10" })
926
+ ] });
927
+ }
928
+ );
929
+ HandleInput.displayName = "HandleInput";
930
+
931
+ // src/pages/products/create/product-create-details-form/components/product-create-details-general-section/product-create-general-section.tsx
932
+ import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
933
+ var ProductCreateGeneralSection = () => {
934
+ const { t } = useTranslation4();
935
+ const form = useTabbedForm();
936
+ return /* @__PURE__ */ jsxs5("div", { id: "general", className: "flex flex-col gap-y-6", children: [
937
+ /* @__PURE__ */ jsx5("div", { className: "flex flex-col gap-y-2", children: /* @__PURE__ */ jsxs5("div", { className: "grid grid-cols-1 gap-4 md:grid-cols-3", children: [
938
+ /* @__PURE__ */ jsx5(
939
+ Form.Field,
940
+ {
941
+ control: form.control,
942
+ name: "title",
943
+ render: ({ field }) => {
944
+ return /* @__PURE__ */ jsxs5(Form.Item, { children: [
945
+ /* @__PURE__ */ jsx5(Form.Label, { children: t("products.fields.title.label") }),
946
+ /* @__PURE__ */ jsx5(Form.Control, { children: /* @__PURE__ */ jsx5(Input3, { ...field, placeholder: "Winter jacket" }) }),
947
+ /* @__PURE__ */ jsx5(Form.ErrorMessage, { children: form.formState.errors.title?.message })
948
+ ] });
949
+ }
950
+ }
951
+ ),
952
+ /* @__PURE__ */ jsx5(
953
+ Form.Field,
954
+ {
955
+ control: form.control,
956
+ name: "subtitle",
957
+ render: ({ field }) => {
958
+ return /* @__PURE__ */ jsxs5(Form.Item, { children: [
959
+ /* @__PURE__ */ jsx5(Form.Label, { optional: true, children: t("products.fields.subtitle.label") }),
960
+ /* @__PURE__ */ jsx5(Form.Control, { children: /* @__PURE__ */ jsx5(Input3, { ...field, placeholder: "Warm and cosy" }) })
961
+ ] });
962
+ }
963
+ }
964
+ ),
965
+ /* @__PURE__ */ jsx5(
966
+ Form.Field,
967
+ {
968
+ control: form.control,
969
+ name: "handle",
970
+ render: ({ field }) => {
971
+ return /* @__PURE__ */ jsxs5(Form.Item, { children: [
972
+ /* @__PURE__ */ jsx5(
973
+ Form.Label,
974
+ {
975
+ tooltip: t("products.fields.handle.tooltip"),
976
+ optional: true,
977
+ children: t("fields.handle")
978
+ }
979
+ ),
980
+ /* @__PURE__ */ jsx5(Form.Control, { children: /* @__PURE__ */ jsx5(HandleInput, { ...field, placeholder: "winter-jacket" }) }),
981
+ /* @__PURE__ */ jsx5(Form.ErrorMessage, { children: form.formState.errors.handle?.message })
982
+ ] });
983
+ }
984
+ }
985
+ )
986
+ ] }) }),
987
+ /* @__PURE__ */ jsx5(
988
+ Form.Field,
989
+ {
990
+ control: form.control,
991
+ name: "description",
992
+ render: ({ field }) => {
993
+ return /* @__PURE__ */ jsxs5(Form.Item, { children: [
994
+ /* @__PURE__ */ jsx5(Form.Label, { optional: true, children: t("products.fields.description.label") }),
995
+ /* @__PURE__ */ jsx5(Form.Control, { children: /* @__PURE__ */ jsx5(Textarea2, { ...field, placeholder: "A warm and cozy jacket" }) })
996
+ ] });
997
+ }
998
+ }
999
+ )
1000
+ ] });
1001
+ };
1002
+
1003
+ // src/pages/products/create/product-create-details-form/components/product-create-details-media-section/product-create-details-media-section.tsx
1004
+ import {
1005
+ defaultDropAnimationSideEffects,
1006
+ DndContext,
1007
+ DragOverlay,
1008
+ KeyboardSensor,
1009
+ PointerSensor,
1010
+ useSensor,
1011
+ useSensors
1012
+ } from "@dnd-kit/core";
1013
+ import {
1014
+ arrayMove,
1015
+ SortableContext,
1016
+ sortableKeyboardCoordinates,
1017
+ useSortable
1018
+ } from "@dnd-kit/sortable";
1019
+ import { CSS } from "@dnd-kit/utilities";
1020
+ import {
1021
+ DotsSix,
1022
+ StackPerspective,
1023
+ ThumbnailBadge,
1024
+ Trash,
1025
+ XMark
1026
+ } from "@medusajs/icons";
1027
+ import { IconButton, Text as Text4 } from "@medusajs/ui";
1028
+ import { useState as useState2 } from "react";
1029
+ import { useFieldArray as useFieldArray2 } from "react-hook-form";
1030
+ import { useTranslation as useTranslation5 } from "react-i18next";
1031
+ import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
1032
+ var dropAnimationConfig = {
1033
+ sideEffects: defaultDropAnimationSideEffects({
1034
+ styles: {
1035
+ active: {
1036
+ opacity: "0.4"
1037
+ }
1038
+ }
1039
+ })
1040
+ };
1041
+ var ProductCreateMediaSection = () => {
1042
+ const form = useTabbedForm();
1043
+ const { fields, append, remove } = useFieldArray2({
1044
+ name: "media",
1045
+ control: form.control,
1046
+ keyName: "field_id"
1047
+ });
1048
+ const [activeId, setActiveId] = useState2(null);
1049
+ const sensors = useSensors(
1050
+ useSensor(PointerSensor),
1051
+ useSensor(KeyboardSensor, {
1052
+ coordinateGetter: sortableKeyboardCoordinates
1053
+ })
1054
+ );
1055
+ const handleDragStart = (event) => {
1056
+ setActiveId(event.active.id);
1057
+ };
1058
+ const handleDragEnd = (event) => {
1059
+ setActiveId(null);
1060
+ const { active, over } = event;
1061
+ if (active.id !== over?.id) {
1062
+ const oldIndex = fields.findIndex((item) => item.field_id === active.id);
1063
+ const newIndex = fields.findIndex((item) => item.field_id === over?.id);
1064
+ form.setValue("media", arrayMove(fields, oldIndex, newIndex), {
1065
+ shouldDirty: true,
1066
+ shouldTouch: true
1067
+ });
1068
+ }
1069
+ };
1070
+ const handleDragCancel = () => {
1071
+ setActiveId(null);
1072
+ };
1073
+ const getOnDelete = (index) => {
1074
+ return () => {
1075
+ remove(index);
1076
+ };
1077
+ };
1078
+ const getMakeThumbnail = (index) => {
1079
+ return () => {
1080
+ const newFields = fields.map((field, i) => {
1081
+ return {
1082
+ ...field,
1083
+ isThumbnail: i === index
1084
+ };
1085
+ });
1086
+ form.setValue("media", newFields, {
1087
+ shouldDirty: true,
1088
+ shouldTouch: true
1089
+ });
1090
+ };
1091
+ };
1092
+ const getItemHandlers = (index) => {
1093
+ return {
1094
+ onDelete: getOnDelete(index),
1095
+ onMakeThumbnail: getMakeThumbnail(index)
1096
+ };
1097
+ };
1098
+ return /* @__PURE__ */ jsxs6("div", { id: "media", className: "flex flex-col gap-y-2", children: [
1099
+ /* @__PURE__ */ jsx6(UploadMediaFormItem, { form, append, showHint: false }),
1100
+ /* @__PURE__ */ jsxs6(
1101
+ DndContext,
1102
+ {
1103
+ sensors,
1104
+ onDragEnd: handleDragEnd,
1105
+ onDragStart: handleDragStart,
1106
+ onDragCancel: handleDragCancel,
1107
+ children: [
1108
+ /* @__PURE__ */ jsx6(DragOverlay, { dropAnimation: dropAnimationConfig, children: activeId ? /* @__PURE__ */ jsx6(
1109
+ MediaGridItemOverlay,
1110
+ {
1111
+ field: fields.find((m) => m.field_id === activeId)
1112
+ }
1113
+ ) : null }),
1114
+ /* @__PURE__ */ jsx6("ul", { className: "flex flex-col gap-y-2", children: /* @__PURE__ */ jsx6(SortableContext, { items: fields.map((field) => field.field_id), children: fields.map((field, index) => {
1115
+ const { onDelete, onMakeThumbnail } = getItemHandlers(index);
1116
+ return /* @__PURE__ */ jsx6(
1117
+ MediaItem,
1118
+ {
1119
+ field,
1120
+ onDelete,
1121
+ onMakeThumbnail
1122
+ },
1123
+ field.field_id
1124
+ );
1125
+ }) }) })
1126
+ ]
1127
+ }
1128
+ )
1129
+ ] });
1130
+ };
1131
+ var MediaItem = ({ field, onDelete, onMakeThumbnail }) => {
1132
+ const { t } = useTranslation5();
1133
+ const {
1134
+ attributes,
1135
+ listeners,
1136
+ setNodeRef,
1137
+ setActivatorNodeRef,
1138
+ transform,
1139
+ transition,
1140
+ isDragging
1141
+ } = useSortable({ id: field.field_id });
1142
+ const style = {
1143
+ opacity: isDragging ? 0.4 : void 0,
1144
+ transform: CSS.Translate.toString(transform),
1145
+ transition
1146
+ };
1147
+ if (!field.file) {
1148
+ return null;
1149
+ }
1150
+ return /* @__PURE__ */ jsxs6(
1151
+ "li",
1152
+ {
1153
+ className: "bg-ui-bg-component shadow-elevation-card-rest flex items-center justify-between rounded-lg px-3 py-2",
1154
+ ref: setNodeRef,
1155
+ style,
1156
+ children: [
1157
+ /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-x-2", children: [
1158
+ /* @__PURE__ */ jsx6(
1159
+ IconButton,
1160
+ {
1161
+ variant: "transparent",
1162
+ type: "button",
1163
+ size: "small",
1164
+ ...attributes,
1165
+ ...listeners,
1166
+ ref: setActivatorNodeRef,
1167
+ className: "cursor-grab touch-none active:cursor-grabbing",
1168
+ children: /* @__PURE__ */ jsx6(DotsSix, { className: "text-ui-fg-muted" })
1169
+ }
1170
+ ),
1171
+ /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-x-3", children: [
1172
+ /* @__PURE__ */ jsx6("div", { className: "bg-ui-bg-base h-10 w-[30px] overflow-hidden rounded-md", children: /* @__PURE__ */ jsx6(ThumbnailPreview, { url: field.url }) }),
1173
+ /* @__PURE__ */ jsxs6("div", { className: "flex flex-col", children: [
1174
+ /* @__PURE__ */ jsx6(Text4, { size: "small", leading: "compact", children: field.file.name }),
1175
+ /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-x-1", children: [
1176
+ field.isThumbnail && /* @__PURE__ */ jsx6(ThumbnailBadge, {}),
1177
+ /* @__PURE__ */ jsx6(
1178
+ Text4,
1179
+ {
1180
+ size: "xsmall",
1181
+ leading: "compact",
1182
+ className: "text-ui-fg-subtle",
1183
+ children: formatFileSize(field.file.size)
1184
+ }
1185
+ )
1186
+ ] })
1187
+ ] })
1188
+ ] })
1189
+ ] }),
1190
+ /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-x-1", children: [
1191
+ /* @__PURE__ */ jsx6(
1192
+ ActionMenu,
1193
+ {
1194
+ groups: [
1195
+ {
1196
+ actions: [
1197
+ {
1198
+ label: t("products.media.makeThumbnail"),
1199
+ icon: /* @__PURE__ */ jsx6(StackPerspective, {}),
1200
+ onClick: onMakeThumbnail
1201
+ }
1202
+ ]
1203
+ },
1204
+ {
1205
+ actions: [
1206
+ {
1207
+ icon: /* @__PURE__ */ jsx6(Trash, {}),
1208
+ label: t("actions.delete"),
1209
+ onClick: onDelete
1210
+ }
1211
+ ]
1212
+ }
1213
+ ]
1214
+ }
1215
+ ),
1216
+ /* @__PURE__ */ jsx6(
1217
+ IconButton,
1218
+ {
1219
+ type: "button",
1220
+ size: "small",
1221
+ variant: "transparent",
1222
+ onClick: onDelete,
1223
+ children: /* @__PURE__ */ jsx6(XMark, {})
1224
+ }
1225
+ )
1226
+ ] })
1227
+ ]
1228
+ }
1229
+ );
1230
+ };
1231
+ var MediaGridItemOverlay = ({ field }) => {
1232
+ return /* @__PURE__ */ jsxs6("li", { className: "bg-ui-bg-component shadow-elevation-card-rest flex items-center justify-between rounded-lg px-3 py-2", children: [
1233
+ /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-x-2", children: [
1234
+ /* @__PURE__ */ jsx6(
1235
+ IconButton,
1236
+ {
1237
+ variant: "transparent",
1238
+ size: "small",
1239
+ className: "cursor-grab touch-none active:cursor-grabbing",
1240
+ children: /* @__PURE__ */ jsx6(DotsSix, { className: "text-ui-fg-muted" })
1241
+ }
1242
+ ),
1243
+ /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-x-3", children: [
1244
+ /* @__PURE__ */ jsx6("div", { className: "bg-ui-bg-base h-10 w-[30px] overflow-hidden rounded-md", children: /* @__PURE__ */ jsx6(ThumbnailPreview, { url: field.url }) }),
1245
+ /* @__PURE__ */ jsxs6("div", { className: "flex flex-col", children: [
1246
+ /* @__PURE__ */ jsx6(Text4, { size: "small", leading: "compact", children: field.file?.name }),
1247
+ /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-x-1", children: [
1248
+ field.isThumbnail && /* @__PURE__ */ jsx6(ThumbnailBadge, {}),
1249
+ /* @__PURE__ */ jsx6(
1250
+ Text4,
1251
+ {
1252
+ size: "xsmall",
1253
+ leading: "compact",
1254
+ className: "text-ui-fg-subtle",
1255
+ children: formatFileSize(field.file?.size ?? 0)
1256
+ }
1257
+ )
1258
+ ] })
1259
+ ] })
1260
+ ] })
1261
+ ] }),
1262
+ /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-x-1", children: [
1263
+ /* @__PURE__ */ jsx6(ActionMenu, { groups: [] }),
1264
+ /* @__PURE__ */ jsx6(
1265
+ IconButton,
1266
+ {
1267
+ type: "button",
1268
+ size: "small",
1269
+ variant: "transparent",
1270
+ onClick: () => {
1271
+ },
1272
+ children: /* @__PURE__ */ jsx6(XMark, {})
1273
+ }
1274
+ )
1275
+ ] })
1276
+ ] });
1277
+ };
1278
+ var ThumbnailPreview = ({ url }) => {
1279
+ if (!url) {
1280
+ return null;
1281
+ }
1282
+ return /* @__PURE__ */ jsx6("img", { src: url, alt: "", className: "size-full object-cover object-center" });
1283
+ };
1284
+ function formatFileSize(bytes, decimalPlaces = 2) {
1285
+ if (bytes === 0) {
1286
+ return "0 Bytes";
1287
+ }
1288
+ const k = 1024;
1289
+ const sizes = ["Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
1290
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
1291
+ return parseFloat((bytes / Math.pow(k, i)).toFixed(decimalPlaces)) + " " + sizes[i];
1292
+ }
1293
+
1294
+ // src/pages/products/create/product-create-details-form/product-create-details-form.tsx
1295
+ import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
1296
+ var Root = ({ children }) => {
1297
+ if (Children.count(children) > 0) {
1298
+ return /* @__PURE__ */ jsx7("div", { className: "flex flex-col items-center p-16", children: /* @__PURE__ */ jsxs7("div", { className: "flex w-full max-w-[720px] flex-col gap-y-8", children: [
1299
+ /* @__PURE__ */ jsx7(Header2, {}),
1300
+ children
1301
+ ] }) });
1302
+ }
1303
+ return /* @__PURE__ */ jsx7("div", { className: "flex flex-col items-center p-16", children: /* @__PURE__ */ jsxs7("div", { className: "flex w-full max-w-[720px] flex-col gap-y-8", children: [
1304
+ /* @__PURE__ */ jsx7(Header2, {}),
1305
+ /* @__PURE__ */ jsxs7("div", { className: "flex flex-col gap-y-6", children: [
1306
+ /* @__PURE__ */ jsx7(ProductCreateGeneralSection, {}),
1307
+ /* @__PURE__ */ jsx7(ProductCreateMediaSection, {})
1308
+ ] })
1309
+ ] }) });
1310
+ };
1311
+ Root._tabMeta = {
1312
+ id: "details",
1313
+ labelKey: "products.create.tabs.details",
1314
+ validationFields: ["title", "media"]
1315
+ };
1316
+ var Header2 = () => {
1317
+ const { t } = useTranslation6();
1318
+ return /* @__PURE__ */ jsx7("div", { className: "flex flex-col", children: /* @__PURE__ */ jsx7(Heading2, { children: t("products.create.tabs.details") }) });
1319
+ };
1320
+ var ProductCreateDetailsForm = Object.assign(Root, {
1321
+ _tabMeta: Root._tabMeta,
1322
+ GeneralSection: ProductCreateGeneralSection,
1323
+ MediaSection: ProductCreateMediaSection
1324
+ });
1325
+
1326
+ // src/pages/products/create/product-create-inventory-kit-form/product-create-inventory-kit-form.tsx
1327
+ import { Children as Children2 } from "react";
1328
+
1329
+ // src/pages/products/create/product-create-inventory-kit-form/components/product-create-inventory-kit-section/product-create-inventory-kit-section.tsx
1330
+ import { Button as Button2, Heading as Heading3, IconButton as IconButton2, Input as Input4, Label } from "@medusajs/ui";
1331
+ import { useFieldArray as useFieldArray3, useWatch } from "react-hook-form";
1332
+ import { XMarkMini as XMarkMini2 } from "@medusajs/icons";
1333
+ import { useTranslation as useTranslation7 } from "react-i18next";
1334
+ import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
1335
+ function VariantSection({ variant, index }) {
1336
+ const { t } = useTranslation7();
1337
+ const form = useTabbedForm();
1338
+ const inventory = useFieldArray3({
1339
+ control: form.control,
1340
+ name: `variants.${index}.inventory`
1341
+ });
1342
+ const inventoryFormData = useWatch({
1343
+ control: form.control,
1344
+ name: `variants.${index}.inventory`
1345
+ });
1346
+ const items = useComboboxData({
1347
+ queryKey: ["inventory_items"],
1348
+ queryFn: (params) => fetchQuery(`/vendor/inventory-items`, {
1349
+ method: "GET",
1350
+ query: params
1351
+ }),
1352
+ getOptions: (data) => data.inventory_items.map((item) => ({
1353
+ label: item.title || item.sku || item.id,
1354
+ value: item.id
1355
+ }))
1356
+ });
1357
+ const isItemOptionDisabled = (option, inventoryIndex) => {
1358
+ return inventoryFormData?.some(
1359
+ (i, index2) => index2 != inventoryIndex && i.inventory_item_id === option.value
1360
+ );
1361
+ };
1362
+ return /* @__PURE__ */ jsxs8("div", { className: "grid gap-y-4", children: [
1363
+ /* @__PURE__ */ jsxs8("div", { className: "flex items-start justify-between gap-x-4", children: [
1364
+ /* @__PURE__ */ jsxs8("div", { className: "flex flex-col", children: [
1365
+ /* @__PURE__ */ jsx8(Form.Label, { children: variant.title }),
1366
+ /* @__PURE__ */ jsx8(Form.Hint, { children: t("products.create.inventory.label") })
1367
+ ] }),
1368
+ /* @__PURE__ */ jsx8(
1369
+ Button2,
1370
+ {
1371
+ size: "small",
1372
+ variant: "secondary",
1373
+ type: "button",
1374
+ onClick: () => {
1375
+ inventory.append({
1376
+ inventory_item_id: "",
1377
+ required_quantity: ""
1378
+ });
1379
+ },
1380
+ children: t("actions.add")
1381
+ }
1382
+ )
1383
+ ] }),
1384
+ inventory.fields.map((inventoryItem, inventoryIndex) => /* @__PURE__ */ jsxs8(
1385
+ "li",
1386
+ {
1387
+ className: "bg-ui-bg-component shadow-elevation-card-rest grid grid-cols-[1fr_28px] items-center gap-1.5 rounded-xl p-1.5",
1388
+ children: [
1389
+ /* @__PURE__ */ jsxs8("div", { className: "grid grid-cols-[min-content,1fr] items-center gap-1.5", children: [
1390
+ /* @__PURE__ */ jsx8("div", { className: "flex items-center px-2 py-1.5", children: /* @__PURE__ */ jsx8(
1391
+ Label,
1392
+ {
1393
+ size: "xsmall",
1394
+ weight: "plus",
1395
+ className: "text-ui-fg-subtle",
1396
+ htmlFor: `variants.${index}.inventory.${inventoryIndex}.inventory_item_id`,
1397
+ children: t("fields.item")
1398
+ }
1399
+ ) }),
1400
+ /* @__PURE__ */ jsx8(
1401
+ Form.Field,
1402
+ {
1403
+ control: form.control,
1404
+ name: `variants.${index}.inventory.${inventoryIndex}.inventory_item_id`,
1405
+ render: ({ field }) => {
1406
+ return /* @__PURE__ */ jsx8(Form.Item, { children: /* @__PURE__ */ jsx8(Form.Control, { children: /* @__PURE__ */ jsx8(
1407
+ Combobox,
1408
+ {
1409
+ ...field,
1410
+ options: items.options.map((o) => ({
1411
+ ...o,
1412
+ disabled: isItemOptionDisabled(o, inventoryIndex)
1413
+ })),
1414
+ searchValue: items.searchValue,
1415
+ onSearchValueChange: items.onSearchValueChange,
1416
+ fetchNextPage: items.fetchNextPage,
1417
+ className: "bg-ui-bg-field-component hover:bg-ui-bg-field-component-hover",
1418
+ placeholder: t(
1419
+ "products.create.inventory.itemPlaceholder"
1420
+ )
1421
+ }
1422
+ ) }) });
1423
+ }
1424
+ }
1425
+ ),
1426
+ /* @__PURE__ */ jsx8("div", { className: "flex items-center px-2 py-1.5", children: /* @__PURE__ */ jsx8(
1427
+ Label,
1428
+ {
1429
+ size: "xsmall",
1430
+ weight: "plus",
1431
+ className: "text-ui-fg-subtle",
1432
+ htmlFor: `variants.${index}.inventory.${inventoryIndex}.required_quantity`,
1433
+ children: t("fields.quantity")
1434
+ }
1435
+ ) }),
1436
+ /* @__PURE__ */ jsx8(
1437
+ Form.Field,
1438
+ {
1439
+ control: form.control,
1440
+ name: `variants.${index}.inventory.${inventoryIndex}.required_quantity`,
1441
+ render: ({ field: { onChange, value, ...field } }) => {
1442
+ return /* @__PURE__ */ jsxs8(Form.Item, { children: [
1443
+ /* @__PURE__ */ jsx8(Form.Control, { children: /* @__PURE__ */ jsx8(
1444
+ Input4,
1445
+ {
1446
+ type: "number",
1447
+ className: "bg-ui-bg-field-component",
1448
+ min: 0,
1449
+ value,
1450
+ onChange: (e) => {
1451
+ const value2 = e.target.value;
1452
+ if (value2 === "") {
1453
+ onChange(null);
1454
+ } else {
1455
+ onChange(Number(value2));
1456
+ }
1457
+ },
1458
+ ...field,
1459
+ placeholder: t(
1460
+ "products.create.inventory.quantityPlaceholder"
1461
+ )
1462
+ }
1463
+ ) }),
1464
+ /* @__PURE__ */ jsx8(Form.ErrorMessage, {})
1465
+ ] });
1466
+ }
1467
+ }
1468
+ )
1469
+ ] }),
1470
+ /* @__PURE__ */ jsx8(
1471
+ IconButton2,
1472
+ {
1473
+ type: "button",
1474
+ size: "small",
1475
+ variant: "transparent",
1476
+ className: "text-ui-fg-muted",
1477
+ onClick: () => inventory.remove(inventoryIndex),
1478
+ children: /* @__PURE__ */ jsx8(XMarkMini2, {})
1479
+ }
1480
+ )
1481
+ ]
1482
+ },
1483
+ inventoryItem.id
1484
+ ))
1485
+ ] });
1486
+ }
1487
+ var ProductCreateInventoryKitSection = () => {
1488
+ const { t } = useTranslation7();
1489
+ const form = useTabbedForm();
1490
+ const variants = useFieldArray3({
1491
+ control: form.control,
1492
+ name: "variants"
1493
+ });
1494
+ return /* @__PURE__ */ jsxs8("div", { id: "organize", className: "flex flex-col gap-y-8", children: [
1495
+ /* @__PURE__ */ jsx8(Heading3, { children: t("products.create.inventory.heading") }),
1496
+ variants.fields.filter((v) => v.inventory_kit).map((variant, variantIndex) => /* @__PURE__ */ jsx8(
1497
+ VariantSection,
1498
+ {
1499
+ variant,
1500
+ index: variantIndex
1501
+ },
1502
+ variant.id
1503
+ ))
1504
+ ] });
1505
+ };
1506
+
1507
+ // src/pages/products/create/product-create-inventory-kit-form/product-create-inventory-kit-form.tsx
1508
+ import { jsx as jsx9 } from "react/jsx-runtime";
1509
+ var Root2 = ({ children }) => {
1510
+ if (Children2.count(children) > 0) {
1511
+ return /* @__PURE__ */ jsx9("div", { className: "flex flex-col items-center p-16", children: /* @__PURE__ */ jsx9("div", { className: "flex w-full max-w-[720px] flex-col gap-y-8", children }) });
1512
+ }
1513
+ return /* @__PURE__ */ jsx9("div", { className: "flex flex-col items-center p-16", children: /* @__PURE__ */ jsx9("div", { className: "flex w-full max-w-[720px] flex-col gap-y-8", children: /* @__PURE__ */ jsx9(ProductCreateInventoryKitSection, {}) }) });
1514
+ };
1515
+ Root2._tabMeta = {
1516
+ id: "inventory",
1517
+ labelKey: "products.create.tabs.inventory",
1518
+ isVisible: (form) => form.getValues("variants").some((v) => v.manage_inventory && v.inventory_kit)
1519
+ };
1520
+ var ProductCreateInventoryKitForm = Object.assign(Root2, {
1521
+ _tabMeta: Root2._tabMeta,
1522
+ InventoryKitSection: ProductCreateInventoryKitSection
1523
+ });
1524
+
1525
+ // src/pages/products/create/product-create-organize-form/product-create-organize-form.tsx
1526
+ import { Children as Children3 } from "react";
1527
+
1528
+ // src/pages/products/create/product-create-organize-form/components/product-create-organize-section/product-create-details-organize-section.tsx
1529
+ import { useState as useState3 } from "react";
1530
+ import { Heading as Heading4 } from "@medusajs/ui";
1531
+ import { useTranslation as useTranslation8 } from "react-i18next";
1532
+ import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
1533
+ var ProductCreateOrganizationSection = () => {
1534
+ const { t } = useTranslation8();
1535
+ const form = useTabbedForm();
1536
+ const collections = useComboboxData({
1537
+ queryKey: ["product_collections"],
1538
+ queryFn: (params) => sdk.vendor.collections.query({ offset: 0, limit: 100, ...params }),
1539
+ getOptions: (data) => data.collections.map((collection) => ({
1540
+ label: collection.title,
1541
+ value: collection.id
1542
+ }))
1543
+ });
1544
+ const types = useComboboxData({
1545
+ queryKey: ["product_types", "creating"],
1546
+ queryFn: (params) => fetchQuery("/vendor/product-types", {
1547
+ method: "GET",
1548
+ query: params
1549
+ }),
1550
+ getOptions: (data) => data.product_types.map((type) => ({
1551
+ label: type.value,
1552
+ value: type.id
1553
+ }))
1554
+ });
1555
+ const tags = useComboboxData({
1556
+ queryKey: ["product_tags", "creating"],
1557
+ queryFn: (params) => fetchQuery("/vendor/product-tags", {
1558
+ method: "GET",
1559
+ query: params
1560
+ }),
1561
+ getOptions: (data) => data.product_tags.map((tag) => ({
1562
+ label: tag.value,
1563
+ value: tag.id
1564
+ }))
1565
+ });
1566
+ return /* @__PURE__ */ jsxs9("div", { id: "organize", className: "flex flex-col gap-y-8", children: [
1567
+ /* @__PURE__ */ jsx10(Heading4, { children: t("products.organization.header") }),
1568
+ /* @__PURE__ */ jsx10(
1569
+ SwitchBox,
1570
+ {
1571
+ control: form.control,
1572
+ name: "discountable",
1573
+ label: t("products.fields.discountable.label"),
1574
+ description: t("products.fields.discountable.hint"),
1575
+ optional: true
1576
+ }
1577
+ ),
1578
+ /* @__PURE__ */ jsxs9("div", { className: "grid grid-cols-1 gap-4 md:grid-cols-2", children: [
1579
+ /* @__PURE__ */ jsx10(
1580
+ Form.Field,
1581
+ {
1582
+ control: form.control,
1583
+ name: "tags",
1584
+ render: ({ field }) => {
1585
+ return /* @__PURE__ */ jsxs9(Form.Item, { children: [
1586
+ /* @__PURE__ */ jsx10(Form.Label, { optional: true, children: t("products.fields.tags.label") }),
1587
+ /* @__PURE__ */ jsx10(Form.Control, { children: /* @__PURE__ */ jsx10(
1588
+ Combobox,
1589
+ {
1590
+ ...field,
1591
+ options: tags.options,
1592
+ searchValue: tags.searchValue,
1593
+ onSearchValueChange: tags.onSearchValueChange,
1594
+ fetchNextPage: tags.fetchNextPage
1595
+ }
1596
+ ) }),
1597
+ /* @__PURE__ */ jsx10(Form.ErrorMessage, {})
1598
+ ] });
1599
+ }
1600
+ }
1601
+ ),
1602
+ /* @__PURE__ */ jsx10(
1603
+ Form.Field,
1604
+ {
1605
+ control: form.control,
1606
+ name: "type_id",
1607
+ render: ({ field }) => {
1608
+ return /* @__PURE__ */ jsxs9(Form.Item, { children: [
1609
+ /* @__PURE__ */ jsx10(Form.Label, { optional: true, children: t("products.fields.type.label") }),
1610
+ /* @__PURE__ */ jsx10(Form.Control, { children: /* @__PURE__ */ jsx10(
1611
+ Combobox,
1612
+ {
1613
+ ...field,
1614
+ options: types.options,
1615
+ searchValue: types.searchValue,
1616
+ onSearchValueChange: types.onSearchValueChange,
1617
+ fetchNextPage: types.fetchNextPage,
1618
+ allowClear: true
1619
+ }
1620
+ ) }),
1621
+ /* @__PURE__ */ jsx10(Form.ErrorMessage, {})
1622
+ ] });
1623
+ }
1624
+ }
1625
+ )
1626
+ ] }),
1627
+ /* @__PURE__ */ jsxs9("div", { className: "grid grid-cols-1 gap-4 md:grid-cols-2", children: [
1628
+ /* @__PURE__ */ jsx10(
1629
+ Form.Field,
1630
+ {
1631
+ control: form.control,
1632
+ name: "categories",
1633
+ render: ({ field }) => {
1634
+ const [isFocused, setIsFocused] = useState3(false);
1635
+ return /* @__PURE__ */ jsxs9(Form.Item, { children: [
1636
+ /* @__PURE__ */ jsx10(Form.Label, { tooltip: t("products.fields.primaryCategory.tooltip"), children: t("products.fields.primaryCategory.label") }),
1637
+ /* @__PURE__ */ jsx10(Form.Control, { children: /* @__PURE__ */ jsx10(
1638
+ CategoryCombobox,
1639
+ {
1640
+ ...field,
1641
+ onFocus: () => setIsFocused(true),
1642
+ onBlur: () => {
1643
+ setIsFocused(false);
1644
+ field.onBlur();
1645
+ },
1646
+ isSingleSelect: true,
1647
+ allowClear: false
1648
+ }
1649
+ ) }),
1650
+ !isFocused && /* @__PURE__ */ jsx10(Form.ErrorMessage, {})
1651
+ ] });
1652
+ }
1653
+ }
1654
+ ),
1655
+ /* @__PURE__ */ jsx10(
1656
+ Form.Field,
1657
+ {
1658
+ control: form.control,
1659
+ name: "secondary_categories",
1660
+ render: ({ field }) => {
1661
+ return /* @__PURE__ */ jsxs9(Form.Item, { children: [
1662
+ /* @__PURE__ */ jsx10(Form.Label, { optional: true, children: t("products.fields.secondaryCategories.label", "Secondary Categories") }),
1663
+ /* @__PURE__ */ jsx10(Form.Control, { children: /* @__PURE__ */ jsx10(
1664
+ CategoryCombobox,
1665
+ {
1666
+ ...field,
1667
+ value: field.value || []
1668
+ }
1669
+ ) }),
1670
+ /* @__PURE__ */ jsx10(Form.ErrorMessage, {})
1671
+ ] });
1672
+ }
1673
+ }
1674
+ )
1675
+ ] }),
1676
+ /* @__PURE__ */ jsx10("div", { className: "grid grid-cols-1 gap-4 md:grid-cols-2", children: /* @__PURE__ */ jsx10(
1677
+ Form.Field,
1678
+ {
1679
+ control: form.control,
1680
+ name: "collection_id",
1681
+ render: ({ field }) => {
1682
+ return /* @__PURE__ */ jsxs9(Form.Item, { children: [
1683
+ /* @__PURE__ */ jsx10(Form.Label, { optional: true, children: t("products.fields.collection.label") }),
1684
+ /* @__PURE__ */ jsx10(Form.Control, { children: /* @__PURE__ */ jsx10(
1685
+ Combobox,
1686
+ {
1687
+ ...field,
1688
+ options: collections.options,
1689
+ searchValue: collections.searchValue,
1690
+ onSearchValueChange: collections.onSearchValueChange,
1691
+ fetchNextPage: collections.fetchNextPage,
1692
+ allowClear: true
1693
+ }
1694
+ ) }),
1695
+ /* @__PURE__ */ jsx10(Form.ErrorMessage, {})
1696
+ ] });
1697
+ }
1698
+ }
1699
+ ) })
1700
+ ] });
1701
+ };
1702
+
1703
+ // src/pages/products/create/product-create-organize-form/components/product-create-organize-attribute-section/product-create-details-attribute-section.tsx
1704
+ import { Heading as Heading5, Input as Input5 } from "@medusajs/ui";
1705
+ import { useTranslation as useTranslation9 } from "react-i18next";
1706
+ import { jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
1707
+ var ProductCreateAttributeSection = () => {
1708
+ const { t } = useTranslation9();
1709
+ const form = useTabbedForm();
1710
+ return /* @__PURE__ */ jsxs10("div", { id: "attributes", className: "flex flex-col gap-y-8", children: [
1711
+ /* @__PURE__ */ jsx11(Heading5, { level: "h2", children: t("products.attributes") }),
1712
+ /* @__PURE__ */ jsxs10("div", { className: "grid grid-cols-2 gap-x-4 gap-y-8", children: [
1713
+ /* @__PURE__ */ jsx11(
1714
+ Form.Field,
1715
+ {
1716
+ control: form.control,
1717
+ name: "origin_country",
1718
+ render: ({ field }) => {
1719
+ return /* @__PURE__ */ jsxs10(Form.Item, { children: [
1720
+ /* @__PURE__ */ jsx11(Form.Label, { optional: true, children: t("products.fields.countryOrigin.label") }),
1721
+ /* @__PURE__ */ jsx11(Form.Control, { children: /* @__PURE__ */ jsx11(CountrySelect, { ...field }) })
1722
+ ] });
1723
+ }
1724
+ }
1725
+ ),
1726
+ /* @__PURE__ */ jsx11(
1727
+ Form.Field,
1728
+ {
1729
+ control: form.control,
1730
+ name: "material",
1731
+ render: ({ field }) => {
1732
+ return /* @__PURE__ */ jsxs10(Form.Item, { children: [
1733
+ /* @__PURE__ */ jsx11(Form.Label, { optional: true, children: t("products.fields.material.label") }),
1734
+ /* @__PURE__ */ jsx11(Form.Control, { children: /* @__PURE__ */ jsx11(Input5, { ...field }) })
1735
+ ] });
1736
+ }
1737
+ }
1738
+ )
1739
+ ] }),
1740
+ /* @__PURE__ */ jsxs10("div", { className: "grid grid-cols-2 gap-x-4 gap-y-8", children: [
1741
+ /* @__PURE__ */ jsx11(
1742
+ Form.Field,
1743
+ {
1744
+ control: form.control,
1745
+ name: "width",
1746
+ render: ({ field }) => {
1747
+ return /* @__PURE__ */ jsxs10(Form.Item, { children: [
1748
+ /* @__PURE__ */ jsx11(Form.Label, { optional: true, children: t("products.fields.width.label") }),
1749
+ /* @__PURE__ */ jsx11(Form.Control, { children: /* @__PURE__ */ jsx11(Input5, { ...field, type: "number", min: 0 }) })
1750
+ ] });
1751
+ }
1752
+ }
1753
+ ),
1754
+ /* @__PURE__ */ jsx11(
1755
+ Form.Field,
1756
+ {
1757
+ control: form.control,
1758
+ name: "length",
1759
+ render: ({ field }) => {
1760
+ return /* @__PURE__ */ jsxs10(Form.Item, { children: [
1761
+ /* @__PURE__ */ jsx11(Form.Label, { optional: true, children: t("products.fields.length.label") }),
1762
+ /* @__PURE__ */ jsx11(Form.Control, { children: /* @__PURE__ */ jsx11(Input5, { ...field, type: "number", min: 0 }) })
1763
+ ] });
1764
+ }
1765
+ }
1766
+ ),
1767
+ /* @__PURE__ */ jsx11(
1768
+ Form.Field,
1769
+ {
1770
+ control: form.control,
1771
+ name: "height",
1772
+ render: ({ field }) => {
1773
+ return /* @__PURE__ */ jsxs10(Form.Item, { children: [
1774
+ /* @__PURE__ */ jsx11(Form.Label, { optional: true, children: t("products.fields.height.label") }),
1775
+ /* @__PURE__ */ jsx11(Form.Control, { children: /* @__PURE__ */ jsx11(Input5, { ...field, type: "number", min: 0 }) })
1776
+ ] });
1777
+ }
1778
+ }
1779
+ ),
1780
+ /* @__PURE__ */ jsx11(
1781
+ Form.Field,
1782
+ {
1783
+ control: form.control,
1784
+ name: "weight",
1785
+ render: ({ field }) => {
1786
+ return /* @__PURE__ */ jsxs10(Form.Item, { children: [
1787
+ /* @__PURE__ */ jsx11(Form.Label, { optional: true, children: t("products.fields.weight.label") }),
1788
+ /* @__PURE__ */ jsx11(Form.Control, { children: /* @__PURE__ */ jsx11(Input5, { ...field, type: "number", min: 0 }) })
1789
+ ] });
1790
+ }
1791
+ }
1792
+ ),
1793
+ /* @__PURE__ */ jsx11(
1794
+ Form.Field,
1795
+ {
1796
+ control: form.control,
1797
+ name: "mid_code",
1798
+ render: ({ field }) => {
1799
+ return /* @__PURE__ */ jsxs10(Form.Item, { children: [
1800
+ /* @__PURE__ */ jsx11(Form.Label, { optional: true, children: t("products.fields.mid_code.label") }),
1801
+ /* @__PURE__ */ jsx11(Form.Control, { children: /* @__PURE__ */ jsx11(Input5, { ...field }) })
1802
+ ] });
1803
+ }
1804
+ }
1805
+ ),
1806
+ /* @__PURE__ */ jsx11(
1807
+ Form.Field,
1808
+ {
1809
+ control: form.control,
1810
+ name: "hs_code",
1811
+ render: ({ field }) => {
1812
+ return /* @__PURE__ */ jsxs10(Form.Item, { children: [
1813
+ /* @__PURE__ */ jsx11(Form.Label, { optional: true, children: t("products.fields.hs_code.label") }),
1814
+ /* @__PURE__ */ jsx11(Form.Control, { children: /* @__PURE__ */ jsx11(Input5, { ...field }) })
1815
+ ] });
1816
+ }
1817
+ }
1818
+ )
1819
+ ] })
1820
+ ] });
1821
+ };
1822
+
1823
+ // src/pages/products/create/product-create-organize-form/components/product-create-sales-channel-stacked-modal/product-create-sales-channel-drawer.tsx
1824
+ import {
1825
+ Button as Button3,
1826
+ createDataTableColumnHelper
1827
+ } from "@medusajs/ui";
1828
+ import { useEffect as useEffect3, useMemo as useMemo2, useState as useState4 } from "react";
1829
+ import { useTranslation as useTranslation10 } from "react-i18next";
1830
+ import { keepPreviousData } from "@tanstack/react-query";
1831
+
1832
+ // src/pages/products/create/product-create-organize-form/constants.ts
1833
+ var SC_STACKED_MODAL_ID = "sc";
1834
+
1835
+ // src/pages/products/create/product-create-organize-form/components/product-create-sales-channel-stacked-modal/product-create-sales-channel-drawer.tsx
1836
+ import { jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
1837
+ var PAGE_SIZE = 50;
1838
+ var ProductCreateSalesChannelStackedModal = () => {
1839
+ const { t } = useTranslation10();
1840
+ const form = useTabbedForm();
1841
+ const { getValues, setValue } = form;
1842
+ const { setIsOpen, getIsOpen } = useStackedModal();
1843
+ const [rowSelection, setRowSelection] = useState4(
1844
+ {}
1845
+ );
1846
+ const [state, setState] = useState4([]);
1847
+ const searchParams = useSalesChannelTableQuery({
1848
+ pageSize: PAGE_SIZE,
1849
+ prefix: SC_STACKED_MODAL_ID
1850
+ });
1851
+ const { sales_channels, count, isLoading, isError, error } = useSalesChannels(
1852
+ searchParams,
1853
+ {
1854
+ placeholderData: keepPreviousData
1855
+ }
1856
+ );
1857
+ const open = getIsOpen(SC_STACKED_MODAL_ID);
1858
+ useEffect3(() => {
1859
+ if (!open) {
1860
+ return;
1861
+ }
1862
+ const salesChannels = getValues("sales_channels");
1863
+ if (salesChannels) {
1864
+ setState(
1865
+ salesChannels.map((channel) => ({
1866
+ id: channel.id,
1867
+ name: channel.name
1868
+ }))
1869
+ );
1870
+ setRowSelection(
1871
+ salesChannels.reduce(
1872
+ (acc, channel) => ({
1873
+ ...acc,
1874
+ [channel.id]: true
1875
+ }),
1876
+ {}
1877
+ )
1878
+ );
1879
+ }
1880
+ }, [open, getValues]);
1881
+ const onRowSelectionChange = (state2) => {
1882
+ const ids = Object.keys(state2);
1883
+ const addedIdsSet = new Set(
1884
+ ids.filter((id) => state2[id] && !rowSelection[id])
1885
+ );
1886
+ let addedSalesChannels = [];
1887
+ if (addedIdsSet.size > 0) {
1888
+ addedSalesChannels = sales_channels?.filter((channel) => addedIdsSet.has(channel.id)) ?? [];
1889
+ }
1890
+ setState((prev) => {
1891
+ const filteredPrev = prev.filter((channel) => state2[channel.id]);
1892
+ return Array.from(/* @__PURE__ */ new Set([...filteredPrev, ...addedSalesChannels]));
1893
+ });
1894
+ setRowSelection(state2);
1895
+ };
1896
+ const handleAdd = () => {
1897
+ setValue("sales_channels", state, {
1898
+ shouldDirty: true,
1899
+ shouldTouch: true
1900
+ });
1901
+ setIsOpen(SC_STACKED_MODAL_ID, false);
1902
+ };
1903
+ const filters = useSalesChannelTableFilters();
1904
+ const columns = useColumns();
1905
+ const emptyState = useSalesChannelTableEmptyState();
1906
+ if (isError) {
1907
+ throw error;
1908
+ }
1909
+ return /* @__PURE__ */ jsxs11(StackedFocusModal.Content, { className: "flex flex-col overflow-hidden", children: [
1910
+ /* @__PURE__ */ jsx12(StackedFocusModal.Header, {}),
1911
+ /* @__PURE__ */ jsx12(StackedFocusModal.Body, { className: "flex-1 overflow-hidden", children: /* @__PURE__ */ jsx12(
1912
+ DataTable,
1913
+ {
1914
+ data: sales_channels,
1915
+ columns,
1916
+ filters,
1917
+ emptyState,
1918
+ rowCount: count,
1919
+ pageSize: PAGE_SIZE,
1920
+ getRowId: (row) => row.id,
1921
+ rowSelection: {
1922
+ state: rowSelection,
1923
+ onRowSelectionChange
1924
+ },
1925
+ isLoading,
1926
+ layout: "fill",
1927
+ prefix: SC_STACKED_MODAL_ID
1928
+ }
1929
+ ) }),
1930
+ /* @__PURE__ */ jsx12(StackedFocusModal.Footer, { children: /* @__PURE__ */ jsxs11("div", { className: "flex items-center justify-end gap-x-2", children: [
1931
+ /* @__PURE__ */ jsx12(StackedFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsx12(Button3, { size: "small", variant: "secondary", type: "button", children: t("actions.cancel") }) }),
1932
+ /* @__PURE__ */ jsx12(Button3, { size: "small", onClick: handleAdd, type: "button", children: t("actions.save") })
1933
+ ] }) })
1934
+ ] });
1935
+ };
1936
+ var columnHelper = createDataTableColumnHelper();
1937
+ var useColumns = () => {
1938
+ const base = useSalesChannelTableColumns();
1939
+ return useMemo2(() => [columnHelper.select(), ...base], [base]);
1940
+ };
1941
+
1942
+ // src/pages/products/create/product-create-organize-form/product-create-organize-form.tsx
1943
+ import { jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
1944
+ var Root3 = ({ children }) => {
1945
+ if (Children3.count(children) > 0) {
1946
+ return /* @__PURE__ */ jsxs12(StackedFocusModal, { id: SC_STACKED_MODAL_ID, children: [
1947
+ /* @__PURE__ */ jsx13("div", { className: "flex flex-col items-center p-16", children: /* @__PURE__ */ jsx13("div", { className: "flex w-full max-w-[720px] flex-col gap-y-8", children }) }),
1948
+ /* @__PURE__ */ jsx13(ProductCreateSalesChannelStackedModal, {})
1949
+ ] });
1950
+ }
1951
+ return /* @__PURE__ */ jsxs12(StackedFocusModal, { id: SC_STACKED_MODAL_ID, children: [
1952
+ /* @__PURE__ */ jsx13("div", { className: "flex flex-col items-center p-16", children: /* @__PURE__ */ jsx13("div", { className: "flex w-full max-w-[720px] flex-col gap-y-8", children: /* @__PURE__ */ jsx13(ProductCreateOrganizationSection, {}) }) }),
1953
+ /* @__PURE__ */ jsx13(ProductCreateSalesChannelStackedModal, {})
1954
+ ] });
1955
+ };
1956
+ Root3._tabMeta = {
1957
+ id: "organize",
1958
+ labelKey: "products.create.tabs.organize",
1959
+ validationFields: ["discountable", "categories", "tags", "sales_channels"]
1960
+ };
1961
+ var ProductCreateOrganizeForm = Object.assign(Root3, {
1962
+ _tabMeta: Root3._tabMeta,
1963
+ OrganizationSection: ProductCreateOrganizationSection,
1964
+ AttributeSection: ProductCreateAttributeSection,
1965
+ SalesChannelModal: ProductCreateSalesChannelStackedModal
1966
+ });
1967
+
1968
+ // src/pages/products/create/product-create-variants-form/product-create-variants-form.tsx
1969
+ import { useCallback, useEffect as useEffect4, useMemo as useMemo3, useRef as useRef2, useState as useState5 } from "react";
1970
+ import { Checkbox, Tooltip as Tooltip2 } from "@medusajs/ui";
1971
+ import { useWatch as useWatch2 } from "react-hook-form";
1972
+ import { useTranslation as useTranslation11 } from "react-i18next";
1973
+ import { jsx as jsx14 } from "react/jsx-runtime";
1974
+ var ProductCreateVariantsForm = ({
1975
+ form,
1976
+ store,
1977
+ regions = [],
1978
+ pricePreferences = [],
1979
+ onOpenMediaModal,
1980
+ productMedia = []
1981
+ }) => {
1982
+ const { t } = useTranslation11();
1983
+ const [searchValue, setSearchValue] = useState5("");
1984
+ const variants = useWatch2({
1985
+ control: form.control,
1986
+ name: "variants",
1987
+ defaultValue: []
1988
+ });
1989
+ const attributesResult = useAttributes();
1990
+ const allAttributes = attributesResult.attributes || [];
1991
+ const { stock_locations = [] } = useStockLocations({
1992
+ limit: 9999,
1993
+ fields: "id,name"
1994
+ });
1995
+ const formValues = useWatch2({
1996
+ control: form.control
1997
+ });
1998
+ const variantAttributes = useMemo3(() => {
1999
+ const result = [];
2000
+ allAttributes.forEach((attr) => {
2001
+ if (attr.ui_component === "multivalue") {
2002
+ const useForVariants = formValues?.[`${attr.handle}UseForVariants`];
2003
+ if (useForVariants === false) return;
2004
+ const selectedValueIds = formValues?.[attr.handle];
2005
+ if (selectedValueIds && Array.isArray(selectedValueIds) && selectedValueIds.length > 0) {
2006
+ const selectedValues = selectedValueIds.map((valueId) => {
2007
+ const possibleValue = attr.possible_values?.find(
2008
+ (pv) => pv.id === valueId
2009
+ );
2010
+ return possibleValue ? { id: valueId, value: possibleValue.value } : null;
2011
+ }).filter(
2012
+ (item) => item !== null
2013
+ );
2014
+ if (selectedValues.length > 0) {
2015
+ result.push({
2016
+ handle: attr.handle,
2017
+ name: attr.name,
2018
+ selectedValues
2019
+ });
2020
+ }
2021
+ }
2022
+ }
2023
+ });
2024
+ const options = formValues?.options || [];
2025
+ options.forEach((option) => {
2026
+ if (option?.useForVariants !== false && option?.title && option?.values && Array.isArray(option.values) && option.values.length > 0) {
2027
+ result.push({
2028
+ handle: `option-${option.title}`,
2029
+ name: option.title,
2030
+ selectedValues: option.values.map((value) => ({
2031
+ id: value,
2032
+ value
2033
+ }))
2034
+ });
2035
+ }
2036
+ });
2037
+ return result;
2038
+ }, [allAttributes, formValues]);
2039
+ const hasProductMedia = productMedia.length > 0;
2040
+ const columns = useColumns2({
2041
+ variantAttributes,
2042
+ store,
2043
+ regions,
2044
+ pricePreferences,
2045
+ stockLocations: stock_locations,
2046
+ onOpenMediaModal,
2047
+ form,
2048
+ productMedia,
2049
+ hasProductMedia
2050
+ });
2051
+ const variantData = useMemo3(() => {
2052
+ const ret = [];
2053
+ if (variantAttributes.length > 0) {
2054
+ const totalCombinations = variantAttributes.reduce(
2055
+ (acc, attr) => acc * attr.selectedValues.length,
2056
+ 1
2057
+ );
2058
+ for (let i = 0; i < totalCombinations; i++) {
2059
+ const variantOptions = {};
2060
+ variantAttributes.forEach((attr) => {
2061
+ let valueIndex = 0;
2062
+ let divisor = 1;
2063
+ for (let j = variantAttributes.length - 1; j >= 0; j--) {
2064
+ if (variantAttributes[j].handle === attr.handle) {
2065
+ valueIndex = Math.floor(i / divisor) % attr.selectedValues.length;
2066
+ break;
2067
+ }
2068
+ divisor *= variantAttributes[j].selectedValues.length;
2069
+ }
2070
+ variantOptions[attr.name] = attr.selectedValues[valueIndex]?.value || "";
2071
+ });
2072
+ const autoTitle = variantAttributes.map((attr) => variantOptions[attr.name]).filter(Boolean).join(" / ");
2073
+ const existingVariant = variants.find((v) => {
2074
+ if (!v.options) return false;
2075
+ return variantAttributes.every(
2076
+ (attr) => v.options[attr.name] === variantOptions[attr.name]
2077
+ );
2078
+ });
2079
+ ret.push({
2080
+ title: autoTitle,
2081
+ should_create: existingVariant?.should_create ?? true,
2082
+ variant_rank: i,
2083
+ options: variantOptions,
2084
+ sku: existingVariant?.sku || "",
2085
+ prices: existingVariant?.prices || {},
2086
+ is_default: i === 0,
2087
+ media: existingVariant?.media || [],
2088
+ originalIndex: existingVariant ? variants.indexOf(existingVariant) : i
2089
+ });
2090
+ }
2091
+ } else {
2092
+ variants.forEach((v, i) => {
2093
+ if (v.should_create) {
2094
+ ret.push({
2095
+ ...v,
2096
+ originalIndex: i
2097
+ });
2098
+ }
2099
+ });
2100
+ }
2101
+ return ret;
2102
+ }, [variants, variantAttributes]);
2103
+ const filteredVariantData = useMemo3(() => {
2104
+ if (!searchValue.trim()) return variantData;
2105
+ return variantData.filter(
2106
+ (variant) => variant.title.toLowerCase().includes(searchValue.toLowerCase())
2107
+ );
2108
+ }, [variantData, searchValue]);
2109
+ const variantStructureKey = useMemo3(() => {
2110
+ return variantAttributes.map(
2111
+ (attr) => `${attr.handle}:${attr.selectedValues.map((v) => v.id).join(",")}`
2112
+ ).join("|");
2113
+ }, [variantAttributes]);
2114
+ useEffect4(() => {
2115
+ if (variantAttributes.length > 0) {
2116
+ const totalCombinations = variantAttributes.reduce(
2117
+ (acc, attr) => acc * attr.selectedValues.length,
2118
+ 1
2119
+ );
2120
+ const currentVariants = form.getValues("variants") || [];
2121
+ const newVariants = [];
2122
+ for (let i = 0; i < totalCombinations; i++) {
2123
+ const variantOptions = {};
2124
+ variantAttributes.forEach((attr) => {
2125
+ let valueIndex = 0;
2126
+ let divisor = 1;
2127
+ for (let j = variantAttributes.length - 1; j >= 0; j--) {
2128
+ if (variantAttributes[j].handle === attr.handle) {
2129
+ valueIndex = Math.floor(i / divisor) % attr.selectedValues.length;
2130
+ break;
2131
+ }
2132
+ divisor *= variantAttributes[j].selectedValues.length;
2133
+ }
2134
+ variantOptions[attr.name] = attr.selectedValues[valueIndex]?.value || "";
2135
+ });
2136
+ const autoTitle = variantAttributes.map((attr) => variantOptions[attr.name]).filter(Boolean).join(" / ");
2137
+ const existingVariant = currentVariants.find((v) => {
2138
+ if (!v.options) return false;
2139
+ return variantAttributes.every(
2140
+ (attr) => v.options[attr.name] === variantOptions[attr.name]
2141
+ );
2142
+ });
2143
+ newVariants.push({
2144
+ title: autoTitle,
2145
+ should_create: existingVariant?.should_create ?? true,
2146
+ variant_rank: i,
2147
+ options: variantOptions,
2148
+ sku: existingVariant?.sku || "",
2149
+ prices: existingVariant?.prices || {},
2150
+ is_default: i === 0,
2151
+ media: existingVariant?.media || []
2152
+ });
2153
+ }
2154
+ form.setValue("variants", newVariants);
2155
+ } else {
2156
+ const currentVariants = form.getValues("variants") || [];
2157
+ if (currentVariants.length === 0) {
2158
+ const defaultVariant = decorateVariantsWithDefaultValues([
2159
+ {
2160
+ title: "Default variant",
2161
+ should_create: true,
2162
+ variant_rank: 0,
2163
+ options: {},
2164
+ sku: "",
2165
+ prices: {},
2166
+ is_default: true,
2167
+ media: []
2168
+ }
2169
+ ]);
2170
+ form.setValue("variants", defaultVariant);
2171
+ } else {
2172
+ const hasOnlyDefaultVariant = currentVariants.length === 1 && currentVariants[0].is_default;
2173
+ if (!hasOnlyDefaultVariant) {
2174
+ const defaultVariant = decorateVariantsWithDefaultValues([
2175
+ {
2176
+ title: "Default variant",
2177
+ should_create: true,
2178
+ variant_rank: 0,
2179
+ options: {},
2180
+ sku: "",
2181
+ prices: {},
2182
+ is_default: true,
2183
+ media: []
2184
+ }
2185
+ ]);
2186
+ form.setValue("variants", defaultVariant);
2187
+ }
2188
+ }
2189
+ }
2190
+ }, [variantStructureKey, form]);
2191
+ return /* @__PURE__ */ jsx14("div", { className: "border-ui-border flex h-full flex-col justify-between divide-y", children: /* @__PURE__ */ jsx14(
2192
+ DataGrid,
2193
+ {
2194
+ columns,
2195
+ data: filteredVariantData,
2196
+ state: form,
2197
+ searchValue,
2198
+ onSearchChange: setSearchValue,
2199
+ searchPlaceholder: t(
2200
+ "products.create.variants.productVariants.searchPlaceholder"
2201
+ )
2202
+ }
2203
+ ) });
2204
+ };
2205
+ var columnHelper2 = createDataGridHelper();
2206
+ var useColumns2 = ({
2207
+ variantAttributes = [],
2208
+ store,
2209
+ regions = [],
2210
+ pricePreferences = [],
2211
+ stockLocations = [],
2212
+ onOpenMediaModal,
2213
+ form,
2214
+ productMedia = [],
2215
+ hasProductMedia = false
2216
+ }) => {
2217
+ const { t } = useTranslation11();
2218
+ const variants = useWatch2({
2219
+ control: form.control,
2220
+ name: "variants",
2221
+ defaultValue: []
2222
+ });
2223
+ const variantsRef = useRef2(variants);
2224
+ variantsRef.current = variants;
2225
+ const allSelected = variants.length > 0 && variants.every((v) => v.should_create);
2226
+ const someSelected = variants.some((v) => v.should_create) && !allSelected;
2227
+ const handleSelectAll = useCallback(
2228
+ (checked) => {
2229
+ const currentVariants = form.getValues("variants") || [];
2230
+ const updatedVariants = currentVariants.map((v) => ({
2231
+ ...v,
2232
+ should_create: checked
2233
+ }));
2234
+ form.setValue("variants", updatedVariants);
2235
+ },
2236
+ [form]
2237
+ );
2238
+ return useMemo3(
2239
+ () => [
2240
+ columnHelper2.column({
2241
+ id: "checkbox",
2242
+ header: () => /* @__PURE__ */ jsx14(
2243
+ Checkbox,
2244
+ {
2245
+ checked: allSelected ? true : someSelected ? "indeterminate" : false,
2246
+ onCheckedChange: handleSelectAll
2247
+ }
2248
+ ),
2249
+ field: (context) => {
2250
+ const rowData = context.row.original;
2251
+ return `variants.${rowData.originalIndex}.should_create`;
2252
+ },
2253
+ type: "boolean",
2254
+ cell: (context) => /* @__PURE__ */ jsx14(DataGrid.BooleanCell, { context }),
2255
+ disableHiding: true,
2256
+ size: 52,
2257
+ pin: "left"
2258
+ }),
2259
+ columnHelper2.column({
2260
+ id: "options_combined",
2261
+ name: variantAttributes.length > 0 ? variantAttributes.map((attr) => attr.name).join(" / ") : "Options",
2262
+ header: () => {
2263
+ const label = variantAttributes.length > 0 ? variantAttributes.map((attr) => attr.name).join(" / ") : "Options";
2264
+ return /* @__PURE__ */ jsx14(Tooltip2, { content: label, children: /* @__PURE__ */ jsx14("span", { className: "w-full truncate", children: label }) });
2265
+ },
2266
+ cell: (context) => {
2267
+ if (variantAttributes.length === 0) {
2268
+ return /* @__PURE__ */ jsx14(DataGrid.ReadonlyCell, { context });
2269
+ }
2270
+ const rowData = context.row.original;
2271
+ const combinedValue = variantAttributes.map(
2272
+ (attr) => rowData.options?.[attr.name] || ""
2273
+ ).filter(Boolean).join(" / ");
2274
+ return /* @__PURE__ */ jsx14(DataGrid.ReadonlyCell, { context, children: combinedValue });
2275
+ },
2276
+ disableHiding: true,
2277
+ pin: "left"
2278
+ }),
2279
+ columnHelper2.column({
2280
+ id: "title",
2281
+ name: t("fields.title"),
2282
+ header: t("fields.title"),
2283
+ field: (context) => {
2284
+ const rowData = context.row.original;
2285
+ return `variants.${rowData.originalIndex}.title`;
2286
+ },
2287
+ type: "text",
2288
+ cell: (context) => /* @__PURE__ */ jsx14(DataGrid.TextCell, { context }),
2289
+ disableHiding: true,
2290
+ pin: "left"
2291
+ }),
2292
+ columnHelper2.column({
2293
+ id: "media",
2294
+ name: t(
2295
+ "products.create.variants.productVariants.media"
2296
+ ),
2297
+ header: t(
2298
+ "products.create.variants.productVariants.media"
2299
+ ),
2300
+ field: (context) => {
2301
+ const rowData = context.row.original;
2302
+ return `variants.${rowData.originalIndex}.media`;
2303
+ },
2304
+ type: "media",
2305
+ cell: (context) => {
2306
+ const rowData = context.row.original;
2307
+ return /* @__PURE__ */ jsx14(
2308
+ DataGridMediaCell,
2309
+ {
2310
+ context,
2311
+ disabled: !hasProductMedia,
2312
+ onOpenMediaModal: hasProductMedia ? () => {
2313
+ const currentMedia = variantsRef.current[rowData.originalIndex]?.media;
2314
+ onOpenMediaModal?.(
2315
+ rowData.originalIndex,
2316
+ rowData.title,
2317
+ currentMedia,
2318
+ productMedia
2319
+ );
2320
+ } : void 0
2321
+ }
2322
+ );
2323
+ }
2324
+ }),
2325
+ columnHelper2.column({
2326
+ id: "sku",
2327
+ name: t("fields.sku"),
2328
+ header: t("fields.sku"),
2329
+ field: (context) => {
2330
+ const rowData = context.row.original;
2331
+ return `variants.${rowData.originalIndex}.sku`;
2332
+ },
2333
+ type: "text",
2334
+ cell: (context) => /* @__PURE__ */ jsx14(DataGrid.TextCell, { context })
2335
+ }),
2336
+ ...createDataGridPriceColumns({
2337
+ currencies: store?.supported_currencies?.map(
2338
+ (c) => c.currency_code
2339
+ ) || [],
2340
+ pricePreferences,
2341
+ getFieldName: (context, value) => {
2342
+ const rowData = context.row.original;
2343
+ return `variants.${rowData.originalIndex}.prices.${value}`;
2344
+ },
2345
+ t
2346
+ })
2347
+ ],
2348
+ [
2349
+ variantAttributes,
2350
+ t,
2351
+ store,
2352
+ regions,
2353
+ pricePreferences,
2354
+ stockLocations,
2355
+ onOpenMediaModal,
2356
+ allSelected,
2357
+ someSelected,
2358
+ handleSelectAll,
2359
+ hasProductMedia,
2360
+ productMedia
2361
+ ]
2362
+ );
2363
+ };
2364
+
2365
+ // src/pages/products/create/product-create-form/product-create-form.tsx
2366
+ import { jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
2367
+ var SAVE_DRAFT_BUTTON = "save-draft-button";
2368
+ var SEC_CAT_PRODUCT_KEY = "sec_cat_product_key";
2369
+ var TAB_ORDER = [
2370
+ "details" /* DETAILS */,
2371
+ "organize" /* ORGANIZE */,
2372
+ "attributes" /* ATTRIBUTES */,
2373
+ "variants" /* VARIANTS */,
2374
+ "inventory" /* INVENTORY */
2375
+ ];
2376
+ var isMovingForward = (currentTab, newTab) => {
2377
+ const currentIndex = TAB_ORDER.indexOf(currentTab);
2378
+ const newIndex = TAB_ORDER.indexOf(newTab);
2379
+ return newIndex > currentIndex;
2380
+ };
2381
+ var ProductCreateForm = ({
2382
+ defaultChannel,
2383
+ store,
2384
+ onOpenMediaModal,
2385
+ onSaveVariantMediaRef
2386
+ }) => {
2387
+ const [tab, setTab] = useState6("details" /* DETAILS */);
2388
+ const [maxReachedTab, setMaxReachedTab] = useState6("details" /* DETAILS */);
2389
+ const [tabState, setTabState] = useState6({
2390
+ ["details" /* DETAILS */]: "in-progress",
2391
+ ["organize" /* ORGANIZE */]: "not-started",
2392
+ ["attributes" /* ATTRIBUTES */]: "not-started",
2393
+ ["variants" /* VARIANTS */]: "not-started",
2394
+ ["inventory" /* INVENTORY */]: "not-started"
2395
+ });
2396
+ const { t } = useTranslation12();
2397
+ const { handleSuccess } = useRouteModal();
2398
+ const { regions } = useRegions({ limit: 9999 });
2399
+ const { price_preferences: pricePreferences } = usePricePreferences({
2400
+ limit: 9999
2401
+ });
2402
+ const { attributes: allAttributes } = useAttributes({
2403
+ fields: "id,name,handle,description,ui_component,is_required,product_categories.*,possible_values.*"
2404
+ });
2405
+ const { stock_locations = [] } = useStockLocations({
2406
+ limit: 9999,
2407
+ fields: "id,name"
2408
+ });
2409
+ const dynamicAttributeSchema = useMemo4(() => {
2410
+ const attributeFields = {};
2411
+ allAttributes?.forEach((attr) => {
2412
+ switch (attr.ui_component) {
2413
+ case "multivalue":
2414
+ attributeFields[attr.handle] = z2.array(z2.string()).optional();
2415
+ attributeFields[`${attr.handle}UseForVariants`] = z2.boolean().optional();
2416
+ break;
2417
+ case "select":
2418
+ case "text":
2419
+ case "text_area":
2420
+ attributeFields[attr.handle] = z2.string().optional();
2421
+ break;
2422
+ case "unit":
2423
+ attributeFields[attr.handle] = z2.union([z2.string(), z2.number()]).optional();
2424
+ break;
2425
+ case "toggle":
2426
+ attributeFields[attr.handle] = z2.string().optional();
2427
+ break;
2428
+ }
2429
+ });
2430
+ return attributeFields;
2431
+ }, [allAttributes]);
2432
+ const extendedSchema = useMemo4(() => {
2433
+ const baseSchema = ProductCreateSchema.innerType();
2434
+ const extendedBaseSchema = baseSchema.extend({
2435
+ ...dynamicAttributeSchema
2436
+ });
2437
+ return extendedBaseSchema.superRefine((data, ctx) => {
2438
+ if (data.variants.every((v) => !v.should_create)) {
2439
+ return ctx.addIssue({
2440
+ code: z2.ZodIssueCode.custom,
2441
+ path: ["variants"],
2442
+ message: "invalid_length"
2443
+ });
2444
+ }
2445
+ const skus = /* @__PURE__ */ new Set();
2446
+ data.variants.forEach((v, index) => {
2447
+ if (v.sku) {
2448
+ if (skus.has(v.sku)) {
2449
+ ctx.addIssue({
2450
+ code: z2.ZodIssueCode.custom,
2451
+ path: [`variants.${index}.sku`],
2452
+ message: "SKU must be unique"
2453
+ });
2454
+ }
2455
+ skus.add(v.sku);
2456
+ }
2457
+ });
2458
+ });
2459
+ }, [dynamicAttributeSchema]);
2460
+ const dynamicDefaultValues = useMemo4(() => {
2461
+ const defaults = {};
2462
+ allAttributes?.forEach((attr) => {
2463
+ switch (attr.ui_component) {
2464
+ case "multivalue":
2465
+ defaults[attr.handle] = [];
2466
+ defaults[`${attr.handle}UseForVariants`] = false;
2467
+ break;
2468
+ case "select":
2469
+ case "text":
2470
+ case "unit":
2471
+ case "text_area":
2472
+ case "toggle":
2473
+ defaults[attr.handle] = void 0;
2474
+ break;
2475
+ }
2476
+ });
2477
+ return defaults;
2478
+ }, [allAttributes]);
2479
+ const form = useForm({
2480
+ defaultValues: {
2481
+ ...PRODUCT_CREATE_FORM_DEFAULTS,
2482
+ ...dynamicDefaultValues,
2483
+ sales_channels: defaultChannel ? [{ id: defaultChannel.id, name: defaultChannel.name }] : []
2484
+ },
2485
+ resolver: zodResolver(extendedSchema),
2486
+ mode: "onBlur"
2487
+ });
2488
+ const { mutateAsync, isPending } = useCreateProduct();
2489
+ const attributesFormRef = useRef3(null);
2490
+ const watchedVariants = useWatch3({
2491
+ control: form.control,
2492
+ name: "variants"
2493
+ });
2494
+ const watchedMedia = useWatch3({
2495
+ control: form.control,
2496
+ name: "media"
2497
+ });
2498
+ const showInventoryTab = useMemo4(
2499
+ () => watchedVariants.some(
2500
+ (v) => v.manage_inventory && v.inventory_kit
2501
+ ),
2502
+ [watchedVariants]
2503
+ );
2504
+ const handleSaveVariantMedia = useCallback2(
2505
+ (variantIndex, media) => {
2506
+ const currentVariants = form.getValues("variants") || [];
2507
+ if (currentVariants[variantIndex]) {
2508
+ const updatedVariants = [...currentVariants];
2509
+ updatedVariants[variantIndex] = {
2510
+ ...updatedVariants[variantIndex],
2511
+ media
2512
+ };
2513
+ form.setValue("variants", updatedVariants, {
2514
+ shouldDirty: true
2515
+ });
2516
+ }
2517
+ },
2518
+ [form]
2519
+ );
2520
+ useEffect5(() => {
2521
+ if (tab === "variants" /* VARIANTS */) {
2522
+ const currentOptions = form.getValues("options");
2523
+ const currentVariants = form.getValues("variants");
2524
+ if (currentOptions.length === 0 && currentVariants.length === 0) {
2525
+ form.setValue(
2526
+ "variants",
2527
+ decorateVariantsWithDefaultValues([
2528
+ {
2529
+ title: "Default variant",
2530
+ should_create: true,
2531
+ variant_rank: 0,
2532
+ options: {},
2533
+ is_default: true
2534
+ }
2535
+ ])
2536
+ );
2537
+ }
2538
+ }
2539
+ }, [tab]);
2540
+ useEffect5(() => {
2541
+ if (onSaveVariantMediaRef) {
2542
+ onSaveVariantMediaRef.current = handleSaveVariantMedia;
2543
+ }
2544
+ }, [handleSaveVariantMedia, onSaveVariantMediaRef]);
2545
+ const handleSubmit = form.handleSubmit(async (values, e) => {
2546
+ let isDraftSubmission = false;
2547
+ if (e?.nativeEvent instanceof SubmitEvent) {
2548
+ const submitter = e?.nativeEvent?.submitter;
2549
+ isDraftSubmission = submitter.dataset.name === SAVE_DRAFT_BUTTON;
2550
+ }
2551
+ const media = values.media || [];
2552
+ const { secondary_categories, ...rest } = values;
2553
+ const secCatProductKey = Array.isArray(secondary_categories) && secondary_categories.length > 0 ? `sec-cat-${Date.now()}-${Math.random().toString(36).slice(2, 10)}` : void 0;
2554
+ const adminAttributes = [];
2555
+ const vendorAttributes = [];
2556
+ const allFieldNames = Object.keys(values);
2557
+ let dynamicAttributeFields = [];
2558
+ if (allAttributes && allAttributes.length > 0) {
2559
+ dynamicAttributeFields = allAttributes.map(
2560
+ (attr) => attr.handle || attr.id
2561
+ );
2562
+ }
2563
+ const vendorOptions = rest.options?.filter(
2564
+ (opt) => opt.metadata?.author === "vendor" && opt.title && opt.values?.length > 0
2565
+ ) || [];
2566
+ const vendorOptionsForVariants = vendorOptions.filter(
2567
+ (opt) => opt.useForVariants === true
2568
+ );
2569
+ const adminOptionsForVariants = (rest.options || []).filter(
2570
+ (opt) => opt.useForVariants === true && opt.metadata?.author === "admin" && opt.attributeId && opt.title && opt.values?.length > 0
2571
+ );
2572
+ const requiredAttributeOptions = [];
2573
+ allAttributes?.forEach((attr) => {
2574
+ if (!attr.is_required) return;
2575
+ const fieldHandle = attr.handle || attr.id;
2576
+ const value = form.getValues(fieldHandle);
2577
+ if (value === void 0 || value === null || value === "")
2578
+ return;
2579
+ if (attr.ui_component === "multivalue" && Array.isArray(value) && value.length > 0) {
2580
+ const useForVariants = form.getValues(
2581
+ `${fieldHandle}UseForVariants`
2582
+ );
2583
+ const selectedValues = value.map((valueId) => {
2584
+ const possibleValue = attr.possible_values?.find(
2585
+ (pv) => pv.id === valueId
2586
+ );
2587
+ return possibleValue ? possibleValue.value : null;
2588
+ }).filter((item) => item !== null);
2589
+ if (selectedValues.length > 0 && useForVariants === true) {
2590
+ requiredAttributeOptions.push({
2591
+ title: attr.name,
2592
+ values: selectedValues,
2593
+ metadata: { author: "admin" },
2594
+ useForVariants: true
2595
+ });
2596
+ }
2597
+ }
2598
+ });
2599
+ const allOptions = [
2600
+ ...vendorOptionsForVariants,
2601
+ ...requiredAttributeOptions,
2602
+ ...adminOptionsForVariants
2603
+ ];
2604
+ dynamicAttributeFields.forEach((fieldName) => {
2605
+ const value = form.getValues(fieldName);
2606
+ if (value === void 0 || value === null || value === "")
2607
+ return;
2608
+ const attribute = allAttributes?.find(
2609
+ (attr) => (attr.handle || attr.id) === fieldName
2610
+ );
2611
+ if (!attribute) return;
2612
+ if (Array.isArray(value) && value.length > 0) {
2613
+ const attrFieldHandle = attribute.handle || attribute.id;
2614
+ const useForVariants = form.getValues(
2615
+ `${attrFieldHandle}UseForVariants`
2616
+ );
2617
+ const vals = value.map((valueId) => {
2618
+ const possibleValue = attribute.possible_values?.find(
2619
+ (pv) => pv.id === valueId
2620
+ );
2621
+ return possibleValue ? possibleValue.value : valueId;
2622
+ }).filter(
2623
+ (item) => item !== null && item !== void 0
2624
+ );
2625
+ if (vals.length > 0) {
2626
+ adminAttributes.push({
2627
+ attribute_id: attribute.id,
2628
+ values: vals.map((item) => String(item)),
2629
+ use_for_variations: useForVariants === true
2630
+ });
2631
+ }
2632
+ } else if (!Array.isArray(value)) {
2633
+ let actualValue = value;
2634
+ if (attribute.possible_values && typeof value === "string") {
2635
+ const possibleValue = attribute.possible_values.find(
2636
+ (pv) => pv.id === value
2637
+ );
2638
+ if (possibleValue) {
2639
+ actualValue = possibleValue.value;
2640
+ }
2641
+ }
2642
+ adminAttributes.push({
2643
+ attribute_id: attribute.id,
2644
+ values: [String(actualValue)],
2645
+ use_for_variations: false
2646
+ });
2647
+ }
2648
+ });
2649
+ vendorOptions.forEach((option) => {
2650
+ vendorAttributes.push({
2651
+ name: option.title,
2652
+ values: option.values.map((value) => String(value)),
2653
+ use_for_variations: option.useForVariants === true,
2654
+ ui_component: "multivalue"
2655
+ });
2656
+ });
2657
+ const allFormOptions = rest.options || [];
2658
+ allFormOptions.filter(
2659
+ (opt) => opt.useForVariants === false && opt.metadata?.author === "admin" && opt.attributeId && opt.title && opt.values?.length > 0
2660
+ ).forEach((option) => {
2661
+ adminAttributes.push({
2662
+ attribute_id: option.attributeId,
2663
+ values: option.values.map(
2664
+ (value) => String(value)
2665
+ ),
2666
+ use_for_variations: false
2667
+ });
2668
+ });
2669
+ adminOptionsForVariants.forEach((option) => {
2670
+ adminAttributes.push({
2671
+ attribute_id: option.attributeId,
2672
+ values: option.values.map((value) => String(value)),
2673
+ use_for_variations: true
2674
+ });
2675
+ });
2676
+ const { ...payload } = rest;
2677
+ dynamicAttributeFields.forEach((fieldName) => {
2678
+ delete payload[fieldName];
2679
+ });
2680
+ const useForVariantsFields = allFieldNames.filter(
2681
+ (fieldName) => fieldName.endsWith("UseForVariants")
2682
+ );
2683
+ useForVariantsFields.forEach((fieldName) => {
2684
+ delete payload[fieldName];
2685
+ });
2686
+ const finalPayload = { ...payload, media: void 0 };
2687
+ let uploadedMedia = [];
2688
+ try {
2689
+ if (media.length) {
2690
+ const thumbnailReq = media.filter(
2691
+ (m) => m.isThumbnail && m.file
2692
+ );
2693
+ const otherMediaReq = media.filter(
2694
+ (m) => !m.isThumbnail && m.file
2695
+ );
2696
+ const fileReqs = [];
2697
+ if (thumbnailReq?.length) {
2698
+ fileReqs.push(
2699
+ uploadFilesQuery(thumbnailReq).then(
2700
+ (r) => (Array.isArray(r?.files) ? r.files : []).map(
2701
+ (f) => ({
2702
+ ...f,
2703
+ isThumbnail: true
2704
+ })
2705
+ )
2706
+ )
2707
+ );
2708
+ }
2709
+ if (otherMediaReq?.length) {
2710
+ fileReqs.push(
2711
+ uploadFilesQuery(otherMediaReq).then(
2712
+ (r) => (Array.isArray(r?.files) ? r.files : []).map(
2713
+ (f) => ({
2714
+ ...f,
2715
+ isThumbnail: false
2716
+ })
2717
+ )
2718
+ )
2719
+ );
2720
+ }
2721
+ uploadedMedia = (await Promise.all(fileReqs)).flat();
2722
+ }
2723
+ } catch (error) {
2724
+ if (error instanceof Error) {
2725
+ toast.error(error.message);
2726
+ }
2727
+ }
2728
+ const blobToUploadedUrl = /* @__PURE__ */ new Map();
2729
+ const allOriginalMedia = media;
2730
+ if (uploadedMedia.length > 0) {
2731
+ const thumbnailItems = allOriginalMedia.filter(
2732
+ (m) => m.isThumbnail && m.file
2733
+ );
2734
+ const otherItems = allOriginalMedia.filter(
2735
+ (m) => !m.isThumbnail && m.file
2736
+ );
2737
+ let thumbIdx = 0;
2738
+ let otherIdx = 0;
2739
+ for (const uploaded of uploadedMedia) {
2740
+ if (uploaded.isThumbnail && thumbIdx < thumbnailItems.length) {
2741
+ const blobUrl = thumbnailItems[thumbIdx].url;
2742
+ if (blobUrl) {
2743
+ blobToUploadedUrl.set(blobUrl, uploaded.url);
2744
+ }
2745
+ thumbIdx++;
2746
+ }
2747
+ if (!uploaded.isThumbnail && otherIdx < otherItems.length) {
2748
+ const blobUrl = otherItems[otherIdx].url;
2749
+ if (blobUrl) {
2750
+ blobToUploadedUrl.set(blobUrl, uploaded.url);
2751
+ }
2752
+ otherIdx++;
2753
+ }
2754
+ }
2755
+ }
2756
+ const variantsToCreate = finalPayload.variants.filter(
2757
+ (variant) => variant.should_create === true
2758
+ );
2759
+ const variantImageKeyByIndex = /* @__PURE__ */ new Map();
2760
+ const variantsImages = [];
2761
+ for (let i = 0; i < variantsToCreate.length; i++) {
2762
+ const variant = variantsToCreate[i];
2763
+ const variantMedia = variant.media || [];
2764
+ if (!variantMedia.length) continue;
2765
+ const resolvedUrls = variantMedia.map(
2766
+ (m) => m.url ? blobToUploadedUrl.get(m.url) : void 0
2767
+ ).filter((url) => !!url);
2768
+ if (resolvedUrls.length === 0) continue;
2769
+ const variantThumb = variantMedia.find(
2770
+ (m) => m.isThumbnail
2771
+ );
2772
+ const resolvedThumbUrl = variantThumb?.url ? blobToUploadedUrl.get(variantThumb.url) : void 0;
2773
+ const thumbnailUrl = resolvedThumbUrl || resolvedUrls[0];
2774
+ const variantImageKey = `variant-${i}-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
2775
+ variantImageKeyByIndex.set(i, variantImageKey);
2776
+ variantsImages.push({
2777
+ variant_image_key: variantImageKey,
2778
+ image_urls: resolvedUrls,
2779
+ thumbnail_url: thumbnailUrl
2780
+ });
2781
+ }
2782
+ const mappedVariants = variantsToCreate.map(
2783
+ (variant, index) => {
2784
+ const mappedOptions = {};
2785
+ allOptions.forEach((option) => {
2786
+ if (variant.options && variant.options[option.title]) {
2787
+ mappedOptions[option.title] = variant.options[option.title];
2788
+ } else {
2789
+ const variantTitle = variant.title || "";
2790
+ const optionValues = option.values || [];
2791
+ const matchingValue = optionValues.find(
2792
+ (value) => variantTitle.includes(value)
2793
+ );
2794
+ if (matchingValue) {
2795
+ mappedOptions[option.title] = matchingValue;
2796
+ } else if (optionValues.length > 0) {
2797
+ mappedOptions[option.title] = optionValues[0];
2798
+ }
2799
+ }
2800
+ });
2801
+ const variantImageKey = variantImageKeyByIndex.get(index);
2802
+ const {
2803
+ media: _media,
2804
+ stock_locations: _sl,
2805
+ ...variantWithoutMedia
2806
+ } = variant;
2807
+ return {
2808
+ ...variantWithoutMedia,
2809
+ options: Object.keys(mappedOptions).length > 0 ? mappedOptions : { "Default option": "Default option value" },
2810
+ ...variantImageKey && {
2811
+ metadata: { variant_image_key: variantImageKey }
2812
+ }
2813
+ };
2814
+ }
2815
+ );
2816
+ const payloadToSend = {
2817
+ ...finalPayload,
2818
+ status: isDraftSubmission ? "draft" : "proposed",
2819
+ images: uploadedMedia,
2820
+ weight: parseInt(finalPayload.weight || "") || void 0,
2821
+ length: parseInt(finalPayload.length || "") || void 0,
2822
+ height: parseInt(finalPayload.height || "") || void 0,
2823
+ width: parseInt(finalPayload.width || "") || void 0,
2824
+ type_id: finalPayload.type_id || void 0,
2825
+ tags: finalPayload.tags?.map((tag) => ({
2826
+ id: tag
2827
+ })) || [],
2828
+ collection_id: finalPayload.collection_id || void 0,
2829
+ shipping_profile_id: void 0,
2830
+ enable_variants: void 0,
2831
+ options: allOptions.length > 0 ? allOptions : [
2832
+ {
2833
+ title: "Default option",
2834
+ values: ["Default option value"]
2835
+ }
2836
+ ],
2837
+ metadata: (() => {
2838
+ const existing = finalPayload?.metadata ?? void 0;
2839
+ if (!secCatProductKey) return existing;
2840
+ return {
2841
+ ...existing ?? {},
2842
+ [SEC_CAT_PRODUCT_KEY]: secCatProductKey
2843
+ };
2844
+ })(),
2845
+ additional_data: (() => {
2846
+ const additionalData = {};
2847
+ if (adminAttributes.length > 0) {
2848
+ additionalData.admin_attributes = adminAttributes;
2849
+ }
2850
+ if (vendorAttributes.length > 0) {
2851
+ additionalData.vendor_attributes = vendorAttributes;
2852
+ }
2853
+ if (Array.isArray(secondary_categories) && secondary_categories.length > 0 && secCatProductKey) {
2854
+ additionalData.secondary_categories = [
2855
+ {
2856
+ sec_cat_product_key: secCatProductKey,
2857
+ category_ids: secondary_categories
2858
+ }
2859
+ ];
2860
+ }
2861
+ if (variantsImages.length > 0) {
2862
+ additionalData.variants_images = variantsImages;
2863
+ }
2864
+ return Object.keys(additionalData).length > 0 ? additionalData : void 0;
2865
+ })(),
2866
+ categories: finalPayload.categories.map((cat) => ({
2867
+ id: cat
2868
+ })),
2869
+ variants: mappedVariants.map((variant) => {
2870
+ const {
2871
+ media: _m,
2872
+ stock_locations: _sl,
2873
+ ...variantWithoutMedia
2874
+ } = variant;
2875
+ return {
2876
+ ...variantWithoutMedia,
2877
+ sku: variant.sku === "" ? void 0 : variant.sku,
2878
+ manage_inventory: true,
2879
+ allow_backorder: false,
2880
+ should_create: void 0,
2881
+ is_default: void 0,
2882
+ inventory_kit: void 0,
2883
+ inventory: void 0,
2884
+ prices: Object.keys(variant.prices || {}).map(
2885
+ (key) => ({
2886
+ currency_code: key,
2887
+ amount: parseFloat(variant.prices?.[key])
2888
+ })
2889
+ )
2890
+ };
2891
+ })
2892
+ };
2893
+ const productData = await mutateAsync(payloadToSend, {
2894
+ onError: (error) => {
2895
+ toast.error(error.message);
2896
+ }
2897
+ });
2898
+ toast.success(t("products.create.successToast", { title: productData.product.title }));
2899
+ handleSuccess(`../${productData.product.id}`);
2900
+ });
2901
+ const onNext = async (currentTab) => {
2902
+ let fieldsToValidate = [];
2903
+ let shouldProceed = true;
2904
+ switch (currentTab) {
2905
+ case "details" /* DETAILS */:
2906
+ fieldsToValidate = ["title", "handle"];
2907
+ break;
2908
+ case "organize" /* ORGANIZE */:
2909
+ fieldsToValidate = ["categories"];
2910
+ break;
2911
+ case "attributes" /* ATTRIBUTES */:
2912
+ if (attributesFormRef.current) {
2913
+ shouldProceed = await attributesFormRef.current.validateAttributes();
2914
+ }
2915
+ break;
2916
+ case "variants" /* VARIANTS */:
2917
+ fieldsToValidate = ["variants", "options"];
2918
+ break;
2919
+ case "inventory" /* INVENTORY */:
2920
+ break;
2921
+ }
2922
+ if (fieldsToValidate.length > 0) {
2923
+ const valid = await form.trigger(fieldsToValidate);
2924
+ if (!valid) return;
2925
+ }
2926
+ if (!shouldProceed) return;
2927
+ let nextTab;
2928
+ if (currentTab === "details" /* DETAILS */) {
2929
+ nextTab = "organize" /* ORGANIZE */;
2930
+ } else if (currentTab === "organize" /* ORGANIZE */) {
2931
+ nextTab = "attributes" /* ATTRIBUTES */;
2932
+ } else if (currentTab === "attributes" /* ATTRIBUTES */) {
2933
+ nextTab = "variants" /* VARIANTS */;
2934
+ } else if (currentTab === "variants" /* VARIANTS */) {
2935
+ nextTab = "inventory" /* INVENTORY */;
2936
+ } else {
2937
+ return;
2938
+ }
2939
+ const currentTabIndex = TAB_ORDER.indexOf(currentTab);
2940
+ const currentMaxIndex = TAB_ORDER.indexOf(maxReachedTab);
2941
+ if (currentTabIndex >= currentMaxIndex) {
2942
+ setMaxReachedTab(TAB_ORDER[currentMaxIndex + 1]);
2943
+ }
2944
+ setTab(nextTab);
2945
+ };
2946
+ useEffect5(() => {
2947
+ const currentIndex = TAB_ORDER.indexOf(tab);
2948
+ const maxReachedIndex = TAB_ORDER.indexOf(maxReachedTab);
2949
+ const currentState = {
2950
+ ["details" /* DETAILS */]: "not-started",
2951
+ ["organize" /* ORGANIZE */]: "not-started",
2952
+ ["attributes" /* ATTRIBUTES */]: "not-started",
2953
+ ["variants" /* VARIANTS */]: "not-started",
2954
+ ["inventory" /* INVENTORY */]: "not-started"
2955
+ };
2956
+ TAB_ORDER.forEach((tabItem, index) => {
2957
+ if (index < currentIndex && index <= maxReachedIndex) {
2958
+ currentState[tabItem] = "completed";
2959
+ } else if (index === currentIndex) {
2960
+ currentState[tabItem] = "in-progress";
2961
+ } else if (index > currentIndex && index <= maxReachedIndex) {
2962
+ currentState[tabItem] = "completed";
2963
+ } else {
2964
+ currentState[tabItem] = "not-started";
2965
+ }
2966
+ });
2967
+ setTabState(currentState);
2968
+ }, [tab, maxReachedTab]);
2969
+ return /* @__PURE__ */ jsx15(TabbedFormContext.Provider, { value: form, children: /* @__PURE__ */ jsx15(RouteFocusModal.Form, { form, children: /* @__PURE__ */ jsxs13(
2970
+ KeyboundForm,
2971
+ {
2972
+ onKeyDown: (e) => {
2973
+ if (e.key === "Enter") {
2974
+ if (e.target instanceof HTMLTextAreaElement && !(e.metaKey || e.ctrlKey)) {
2975
+ return;
2976
+ }
2977
+ e.preventDefault();
2978
+ if (e.metaKey || e.ctrlKey) {
2979
+ if (tab !== "variants" /* VARIANTS */) {
2980
+ e.stopPropagation();
2981
+ onNext(tab);
2982
+ return;
2983
+ }
2984
+ handleSubmit();
2985
+ }
2986
+ }
2987
+ },
2988
+ onSubmit: handleSubmit,
2989
+ className: "flex h-full flex-col",
2990
+ children: [
2991
+ /* @__PURE__ */ jsxs13(
2992
+ ProgressTabs,
2993
+ {
2994
+ value: tab,
2995
+ onValueChange: async (newTab) => {
2996
+ const newTabValue = newTab;
2997
+ const currentIndex = TAB_ORDER.indexOf(tab);
2998
+ const newIndex = TAB_ORDER.indexOf(newTabValue);
2999
+ const maxReachedIndex = TAB_ORDER.indexOf(maxReachedTab);
3000
+ const movingForward = isMovingForward(
3001
+ tab,
3002
+ newTabValue
3003
+ );
3004
+ if (movingForward) {
3005
+ if (newIndex > maxReachedIndex + 1) return;
3006
+ let fieldsToValidate = [];
3007
+ switch (tab) {
3008
+ case "details" /* DETAILS */:
3009
+ fieldsToValidate = ["title", "handle"];
3010
+ break;
3011
+ case "organize" /* ORGANIZE */:
3012
+ fieldsToValidate = ["categories"];
3013
+ break;
3014
+ case "attributes" /* ATTRIBUTES */:
3015
+ fieldsToValidate = [];
3016
+ break;
3017
+ case "variants" /* VARIANTS */:
3018
+ fieldsToValidate = ["variants", "options"];
3019
+ break;
3020
+ case "inventory" /* INVENTORY */:
3021
+ break;
3022
+ }
3023
+ if (fieldsToValidate.length > 0) {
3024
+ const valid = await form.trigger(fieldsToValidate);
3025
+ if (!valid) return;
3026
+ } else if (tab === "attributes" /* ATTRIBUTES */) {
3027
+ if (attributesFormRef.current) {
3028
+ const valid = await attributesFormRef.current.validateAttributes();
3029
+ if (!valid) return;
3030
+ }
3031
+ }
3032
+ if (currentIndex >= maxReachedIndex) {
3033
+ setMaxReachedTab(
3034
+ TAB_ORDER[currentIndex + 1]
3035
+ );
3036
+ }
3037
+ }
3038
+ setTab(newTabValue);
3039
+ },
3040
+ className: "flex h-full flex-col overflow-hidden",
3041
+ children: [
3042
+ /* @__PURE__ */ jsx15(RouteFocusModal.Header, { children: /* @__PURE__ */ jsx15("div", { className: "-my-2 w-full border-l", children: /* @__PURE__ */ jsxs13(ProgressTabs.List, { className: "justify-start-start flex w-full items-center", children: [
3043
+ /* @__PURE__ */ jsx15(
3044
+ ProgressTabs.Trigger,
3045
+ {
3046
+ status: tabState["details" /* DETAILS */],
3047
+ value: "details" /* DETAILS */,
3048
+ className: "max-w-[200px] truncate",
3049
+ children: t("products.create.tabs.details")
3050
+ }
3051
+ ),
3052
+ /* @__PURE__ */ jsx15(
3053
+ ProgressTabs.Trigger,
3054
+ {
3055
+ status: tabState["organize" /* ORGANIZE */],
3056
+ value: "organize" /* ORGANIZE */,
3057
+ className: "max-w-[200px] truncate",
3058
+ children: t("products.create.tabs.organize")
3059
+ }
3060
+ ),
3061
+ /* @__PURE__ */ jsx15(
3062
+ ProgressTabs.Trigger,
3063
+ {
3064
+ status: tabState["attributes" /* ATTRIBUTES */],
3065
+ value: "attributes" /* ATTRIBUTES */,
3066
+ className: "max-w-[200px] truncate",
3067
+ children: t("products.create.tabs.attributes")
3068
+ }
3069
+ ),
3070
+ /* @__PURE__ */ jsx15(
3071
+ ProgressTabs.Trigger,
3072
+ {
3073
+ status: tabState["variants" /* VARIANTS */],
3074
+ value: "variants" /* VARIANTS */,
3075
+ className: "max-w-[200px] truncate",
3076
+ children: t("products.create.tabs.variants")
3077
+ }
3078
+ ),
3079
+ showInventoryTab && /* @__PURE__ */ jsx15(
3080
+ ProgressTabs.Trigger,
3081
+ {
3082
+ status: tabState["inventory" /* INVENTORY */],
3083
+ value: "inventory" /* INVENTORY */,
3084
+ className: "max-w-[200px] truncate",
3085
+ children: t("products.create.tabs.inventory")
3086
+ }
3087
+ )
3088
+ ] }) }) }),
3089
+ /* @__PURE__ */ jsxs13(RouteFocusModal.Body, { className: "size-full overflow-hidden", children: [
3090
+ /* @__PURE__ */ jsx15(
3091
+ ProgressTabs.Content,
3092
+ {
3093
+ className: "size-full overflow-y-auto",
3094
+ value: "details" /* DETAILS */,
3095
+ children: /* @__PURE__ */ jsx15(ProductCreateDetailsForm, { form })
3096
+ }
3097
+ ),
3098
+ /* @__PURE__ */ jsx15(
3099
+ ProgressTabs.Content,
3100
+ {
3101
+ className: "size-full overflow-y-auto",
3102
+ value: "organize" /* ORGANIZE */,
3103
+ children: /* @__PURE__ */ jsx15(
3104
+ ProductCreateOrganizeForm,
3105
+ {
3106
+ form
3107
+ }
3108
+ )
3109
+ }
3110
+ ),
3111
+ /* @__PURE__ */ jsx15(
3112
+ ProgressTabs.Content,
3113
+ {
3114
+ className: "size-full overflow-y-auto",
3115
+ value: "attributes" /* ATTRIBUTES */,
3116
+ children: /* @__PURE__ */ jsx15(
3117
+ ProductCreateAttributesForm,
3118
+ {
3119
+ form,
3120
+ ref: attributesFormRef
3121
+ }
3122
+ )
3123
+ }
3124
+ ),
3125
+ /* @__PURE__ */ jsx15(
3126
+ ProgressTabs.Content,
3127
+ {
3128
+ className: "size-full overflow-y-auto",
3129
+ value: "variants" /* VARIANTS */,
3130
+ children: /* @__PURE__ */ jsx15(
3131
+ ProductCreateVariantsForm,
3132
+ {
3133
+ form,
3134
+ store,
3135
+ regions,
3136
+ pricePreferences,
3137
+ onOpenMediaModal,
3138
+ productMedia: watchedMedia || []
3139
+ }
3140
+ )
3141
+ }
3142
+ ),
3143
+ showInventoryTab && /* @__PURE__ */ jsx15(
3144
+ ProgressTabs.Content,
3145
+ {
3146
+ className: "size-full overflow-y-auto",
3147
+ value: "inventory" /* INVENTORY */,
3148
+ children: /* @__PURE__ */ jsx15(
3149
+ ProductCreateInventoryKitForm,
3150
+ {
3151
+ form
3152
+ }
3153
+ )
3154
+ }
3155
+ )
3156
+ ] })
3157
+ ]
3158
+ }
3159
+ ),
3160
+ /* @__PURE__ */ jsx15(RouteFocusModal.Footer, { children: /* @__PURE__ */ jsxs13("div", { className: "flex items-center justify-end gap-x-2", children: [
3161
+ /* @__PURE__ */ jsx15(RouteFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsx15(Button4, { variant: "secondary", size: "small", children: t("actions.cancel") }) }),
3162
+ /* @__PURE__ */ jsx15(
3163
+ Button4,
3164
+ {
3165
+ "data-name": SAVE_DRAFT_BUTTON,
3166
+ size: "small",
3167
+ type: "submit",
3168
+ onClick: () => {
3169
+ if (form.getValues("categories").length === 0 && form.getValues("title")) {
3170
+ onNext("details" /* DETAILS */);
3171
+ return;
3172
+ }
3173
+ handleSubmit();
3174
+ },
3175
+ isLoading: isPending,
3176
+ variant: "secondary",
3177
+ className: "whitespace-nowrap",
3178
+ children: t("actions.saveAsDraft")
3179
+ }
3180
+ ),
3181
+ /* @__PURE__ */ jsx15(
3182
+ PrimaryButton,
3183
+ {
3184
+ tab,
3185
+ next: onNext,
3186
+ isLoading: isPending,
3187
+ showInventoryTab
3188
+ }
3189
+ )
3190
+ ] }) })
3191
+ ]
3192
+ }
3193
+ ) }) });
3194
+ };
3195
+ var PrimaryButton = ({
3196
+ tab,
3197
+ next,
3198
+ isLoading,
3199
+ showInventoryTab
3200
+ }) => {
3201
+ const { t } = useTranslation12();
3202
+ if (tab === "variants" /* VARIANTS */ && !showInventoryTab || tab === "inventory" /* INVENTORY */ && showInventoryTab) {
3203
+ return /* @__PURE__ */ jsx15(
3204
+ Button4,
3205
+ {
3206
+ "data-name": "publish-button",
3207
+ type: "submit",
3208
+ variant: "primary",
3209
+ size: "small",
3210
+ isLoading,
3211
+ children: t("actions.publish")
3212
+ },
3213
+ "submit-button"
3214
+ );
3215
+ }
3216
+ return /* @__PURE__ */ jsx15(
3217
+ Button4,
3218
+ {
3219
+ type: "button",
3220
+ variant: "primary",
3221
+ size: "small",
3222
+ onClick: () => next(tab),
3223
+ children: t("actions.continue")
3224
+ },
3225
+ "next-button"
3226
+ );
3227
+ };
3228
+
3229
+ // src/pages/products/create/variant-media-view/variant-media-view.tsx
3230
+ import { useRef as useRef4, useState as useState9 } from "react";
3231
+ import { Button as Button6 } from "@medusajs/ui";
3232
+ import { useTranslation as useTranslation15 } from "react-i18next";
3233
+
3234
+ // src/pages/products/create/edit-variant-media-form/edit-variant-media-form.tsx
3235
+ import { Fragment as Fragment4, useCallback as useCallback3, useEffect as useEffect6, useMemo as useMemo5, useState as useState7 } from "react";
3236
+ import { ThumbnailBadge as ThumbnailBadge2 } from "@medusajs/icons";
3237
+ import { Checkbox as Checkbox2, clx, CommandBar, Tooltip as Tooltip3 } from "@medusajs/ui";
3238
+ import { useTranslation as useTranslation13 } from "react-i18next";
3239
+ import { jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
3240
+ var EditVariantMediaForm = ({
3241
+ variantIndex,
3242
+ onSaveMedia,
3243
+ onClose,
3244
+ saveRef,
3245
+ initialMedia = [],
3246
+ productMedia = []
3247
+ }) => {
3248
+ const { t } = useTranslation13();
3249
+ const [selectedUrls, setSelectedUrls] = useState7(
3250
+ () => new Set(initialMedia.filter((m) => m.url).map((m) => m.url))
3251
+ );
3252
+ const [thumbnailUrl, setThumbnailUrl] = useState7(
3253
+ () => {
3254
+ const thumb = initialMedia.find((m) => m.isThumbnail);
3255
+ return thumb?.url ?? null;
3256
+ }
3257
+ );
3258
+ const [checkedUrls, setCheckedUrls] = useState7({});
3259
+ const availableMedia = useMemo5(
3260
+ () => productMedia.filter(
3261
+ (m) => !!m.url
3262
+ ),
3263
+ [productMedia]
3264
+ );
3265
+ const selectedImages = useMemo5(
3266
+ () => availableMedia.filter((m) => selectedUrls.has(m.url)),
3267
+ [availableMedia, selectedUrls]
3268
+ );
3269
+ const unselectedImages = useMemo5(
3270
+ () => availableMedia.filter((m) => !selectedUrls.has(m.url)),
3271
+ [availableMedia, selectedUrls]
3272
+ );
3273
+ const handleSelectImage = useCallback3((url) => {
3274
+ setSelectedUrls((prev) => {
3275
+ const next = new Set(prev);
3276
+ next.add(url);
3277
+ return next;
3278
+ });
3279
+ }, []);
3280
+ const handleDeselectImage = useCallback3(
3281
+ (url) => {
3282
+ setSelectedUrls((prev) => {
3283
+ const next = new Set(prev);
3284
+ next.delete(url);
3285
+ return next;
3286
+ });
3287
+ if (thumbnailUrl === url) {
3288
+ setThumbnailUrl(null);
3289
+ }
3290
+ const { [url]: _, ...restChecked } = checkedUrls;
3291
+ setCheckedUrls(restChecked);
3292
+ },
3293
+ [thumbnailUrl, checkedUrls]
3294
+ );
3295
+ const handleCheckedChange = useCallback3(
3296
+ (url, value) => {
3297
+ if (!value) {
3298
+ const { [url]: _, ...rest } = checkedUrls;
3299
+ setCheckedUrls(rest);
3300
+ return;
3301
+ }
3302
+ setCheckedUrls((prev) => ({ ...prev, [url]: true }));
3303
+ },
3304
+ [checkedUrls]
3305
+ );
3306
+ const handlePromoteToThumbnail = useCallback3(() => {
3307
+ const urls = Object.keys(checkedUrls);
3308
+ if (urls.length !== 1) {
3309
+ return;
3310
+ }
3311
+ setThumbnailUrl(urls[0]);
3312
+ setCheckedUrls({});
3313
+ }, [checkedUrls]);
3314
+ const getEffectiveThumbnailUrl = useCallback3(() => {
3315
+ if (selectedUrls.size === 0) {
3316
+ return null;
3317
+ }
3318
+ if (thumbnailUrl && selectedUrls.has(thumbnailUrl)) {
3319
+ return thumbnailUrl;
3320
+ }
3321
+ return [...selectedUrls][0];
3322
+ }, [selectedUrls, thumbnailUrl]);
3323
+ const handleSave = useCallback3(() => {
3324
+ const effectiveThumb = getEffectiveThumbnailUrl();
3325
+ const media = [...selectedUrls].map((url) => ({
3326
+ url,
3327
+ isThumbnail: url === effectiveThumb
3328
+ }));
3329
+ onSaveMedia?.(variantIndex, media);
3330
+ onClose?.();
3331
+ }, [
3332
+ getEffectiveThumbnailUrl,
3333
+ selectedUrls,
3334
+ onSaveMedia,
3335
+ variantIndex,
3336
+ onClose
3337
+ ]);
3338
+ useEffect6(() => {
3339
+ saveRef.current = handleSave;
3340
+ }, [handleSave, saveRef]);
3341
+ const checkedCount = Object.keys(checkedUrls).length;
3342
+ return /* @__PURE__ */ jsxs14("div", { className: "flex size-full flex-col overflow-hidden", children: [
3343
+ /* @__PURE__ */ jsxs14("div", { className: "flex size-full", children: [
3344
+ /* @__PURE__ */ jsx16("div", { className: "flex-1 overflow-auto bg-ui-bg-subtle p-6", children: /* @__PURE__ */ jsx16("div", { className: "flex flex-wrap content-start gap-6", children: selectedImages.map((img) => {
3345
+ const effectiveThumb = getEffectiveThumbnailUrl();
3346
+ const isThumb = img.url === effectiveThumb;
3347
+ return /* @__PURE__ */ jsx16(
3348
+ SelectedImageCard,
3349
+ {
3350
+ image: img,
3351
+ isThumbnail: isThumb,
3352
+ checked: !!checkedUrls[img.url],
3353
+ onCheckedChange: (val) => handleCheckedChange(img.url, val)
3354
+ },
3355
+ img.url
3356
+ );
3357
+ }) }) }),
3358
+ /* @__PURE__ */ jsx16("div", { className: "w-px shrink-0 bg-ui-border-base" }),
3359
+ /* @__PURE__ */ jsxs14("div", { className: "flex w-[318px] shrink-0 flex-col", children: [
3360
+ /* @__PURE__ */ jsxs14("div", { className: "p-4", children: [
3361
+ /* @__PURE__ */ jsx16("p", { className: "txt-compact-small-plus text-ui-fg-base", children: t("products.media.selectImages") }),
3362
+ /* @__PURE__ */ jsx16("p", { className: "txt-small mt-1 text-ui-fg-subtle", children: t("products.media.selectImagesHint") })
3363
+ ] }),
3364
+ /* @__PURE__ */ jsx16("div", { className: "h-px bg-ui-border-base" }),
3365
+ /* @__PURE__ */ jsx16("div", { className: "flex-1 overflow-auto p-4", children: /* @__PURE__ */ jsx16("div", { className: "grid grid-cols-2 gap-4", children: unselectedImages.map((img) => /* @__PURE__ */ jsx16(
3366
+ UnselectedImageCard,
3367
+ {
3368
+ image: img,
3369
+ onSelect: () => handleSelectImage(img.url)
3370
+ },
3371
+ img.url
3372
+ )) }) })
3373
+ ] })
3374
+ ] }),
3375
+ /* @__PURE__ */ jsx16(CommandBar, { open: !!checkedCount, children: /* @__PURE__ */ jsxs14(CommandBar.Bar, { children: [
3376
+ /* @__PURE__ */ jsx16(CommandBar.Value, { children: t("general.countSelected", {
3377
+ count: checkedCount
3378
+ }) }),
3379
+ /* @__PURE__ */ jsx16(CommandBar.Seperator, {}),
3380
+ checkedCount === 1 && /* @__PURE__ */ jsxs14(Fragment4, { children: [
3381
+ /* @__PURE__ */ jsx16(
3382
+ CommandBar.Command,
3383
+ {
3384
+ action: handlePromoteToThumbnail,
3385
+ label: t("products.media.makeThumbnail"),
3386
+ shortcut: "t"
3387
+ }
3388
+ ),
3389
+ /* @__PURE__ */ jsx16(CommandBar.Seperator, {})
3390
+ ] }),
3391
+ /* @__PURE__ */ jsx16(
3392
+ CommandBar.Command,
3393
+ {
3394
+ action: () => {
3395
+ Object.keys(checkedUrls).forEach(
3396
+ (url) => handleDeselectImage(url)
3397
+ );
3398
+ setCheckedUrls({});
3399
+ },
3400
+ label: t("actions.remove"),
3401
+ shortcut: "r"
3402
+ }
3403
+ )
3404
+ ] }) })
3405
+ ] });
3406
+ };
3407
+ var SelectedImageCard = ({
3408
+ image,
3409
+ isThumbnail,
3410
+ checked,
3411
+ onCheckedChange
3412
+ }) => {
3413
+ const { t } = useTranslation13();
3414
+ return /* @__PURE__ */ jsxs14(
3415
+ "div",
3416
+ {
3417
+ className: clx(
3418
+ "group relative size-[156px] shrink-0 overflow-hidden rounded-lg",
3419
+ "shadow-elevation-card-rest"
3420
+ ),
3421
+ children: [
3422
+ isThumbnail && /* @__PURE__ */ jsx16("div", { className: "absolute left-2 top-2 z-[1]", children: /* @__PURE__ */ jsx16(
3423
+ Tooltip3,
3424
+ {
3425
+ content: t("products.media.thumbnailTooltip"),
3426
+ children: /* @__PURE__ */ jsx16(ThumbnailBadge2, {})
3427
+ }
3428
+ ) }),
3429
+ /* @__PURE__ */ jsx16(
3430
+ "div",
3431
+ {
3432
+ className: clx(
3433
+ "absolute right-2 top-2 z-[1] opacity-0 transition-opacity",
3434
+ "group-hover:opacity-100",
3435
+ { "opacity-100": checked }
3436
+ ),
3437
+ children: /* @__PURE__ */ jsx16(
3438
+ Checkbox2,
3439
+ {
3440
+ checked,
3441
+ onCheckedChange,
3442
+ "aria-label": t("actions.select")
3443
+ }
3444
+ )
3445
+ }
3446
+ ),
3447
+ /* @__PURE__ */ jsx16(
3448
+ "img",
3449
+ {
3450
+ src: image.url,
3451
+ alt: "",
3452
+ className: "size-full object-cover object-center"
3453
+ }
3454
+ )
3455
+ ]
3456
+ }
3457
+ );
3458
+ };
3459
+ var UnselectedImageCard = ({
3460
+ image,
3461
+ onSelect
3462
+ }) => {
3463
+ const { t } = useTranslation13();
3464
+ return /* @__PURE__ */ jsx16(
3465
+ "button",
3466
+ {
3467
+ type: "button",
3468
+ onClick: onSelect,
3469
+ className: clx(
3470
+ "aspect-square w-full overflow-hidden rounded-lg",
3471
+ "shadow-elevation-card-rest transition-shadow",
3472
+ "hover:shadow-elevation-card-hover",
3473
+ "outline-none focus-visible:shadow-borders-focus"
3474
+ ),
3475
+ "aria-label": t("products.media.selectImages"),
3476
+ children: /* @__PURE__ */ jsx16(
3477
+ "img",
3478
+ {
3479
+ src: image.url,
3480
+ alt: "",
3481
+ className: "size-full object-cover object-center"
3482
+ }
3483
+ )
3484
+ }
3485
+ );
3486
+ };
3487
+
3488
+ // src/pages/products/create/variant-media-view/components/variant-media-gallery/variant-media-gallery.tsx
3489
+ import { useCallback as useCallback4, useEffect as useEffect7, useState as useState8 } from "react";
3490
+ import {
3491
+ ThumbnailBadge as ThumbnailBadge3,
3492
+ TriangleLeftMini,
3493
+ TriangleRightMini
3494
+ } from "@medusajs/icons";
3495
+ import { Button as Button5, clx as clx2, IconButton as IconButton3, Text as Text5, Tooltip as Tooltip4 } from "@medusajs/ui";
3496
+ import { useTranslation as useTranslation14 } from "react-i18next";
3497
+
3498
+ // src/pages/products/create/variant-media-view/variant-media-view-context.tsx
3499
+ import { createContext } from "react";
3500
+ var VariantMediaViewContext = createContext(null);
3501
+
3502
+ // src/pages/products/create/variant-media-view/components/variant-media-gallery/variant-media-gallery.tsx
3503
+ import { Fragment as Fragment5, jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
3504
+ var VariantMediaGallery = ({
3505
+ goToEdit,
3506
+ variantMedia = []
3507
+ }) => {
3508
+ const [curr, setCurr] = useState8(0);
3509
+ const { t } = useTranslation14();
3510
+ const media = (variantMedia || []).map(
3511
+ (m, idx) => ({
3512
+ ...m,
3513
+ id: m.id || `variant-${idx}-${m.url}`
3514
+ })
3515
+ );
3516
+ const next = useCallback4(() => {
3517
+ setCurr((prev2) => (prev2 + 1) % media.length);
3518
+ }, [media.length]);
3519
+ const prev = useCallback4(() => {
3520
+ setCurr((prev2) => (prev2 - 1 + media.length) % media.length);
3521
+ }, [media.length]);
3522
+ const goTo = useCallback4(
3523
+ (index) => {
3524
+ if (index < 0 || index >= media.length) return;
3525
+ setCurr(index);
3526
+ },
3527
+ [media.length]
3528
+ );
3529
+ useEffect7(() => {
3530
+ const handleKeyDown = (e) => {
3531
+ if (e.key === "ArrowRight") next();
3532
+ else if (e.key === "ArrowLeft") prev();
3533
+ };
3534
+ document.addEventListener("keydown", handleKeyDown);
3535
+ return () => document.removeEventListener("keydown", handleKeyDown);
3536
+ }, [next, prev]);
3537
+ const noMedia = !media.length;
3538
+ return /* @__PURE__ */ jsx17(VariantMediaViewContext.Consumer, { children: () => /* @__PURE__ */ jsx17("div", { className: "flex size-full flex-col bg-ui-bg-subtle", children: noMedia ? /* @__PURE__ */ jsxs15("div", { className: "flex size-full flex-col items-center justify-center gap-y-4 bg-ui-bg-subtle pb-8 pt-6", children: [
3539
+ /* @__PURE__ */ jsxs15("div", { className: "flex flex-col items-center", children: [
3540
+ /* @__PURE__ */ jsx17(Text5, { size: "small", leading: "compact", weight: "plus", className: "text-ui-fg-subtle", children: t("products.media.emptyState.header", "No media") }),
3541
+ /* @__PURE__ */ jsx17(Text5, { size: "small", className: "text-ui-fg-muted", children: t("products.media.emptyState.description", "No images assigned to this variant.") })
3542
+ ] }),
3543
+ /* @__PURE__ */ jsx17(Button5, { size: "small", variant: "secondary", onClick: goToEdit, children: t("products.media.emptyState.action", "Add images") })
3544
+ ] }) : /* @__PURE__ */ jsxs15(Fragment5, { children: [
3545
+ /* @__PURE__ */ jsx17("div", { className: "relative size-full overflow-hidden bg-ui-bg-subtle", children: /* @__PURE__ */ jsx17("div", { className: "flex size-full items-center justify-center p-6", children: /* @__PURE__ */ jsxs15("div", { className: "relative inline-block max-h-full max-w-full", children: [
3546
+ media[curr]?.isThumbnail && /* @__PURE__ */ jsx17("div", { className: "absolute left-2 top-2", children: /* @__PURE__ */ jsx17(Tooltip4, { content: t("products.media.thumbnailTooltip"), children: /* @__PURE__ */ jsx17(ThumbnailBadge3, {}) }) }),
3547
+ /* @__PURE__ */ jsx17(
3548
+ "img",
3549
+ {
3550
+ src: media[curr]?.url,
3551
+ alt: "",
3552
+ className: "object-fit max-h-[calc(100vh-200px)] w-auto rounded-xl object-contain shadow-elevation-card-rest"
3553
+ }
3554
+ )
3555
+ ] }) }) }),
3556
+ media.length > 1 && /* @__PURE__ */ jsxs15("div", { className: "flex shrink-0 items-center justify-center gap-x-2 border-t p-3", children: [
3557
+ /* @__PURE__ */ jsx17(IconButton3, { size: "small", variant: "transparent", className: "text-ui-fg-muted", type: "button", onClick: prev, children: /* @__PURE__ */ jsx17(TriangleLeftMini, {}) }),
3558
+ /* @__PURE__ */ jsx17("div", { className: "flex items-center gap-x-2", children: media.slice(0, 8).map((item, idx) => {
3559
+ const isCurrentImage = item.id === media[curr]?.id;
3560
+ const originalIndex = media.findIndex((i) => i.id === item.id);
3561
+ return /* @__PURE__ */ jsx17(
3562
+ "button",
3563
+ {
3564
+ type: "button",
3565
+ onClick: () => goTo(originalIndex),
3566
+ className: clx2("size-7 overflow-hidden rounded-[4px] outline-none transition-fg", {
3567
+ "shadow-borders-focus": isCurrentImage
3568
+ }),
3569
+ children: /* @__PURE__ */ jsx17("img", { src: item.url, alt: "", className: "size-full object-cover" })
3570
+ },
3571
+ item.id
3572
+ );
3573
+ }) }),
3574
+ /* @__PURE__ */ jsx17(IconButton3, { size: "small", variant: "transparent", className: "text-ui-fg-muted", type: "button", onClick: next, children: /* @__PURE__ */ jsx17(TriangleRightMini, {}) })
3575
+ ] })
3576
+ ] }) }) });
3577
+ };
3578
+
3579
+ // src/pages/products/create/variant-media-view/variant-media-view.tsx
3580
+ import { jsx as jsx18, jsxs as jsxs16 } from "react/jsx-runtime";
3581
+ var getView = (currentView) => {
3582
+ if (currentView === "edit" /* EDIT */) return "edit" /* EDIT */;
3583
+ return "gallery" /* GALLERY */;
3584
+ };
3585
+ var VariantMediaView = ({
3586
+ variantIndex,
3587
+ variantTitle,
3588
+ onClose,
3589
+ onSaveMedia,
3590
+ initialMedia,
3591
+ productMedia
3592
+ }) => {
3593
+ const [currentView, setCurrentView] = useState9("edit" /* EDIT */);
3594
+ const view = getView(currentView);
3595
+ const { t } = useTranslation15();
3596
+ const saveRef = useRef4(null);
3597
+ const handleGoToView = (v) => () => setCurrentView(v);
3598
+ const contextValue = {
3599
+ goToGallery: handleGoToView("gallery" /* GALLERY */),
3600
+ goToEdit: handleGoToView("edit" /* EDIT */),
3601
+ onCancel: onClose,
3602
+ onClose
3603
+ };
3604
+ const handleFooterSave = () => {
3605
+ saveRef.current?.();
3606
+ };
3607
+ return /* @__PURE__ */ jsx18(VariantMediaViewContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxs16(StackedFocusModal.Content, { children: [
3608
+ /* @__PURE__ */ jsx18(StackedFocusModal.Header, { children: view === "edit" /* EDIT */ ? /* @__PURE__ */ jsx18(Button6, { variant: "secondary", size: "small", onClick: contextValue.goToGallery, children: t("products.media.galleryLabel", "Gallery") }) : /* @__PURE__ */ jsx18(Button6, { variant: "secondary", size: "small", onClick: contextValue.goToEdit, children: t("products.media.editLabel", "Edit") }) }),
3609
+ /* @__PURE__ */ jsxs16(StackedFocusModal.Body, { className: "flex flex-col overflow-hidden", children: [
3610
+ view === "gallery" /* GALLERY */ && /* @__PURE__ */ jsx18(VariantMediaGallery, { goToEdit: contextValue.goToEdit, variantMedia: initialMedia }),
3611
+ view === "edit" /* EDIT */ && /* @__PURE__ */ jsx18(
3612
+ EditVariantMediaForm,
3613
+ {
3614
+ variantIndex,
3615
+ variantTitle,
3616
+ onSaveMedia,
3617
+ onClose,
3618
+ saveRef,
3619
+ initialMedia,
3620
+ productMedia
3621
+ }
3622
+ )
3623
+ ] }),
3624
+ view === "edit" /* EDIT */ && /* @__PURE__ */ jsx18(StackedFocusModal.Footer, { children: /* @__PURE__ */ jsxs16("div", { className: "flex justify-end gap-x-2", children: [
3625
+ /* @__PURE__ */ jsx18(Button6, { variant: "secondary", size: "small", onClick: onClose, children: t("actions.cancel") }),
3626
+ /* @__PURE__ */ jsx18(Button6, { size: "small", onClick: handleFooterSave, children: t("actions.save") })
3627
+ ] }) })
3628
+ ] }) });
3629
+ };
3630
+
3631
+ // src/pages/products/create/product-create-page.tsx
3632
+ import { Fragment as Fragment6, jsx as jsx19, jsxs as jsxs17 } from "react/jsx-runtime";
3633
+ var ProductCreateFormWithModal = ({
3634
+ defaultChannel,
3635
+ store
3636
+ }) => {
3637
+ const { setIsOpen } = useStackedModal();
3638
+ const [selectedVariantIndex, setSelectedVariantIndex] = useState10(null);
3639
+ const [selectedVariantTitle, setSelectedVariantTitle] = useState10(void 0);
3640
+ const [selectedVariantMedia, setSelectedVariantMedia] = useState10(void 0);
3641
+ const [productMedia, setProductMedia] = useState10([]);
3642
+ const saveVariantMediaRef = useRef5(null);
3643
+ const handleOpenMediaModal = useCallback5(
3644
+ (variantIndex, variantTitle, initialMedia, currentProductMedia) => {
3645
+ setSelectedVariantIndex(variantIndex);
3646
+ setSelectedVariantTitle(variantTitle);
3647
+ setSelectedVariantMedia(initialMedia);
3648
+ setProductMedia(currentProductMedia || []);
3649
+ setIsOpen("variant-media-modal", true);
3650
+ },
3651
+ []
3652
+ );
3653
+ const handleCloseModal = () => {
3654
+ setIsOpen("variant-media-modal", false);
3655
+ setSelectedVariantIndex(null);
3656
+ setSelectedVariantTitle(void 0);
3657
+ setSelectedVariantMedia(void 0);
3658
+ setProductMedia([]);
3659
+ };
3660
+ const handleSaveMedia = useCallback5((variantIndex, media) => {
3661
+ if (saveVariantMediaRef.current) {
3662
+ saveVariantMediaRef.current(variantIndex, media);
3663
+ }
3664
+ handleCloseModal();
3665
+ }, []);
3666
+ return /* @__PURE__ */ jsxs17(Fragment6, { children: [
3667
+ /* @__PURE__ */ jsx19(
3668
+ ProductCreateForm,
3669
+ {
3670
+ defaultChannel,
3671
+ store,
3672
+ onOpenMediaModal: handleOpenMediaModal,
3673
+ onSaveVariantMediaRef: saveVariantMediaRef
3674
+ }
3675
+ ),
3676
+ /* @__PURE__ */ jsx19(
3677
+ StackedFocusModal,
3678
+ {
3679
+ id: "variant-media-modal",
3680
+ onOpenChangeCallback: (open) => {
3681
+ if (!open) {
3682
+ handleCloseModal();
3683
+ }
3684
+ },
3685
+ children: selectedVariantIndex !== null && /* @__PURE__ */ jsx19(
3686
+ VariantMediaView,
3687
+ {
3688
+ variantIndex: selectedVariantIndex,
3689
+ variantTitle: selectedVariantTitle,
3690
+ onClose: handleCloseModal,
3691
+ onSaveMedia: handleSaveMedia,
3692
+ initialMedia: selectedVariantMedia,
3693
+ productMedia
3694
+ }
3695
+ )
3696
+ }
3697
+ )
3698
+ ] });
3699
+ };
3700
+ var Root4 = ({ children }) => {
3701
+ const { t } = useTranslation16();
3702
+ const { store, isPending: isStorePending } = useStore();
3703
+ const { sales_channels, isPending: isSalesChannelPending } = useSalesChannels();
3704
+ const ready = !!store && !isStorePending && !!sales_channels && !isSalesChannelPending;
3705
+ const defaultChannel = sales_channels?.[0];
3706
+ return /* @__PURE__ */ jsxs17(RouteFocusModal, { children: [
3707
+ /* @__PURE__ */ jsx19(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx19("span", { className: "sr-only", children: t("products.create.title") }) }),
3708
+ /* @__PURE__ */ jsx19(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsx19("span", { className: "sr-only", children: t("products.create.description") }) }),
3709
+ ready && (Children4.count(children) > 0 ? children : /* @__PURE__ */ jsx19(ProductCreateFormWithModal, { defaultChannel, store }))
3710
+ ] });
3711
+ };
3712
+ var ProductCreatePage = Object.assign(Root4, {
3713
+ DetailsForm: ProductCreateDetailsForm,
3714
+ OrganizeForm: ProductCreateOrganizeForm,
3715
+ VariantsForm: ProductCreateVariantsForm,
3716
+ InventoryKitForm: ProductCreateInventoryKitForm,
3717
+ Form: ProductCreateForm,
3718
+ Tab: TabbedForm.Tab
3719
+ });
3720
+
3721
+ export {
3722
+ ProductCreatePage
3723
+ };