@mercurjs/vendor 2.1.2 → 2.2.0-canary.2

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 (230) hide show
  1. package/dist/{[id]-H3C3ZSC6.js → [id]-3EC6HYXL.js} +25 -21
  2. package/dist/{[id]-TO6KT3ZE.js → [id]-4OBGG7OH.js} +23 -21
  3. package/dist/{[id]-6PXEWRG7.js → [id]-7BAKUHUO.js} +13 -13
  4. package/dist/{[id]-X4DDKOMQ.js → [id]-COLO4TQJ.js} +26 -22
  5. package/dist/{[id]-7RUAH3TI.js → [id]-K2CT7BXQ.js} +4 -4
  6. package/dist/{[id]-3G5G7ZFV.js → [id]-KJIQTFGE.js} +22 -20
  7. package/dist/{[id]-4VCL3MMM.js → [id]-KRLGIVLR.js} +26 -22
  8. package/dist/{[id]-B3LHVQM5.js → [id]-KVWYLDN3.js} +25 -21
  9. package/dist/{[id]-INOFZHL7.js → [id]-LTNOHLGE.js} +16 -16
  10. package/dist/{[id]-PDGHF5J2.js → [id]-LUFRJLAU.js} +35 -31
  11. package/dist/[id]-UUUQK22M.js +1442 -0
  12. package/dist/{[id]-T2ROPEGY.js → [id]-Y2ISCLUD.js} +7 -7
  13. package/dist/{[id]-Y7GAMNC5.js → [id]-ZCMSBEVM.js} +4 -4
  14. package/dist/{[id]-UTKO3VG4.js → [id]-ZWWMJAKI.js} +9 -9
  15. package/dist/{[location_id]-D55RQOXT.js → [location_id]-NUBXDDJC.js} +9 -9
  16. package/dist/{[province_id]-OFH2ZOFQ.js → [province_id]-H2QAPKVH.js} +20 -18
  17. package/dist/{add-C6OX5C54.js → add-FIWTANZX.js} +34 -30
  18. package/dist/add-PBZQCIZQ.js +392 -0
  19. package/dist/{add-customer-groups-PJRJUWS2.js → add-customer-groups-RAHCP67U.js} +16 -14
  20. package/dist/{add-products-INOLNPO6.js → add-products-N3V2MVLD.js} +23 -19
  21. package/dist/{add-promotions-AHDOP52Q.js → add-promotions-CSCAJZHV.js} +7 -7
  22. package/dist/{add-to-campaign-HL6NGRR4.js → add-to-campaign-DLP7PSQB.js} +4 -4
  23. package/dist/{address-KRENKSLP.js → address-7F5SN7PV.js} +17 -15
  24. package/dist/{adjust-inventory-H4EUP7J3.js → adjust-inventory-SZF4W7LR.js} +2 -2
  25. package/dist/{allocate-items-SUCUZU4D.js → allocate-items-SDFS5GYN.js} +6 -6
  26. package/dist/{areas-UUMZDXLX.js → areas-7Y6BVS5A.js} +8 -8
  27. package/dist/{attributes-CALEHJJG.js → attributes-MBZ76HVZ.js} +3 -3
  28. package/dist/{breadcrumb-BS7Y5OKF.js → breadcrumb-65SAGUUL.js} +2 -2
  29. package/dist/{breadcrumb-6W2VP3OZ.js → breadcrumb-7PURSRTT.js} +13 -11
  30. package/dist/{breadcrumb-M5Z5WA6I.js → breadcrumb-EDPMEN2P.js} +2 -2
  31. package/dist/breadcrumb-FLDHJRVY.js +26 -0
  32. package/dist/{breadcrumb-VNNZ3TTW.js → breadcrumb-HND5FFWC.js} +2 -2
  33. package/dist/{breadcrumb-OIGGCB3L.js → breadcrumb-QV2IAX7N.js} +8 -2
  34. package/dist/{breadcrumb-KQSFIXQ4.js → breadcrumb-VWELWDB2.js} +1 -1
  35. package/dist/{breadcrumb-IG7VZGW2.js → breadcrumb-WRG4SITG.js} +13 -11
  36. package/dist/{breadcrumb-TW5JEOYS.js → breadcrumb-ZCG2RHIU.js} +12 -10
  37. package/dist/{campaigns-HS6MIO7X.js → campaigns-L6ULR6KR.js} +5 -5
  38. package/dist/{categories-PKWR3FM3.js → categories-FUZQKBXV.js} +6 -6
  39. package/dist/{chunk-PDQSPKG5.js → chunk-2DXNJURE.js} +1 -1
  40. package/dist/{chunk-5UD4P6YL.js → chunk-2USXZSTK.js} +4 -4
  41. package/dist/chunk-35G3SZRN.js +101 -0
  42. package/dist/{chunk-6SBMVLJ2.js → chunk-36L54SQQ.js} +1 -1
  43. package/dist/chunk-432S4FGR.js +0 -0
  44. package/dist/{chunk-KQGVSLUI.js → chunk-44RQ5PTN.js} +1803 -914
  45. package/dist/{chunk-Y2QI7KWS.js → chunk-4LVP635F.js} +408 -664
  46. package/dist/{chunk-UL4O5M4S.js → chunk-4S6XGIC6.js} +1 -18
  47. package/dist/chunk-5ATEALH7.js +68 -0
  48. package/dist/{chunk-CNLP35S7.js → chunk-5L2DCA4W.js} +16 -31
  49. package/dist/{chunk-WITQNQXN.js → chunk-6BS2AVGJ.js} +3 -3
  50. package/dist/{chunk-CYTNBXWF.js → chunk-6Y53VZ3C.js} +9 -9
  51. package/dist/{chunk-ZYOXKUKZ.js → chunk-7LBY5JLV.js} +1 -1
  52. package/dist/chunk-7SLWXX6L.js +811 -0
  53. package/dist/{chunk-LQYMBSRQ.js → chunk-AIZM66CG.js} +1 -1
  54. package/dist/{chunk-IZ5RG5XI.js → chunk-AJLGY3LQ.js} +1 -21
  55. package/dist/{chunk-WFE6CT6M.js → chunk-AVOIZO63.js} +21 -77
  56. package/dist/chunk-CFRWIQIZ.js +43 -0
  57. package/dist/{chunk-WNVEMFIK.js → chunk-CNMY5HVP.js} +2 -2
  58. package/dist/{chunk-BLVJAKBA.js → chunk-DDH7ULIQ.js} +1 -1
  59. package/dist/chunk-DIW4GRTI.js +503 -0
  60. package/dist/{chunk-JQP7MOFH.js → chunk-DVEKYLPV.js} +1 -1
  61. package/dist/{chunk-ZZO3INVE.js → chunk-DZIXC7OE.js} +1428 -1325
  62. package/dist/{chunk-QX45GVAL.js → chunk-EIUYXS7E.js} +8 -8
  63. package/dist/{chunk-N7OVXN72.js → chunk-EROX26D4.js} +1 -1
  64. package/dist/{chunk-2RHAI7WK.js → chunk-EZ3JOAUS.js} +1 -1
  65. package/dist/{chunk-HFRHHT36.js → chunk-FDR22JMM.js} +63 -8
  66. package/dist/{chunk-PEKANQ3T.js → chunk-FJUUGFXL.js} +2 -2
  67. package/dist/{chunk-3CK6OINO.js → chunk-GDWBOQI5.js} +3 -5
  68. package/dist/chunk-GGWUWT55.js +95 -0
  69. package/dist/chunk-GKZHBXZK.js +426 -0
  70. package/dist/{chunk-47SXTGLN.js → chunk-GXIAIITP.js} +63 -200
  71. package/dist/{chunk-4MFMCZEJ.js → chunk-H6LZ77GX.js} +2 -2
  72. package/dist/chunk-K4X324QP.js +18 -0
  73. package/dist/{chunk-VQ5EKDA3.js → chunk-KD7RYE6R.js} +1 -1
  74. package/dist/chunk-LEWA4BPH.js +18 -0
  75. package/dist/{chunk-7Q5SDEK7.js → chunk-LNM2D2I4.js} +4 -4
  76. package/dist/{chunk-LPOAVK6Y.js → chunk-LQD232FW.js} +47 -12
  77. package/dist/{chunk-OXXL4WQU.js → chunk-M7KSRYRI.js} +5 -5
  78. package/dist/{chunk-I2IKYOZX.js → chunk-N4MVIBFM.js} +19 -19
  79. package/dist/{chunk-PCMNEUMV.js → chunk-NHFEY3EI.js} +1 -1
  80. package/dist/{chunk-RTAWYMQP.js → chunk-NJMNYS7G.js} +1 -1
  81. package/dist/{chunk-HGQTL7NX.js → chunk-NSZQERLE.js} +2 -2
  82. package/dist/{chunk-RL7SFZOF.js → chunk-NXNJQZCP.js} +1 -1
  83. package/dist/{chunk-D2MA5TAP.js → chunk-PBD36EZJ.js} +2 -2
  84. package/dist/{chunk-4ZGFODSC.js → chunk-PZ44R4AS.js} +1 -1
  85. package/dist/{chunk-ZEVYT6IX.js → chunk-QNNJN4H6.js} +116 -286
  86. package/dist/{chunk-WBI7FEGI.js → chunk-QS6RWIBL.js} +1 -1
  87. package/dist/chunk-QT7YFHCA.js +198 -0
  88. package/dist/{chunk-GYV6SKY7.js → chunk-QXLRABYH.js} +4 -6
  89. package/dist/chunk-RTBNJQOV.js +2063 -0
  90. package/dist/chunk-RXZFEFNV.js +73 -0
  91. package/dist/{chunk-RUE5BPC2.js → chunk-RZLN2Q6G.js} +1 -1
  92. package/dist/{chunk-NYDJTWRL.js → chunk-SGR4DMCW.js} +4 -4
  93. package/dist/chunk-T6LHVNWO.js +27 -0
  94. package/dist/{chunk-DKQ4XMSN.js → chunk-TNVYTMBL.js} +6 -6
  95. package/dist/{chunk-32RYSB2V.js → chunk-TODJFRLH.js} +2 -2
  96. package/dist/{chunk-P3ZTO6T2.js → chunk-UAF2S447.js} +1 -1
  97. package/dist/{chunk-J6BRLL3F.js → chunk-UCQKXXLD.js} +2 -2
  98. package/dist/chunk-UORPTGV2.js +114 -0
  99. package/dist/{chunk-X4FLOQ45.js → chunk-WBHFU3MG.js} +2 -2
  100. package/dist/chunk-WLT7K7K7.js +63 -0
  101. package/dist/{chunk-4URLUCTD.js → chunk-WUPJADSO.js} +2 -2
  102. package/dist/{chunk-5M3SL4UZ.js → chunk-X2FVFUET.js} +9 -104
  103. package/dist/{chunk-ITI54CII.js → chunk-X4INVIWL.js} +5 -5
  104. package/dist/{chunk-PTW7JNAP.js → chunk-XFQJU6FA.js} +4 -4
  105. package/dist/{collections-DJZI2RM2.js → collections-YCAAFGSW.js} +22 -19
  106. package/dist/{configuration-RHPIO2QT.js → configuration-C4IGBNXH.js} +1 -1
  107. package/dist/{configuration-GN3TO77H.js → configuration-UOSNP45I.js} +3 -3
  108. package/dist/{create-G4T2PAJH.js → create-35MYQPVM.js} +23 -21
  109. package/dist/{create-3EK5CNNX.js → create-B5ZXTK3K.js} +33 -29
  110. package/dist/{create-HKJVSFB7.js → create-BJ4OO6LS.js} +23 -21
  111. package/dist/create-FCKGCZSM.js +210 -0
  112. package/dist/{create-7S7CZWEN.js → create-GB3ZA4LH.js} +4 -4
  113. package/dist/{create-YO55Z3YD.js → create-HI5UI2EZ.js} +32 -38
  114. package/dist/create-JDGM5KXE.js +193 -0
  115. package/dist/{create-IDVCZHIX.js → create-ORXYT74H.js} +14 -12
  116. package/dist/{create-GHM7OTCR.js → create-R7K3ECN6.js} +1 -1
  117. package/dist/{create-D6EW3EWC.js → create-SFU3W3ZH.js} +1 -1
  118. package/dist/{create-33TRLASX.js → create-UPYB65PD.js} +1 -1
  119. package/dist/{create-OCFPLNNY.js → create-UQNYMVBM.js} +6 -6
  120. package/dist/{create-OGLPDVOI.js → create-XAD5NMSJ.js} +37 -35
  121. package/dist/{create-KGYL7FBM.js → create-XVHOCZHJ.js} +1 -1
  122. package/dist/{create-4AE3VTWN.js → create-YBF4YGWG.js} +2 -2
  123. package/dist/{create-3ZVXEPX5.js → create-YDDBH4VQ.js} +25 -21
  124. package/dist/{customers-6ZLE65UX.js → customers-ETXVNM3G.js} +5 -5
  125. package/dist/{edit-QBISX7D3.js → edit-2Q7TRUTL.js} +14 -12
  126. package/dist/{edit-B5B3XKDM.js → edit-522DG3BY.js} +1 -1
  127. package/dist/{edit-ATXE6CM5.js → edit-C4OCKQVU.js} +1 -1
  128. package/dist/{edit-IR6V2IDN.js → edit-FKXIQ6ZI.js} +19 -17
  129. package/dist/{edit-4HZHLYI3.js → edit-GQNIINRR.js} +1 -1
  130. package/dist/{edit-LRRJTHV2.js → edit-KAKVPHZZ.js} +1 -1
  131. package/dist/{edit-ZSOI56BQ.js → edit-L5ZZLMAY.js} +22 -22
  132. package/dist/{edit-GIJXLMC3.js → edit-O4JLGKQR.js} +2 -2
  133. package/dist/{edit-5CJZRHAA.js → edit-ORXS3A2Y.js} +1 -1
  134. package/dist/{edit-FC64DWB2.js → edit-Q3UQIOLS.js} +1 -1
  135. package/dist/{edit-7HTH2UJF.js → edit-REDDBLTA.js} +3 -3
  136. package/dist/{edit-2KRJIPRK.js → edit-SGUY2CCK.js} +19 -17
  137. package/dist/{edit-B75KK5ZX.js → edit-UGEC27HP.js} +35 -31
  138. package/dist/{edit-FNDDSSMT.js → edit-VKT62KHG.js} +37 -8
  139. package/dist/{edit-7GVP6SRA.js → edit-ZAHCMF5U.js} +1 -1
  140. package/dist/{edit-RNT555GP.js → edit-ZCXUG42Q.js} +13 -11
  141. package/dist/{edit-MYSWY6W4.js → edit-ZMERG3L7.js} +1 -1
  142. package/dist/{edit-budget-J27CSEZH.js → edit-budget-L3CCEWNF.js} +1 -1
  143. package/dist/{edit-inventory-item-US77M2FF.js → edit-inventory-item-6B7ITDGD.js} +2 -2
  144. package/dist/{edit-inventory-item-attributes-UGAE2NAZ.js → edit-inventory-item-attributes-Y7MQZLXI.js} +3 -3
  145. package/dist/{fulfillment-DCS67LTK.js → fulfillment-75Z4H23W.js} +16 -14
  146. package/dist/{fulfillment-providers-GM5PO6N3.js → fulfillment-providers-DQAU43JZ.js} +20 -17
  147. package/dist/index.css +27 -62
  148. package/dist/index.d.ts +3 -10
  149. package/dist/index.js +522 -458
  150. package/dist/{inventory-OPZ2FSEE.js → inventory-KAUVPMPZ.js} +6 -6
  151. package/dist/{invite-KEJLNXEZ.js → invite-CI2P4GF6.js} +15 -12
  152. package/dist/{invite-764K3TJS.js → invite-Q6EYDZVQ.js} +24 -21
  153. package/dist/loader-FBB5OQRT.js +31 -0
  154. package/dist/{locations-ZVPTQCQY.js → locations-INS6FTMJ.js} +4 -4
  155. package/dist/{login-OUHRNNXA.js → login-KY342RMK.js} +12 -10
  156. package/dist/{manage-locations-YUKEFCBJ.js → manage-locations-WNHEBS3A.js} +2 -2
  157. package/dist/{media-4KYFHB5V.js → media-B6ME2WXY.js} +41 -9
  158. package/dist/{metadata-NYYL26MQ.js → metadata-2CMH4I6U.js} +16 -14
  159. package/dist/{metadata-AWUKZ25V.js → metadata-5BPOBBU2.js} +3 -3
  160. package/dist/{metadata-OCE6A3JE.js → metadata-GWI6R4ES.js} +15 -13
  161. package/dist/{metadata-G7KZXVNE.js → metadata-NUXUC2JA.js} +15 -13
  162. package/dist/{metadata-XP3ZYW2M.js → metadata-TLDUF5KV.js} +17 -15
  163. package/dist/{metadata-PYY4IB7K.js → metadata-WR4RFXO5.js} +16 -14
  164. package/dist/offer-create-page-4Z6L63BU.js +743 -0
  165. package/dist/offer-detail-page-6MAHNNIO.js +488 -0
  166. package/dist/offer-edit-page-DYQFU6JU.js +151 -0
  167. package/dist/offer-inventory-batch-page-WKCWNDNK.js +290 -0
  168. package/dist/offer-pricing-edit-page-4TYGGSOE.js +195 -0
  169. package/dist/offers-ZG6OTDZ2.js +32 -0
  170. package/dist/{onboarding-WXZHW62K.js → onboarding-43LQQQGQ.js} +22 -20
  171. package/dist/{orders-LWJ472VM.js → orders-ZV4D6L2V.js} +24 -21
  172. package/dist/organization-ZTQGRJWS.js +375 -0
  173. package/dist/{organize-RFOMQCBG.js → organize-HNJUHEEG.js} +4 -4
  174. package/dist/{organize-OVKJ3HZO.js → organize-K6QMAMEN.js} +4 -4
  175. package/dist/pages/index.d.ts +415 -758
  176. package/dist/pages/index.js +81 -77
  177. package/dist/{payment-details-UVXYCTUK.js → payment-details-64US5XWD.js} +17 -15
  178. package/dist/{payouts-TR7K5I37.js → payouts-UXJDTXDL.js} +6 -6
  179. package/dist/{price-lists-S2WNELFZ.js → price-lists-KBPUVSZI.js} +8 -8
  180. package/dist/{pricing-UF27DAXA.js → pricing-DF6C5XK4.js} +35 -32
  181. package/dist/{product-tags-2CKH2M6D.js → product-tags-6MZB4W5R.js} +32 -28
  182. package/dist/{product-types-FX43JEO2.js → product-types-UUHBV4IZ.js} +5 -5
  183. package/dist/product-variant-detail-RVWEYVPC.js +220 -0
  184. package/dist/{product-variant-edit-P3DSIFE3.js → product-variant-edit-YYNPHE4L.js} +126 -66
  185. package/dist/{products-H5EMRJYS.js → products-IWKTGZS6.js} +23 -19
  186. package/dist/{products-2LHGS7X3.js → products-MZBU5MEV.js} +40 -43
  187. package/dist/{professional-details-HYKTH44B.js → professional-details-5T2VS6MM.js} +16 -14
  188. package/dist/{profile-PB27WIRW.js → profile-6XGHAT7H.js} +20 -18
  189. package/dist/{promotions-5EYPGHJP.js → promotions-O7U4BTK6.js} +8 -8
  190. package/dist/{register-4O4F6YZK.js → register-N6WOSMLA.js} +16 -14
  191. package/dist/{reset-password-GTWLBOFK.js → reset-password-EICPAY2N.js} +1 -1
  192. package/dist/{return-reasons-LOKYRGMI.js → return-reasons-IX3LIOCU.js} +16 -14
  193. package/dist/{sales-channels-7R2IY3KG.js → sales-channels-B6FULRWI.js} +8 -7
  194. package/dist/{sales-channels-Y4LRP7JC.js → sales-channels-JW3QUYR7.js} +8 -7
  195. package/dist/{settings-2XDLFYMS.js → settings-MV53ZZ53.js} +39 -35
  196. package/dist/{shipment-4GW2JFWB.js → shipment-Q33QBMXX.js} +13 -11
  197. package/dist/{shipping-profile-R3NABPQF.js → shipping-profile-Y4SNEPZX.js} +2 -2
  198. package/dist/{shipping-profiles-QVKNFLCW.js → shipping-profiles-2NWKCEJK.js} +18 -16
  199. package/dist/{stock-5RXNUPUT.js → stock-7CSVEJJU.js} +19 -17
  200. package/dist/{store-DE2RGX7T.js → store-X23G3JCJ.js} +28 -25
  201. package/dist/{store-closure-DNMCHUXD.js → store-closure-P5PD2RSV.js} +16 -14
  202. package/dist/{store-select-GZEJHRZ7.js → store-select-TREPDS3G.js} +17 -15
  203. package/dist/{tax-regions-UD6P5FVC.js → tax-regions-YXZW7UVX.js} +5 -5
  204. package/dist/{team-JXKAVRPU.js → team-SPP5OY5W.js} +25 -23
  205. package/dist/types-CtCEtTE6.d.ts +16 -0
  206. package/package.json +6 -6
  207. package/dist/[id]-BYP37PU4.js +0 -1314
  208. package/dist/add-KRAGFFBJ.js +0 -158
  209. package/dist/bulk-edit-3SMBLIOA.js +0 -244
  210. package/dist/chunk-4KX6CBJ4.js +0 -178
  211. package/dist/chunk-DLNNTQRY.js +0 -217
  212. package/dist/chunk-FX4V5JCF.js +0 -37
  213. package/dist/chunk-GC33DBKG.js +0 -143
  214. package/dist/chunk-NK4NR6MN.js +0 -173
  215. package/dist/chunk-PFU6FSXY.js +0 -430
  216. package/dist/chunk-QJEOPT2P.js +0 -330
  217. package/dist/chunk-QSGR43JM.js +0 -30
  218. package/dist/chunk-STR3NGWE.js +0 -3736
  219. package/dist/create-3DOO3RNH.js +0 -716
  220. package/dist/create-I7HV3RM6.js +0 -150
  221. package/dist/edit-K2AD335I.js +0 -237
  222. package/dist/edit-VO5XLIEL.js +0 -362
  223. package/dist/edit-stocks-and-prices-MHHQFWFA.js +0 -408
  224. package/dist/organization-LPYQRTQC.js +0 -303
  225. package/dist/prices-3OXV5RGY.js +0 -270
  226. package/dist/product-variant-detail-WV4KXVXR.js +0 -590
  227. package/dist/stock-GPC3BCL6.js +0 -500
  228. package/dist/{chunk-SDSEW72R.js → chunk-E2HQPY32.js} +3 -3
  229. package/dist/{chunk-6WY5X4PE.js → chunk-L7QKFC5N.js} +7 -7
  230. /package/dist/{chunk-CAS74NLJ.js → chunk-YV6MK4PZ.js} +0 -0
@@ -0,0 +1,2063 @@
1
+ import {
2
+ HandleInput
3
+ } from "./chunk-HJ56YXBU.js";
4
+ import {
5
+ DataGrid,
6
+ createDataGridHelper
7
+ } from "./chunk-4LVP635F.js";
8
+ import {
9
+ defineTabMeta
10
+ } from "./chunk-LEWA4BPH.js";
11
+ import {
12
+ SwitchBox
13
+ } from "./chunk-YVCBMOJG.js";
14
+ import {
15
+ SingleCategoryCombobox
16
+ } from "./chunk-7SLWXX6L.js";
17
+ import {
18
+ useComboboxData
19
+ } from "./chunk-OVPAOBZB.js";
20
+ import {
21
+ UploadMediaFormItem
22
+ } from "./chunk-2DXNJURE.js";
23
+ import {
24
+ PRODUCT_CREATE_FORM_DEFAULTS,
25
+ ProductCreateSchema,
26
+ decorateVariantsWithDefaultValues,
27
+ generateVariantsFromAttributes,
28
+ normalizeProductFormValues
29
+ } from "./chunk-DIW4GRTI.js";
30
+ import {
31
+ ChipInput
32
+ } from "./chunk-YGRTRAWX.js";
33
+ import {
34
+ useAttributeTableFilters,
35
+ useAttributeTableQuery
36
+ } from "./chunk-WLT7K7K7.js";
37
+ import {
38
+ Combobox
39
+ } from "./chunk-VBRTC2VU.js";
40
+ import {
41
+ TabbedForm,
42
+ useTabbedForm
43
+ } from "./chunk-LQD232FW.js";
44
+ import {
45
+ RouteFocusModal,
46
+ StackedFocusModal,
47
+ useRouteModal,
48
+ useStackedModal
49
+ } from "./chunk-GDWBOQI5.js";
50
+ import {
51
+ Form
52
+ } from "./chunk-3QSRE5LS.js";
53
+ import {
54
+ DataTable
55
+ } from "./chunk-PPLC4IKI.js";
56
+ import {
57
+ require_dist
58
+ } from "./chunk-DZIXC7OE.js";
59
+ import {
60
+ useFeatureFlags
61
+ } from "./chunk-GXIAIITP.js";
62
+ import {
63
+ ActionMenu
64
+ } from "./chunk-BDGZ4EQO.js";
65
+ import {
66
+ useCreateProduct,
67
+ useProductAttributes
68
+ } from "./chunk-QNNJN4H6.js";
69
+ import {
70
+ sdk,
71
+ uploadFilesQuery
72
+ } from "./chunk-RIN4CBRB.js";
73
+ import {
74
+ __toESM
75
+ } from "./chunk-NBMM2TZK.js";
76
+
77
+ // src/pages/products/create/product-create.tsx
78
+ import { Children as Children2 } from "react";
79
+ import { useTranslation as useTranslation10 } from "react-i18next";
80
+
81
+ // src/pages/products/create/components/product-create-form/product-create-form.tsx
82
+ var import_types6 = __toESM(require_dist(), 1);
83
+ import { Button as Button3, toast } from "@medusajs/ui";
84
+ import { useEffect as useEffect3, useMemo as useMemo5, Children } from "react";
85
+ import { useForm, useWatch as useWatch3 } from "react-hook-form";
86
+ import { useTranslation as useTranslation9 } from "react-i18next";
87
+ import { zodResolver } from "@hookform/resolvers/zod";
88
+
89
+ // src/pages/products/create/components/product-create-attributes-form/product-create-attributes-form.tsx
90
+ var import_types = __toESM(require_dist(), 1);
91
+ import { XMarkMini } from "@medusajs/icons";
92
+ import {
93
+ Button as Button2,
94
+ Heading,
95
+ Hint,
96
+ IconButton,
97
+ InlineTip,
98
+ Input,
99
+ Label,
100
+ Select,
101
+ Switch,
102
+ Text,
103
+ Textarea
104
+ } from "@medusajs/ui";
105
+ import { useEffect as useEffect2 } from "react";
106
+ import {
107
+ Controller,
108
+ useFieldArray
109
+ } from "react-hook-form";
110
+ import { useTranslation as useTranslation2 } from "react-i18next";
111
+
112
+ // src/pages/products/create/components/product-create-attributes-form/product-create-add-attributes-modal.tsx
113
+ import {
114
+ Badge,
115
+ Button,
116
+ createDataTableColumnHelper
117
+ } from "@medusajs/ui";
118
+ import { useEffect, useMemo, useState } from "react";
119
+ import { useTranslation } from "react-i18next";
120
+ import { keepPreviousData } from "@tanstack/react-query";
121
+ import { jsx, jsxs } from "react/jsx-runtime";
122
+ var ADD_ATTRIBUTES_MODAL_ID = "add-attributes";
123
+ var PAGE_SIZE = 20;
124
+ var MAX_VISIBLE_VALUES = 2;
125
+ var ATTRIBUTE_TYPE_LABELS = {
126
+ single_select: "attributes.type.select",
127
+ multi_select: "attributes.type.multivalue",
128
+ unit: "attributes.type.unit",
129
+ toggle: "attributes.type.toggle",
130
+ text: "attributes.type.text_area"
131
+ };
132
+ var ProductCreateAddAttributesModal = () => {
133
+ const form = useTabbedForm();
134
+ const { t } = useTranslation();
135
+ const { getValues, setValue } = form;
136
+ const { setIsOpen, getIsOpen } = useStackedModal();
137
+ const [rowSelection, setRowSelection] = useState(
138
+ {}
139
+ );
140
+ const [state, setState] = useState([]);
141
+ const { searchParams } = useAttributeTableQuery({
142
+ pageSize: PAGE_SIZE,
143
+ prefix: ADD_ATTRIBUTES_MODAL_ID
144
+ });
145
+ const { product_attributes, count, isLoading, isError, error } = useProductAttributes(searchParams, {
146
+ placeholderData: keepPreviousData
147
+ });
148
+ const open = getIsOpen(ADD_ATTRIBUTES_MODAL_ID);
149
+ useEffect(() => {
150
+ if (!open) {
151
+ return;
152
+ }
153
+ const attributes = getValues("attributes") ?? [];
154
+ const existing = attributes.filter((a) => a.attribute_id);
155
+ const selection = {};
156
+ const stateEntries = [];
157
+ for (const a of existing) {
158
+ if (a.attribute_id) {
159
+ selection[a.attribute_id] = true;
160
+ const apiAttr = product_attributes?.find(
161
+ (pa) => pa.id === a.attribute_id
162
+ );
163
+ stateEntries.push({
164
+ id: a.attribute_id,
165
+ name: a.title,
166
+ values: Array.isArray(a.values) ? a.values : a.values ? [a.values] : [],
167
+ is_variant_axis: a.use_for_variants,
168
+ type: a.type ?? apiAttr?.type ?? "",
169
+ available_values: a.available_values ?? apiAttr?.values?.map((v) => ({ id: v.id, name: v.name })) ?? []
170
+ });
171
+ }
172
+ }
173
+ if (product_attributes) {
174
+ for (const attr of product_attributes) {
175
+ if (attr.is_required && !selection[attr.id]) {
176
+ selection[attr.id] = true;
177
+ stateEntries.push({
178
+ id: attr.id,
179
+ name: attr.name,
180
+ values: [],
181
+ is_variant_axis: attr.is_variant_axis,
182
+ type: attr.type,
183
+ available_values: attr.values?.map((v) => ({ id: v.id, name: v.name })) ?? []
184
+ });
185
+ }
186
+ }
187
+ }
188
+ setRowSelection(selection);
189
+ setState(stateEntries);
190
+ }, [open, getValues, product_attributes]);
191
+ const onRowSelectionChange = (next) => {
192
+ if (product_attributes) {
193
+ for (const attr of product_attributes) {
194
+ if (attr.is_required) {
195
+ next[attr.id] = true;
196
+ }
197
+ }
198
+ }
199
+ const ids = Object.keys(next);
200
+ const addedIdsSet = new Set(
201
+ ids.filter((id) => next[id] && !rowSelection[id])
202
+ );
203
+ let addedAttributes = [];
204
+ if (addedIdsSet.size > 0) {
205
+ addedAttributes = product_attributes?.filter((attr) => addedIdsSet.has(attr.id)).map((attr) => ({
206
+ id: attr.id,
207
+ name: attr.name,
208
+ values: [],
209
+ is_variant_axis: attr.is_variant_axis,
210
+ type: attr.type,
211
+ available_values: attr.values?.map((v) => ({ id: v.id, name: v.name })) ?? []
212
+ })) ?? [];
213
+ }
214
+ setState((prev) => {
215
+ const filteredPrev = prev.filter((a) => next[a.id]);
216
+ return Array.from(/* @__PURE__ */ new Set([...filteredPrev, ...addedAttributes]));
217
+ });
218
+ setRowSelection(next);
219
+ };
220
+ const handleAdd = () => {
221
+ const currentAttributes = getValues("attributes") ?? [];
222
+ const customAttributes = currentAttributes.filter((a) => a.is_custom);
223
+ const requiredIds = new Set(
224
+ product_attributes?.filter((a) => a.is_required).map((a) => a.id) ?? []
225
+ );
226
+ const selectedAttributes = state.map((a) => ({
227
+ attribute_id: a.id,
228
+ title: a.name,
229
+ values: a.values,
230
+ is_custom: false,
231
+ is_required: requiredIds.has(a.id),
232
+ use_for_variants: a.is_variant_axis,
233
+ type: a.type,
234
+ available_values: a.available_values
235
+ }));
236
+ setValue("attributes", [...selectedAttributes, ...customAttributes], {
237
+ shouldDirty: true,
238
+ shouldTouch: true
239
+ });
240
+ setIsOpen(ADD_ATTRIBUTES_MODAL_ID, false);
241
+ };
242
+ const filters = useAttributeTableFilters();
243
+ const columns = useColumns();
244
+ if (isError) {
245
+ throw error;
246
+ }
247
+ return /* @__PURE__ */ jsxs(StackedFocusModal.Content, { className: "flex flex-col overflow-hidden", children: [
248
+ /* @__PURE__ */ jsx(StackedFocusModal.Header, {}),
249
+ /* @__PURE__ */ jsx(StackedFocusModal.Body, { className: "flex-1 overflow-hidden", children: /* @__PURE__ */ jsx(
250
+ DataTable,
251
+ {
252
+ data: product_attributes,
253
+ columns,
254
+ filters,
255
+ rowCount: count,
256
+ pageSize: PAGE_SIZE,
257
+ getRowId: (row) => row.id,
258
+ rowSelection: {
259
+ state: rowSelection,
260
+ onRowSelectionChange,
261
+ enableRowSelection: (row) => !row.original.is_required
262
+ },
263
+ isLoading,
264
+ layout: "fill",
265
+ prefix: ADD_ATTRIBUTES_MODAL_ID
266
+ }
267
+ ) }),
268
+ /* @__PURE__ */ jsx(StackedFocusModal.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
269
+ /* @__PURE__ */ jsx(StackedFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: t("actions.cancel") }) }),
270
+ /* @__PURE__ */ jsx(Button, { size: "small", onClick: handleAdd, type: "button", children: t("actions.save") })
271
+ ] }) })
272
+ ] });
273
+ };
274
+ var columnHelper = createDataTableColumnHelper();
275
+ var useColumns = () => {
276
+ const { t } = useTranslation();
277
+ return useMemo(
278
+ () => [
279
+ columnHelper.select(),
280
+ columnHelper.accessor("name", {
281
+ header: t("attributes.fields.name"),
282
+ enableSorting: false
283
+ }),
284
+ columnHelper.accessor("handle", {
285
+ header: t("attributes.fields.handle"),
286
+ cell: (info) => {
287
+ const handle = info.getValue();
288
+ return handle ? `/${handle}` : "-";
289
+ },
290
+ enableSorting: false
291
+ }),
292
+ columnHelper.accessor("is_required", {
293
+ header: t("attributes.fields.required"),
294
+ cell: (info) => info.getValue() ? t("filters.radio.yes") : t("filters.radio.no"),
295
+ enableSorting: false
296
+ }),
297
+ columnHelper.accessor("type", {
298
+ header: t("attributes.fields.type"),
299
+ cell: (info) => {
300
+ const type = info.getValue();
301
+ const labelKey = ATTRIBUTE_TYPE_LABELS[type];
302
+ return labelKey ? t(labelKey) : type;
303
+ },
304
+ enableSorting: false
305
+ }),
306
+ columnHelper.accessor("is_variant_axis", {
307
+ header: t("attributes.fields.variantAxis"),
308
+ cell: (info) => info.getValue() ? t("filters.radio.yes") : t("filters.radio.no"),
309
+ enableSorting: false
310
+ }),
311
+ columnHelper.display({
312
+ id: "values",
313
+ header: t("attributes.fields.values"),
314
+ cell: ({ row }) => {
315
+ const values = row.original.values ?? [];
316
+ if (!values.length) {
317
+ return /* @__PURE__ */ jsx("span", { className: "text-ui-fg-muted", children: "-" });
318
+ }
319
+ const visible = values.slice(0, MAX_VISIBLE_VALUES);
320
+ const remaining = values.length - MAX_VISIBLE_VALUES;
321
+ return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-1", children: [
322
+ visible.map((v) => /* @__PURE__ */ jsx(Badge, { size: "2xsmall", color: "grey", children: v.name }, v.id)),
323
+ remaining > 0 && /* @__PURE__ */ jsxs(Badge, { size: "2xsmall", color: "grey", children: [
324
+ "+",
325
+ remaining
326
+ ] })
327
+ ] });
328
+ }
329
+ })
330
+ ],
331
+ [t]
332
+ );
333
+ };
334
+
335
+ // src/pages/products/create/components/product-create-attributes-form/product-create-attributes-form.tsx
336
+ import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
337
+ var Root = () => {
338
+ const { t } = useTranslation2();
339
+ const form = useTabbedForm();
340
+ const { setIsOpen } = useStackedModal();
341
+ const { fields, append, remove } = useFieldArray({
342
+ control: form.control,
343
+ name: "attributes"
344
+ });
345
+ const handleCreateNew = () => {
346
+ append({
347
+ attribute_id: void 0,
348
+ title: "",
349
+ values: [],
350
+ is_custom: true,
351
+ use_for_variants: false
352
+ });
353
+ };
354
+ const handleAddExisting = () => {
355
+ setIsOpen(ADD_ATTRIBUTES_MODAL_ID, true);
356
+ };
357
+ return /* @__PURE__ */ jsxs2(
358
+ "div",
359
+ {
360
+ className: "flex flex-col items-center p-16",
361
+ "data-testid": "product-create-attributes-form",
362
+ children: [
363
+ /* @__PURE__ */ jsx2(StackedFocusModal, { id: ADD_ATTRIBUTES_MODAL_ID, children: /* @__PURE__ */ jsx2(ProductCreateAddAttributesModal, {}) }),
364
+ /* @__PURE__ */ jsxs2("div", { className: "flex w-full max-w-[720px] flex-col gap-y-8", children: [
365
+ /* @__PURE__ */ jsxs2("div", { children: [
366
+ /* @__PURE__ */ jsx2(Heading, { level: "h2", children: t("products.create.attributes.header") }),
367
+ /* @__PURE__ */ jsx2(
368
+ Text,
369
+ {
370
+ size: "small",
371
+ className: "text-ui-fg-subtle mt-1 whitespace-pre-line",
372
+ children: t("products.create.attributes.description")
373
+ }
374
+ )
375
+ ] }),
376
+ /* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-x-2", children: [
377
+ /* @__PURE__ */ jsx2(
378
+ Button2,
379
+ {
380
+ type: "button",
381
+ variant: "secondary",
382
+ size: "small",
383
+ onClick: handleAddExisting,
384
+ children: t("products.create.attributes.addExisting")
385
+ }
386
+ ),
387
+ /* @__PURE__ */ jsx2(
388
+ Button2,
389
+ {
390
+ type: "button",
391
+ variant: "secondary",
392
+ size: "small",
393
+ onClick: handleCreateNew,
394
+ children: t("products.create.attributes.createNew")
395
+ }
396
+ )
397
+ ] }),
398
+ fields.some((f) => !f.is_custom && !!f.attribute_id) && /* @__PURE__ */ jsx2(SelectedAttributes, { fields, remove }),
399
+ fields.some((f) => f.is_custom) && /* @__PURE__ */ jsx2("ul", { className: "flex flex-col gap-y-4", children: fields.map((field, index) => {
400
+ if (!field.is_custom) return null;
401
+ const useForVariants = form.watch(
402
+ `attributes.${index}.use_for_variants`
403
+ );
404
+ return /* @__PURE__ */ jsxs2(
405
+ "li",
406
+ {
407
+ className: "bg-ui-bg-component shadow-elevation-card-rest grid grid-cols-[1fr_28px] items-start gap-1.5 rounded-xl p-1.5",
408
+ children: [
409
+ /* @__PURE__ */ jsxs2("div", { className: "grid grid-cols-[min-content,1fr] items-center gap-1.5", children: [
410
+ /* @__PURE__ */ jsx2("div", { className: "flex items-center px-2 py-1.5", children: /* @__PURE__ */ jsx2(
411
+ Label,
412
+ {
413
+ size: "xsmall",
414
+ weight: "plus",
415
+ className: "text-ui-fg-subtle",
416
+ htmlFor: `attributes.${index}.title`,
417
+ children: t("fields.title")
418
+ }
419
+ ) }),
420
+ /* @__PURE__ */ jsx2(
421
+ Input,
422
+ {
423
+ className: "bg-ui-bg-field-component hover:bg-ui-bg-field-component-hover",
424
+ ...form.register(`attributes.${index}.title`),
425
+ placeholder: t(
426
+ "products.create.attributes.titlePlaceholder"
427
+ )
428
+ }
429
+ ),
430
+ /* @__PURE__ */ jsx2("div", { className: "flex items-center px-2 py-1.5", children: /* @__PURE__ */ jsx2(
431
+ Label,
432
+ {
433
+ size: "xsmall",
434
+ weight: "plus",
435
+ className: "text-ui-fg-subtle",
436
+ htmlFor: `attributes.${index}.values`,
437
+ children: t("fields.values")
438
+ }
439
+ ) }),
440
+ /* @__PURE__ */ jsx2(
441
+ Controller,
442
+ {
443
+ control: form.control,
444
+ name: `attributes.${index}.values`,
445
+ render: ({ field: { onChange, value, ...field2 } }) => useForVariants ? /* @__PURE__ */ jsx2(
446
+ ChipInput,
447
+ {
448
+ ...field2,
449
+ variant: "contrast",
450
+ value: Array.isArray(value) ? value : [],
451
+ onChange,
452
+ placeholder: t(
453
+ "products.create.attributes.valuePlaceholder"
454
+ )
455
+ }
456
+ ) : /* @__PURE__ */ jsx2(
457
+ Textarea,
458
+ {
459
+ ...field2,
460
+ className: "bg-ui-bg-field-component hover:bg-ui-bg-field-component-hover",
461
+ value: Array.isArray(value) ? value[0] ?? "" : value ?? "",
462
+ onChange: (e) => onChange(e.target.value),
463
+ placeholder: t(
464
+ "products.create.attributes.valuePlaceholder"
465
+ )
466
+ }
467
+ )
468
+ }
469
+ ),
470
+ /* @__PURE__ */ jsx2("div", {}),
471
+ /* @__PURE__ */ jsx2(
472
+ Form.Field,
473
+ {
474
+ control: form.control,
475
+ name: `attributes.${index}.use_for_variants`,
476
+ render: ({ field: { value, onChange, ref } }) => /* @__PURE__ */ jsx2(Form.Item, { children: /* @__PURE__ */ jsxs2("div", { className: "flex items-start gap-x-3 py-1.5", children: [
477
+ /* @__PURE__ */ jsx2(Form.Control, { children: /* @__PURE__ */ jsx2(
478
+ Switch,
479
+ {
480
+ ref,
481
+ className: "shrink-0 rtl:rotate-180",
482
+ checked: value,
483
+ onCheckedChange: onChange
484
+ }
485
+ ) }),
486
+ /* @__PURE__ */ jsxs2("div", { className: "flex flex-col", children: [
487
+ /* @__PURE__ */ jsx2(Label, { size: "xsmall", weight: "plus", children: t("products.create.attributes.useForVariants") }),
488
+ /* @__PURE__ */ jsx2(Hint, { className: "!txt-small", children: t(
489
+ "products.create.attributes.useForVariantsDescription"
490
+ ) })
491
+ ] })
492
+ ] }) })
493
+ }
494
+ )
495
+ ] }),
496
+ /* @__PURE__ */ jsx2(
497
+ IconButton,
498
+ {
499
+ type: "button",
500
+ size: "small",
501
+ variant: "transparent",
502
+ className: "text-ui-fg-muted",
503
+ onClick: () => remove(index),
504
+ children: /* @__PURE__ */ jsx2(XMarkMini, {})
505
+ }
506
+ )
507
+ ]
508
+ },
509
+ field.id
510
+ );
511
+ }) }),
512
+ /* @__PURE__ */ jsx2(RequiredAttributes, {})
513
+ ] })
514
+ ]
515
+ }
516
+ );
517
+ };
518
+ var SelectedAttributes = ({
519
+ fields,
520
+ remove
521
+ }) => {
522
+ const { t } = useTranslation2();
523
+ const form = useTabbedForm();
524
+ const entries = fields.map((field, index) => ({ field, index })).filter(
525
+ ({ field }) => !field.is_custom && !field.is_required && !!field.attribute_id
526
+ );
527
+ if (!entries.length) return null;
528
+ return /* @__PURE__ */ jsx2("ul", { className: "flex flex-col gap-y-4", children: entries.map(({ field, index }) => {
529
+ const attrType = field.type;
530
+ const availableValues = field.available_values ?? [];
531
+ return /* @__PURE__ */ jsxs2(
532
+ "li",
533
+ {
534
+ className: "bg-ui-bg-component shadow-elevation-card-rest grid grid-cols-[1fr_28px] items-start gap-1.5 rounded-xl p-1.5",
535
+ children: [
536
+ /* @__PURE__ */ jsxs2("div", { className: "grid grid-cols-[min-content,1fr] items-center gap-1.5", children: [
537
+ /* @__PURE__ */ jsx2("div", { className: "flex items-center px-2 py-1.5", children: /* @__PURE__ */ jsx2(
538
+ Label,
539
+ {
540
+ size: "xsmall",
541
+ weight: "plus",
542
+ className: "text-ui-fg-subtle",
543
+ children: t("fields.title")
544
+ }
545
+ ) }),
546
+ /* @__PURE__ */ jsx2(
547
+ Input,
548
+ {
549
+ value: field.title,
550
+ disabled: true,
551
+ className: "bg-ui-bg-field-component"
552
+ }
553
+ ),
554
+ /* @__PURE__ */ jsx2("div", { className: "flex items-center px-2 py-1.5", children: /* @__PURE__ */ jsx2(
555
+ Label,
556
+ {
557
+ size: "xsmall",
558
+ weight: "plus",
559
+ className: "text-ui-fg-subtle",
560
+ children: t("fields.values")
561
+ }
562
+ ) }),
563
+ attrType === import_types.AttributeType.MULTI_SELECT ? /* @__PURE__ */ jsx2(
564
+ Controller,
565
+ {
566
+ control: form.control,
567
+ name: `attributes.${index}.values`,
568
+ render: ({ field: { onChange, value, ref, ...rest } }) => /* @__PURE__ */ jsx2(
569
+ Combobox,
570
+ {
571
+ ...rest,
572
+ ref,
573
+ value: Array.isArray(value) ? value : [],
574
+ onChange: (val) => onChange(val ?? []),
575
+ options: availableValues.map((v) => ({
576
+ value: v.name,
577
+ label: v.name
578
+ })),
579
+ placeholder: t("products.create.attributes.selectValues")
580
+ }
581
+ )
582
+ }
583
+ ) : attrType === import_types.AttributeType.SINGLE_SELECT ? /* @__PURE__ */ jsx2(
584
+ Controller,
585
+ {
586
+ control: form.control,
587
+ name: `attributes.${index}.values`,
588
+ render: ({ field: { onChange, value, ref, ...rest } }) => /* @__PURE__ */ jsxs2(
589
+ Select,
590
+ {
591
+ ...rest,
592
+ value: typeof value === "string" ? value : value?.[0] ?? "",
593
+ onValueChange: onChange,
594
+ children: [
595
+ /* @__PURE__ */ jsx2(Select.Trigger, { ref, children: /* @__PURE__ */ jsx2(
596
+ Select.Value,
597
+ {
598
+ placeholder: t(
599
+ "products.create.attributes.selectValues"
600
+ )
601
+ }
602
+ ) }),
603
+ /* @__PURE__ */ jsx2(Select.Content, { children: availableValues.map((v) => /* @__PURE__ */ jsx2(Select.Item, { value: v.name, children: v.name }, v.id)) })
604
+ ]
605
+ }
606
+ )
607
+ }
608
+ ) : attrType === import_types.AttributeType.TEXT ? /* @__PURE__ */ jsx2(
609
+ Controller,
610
+ {
611
+ control: form.control,
612
+ name: `attributes.${index}.values`,
613
+ render: ({ field: { onChange, value, ...rest } }) => /* @__PURE__ */ jsx2(
614
+ Textarea,
615
+ {
616
+ ...rest,
617
+ className: "bg-ui-bg-field-component hover:bg-ui-bg-field-component-hover",
618
+ value: typeof value === "string" ? value : value?.[0] ?? "",
619
+ onChange: (e) => onChange(e.target.value),
620
+ placeholder: t(
621
+ "products.create.attributes.valuePlaceholder"
622
+ )
623
+ }
624
+ )
625
+ }
626
+ ) : attrType === import_types.AttributeType.TOGGLE ? /* @__PURE__ */ jsx2(
627
+ Controller,
628
+ {
629
+ control: form.control,
630
+ name: `attributes.${index}.values`,
631
+ render: ({ field: { onChange, value, ...rest } }) => /* @__PURE__ */ jsxs2(
632
+ Select,
633
+ {
634
+ ...rest,
635
+ value: typeof value === "string" ? value : value?.[0] ?? "",
636
+ onValueChange: onChange,
637
+ children: [
638
+ /* @__PURE__ */ jsx2(Select.Trigger, { children: /* @__PURE__ */ jsx2(
639
+ Select.Value,
640
+ {
641
+ placeholder: t(
642
+ "products.create.attributes.selectValues"
643
+ )
644
+ }
645
+ ) }),
646
+ /* @__PURE__ */ jsxs2(Select.Content, { children: [
647
+ /* @__PURE__ */ jsx2(Select.Item, { value: "true", children: t("filters.radio.yes") }),
648
+ /* @__PURE__ */ jsx2(Select.Item, { value: "false", children: t("filters.radio.no") })
649
+ ] })
650
+ ]
651
+ }
652
+ )
653
+ }
654
+ ) : /* @__PURE__ */ jsx2(
655
+ Controller,
656
+ {
657
+ control: form.control,
658
+ name: `attributes.${index}.values`,
659
+ render: ({ field: { onChange, value, ...rest } }) => /* @__PURE__ */ jsx2(
660
+ Input,
661
+ {
662
+ ...rest,
663
+ value: typeof value === "string" ? value : value?.[0] ?? "",
664
+ onChange: (e) => onChange(e.target.value),
665
+ placeholder: t(
666
+ "products.create.attributes.valuePlaceholder"
667
+ )
668
+ }
669
+ )
670
+ }
671
+ ),
672
+ field.use_for_variants && /* @__PURE__ */ jsxs2(Fragment, { children: [
673
+ /* @__PURE__ */ jsx2("div", {}),
674
+ /* @__PURE__ */ jsx2(VariantAxisTip, {})
675
+ ] })
676
+ ] }),
677
+ /* @__PURE__ */ jsx2(
678
+ IconButton,
679
+ {
680
+ type: "button",
681
+ size: "small",
682
+ variant: "transparent",
683
+ className: "text-ui-fg-muted",
684
+ onClick: () => remove(index),
685
+ children: /* @__PURE__ */ jsx2(XMarkMini, {})
686
+ }
687
+ )
688
+ ]
689
+ },
690
+ field.id
691
+ );
692
+ }) });
693
+ };
694
+ var RequiredAttributes = () => {
695
+ const { t } = useTranslation2();
696
+ const form = useTabbedForm();
697
+ const categoryId = form.watch("category_id");
698
+ const { product_attributes } = useProductAttributes(
699
+ {
700
+ category_id: categoryId,
701
+ is_required: true
702
+ },
703
+ { enabled: !!categoryId }
704
+ );
705
+ const attributes = form.watch("attributes") || [];
706
+ useEffect2(() => {
707
+ if (!product_attributes) return;
708
+ const currentAttributes = form.getValues("attributes") || [];
709
+ const requiredIds = new Set(product_attributes.map((a) => a.id));
710
+ const otherAttributes = currentAttributes.filter(
711
+ (a) => a.is_custom || !requiredIds.has(a.attribute_id ?? "")
712
+ );
713
+ const requiredAttributes = product_attributes.map((attr) => {
714
+ const existing = currentAttributes.find(
715
+ (a) => a.attribute_id === attr.id
716
+ );
717
+ if (existing) return existing;
718
+ return {
719
+ attribute_id: attr.id,
720
+ title: attr.name,
721
+ values: attr.type === import_types.AttributeType.MULTI_SELECT ? [] : "",
722
+ is_custom: false,
723
+ is_required: true,
724
+ use_for_variants: attr.is_variant_axis
725
+ };
726
+ });
727
+ form.setValue("attributes", [...otherAttributes, ...requiredAttributes]);
728
+ }, [product_attributes]);
729
+ if (!categoryId || !product_attributes?.length) return null;
730
+ const requiredEntries = attributes.map((attr, index) => ({ attr, index })).filter(({ attr }) => !attr.is_custom);
731
+ return /* @__PURE__ */ jsxs2(Fragment, { children: [
732
+ /* @__PURE__ */ jsx2("div", { className: "border-ui-border-base border-t border-dashed" }),
733
+ /* @__PURE__ */ jsxs2("div", { className: "flex flex-col gap-y-6", children: [
734
+ /* @__PURE__ */ jsxs2("div", { children: [
735
+ /* @__PURE__ */ jsx2(Text, { size: "small", weight: "plus", leading: "compact", children: t("products.create.attributes.requiredAttributes") }),
736
+ /* @__PURE__ */ jsx2(Text, { size: "small", className: "text-ui-fg-subtle", children: t("products.create.attributes.requiredAttributesHint") })
737
+ ] }),
738
+ requiredEntries.map(({ attr, index }) => {
739
+ const apiAttr = product_attributes.find(
740
+ (a) => a.id === attr.attribute_id
741
+ );
742
+ if (!apiAttr) return null;
743
+ return /* @__PURE__ */ jsx2(
744
+ RequiredAttributeField,
745
+ {
746
+ attribute: apiAttr,
747
+ index
748
+ },
749
+ apiAttr.id
750
+ );
751
+ })
752
+ ] })
753
+ ] });
754
+ };
755
+ var RequiredAttributeField = ({
756
+ attribute,
757
+ index
758
+ }) => {
759
+ const { t } = useTranslation2();
760
+ const form = useTabbedForm();
761
+ return /* @__PURE__ */ jsx2(
762
+ Form.Field,
763
+ {
764
+ control: form.control,
765
+ name: `attributes.${index}.values`,
766
+ render: ({ field: { onChange, value, ref, ...field } }) => /* @__PURE__ */ jsxs2(Form.Item, { children: [
767
+ /* @__PURE__ */ jsx2(Form.Label, { children: attribute.name }),
768
+ /* @__PURE__ */ jsx2(Form.Control, { children: attribute.type === import_types.AttributeType.SINGLE_SELECT ? /* @__PURE__ */ jsxs2(
769
+ Select,
770
+ {
771
+ ...field,
772
+ value: typeof value === "string" ? value : value?.[0] ?? "",
773
+ onValueChange: onChange,
774
+ children: [
775
+ /* @__PURE__ */ jsx2(Select.Trigger, { ref, children: /* @__PURE__ */ jsx2(
776
+ Select.Value,
777
+ {
778
+ placeholder: t(
779
+ "products.create.attributes.valuePlaceholder"
780
+ )
781
+ }
782
+ ) }),
783
+ /* @__PURE__ */ jsx2(Select.Content, { children: attribute.values?.map((v) => /* @__PURE__ */ jsx2(Select.Item, { value: v.name, children: v.name }, v.id)) })
784
+ ]
785
+ }
786
+ ) : attribute.type === import_types.AttributeType.MULTI_SELECT ? /* @__PURE__ */ jsx2(
787
+ Combobox,
788
+ {
789
+ ...field,
790
+ ref,
791
+ value: Array.isArray(value) ? value : [],
792
+ onChange: (val) => onChange(val ?? []),
793
+ options: attribute.values?.map((v) => ({
794
+ value: v.name,
795
+ label: v.name
796
+ })) ?? [],
797
+ placeholder: t("products.create.attributes.selectValues")
798
+ }
799
+ ) : attribute.type === import_types.AttributeType.TEXT ? /* @__PURE__ */ jsx2(
800
+ Input,
801
+ {
802
+ ...field,
803
+ ref,
804
+ value: typeof value === "string" ? value : value?.[0] ?? "",
805
+ onChange: (e) => onChange(e.target.value),
806
+ placeholder: t("products.create.attributes.valuePlaceholder")
807
+ }
808
+ ) : attribute.type === import_types.AttributeType.TOGGLE ? /* @__PURE__ */ jsx2(
809
+ Switch,
810
+ {
811
+ ...field,
812
+ className: "rtl:rotate-180",
813
+ checked: value === "true" || value === true,
814
+ onCheckedChange: (checked) => onChange(String(checked))
815
+ }
816
+ ) : /* @__PURE__ */ jsx2(
817
+ Input,
818
+ {
819
+ ...field,
820
+ ref,
821
+ value: typeof value === "string" ? value : value?.[0] ?? "",
822
+ onChange: (e) => onChange(e.target.value),
823
+ placeholder: t("products.create.attributes.valuePlaceholder")
824
+ }
825
+ ) }),
826
+ /* @__PURE__ */ jsx2(Form.ErrorMessage, {}),
827
+ attribute.is_variant_axis && /* @__PURE__ */ jsx2(VariantAxisTip, {})
828
+ ] })
829
+ }
830
+ );
831
+ };
832
+ var VariantAxisTip = () => {
833
+ const { t } = useTranslation2();
834
+ return /* @__PURE__ */ jsx2(InlineTip, { label: t("products.create.attributes.tip"), children: t("products.create.attributes.variantAxisTip") });
835
+ };
836
+ Root._tabMeta = defineTabMeta({
837
+ id: "attributes",
838
+ labelKey: "products.create.tabs.attributes",
839
+ validationFields: ["attributes"]
840
+ });
841
+ var ProductCreateAttributesForm = Root;
842
+
843
+ // src/pages/products/create/components/product-create-details-form/product-create-details-form.tsx
844
+ import { Heading as Heading3 } from "@medusajs/ui";
845
+ import { useTranslation as useTranslation6 } from "react-i18next";
846
+
847
+ // src/pages/products/create/components/product-create-details-form/components/product-create-details-general-section/product-create-general-section.tsx
848
+ import { Input as Input2, Textarea as Textarea2 } from "@medusajs/ui";
849
+ import { useTranslation as useTranslation3 } from "react-i18next";
850
+ import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
851
+ var ProductCreateGeneralSection = () => {
852
+ const form = useTabbedForm();
853
+ const { t } = useTranslation3();
854
+ return /* @__PURE__ */ jsxs3("div", { id: "general", className: "flex flex-col gap-y-6", "data-testid": "product-create-general-section", children: [
855
+ /* @__PURE__ */ jsx3("div", { className: "flex flex-col gap-y-2", "data-testid": "product-create-general-section-fields", children: /* @__PURE__ */ jsxs3("div", { className: "grid grid-cols-1 gap-4 md:grid-cols-3", "data-testid": "product-create-general-section-title-fields", children: [
856
+ /* @__PURE__ */ jsx3(
857
+ Form.Field,
858
+ {
859
+ control: form.control,
860
+ name: "title",
861
+ render: ({ field }) => {
862
+ return /* @__PURE__ */ jsxs3(Form.Item, { "data-testid": "product-create-general-section-title-item", children: [
863
+ /* @__PURE__ */ jsx3(Form.Label, { "data-testid": "product-create-general-section-title-label", children: t("products.fields.title.label") }),
864
+ /* @__PURE__ */ jsx3(Form.Control, { "data-testid": "product-create-general-section-title-control", children: /* @__PURE__ */ jsx3(Input2, { ...field, placeholder: t("products.fields.title.placeholder"), "data-testid": "product-create-general-section-title-input" }) })
865
+ ] });
866
+ }
867
+ }
868
+ ),
869
+ /* @__PURE__ */ jsx3(
870
+ Form.Field,
871
+ {
872
+ control: form.control,
873
+ name: "subtitle",
874
+ render: ({ field }) => {
875
+ return /* @__PURE__ */ jsxs3(Form.Item, { "data-testid": "product-create-general-section-subtitle-item", children: [
876
+ /* @__PURE__ */ jsx3(Form.Label, { optional: true, "data-testid": "product-create-general-section-subtitle-label", children: t("products.fields.subtitle.label") }),
877
+ /* @__PURE__ */ jsx3(Form.Control, { "data-testid": "product-create-general-section-subtitle-control", children: /* @__PURE__ */ jsx3(Input2, { ...field, placeholder: t("products.fields.subtitle.placeholder"), "data-testid": "product-create-general-section-subtitle-input" }) })
878
+ ] });
879
+ }
880
+ }
881
+ ),
882
+ /* @__PURE__ */ jsx3(
883
+ Form.Field,
884
+ {
885
+ control: form.control,
886
+ name: "handle",
887
+ render: ({ field }) => {
888
+ return /* @__PURE__ */ jsxs3(Form.Item, { "data-testid": "product-create-general-section-handle-item", children: [
889
+ /* @__PURE__ */ jsx3(
890
+ Form.Label,
891
+ {
892
+ tooltip: t("products.fields.handle.tooltip"),
893
+ optional: true,
894
+ "data-testid": "product-create-general-section-handle-label",
895
+ children: t("fields.handle")
896
+ }
897
+ ),
898
+ /* @__PURE__ */ jsx3(Form.Control, { "data-testid": "product-create-general-section-handle-control", children: /* @__PURE__ */ jsx3(HandleInput, { ...field, placeholder: t("products.fields.handle.placeholder"), "data-testid": "product-create-general-section-handle-input" }) })
899
+ ] });
900
+ }
901
+ }
902
+ )
903
+ ] }) }),
904
+ /* @__PURE__ */ jsx3(
905
+ Form.Field,
906
+ {
907
+ control: form.control,
908
+ name: "description",
909
+ render: ({ field }) => {
910
+ return /* @__PURE__ */ jsxs3(Form.Item, { "data-testid": "product-create-general-section-description-item", children: [
911
+ /* @__PURE__ */ jsx3(Form.Label, { optional: true, "data-testid": "product-create-general-section-description-label", children: t("products.fields.description.label") }),
912
+ /* @__PURE__ */ jsx3(Form.Control, { "data-testid": "product-create-general-section-description-control", children: /* @__PURE__ */ jsx3(Textarea2, { ...field, placeholder: t("products.fields.description.placeholder"), "data-testid": "product-create-general-section-description-input" }) })
913
+ ] });
914
+ }
915
+ }
916
+ )
917
+ ] });
918
+ };
919
+
920
+ // src/pages/products/create/components/product-create-details-form/components/product-create-details-media-section/product-create-details-media-section.tsx
921
+ import {
922
+ defaultDropAnimationSideEffects,
923
+ DndContext,
924
+ DragOverlay,
925
+ KeyboardSensor,
926
+ PointerSensor,
927
+ useSensor,
928
+ useSensors
929
+ } from "@dnd-kit/core";
930
+ import {
931
+ arrayMove,
932
+ SortableContext,
933
+ sortableKeyboardCoordinates,
934
+ useSortable
935
+ } from "@dnd-kit/sortable";
936
+ import { CSS } from "@dnd-kit/utilities";
937
+ import {
938
+ DotsSix,
939
+ StackPerspective,
940
+ ThumbnailBadge,
941
+ Trash,
942
+ XMark
943
+ } from "@medusajs/icons";
944
+ import { IconButton as IconButton2, Text as Text2 } from "@medusajs/ui";
945
+ import { useState as useState2 } from "react";
946
+ import { useFieldArray as useFieldArray2 } from "react-hook-form";
947
+ import { useTranslation as useTranslation4 } from "react-i18next";
948
+ import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
949
+ var dropAnimationConfig = {
950
+ sideEffects: defaultDropAnimationSideEffects({
951
+ styles: {
952
+ active: {
953
+ opacity: "0.4"
954
+ }
955
+ }
956
+ })
957
+ };
958
+ var ProductCreateMediaSection = () => {
959
+ const form = useTabbedForm();
960
+ const { fields, append, remove } = useFieldArray2({
961
+ name: "media",
962
+ control: form.control,
963
+ keyName: "field_id"
964
+ });
965
+ const [activeId, setActiveId] = useState2(null);
966
+ const sensors = useSensors(
967
+ useSensor(PointerSensor),
968
+ useSensor(KeyboardSensor, {
969
+ coordinateGetter: sortableKeyboardCoordinates
970
+ })
971
+ );
972
+ const handleDragStart = (event) => {
973
+ setActiveId(event.active.id);
974
+ };
975
+ const handleDragEnd = (event) => {
976
+ setActiveId(null);
977
+ const { active, over } = event;
978
+ if (active.id !== over?.id) {
979
+ const oldIndex = fields.findIndex((item) => item.field_id === active.id);
980
+ const newIndex = fields.findIndex((item) => item.field_id === over?.id);
981
+ form.setValue("media", arrayMove(fields, oldIndex, newIndex), {
982
+ shouldDirty: true,
983
+ shouldTouch: true
984
+ });
985
+ }
986
+ };
987
+ const handleDragCancel = () => {
988
+ setActiveId(null);
989
+ };
990
+ const getOnDelete = (index) => {
991
+ return () => {
992
+ remove(index);
993
+ };
994
+ };
995
+ const getMakeThumbnail = (index) => {
996
+ return () => {
997
+ const newFields = fields.map((field, i) => {
998
+ return {
999
+ ...field,
1000
+ isThumbnail: i === index
1001
+ };
1002
+ });
1003
+ form.setValue("media", newFields, {
1004
+ shouldDirty: true,
1005
+ shouldTouch: true
1006
+ });
1007
+ };
1008
+ };
1009
+ const getItemHandlers = (index) => {
1010
+ return {
1011
+ onDelete: getOnDelete(index),
1012
+ onMakeThumbnail: getMakeThumbnail(index)
1013
+ };
1014
+ };
1015
+ return /* @__PURE__ */ jsxs4("div", { id: "media", className: "flex flex-col gap-y-2", "data-testid": "product-create-media-section", children: [
1016
+ /* @__PURE__ */ jsx4(UploadMediaFormItem, { form, append, showHint: false }),
1017
+ /* @__PURE__ */ jsxs4(
1018
+ DndContext,
1019
+ {
1020
+ sensors,
1021
+ onDragEnd: handleDragEnd,
1022
+ onDragStart: handleDragStart,
1023
+ onDragCancel: handleDragCancel,
1024
+ children: [
1025
+ /* @__PURE__ */ jsx4(DragOverlay, { dropAnimation: dropAnimationConfig, children: activeId ? /* @__PURE__ */ jsx4(
1026
+ MediaGridItemOverlay,
1027
+ {
1028
+ field: fields.find((m) => m.field_id === activeId)
1029
+ }
1030
+ ) : null }),
1031
+ /* @__PURE__ */ jsx4("ul", { className: "flex flex-col gap-y-2", "data-testid": "product-create-media-section-list", children: /* @__PURE__ */ jsx4(SortableContext, { items: fields.map((field) => field.field_id), children: fields.map((field, index) => {
1032
+ const { onDelete, onMakeThumbnail } = getItemHandlers(index);
1033
+ return /* @__PURE__ */ jsx4(
1034
+ MediaItem,
1035
+ {
1036
+ field,
1037
+ onDelete,
1038
+ onMakeThumbnail
1039
+ },
1040
+ field.field_id
1041
+ );
1042
+ }) }) })
1043
+ ]
1044
+ }
1045
+ )
1046
+ ] });
1047
+ };
1048
+ var MediaItem = ({ field, onDelete, onMakeThumbnail }) => {
1049
+ const { t } = useTranslation4();
1050
+ const {
1051
+ attributes,
1052
+ listeners,
1053
+ setNodeRef,
1054
+ setActivatorNodeRef,
1055
+ transform,
1056
+ transition,
1057
+ isDragging
1058
+ } = useSortable({ id: field.field_id });
1059
+ const style = {
1060
+ opacity: isDragging ? 0.4 : void 0,
1061
+ transform: CSS.Translate.toString(transform),
1062
+ transition
1063
+ };
1064
+ if (!field.file) {
1065
+ return null;
1066
+ }
1067
+ return /* @__PURE__ */ jsxs4(
1068
+ "li",
1069
+ {
1070
+ className: "bg-ui-bg-component shadow-elevation-card-rest flex items-center justify-between rounded-lg px-3 py-2",
1071
+ ref: setNodeRef,
1072
+ style,
1073
+ "data-testid": `product-create-media-section-item-${field.field_id}`,
1074
+ children: [
1075
+ /* @__PURE__ */ jsxs4("div", { className: "flex items-center gap-x-2", children: [
1076
+ /* @__PURE__ */ jsx4(
1077
+ IconButton2,
1078
+ {
1079
+ variant: "transparent",
1080
+ type: "button",
1081
+ size: "small",
1082
+ ...attributes,
1083
+ ...listeners,
1084
+ ref: setActivatorNodeRef,
1085
+ className: "cursor-grab touch-none active:cursor-grabbing",
1086
+ children: /* @__PURE__ */ jsx4(DotsSix, { className: "text-ui-fg-muted" })
1087
+ }
1088
+ ),
1089
+ /* @__PURE__ */ jsxs4("div", { className: "flex items-center gap-x-3", children: [
1090
+ /* @__PURE__ */ jsx4("div", { className: "bg-ui-bg-base h-10 w-[30px] overflow-hidden rounded-md", children: /* @__PURE__ */ jsx4(ThumbnailPreview, { url: field.url }) }),
1091
+ /* @__PURE__ */ jsxs4("div", { className: "flex flex-col", children: [
1092
+ /* @__PURE__ */ jsx4(Text2, { size: "small", leading: "compact", children: field.file.name }),
1093
+ /* @__PURE__ */ jsxs4("div", { className: "flex items-center gap-x-1", children: [
1094
+ field.isThumbnail && /* @__PURE__ */ jsx4(ThumbnailBadge, {}),
1095
+ /* @__PURE__ */ jsx4(
1096
+ Text2,
1097
+ {
1098
+ size: "xsmall",
1099
+ leading: "compact",
1100
+ className: "text-ui-fg-subtle",
1101
+ children: formatFileSize(field.file.size)
1102
+ }
1103
+ )
1104
+ ] })
1105
+ ] })
1106
+ ] })
1107
+ ] }),
1108
+ /* @__PURE__ */ jsxs4("div", { className: "flex items-center gap-x-1", children: [
1109
+ /* @__PURE__ */ jsx4(
1110
+ ActionMenu,
1111
+ {
1112
+ groups: [
1113
+ {
1114
+ actions: [
1115
+ {
1116
+ label: t("products.media.makeThumbnail"),
1117
+ icon: /* @__PURE__ */ jsx4(StackPerspective, {}),
1118
+ onClick: onMakeThumbnail
1119
+ }
1120
+ ]
1121
+ },
1122
+ {
1123
+ actions: [
1124
+ {
1125
+ icon: /* @__PURE__ */ jsx4(Trash, {}),
1126
+ label: t("actions.delete"),
1127
+ onClick: onDelete
1128
+ }
1129
+ ]
1130
+ }
1131
+ ]
1132
+ }
1133
+ ),
1134
+ /* @__PURE__ */ jsx4(
1135
+ IconButton2,
1136
+ {
1137
+ type: "button",
1138
+ size: "small",
1139
+ variant: "transparent",
1140
+ onClick: onDelete,
1141
+ children: /* @__PURE__ */ jsx4(XMark, {})
1142
+ }
1143
+ )
1144
+ ] })
1145
+ ]
1146
+ }
1147
+ );
1148
+ };
1149
+ var MediaGridItemOverlay = ({ field }) => {
1150
+ return /* @__PURE__ */ jsxs4("li", { className: "bg-ui-bg-component shadow-elevation-card-rest flex items-center justify-between rounded-lg px-3 py-2", children: [
1151
+ /* @__PURE__ */ jsxs4("div", { className: "flex items-center gap-x-2", children: [
1152
+ /* @__PURE__ */ jsx4(
1153
+ IconButton2,
1154
+ {
1155
+ variant: "transparent",
1156
+ size: "small",
1157
+ className: "cursor-grab touch-none active:cursor-grabbing",
1158
+ children: /* @__PURE__ */ jsx4(DotsSix, { className: "text-ui-fg-muted" })
1159
+ }
1160
+ ),
1161
+ /* @__PURE__ */ jsxs4("div", { className: "flex items-center gap-x-3", children: [
1162
+ /* @__PURE__ */ jsx4("div", { className: "bg-ui-bg-base h-10 w-[30px] overflow-hidden rounded-md", children: /* @__PURE__ */ jsx4(ThumbnailPreview, { url: field.url }) }),
1163
+ /* @__PURE__ */ jsxs4("div", { className: "flex flex-col", children: [
1164
+ /* @__PURE__ */ jsx4(Text2, { size: "small", leading: "compact", children: field.file?.name }),
1165
+ /* @__PURE__ */ jsxs4("div", { className: "flex items-center gap-x-1", children: [
1166
+ field.isThumbnail && /* @__PURE__ */ jsx4(ThumbnailBadge, {}),
1167
+ /* @__PURE__ */ jsx4(
1168
+ Text2,
1169
+ {
1170
+ size: "xsmall",
1171
+ leading: "compact",
1172
+ className: "text-ui-fg-subtle",
1173
+ children: formatFileSize(field.file?.size ?? 0)
1174
+ }
1175
+ )
1176
+ ] })
1177
+ ] })
1178
+ ] })
1179
+ ] }),
1180
+ /* @__PURE__ */ jsxs4("div", { className: "flex items-center gap-x-1", children: [
1181
+ /* @__PURE__ */ jsx4(ActionMenu, { groups: [] }),
1182
+ /* @__PURE__ */ jsx4(
1183
+ IconButton2,
1184
+ {
1185
+ type: "button",
1186
+ size: "small",
1187
+ variant: "transparent",
1188
+ onClick: () => {
1189
+ },
1190
+ children: /* @__PURE__ */ jsx4(XMark, {})
1191
+ }
1192
+ )
1193
+ ] })
1194
+ ] });
1195
+ };
1196
+ var ThumbnailPreview = ({ url }) => {
1197
+ if (!url) {
1198
+ return null;
1199
+ }
1200
+ return /* @__PURE__ */ jsx4("img", { src: url, alt: "", className: "size-full object-cover object-center" });
1201
+ };
1202
+ function formatFileSize(bytes, decimalPlaces = 2) {
1203
+ if (bytes === 0) {
1204
+ return "0 Bytes";
1205
+ }
1206
+ const k = 1024;
1207
+ const sizes = ["Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
1208
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
1209
+ return parseFloat((bytes / Math.pow(k, i)).toFixed(decimalPlaces)) + " " + sizes[i];
1210
+ }
1211
+
1212
+ // src/pages/products/create/components/product-create-details-form/components/product-create-details-variant-section/product-create-details-variant-section.tsx
1213
+ import {
1214
+ Alert,
1215
+ Checkbox,
1216
+ clx as clx2,
1217
+ Heading as Heading2,
1218
+ Hint as Hint2,
1219
+ InlineTip as InlineTip2,
1220
+ Label as Label2,
1221
+ Text as Text3
1222
+ } from "@medusajs/ui";
1223
+ import { useFieldArray as useFieldArray3, useWatch } from "react-hook-form";
1224
+ import { useTranslation as useTranslation5 } from "react-i18next";
1225
+ import { useMemo as useMemo3 } from "react";
1226
+
1227
+ // src/components/common/sortable-list/sortable-list.tsx
1228
+ import {
1229
+ DndContext as DndContext2,
1230
+ DragOverlay as DragOverlay2,
1231
+ KeyboardSensor as KeyboardSensor2,
1232
+ PointerSensor as PointerSensor2,
1233
+ defaultDropAnimationSideEffects as defaultDropAnimationSideEffects2,
1234
+ useSensor as useSensor2,
1235
+ useSensors as useSensors2
1236
+ } from "@dnd-kit/core";
1237
+ import {
1238
+ SortableContext as SortableContext2,
1239
+ arrayMove as arrayMove2,
1240
+ sortableKeyboardCoordinates as sortableKeyboardCoordinates2,
1241
+ useSortable as useSortable2
1242
+ } from "@dnd-kit/sortable";
1243
+ import { CSS as CSS2 } from "@dnd-kit/utilities";
1244
+ import { DotsSix as DotsSix2 } from "@medusajs/icons";
1245
+ import { IconButton as IconButton3, clx } from "@medusajs/ui";
1246
+ import {
1247
+ Fragment as Fragment2,
1248
+ createContext,
1249
+ useContext,
1250
+ useMemo as useMemo2,
1251
+ useState as useState3
1252
+ } from "react";
1253
+ import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
1254
+ var List = ({
1255
+ items,
1256
+ onChange,
1257
+ renderItem
1258
+ }) => {
1259
+ const [active, setActive] = useState3(null);
1260
+ const [activeItem, activeIndex] = useMemo2(() => {
1261
+ if (active === null) {
1262
+ return [null, null];
1263
+ }
1264
+ const index = items.findIndex(({ id }) => id === active.id);
1265
+ return [items[index], index];
1266
+ }, [active, items]);
1267
+ const sensors = useSensors2(
1268
+ useSensor2(PointerSensor2),
1269
+ useSensor2(KeyboardSensor2, {
1270
+ coordinateGetter: sortableKeyboardCoordinates2
1271
+ })
1272
+ );
1273
+ const handleDragStart = ({ active: active2 }) => {
1274
+ setActive(active2);
1275
+ };
1276
+ const handleDragEnd = ({ active: active2, over }) => {
1277
+ if (over && active2.id !== over.id) {
1278
+ const activeIndex2 = items.findIndex(({ id }) => id === active2.id);
1279
+ const overIndex = items.findIndex(({ id }) => id === over.id);
1280
+ onChange(arrayMove2(items, activeIndex2, overIndex));
1281
+ }
1282
+ setActive(null);
1283
+ };
1284
+ const handleDragCancel = () => {
1285
+ setActive(null);
1286
+ };
1287
+ return /* @__PURE__ */ jsxs5(
1288
+ DndContext2,
1289
+ {
1290
+ sensors,
1291
+ onDragStart: handleDragStart,
1292
+ onDragEnd: handleDragEnd,
1293
+ onDragCancel: handleDragCancel,
1294
+ children: [
1295
+ /* @__PURE__ */ jsx5(Overlay, { children: activeItem && activeIndex !== null ? renderItem(activeItem, activeIndex) : null }),
1296
+ /* @__PURE__ */ jsx5(SortableContext2, { items, children: /* @__PURE__ */ jsx5(
1297
+ "ul",
1298
+ {
1299
+ role: "application",
1300
+ className: "flex list-inside list-none list-image-none flex-col p-0",
1301
+ children: items.map((item, index) => /* @__PURE__ */ jsx5(Fragment2, { children: renderItem(item, index) }, item.id))
1302
+ }
1303
+ ) })
1304
+ ]
1305
+ }
1306
+ );
1307
+ };
1308
+ var dropAnimationConfig2 = {
1309
+ sideEffects: defaultDropAnimationSideEffects2({
1310
+ styles: {
1311
+ active: {
1312
+ opacity: "0.4"
1313
+ }
1314
+ }
1315
+ })
1316
+ };
1317
+ var Overlay = ({ children }) => {
1318
+ return /* @__PURE__ */ jsx5(
1319
+ DragOverlay2,
1320
+ {
1321
+ className: "shadow-elevation-card-hover overflow-hidden rounded-md [&>li]:border-b-0",
1322
+ dropAnimation: dropAnimationConfig2,
1323
+ children
1324
+ }
1325
+ );
1326
+ };
1327
+ var SortableItemContext = createContext(null);
1328
+ var useSortableItemContext = () => {
1329
+ const context = useContext(SortableItemContext);
1330
+ if (!context) {
1331
+ throw new Error(
1332
+ "useSortableItemContext must be used within a SortableItemContext"
1333
+ );
1334
+ }
1335
+ return context;
1336
+ };
1337
+ var Item = ({
1338
+ id,
1339
+ className,
1340
+ children
1341
+ }) => {
1342
+ const {
1343
+ attributes,
1344
+ isDragging,
1345
+ listeners,
1346
+ setNodeRef,
1347
+ setActivatorNodeRef,
1348
+ transform,
1349
+ transition
1350
+ } = useSortable2({ id });
1351
+ const context = useMemo2(
1352
+ () => ({
1353
+ attributes,
1354
+ listeners,
1355
+ ref: setActivatorNodeRef,
1356
+ isDragging
1357
+ }),
1358
+ [attributes, listeners, setActivatorNodeRef, isDragging]
1359
+ );
1360
+ const style = {
1361
+ opacity: isDragging ? 0.4 : void 0,
1362
+ transform: CSS2.Translate.toString(transform),
1363
+ transition
1364
+ };
1365
+ return /* @__PURE__ */ jsx5(SortableItemContext.Provider, { value: context, children: /* @__PURE__ */ jsx5(
1366
+ "li",
1367
+ {
1368
+ className: clx("transition-fg flex flex-1 list-none", className),
1369
+ ref: setNodeRef,
1370
+ style,
1371
+ children
1372
+ }
1373
+ ) });
1374
+ };
1375
+ var DragHandle = () => {
1376
+ const { attributes, listeners, ref } = useSortableItemContext();
1377
+ return /* @__PURE__ */ jsx5(
1378
+ IconButton3,
1379
+ {
1380
+ variant: "transparent",
1381
+ size: "small",
1382
+ ...attributes,
1383
+ ...listeners,
1384
+ ref,
1385
+ className: "cursor-grab touch-none active:cursor-grabbing",
1386
+ children: /* @__PURE__ */ jsx5(DotsSix2, { className: "text-ui-fg-muted" })
1387
+ }
1388
+ );
1389
+ };
1390
+ var SortableList = Object.assign(List, {
1391
+ Item,
1392
+ DragHandle
1393
+ });
1394
+
1395
+ // src/pages/products/create/components/product-create-details-form/components/product-create-details-variant-section/product-create-details-variant-section.tsx
1396
+ import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
1397
+ var ProductCreateVariantsSection = () => {
1398
+ const form = useTabbedForm();
1399
+ const { t } = useTranslation5();
1400
+ const variants = useFieldArray3({
1401
+ control: form.control,
1402
+ name: "variants"
1403
+ });
1404
+ const watchedAttributes = useWatch({
1405
+ control: form.control,
1406
+ name: "attributes",
1407
+ defaultValue: []
1408
+ });
1409
+ const watchedVariants = useWatch({
1410
+ control: form.control,
1411
+ name: "variants",
1412
+ defaultValue: []
1413
+ });
1414
+ const variantAxes = useMemo3(() => {
1415
+ return (watchedAttributes ?? []).filter((attr) => attr.use_for_variants).map((attr) => ({
1416
+ title: attr.title,
1417
+ values: Array.isArray(attr.values) ? attr.values : attr.values ? [attr.values] : []
1418
+ })).filter((axis) => axis.title && axis.values.length > 0);
1419
+ }, [watchedAttributes]);
1420
+ const hasVariantAxes = variantAxes.length > 0;
1421
+ const showInvalidVariantsMessage = form.formState.errors.variants?.root?.message === "invalid_length";
1422
+ const handleRankChange = (items) => {
1423
+ const update = items.map((item, index) => {
1424
+ const variant = watchedVariants.find((v) => v.title === item.title);
1425
+ return {
1426
+ id: item.id,
1427
+ ...variant || item,
1428
+ variant_rank: index
1429
+ };
1430
+ });
1431
+ variants.replace(update);
1432
+ };
1433
+ const getCheckboxState = (variants2) => {
1434
+ if (variants2.every((variant) => variant.should_create)) {
1435
+ return true;
1436
+ }
1437
+ if (variants2.some((variant) => variant.should_create)) {
1438
+ return "indeterminate";
1439
+ }
1440
+ return false;
1441
+ };
1442
+ const onCheckboxChange = (value) => {
1443
+ switch (value) {
1444
+ case true: {
1445
+ const update = watchedVariants.map((variant) => ({
1446
+ ...variant,
1447
+ should_create: true
1448
+ }));
1449
+ form.setValue("variants", update);
1450
+ break;
1451
+ }
1452
+ case false: {
1453
+ const update = watchedVariants.map((variant) => ({
1454
+ ...variant,
1455
+ should_create: false
1456
+ }));
1457
+ form.setValue("variants", decorateVariantsWithDefaultValues(update));
1458
+ break;
1459
+ }
1460
+ case "indeterminate":
1461
+ break;
1462
+ }
1463
+ };
1464
+ if (!hasVariantAxes) {
1465
+ return null;
1466
+ }
1467
+ return /* @__PURE__ */ jsxs6(
1468
+ "div",
1469
+ {
1470
+ id: "variants",
1471
+ className: "flex flex-col gap-y-8",
1472
+ "data-testid": "product-create-variants-section",
1473
+ children: [
1474
+ /* @__PURE__ */ jsx6("div", { className: "flex flex-col gap-y-6", children: /* @__PURE__ */ jsx6(Heading2, { level: "h2", children: t("products.create.variants.header") }) }),
1475
+ /* @__PURE__ */ jsx6("div", { className: "grid grid-cols-1 gap-x-4 gap-y-8", children: /* @__PURE__ */ jsxs6("div", { className: "flex flex-col gap-y-6", children: [
1476
+ /* @__PURE__ */ jsxs6("div", { className: "flex flex-col", children: [
1477
+ /* @__PURE__ */ jsx6(Label2, { weight: "plus", children: t("products.create.variants.productVariants.label") }),
1478
+ /* @__PURE__ */ jsx6(Hint2, { children: t("products.create.variants.productVariants.hint") })
1479
+ ] }),
1480
+ showInvalidVariantsMessage && /* @__PURE__ */ jsx6(Alert, { dismissible: true, variant: "error", children: t("products.create.errors.variants") }),
1481
+ variants.fields.length > 0 ? /* @__PURE__ */ jsxs6("div", { className: "overflow-hidden rounded-xl border", children: [
1482
+ /* @__PURE__ */ jsxs6(
1483
+ "div",
1484
+ {
1485
+ className: "bg-ui-bg-component text-ui-fg-subtle grid items-center gap-3 border-b px-6 py-2.5",
1486
+ style: {
1487
+ gridTemplateColumns: `20px 28px repeat(${variantAxes.length}, 1fr)`
1488
+ },
1489
+ children: [
1490
+ /* @__PURE__ */ jsx6("div", { children: /* @__PURE__ */ jsx6(
1491
+ Checkbox,
1492
+ {
1493
+ className: "relative",
1494
+ checked: getCheckboxState(watchedVariants),
1495
+ onCheckedChange: onCheckboxChange
1496
+ }
1497
+ ) }),
1498
+ /* @__PURE__ */ jsx6("div", {}),
1499
+ variantAxes.map((axis, index) => /* @__PURE__ */ jsx6("div", { children: /* @__PURE__ */ jsx6(Text3, { size: "small", leading: "compact", weight: "plus", children: axis.title }) }, index))
1500
+ ]
1501
+ }
1502
+ ),
1503
+ /* @__PURE__ */ jsx6(
1504
+ SortableList,
1505
+ {
1506
+ items: variants.fields,
1507
+ onChange: handleRankChange,
1508
+ renderItem: (item, index) => {
1509
+ return /* @__PURE__ */ jsx6(
1510
+ SortableList.Item,
1511
+ {
1512
+ id: item.id,
1513
+ className: clx2("bg-ui-bg-base border-b", {
1514
+ "border-b-0": index === variants.fields.length - 1
1515
+ }),
1516
+ children: /* @__PURE__ */ jsxs6(
1517
+ "div",
1518
+ {
1519
+ className: "text-ui-fg-subtle grid w-full items-center gap-3 px-6 py-2.5",
1520
+ style: {
1521
+ gridTemplateColumns: `20px 28px repeat(${variantAxes.length}, 1fr)`
1522
+ },
1523
+ children: [
1524
+ /* @__PURE__ */ jsx6(
1525
+ Form.Field,
1526
+ {
1527
+ control: form.control,
1528
+ name: `variants.${index}.should_create`,
1529
+ render: ({
1530
+ field: { value, onChange, ...field }
1531
+ }) => /* @__PURE__ */ jsx6(Form.Item, { children: /* @__PURE__ */ jsx6(Form.Control, { children: /* @__PURE__ */ jsx6(
1532
+ Checkbox,
1533
+ {
1534
+ className: "relative",
1535
+ ...field,
1536
+ checked: value,
1537
+ onCheckedChange: onChange
1538
+ }
1539
+ ) }) })
1540
+ }
1541
+ ),
1542
+ /* @__PURE__ */ jsx6(SortableList.DragHandle, {}),
1543
+ variantAxes.map((axis, i) => /* @__PURE__ */ jsx6(Text3, { size: "small", leading: "compact", children: item.attribute_values?.[axis.title] ?? "-" }, i))
1544
+ ]
1545
+ }
1546
+ )
1547
+ }
1548
+ );
1549
+ }
1550
+ }
1551
+ )
1552
+ ] }) : /* @__PURE__ */ jsx6(Alert, { children: t("products.create.variants.productVariants.alert") }),
1553
+ variants.fields.length > 0 && /* @__PURE__ */ jsx6(InlineTip2, { label: t("general.tip"), children: t("products.create.variants.productVariants.tip") })
1554
+ ] }) })
1555
+ ]
1556
+ }
1557
+ );
1558
+ };
1559
+
1560
+ // src/pages/products/create/components/product-create-details-form/product-create-details-form.tsx
1561
+ import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
1562
+ var Root2 = () => {
1563
+ return /* @__PURE__ */ jsx7(
1564
+ "div",
1565
+ {
1566
+ className: "flex flex-col items-center p-16",
1567
+ "data-testid": "product-create-details-form",
1568
+ children: /* @__PURE__ */ jsxs7(
1569
+ "div",
1570
+ {
1571
+ className: "flex w-full max-w-[720px] flex-col gap-y-8",
1572
+ "data-testid": "product-create-details-form-content",
1573
+ children: [
1574
+ /* @__PURE__ */ jsx7(Header, {}),
1575
+ /* @__PURE__ */ jsxs7(
1576
+ "div",
1577
+ {
1578
+ className: "flex flex-col gap-y-6",
1579
+ "data-testid": "product-create-details-form-sections",
1580
+ children: [
1581
+ /* @__PURE__ */ jsx7(ProductCreateGeneralSection, {}),
1582
+ /* @__PURE__ */ jsx7(ProductCreateMediaSection, {})
1583
+ ]
1584
+ }
1585
+ ),
1586
+ /* @__PURE__ */ jsx7(ProductCreateVariantsSection, {})
1587
+ ]
1588
+ }
1589
+ )
1590
+ }
1591
+ );
1592
+ };
1593
+ Root2._tabMeta = defineTabMeta({
1594
+ id: "details",
1595
+ labelKey: "products.create.tabs.details",
1596
+ validationFields: ["title", "handle", "description", "media"]
1597
+ });
1598
+ var ProductCreateDetailsForm = Root2;
1599
+ var Header = () => {
1600
+ const { t } = useTranslation6();
1601
+ return /* @__PURE__ */ jsx7(
1602
+ "div",
1603
+ {
1604
+ className: "flex flex-col",
1605
+ "data-testid": "product-create-details-form-header",
1606
+ children: /* @__PURE__ */ jsx7(Heading3, { "data-testid": "product-create-details-form-heading", children: t("products.create.header") })
1607
+ }
1608
+ );
1609
+ };
1610
+
1611
+ // src/pages/products/create/components/product-create-organize-form/components/product-create-organize-section/product-create-details-organize-section.tsx
1612
+ import { Heading as Heading4 } from "@medusajs/ui";
1613
+ import { useTranslation as useTranslation7 } from "react-i18next";
1614
+ import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
1615
+ var ProductCreateOrganizationSection = () => {
1616
+ const form = useTabbedForm();
1617
+ const { t } = useTranslation7();
1618
+ const collections = useComboboxData({
1619
+ queryKey: ["product_collections"],
1620
+ queryFn: (params) => sdk.vendor.collections.query(params),
1621
+ getOptions: (data) => data.collections.map((collection) => ({
1622
+ label: collection.title,
1623
+ value: collection.id
1624
+ }))
1625
+ });
1626
+ const types = useComboboxData({
1627
+ queryKey: ["product_types"],
1628
+ queryFn: (params) => sdk.vendor.productTypes.query(params),
1629
+ getOptions: (data) => data.product_types.map((type) => ({
1630
+ label: type.value,
1631
+ value: type.id
1632
+ }))
1633
+ });
1634
+ const tags = useComboboxData({
1635
+ queryKey: ["product_tags"],
1636
+ queryFn: (params) => sdk.vendor.productTags.query(params),
1637
+ getOptions: (data) => data.product_tags.map((tag) => ({
1638
+ label: tag.value,
1639
+ value: tag.id
1640
+ }))
1641
+ });
1642
+ return /* @__PURE__ */ jsxs8("div", { id: "organize", className: "flex flex-col gap-y-8", "data-testid": "product-create-organize-section", children: [
1643
+ /* @__PURE__ */ jsx8(Heading4, { "data-testid": "product-create-organize-section-heading", children: t("products.organization.header") }),
1644
+ /* @__PURE__ */ jsx8(
1645
+ SwitchBox,
1646
+ {
1647
+ control: form.control,
1648
+ name: "discountable",
1649
+ label: t("products.fields.discountable.label"),
1650
+ description: t("products.fields.discountable.hint"),
1651
+ optional: true
1652
+ }
1653
+ ),
1654
+ /* @__PURE__ */ jsxs8("div", { className: "grid grid-cols-1 gap-4 md:grid-cols-2", "data-testid": "product-create-organize-section-category-collection", children: [
1655
+ /* @__PURE__ */ jsx8(
1656
+ Form.Field,
1657
+ {
1658
+ control: form.control,
1659
+ name: "category_id",
1660
+ render: ({ field }) => {
1661
+ return /* @__PURE__ */ jsxs8(Form.Item, { "data-testid": "product-create-organize-section-category-item", children: [
1662
+ /* @__PURE__ */ jsx8(Form.Label, { "data-testid": "product-create-organize-section-category-label", children: t("fields.category") }),
1663
+ /* @__PURE__ */ jsx8(Form.Control, { "data-testid": "product-create-organize-section-category-control", children: /* @__PURE__ */ jsx8(SingleCategoryCombobox, { ...field }) }),
1664
+ /* @__PURE__ */ jsx8(Form.ErrorMessage, {})
1665
+ ] });
1666
+ }
1667
+ }
1668
+ ),
1669
+ /* @__PURE__ */ jsx8(
1670
+ Form.Field,
1671
+ {
1672
+ control: form.control,
1673
+ name: "collection_id",
1674
+ render: ({ field }) => {
1675
+ return /* @__PURE__ */ jsxs8(Form.Item, { "data-testid": "product-create-organize-section-collection-item", children: [
1676
+ /* @__PURE__ */ jsx8(Form.Label, { optional: true, "data-testid": "product-create-organize-section-collection-label", children: t("products.fields.collection.label") }),
1677
+ /* @__PURE__ */ jsx8(Form.Control, { "data-testid": "product-create-organize-section-collection-control", children: /* @__PURE__ */ jsx8(
1678
+ Combobox,
1679
+ {
1680
+ ...field,
1681
+ options: collections.options,
1682
+ searchValue: collections.searchValue,
1683
+ onSearchValueChange: collections.onSearchValueChange,
1684
+ fetchNextPage: collections.fetchNextPage
1685
+ }
1686
+ ) }),
1687
+ /* @__PURE__ */ jsx8(Form.ErrorMessage, {})
1688
+ ] });
1689
+ }
1690
+ }
1691
+ )
1692
+ ] }),
1693
+ /* @__PURE__ */ jsxs8("div", { className: "grid grid-cols-1 gap-4 md:grid-cols-2", "data-testid": "product-create-organize-section-type-tags", children: [
1694
+ /* @__PURE__ */ jsx8(
1695
+ Form.Field,
1696
+ {
1697
+ control: form.control,
1698
+ name: "type_id",
1699
+ render: ({ field }) => {
1700
+ return /* @__PURE__ */ jsxs8(Form.Item, { "data-testid": "product-create-organize-section-type-item", children: [
1701
+ /* @__PURE__ */ jsx8(Form.Label, { optional: true, "data-testid": "product-create-organize-section-type-label", children: t("products.fields.type.label") }),
1702
+ /* @__PURE__ */ jsx8(Form.Control, { "data-testid": "product-create-organize-section-type-control", children: /* @__PURE__ */ jsx8(
1703
+ Combobox,
1704
+ {
1705
+ ...field,
1706
+ options: types.options,
1707
+ searchValue: types.searchValue,
1708
+ onSearchValueChange: types.onSearchValueChange,
1709
+ fetchNextPage: types.fetchNextPage
1710
+ }
1711
+ ) }),
1712
+ /* @__PURE__ */ jsx8(Form.ErrorMessage, {})
1713
+ ] });
1714
+ }
1715
+ }
1716
+ ),
1717
+ /* @__PURE__ */ jsx8(
1718
+ Form.Field,
1719
+ {
1720
+ control: form.control,
1721
+ name: "tags",
1722
+ render: ({ field }) => {
1723
+ return /* @__PURE__ */ jsxs8(Form.Item, { "data-testid": "product-create-organize-section-tags-item", children: [
1724
+ /* @__PURE__ */ jsx8(Form.Label, { optional: true, "data-testid": "product-create-organize-section-tags-label", children: t("products.fields.tags.label") }),
1725
+ /* @__PURE__ */ jsx8(Form.Control, { "data-testid": "product-create-organize-section-tags-control", children: /* @__PURE__ */ jsx8(
1726
+ Combobox,
1727
+ {
1728
+ ...field,
1729
+ options: tags.options,
1730
+ searchValue: tags.searchValue,
1731
+ onSearchValueChange: tags.onSearchValueChange,
1732
+ fetchNextPage: tags.fetchNextPage
1733
+ }
1734
+ ) }),
1735
+ /* @__PURE__ */ jsx8(Form.ErrorMessage, {})
1736
+ ] });
1737
+ }
1738
+ }
1739
+ )
1740
+ ] })
1741
+ ] });
1742
+ };
1743
+
1744
+ // src/pages/products/create/components/product-create-organize-form/product-create-organize-form.tsx
1745
+ import { jsx as jsx9 } from "react/jsx-runtime";
1746
+ var Root3 = () => {
1747
+ return /* @__PURE__ */ jsx9(
1748
+ "div",
1749
+ {
1750
+ className: "flex flex-col items-center p-16",
1751
+ "data-testid": "product-create-organize-form",
1752
+ children: /* @__PURE__ */ jsx9(
1753
+ "div",
1754
+ {
1755
+ className: "flex w-full max-w-[720px] flex-col gap-y-8",
1756
+ "data-testid": "product-create-organize-form-content",
1757
+ children: /* @__PURE__ */ jsx9(ProductCreateOrganizationSection, {})
1758
+ }
1759
+ )
1760
+ }
1761
+ );
1762
+ };
1763
+ Root3._tabMeta = defineTabMeta({
1764
+ id: "organize",
1765
+ labelKey: "products.create.tabs.organize",
1766
+ validationFields: [
1767
+ "type_id",
1768
+ "collection_id",
1769
+ "category_id",
1770
+ "tags",
1771
+ "origin_country",
1772
+ "material",
1773
+ "width",
1774
+ "length",
1775
+ "height",
1776
+ "weight",
1777
+ "mid_code",
1778
+ "hs_code"
1779
+ ]
1780
+ });
1781
+ var ProductCreateOrganizeForm = Root3;
1782
+
1783
+ // src/pages/products/create/components/product-create-variants-form/product-create-variants-form.tsx
1784
+ import { useMemo as useMemo4 } from "react";
1785
+ import { useWatch as useWatch2 } from "react-hook-form";
1786
+ import { useTranslation as useTranslation8 } from "react-i18next";
1787
+ import { jsx as jsx10 } from "react/jsx-runtime";
1788
+ var Root4 = () => {
1789
+ const form = useTabbedForm();
1790
+ const { setCloseOnEscape } = useRouteModal();
1791
+ const variants = useWatch2({
1792
+ control: form.control,
1793
+ name: "variants",
1794
+ defaultValue: []
1795
+ });
1796
+ const watchedAttributes = useWatch2({
1797
+ control: form.control,
1798
+ name: "attributes",
1799
+ defaultValue: []
1800
+ });
1801
+ const variantAxes = useMemo4(() => {
1802
+ return (watchedAttributes ?? []).filter((attr) => attr.use_for_variants && attr.title).map((attr) => ({
1803
+ title: attr.title
1804
+ }));
1805
+ }, [watchedAttributes]);
1806
+ const columns = useColumns2({ variantAxes });
1807
+ const variantData = useMemo4(() => {
1808
+ const ret = [];
1809
+ variants.forEach((v, i) => {
1810
+ if (v.should_create) {
1811
+ ret.push({ ...v, originalIndex: i });
1812
+ }
1813
+ });
1814
+ return ret;
1815
+ }, [variants]);
1816
+ return /* @__PURE__ */ jsx10(
1817
+ "div",
1818
+ {
1819
+ className: "flex size-full flex-col divide-y overflow-hidden",
1820
+ "data-testid": "product-create-variants-form",
1821
+ children: /* @__PURE__ */ jsx10("div", { "data-testid": "product-create-variants-form-datagrid", children: /* @__PURE__ */ jsx10(
1822
+ DataGrid,
1823
+ {
1824
+ columns,
1825
+ data: variantData,
1826
+ state: form,
1827
+ onEditingChange: (editing) => setCloseOnEscape(!editing)
1828
+ }
1829
+ ) })
1830
+ }
1831
+ );
1832
+ };
1833
+ Root4._tabMeta = defineTabMeta({
1834
+ id: "variants",
1835
+ labelKey: "products.create.tabs.variants",
1836
+ validationFields: ["variants"]
1837
+ });
1838
+ var ProductCreateVariantsForm = Root4;
1839
+ var columnHelper2 = createDataGridHelper();
1840
+ var useColumns2 = ({
1841
+ variantAxes
1842
+ }) => {
1843
+ const { t } = useTranslation8();
1844
+ return useMemo4(
1845
+ () => [
1846
+ columnHelper2.column({
1847
+ id: "attributes",
1848
+ header: () => /* @__PURE__ */ jsx10("div", { className: "flex size-full items-center overflow-hidden", children: /* @__PURE__ */ jsx10("span", { className: "truncate", children: variantAxes.map((a) => a.title).join(" / ") }) }),
1849
+ cell: (context) => {
1850
+ return /* @__PURE__ */ jsx10(DataGrid.ReadonlyCell, { context, children: variantAxes.map((a) => context.row.original.attribute_values?.[a.title]).join(" / ") });
1851
+ },
1852
+ disableHiding: true
1853
+ }),
1854
+ columnHelper2.column({
1855
+ id: "title",
1856
+ name: t("fields.title"),
1857
+ header: t("fields.title"),
1858
+ field: (context) => `variants.${context.row.original.originalIndex}.title`,
1859
+ type: "text",
1860
+ cell: (context) => {
1861
+ return /* @__PURE__ */ jsx10(DataGrid.TextCell, { context });
1862
+ }
1863
+ }),
1864
+ columnHelper2.column({
1865
+ id: "sku",
1866
+ name: t("fields.sku"),
1867
+ header: t("fields.sku"),
1868
+ field: (context) => `variants.${context.row.original.originalIndex}.sku`,
1869
+ type: "text",
1870
+ cell: (context) => {
1871
+ return /* @__PURE__ */ jsx10(DataGrid.TextCell, { context });
1872
+ }
1873
+ })
1874
+ ],
1875
+ [variantAxes, t]
1876
+ );
1877
+ };
1878
+
1879
+ // src/pages/products/create/components/product-create-form/product-create-form.tsx
1880
+ import { jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
1881
+ var SAVE_DRAFT_BUTTON = "save-draft-button";
1882
+ var ProductCreateForm = ({
1883
+ children,
1884
+ schema,
1885
+ defaultValues: extraDefaults
1886
+ }) => {
1887
+ const { t } = useTranslation9();
1888
+ const { handleSuccess } = useRouteModal();
1889
+ const form = useForm({
1890
+ defaultValues: {
1891
+ ...PRODUCT_CREATE_FORM_DEFAULTS,
1892
+ ...extraDefaults
1893
+ },
1894
+ resolver: zodResolver(schema ?? ProductCreateSchema)
1895
+ });
1896
+ const { mutateAsync, isPending } = useCreateProduct();
1897
+ const { feature_flags } = useFeatureFlags();
1898
+ const productRequestEnabled = !!feature_flags?.[import_types6.MercurFeatureFlags.PRODUCT_REQUEST];
1899
+ const watchedAttributes = useWatch3({
1900
+ control: form.control,
1901
+ name: "attributes"
1902
+ });
1903
+ useEffect3(() => {
1904
+ const currentVariants = form.getValues("variants") ?? [];
1905
+ const newVariants = generateVariantsFromAttributes(
1906
+ watchedAttributes ?? [],
1907
+ currentVariants
1908
+ );
1909
+ if (JSON.stringify(newVariants.map((v) => v.attribute_values)) !== JSON.stringify(currentVariants.map((v) => v.attribute_values))) {
1910
+ form.setValue("variants", newVariants);
1911
+ }
1912
+ }, [watchedAttributes]);
1913
+ const handleSubmit = form.handleSubmit(async (values, e) => {
1914
+ let isDraftSubmission = false;
1915
+ if (e?.nativeEvent instanceof SubmitEvent) {
1916
+ const submitter = e?.nativeEvent?.submitter;
1917
+ isDraftSubmission = submitter?.dataset?.name === SAVE_DRAFT_BUTTON;
1918
+ }
1919
+ const media = values.media || [];
1920
+ const payload = { ...values, media: void 0 };
1921
+ let uploadedMedia = [];
1922
+ try {
1923
+ const filesToUpload = media.map((m, i) => ({ file: m.file, isThumbnail: m.isThumbnail, index: i })).filter((m) => !!m.file);
1924
+ if (filesToUpload.length) {
1925
+ const result = await uploadFilesQuery(
1926
+ filesToUpload.map(({ file }) => ({ file }))
1927
+ );
1928
+ const uploadedFiles = result?.files ?? [];
1929
+ uploadedMedia = uploadedFiles.map((file, i) => ({
1930
+ ...file,
1931
+ isThumbnail: filesToUpload[i].isThumbnail
1932
+ }));
1933
+ }
1934
+ } catch (error) {
1935
+ if (error instanceof Error) {
1936
+ toast.error(error.message);
1937
+ }
1938
+ }
1939
+ const submittedStatus = isDraftSubmission ? "draft" : productRequestEnabled ? "proposed" : "published";
1940
+ await mutateAsync(
1941
+ normalizeProductFormValues({
1942
+ ...payload,
1943
+ media: uploadedMedia,
1944
+ status: submittedStatus
1945
+ }),
1946
+ {
1947
+ onSuccess: (data) => {
1948
+ if (submittedStatus === "proposed") {
1949
+ toast.success(t("products.create.requestSuccessToast"));
1950
+ } else {
1951
+ toast.success(
1952
+ t("products.create.successToast", {
1953
+ title: data.product.title
1954
+ })
1955
+ );
1956
+ }
1957
+ handleSuccess(`../${data.product.id}`);
1958
+ },
1959
+ onError: (error) => {
1960
+ toast.error(error.message);
1961
+ }
1962
+ }
1963
+ );
1964
+ });
1965
+ const defaultTabs = useMemo5(
1966
+ () => [
1967
+ /* @__PURE__ */ jsx11(ProductCreateDetailsForm, {}, "details"),
1968
+ /* @__PURE__ */ jsx11(ProductCreateOrganizeForm, {}, "organize"),
1969
+ /* @__PURE__ */ jsx11(ProductCreateAttributesForm, {}, "attributes"),
1970
+ /* @__PURE__ */ jsx11(ProductCreateVariantsForm, {}, "variants")
1971
+ ],
1972
+ []
1973
+ );
1974
+ const hasCustomChildren = Children.count(children) > 0;
1975
+ return /* @__PURE__ */ jsx11(
1976
+ TabbedForm,
1977
+ {
1978
+ form,
1979
+ onSubmit: handleSubmit,
1980
+ isLoading: isPending,
1981
+ footer: ({ isLastTab, onNext, isLoading }) => /* @__PURE__ */ jsxs9(
1982
+ "div",
1983
+ {
1984
+ className: "flex items-center justify-end gap-x-2",
1985
+ "data-testid": "product-create-form-footer-actions",
1986
+ children: [
1987
+ /* @__PURE__ */ jsx11(RouteFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsx11(
1988
+ Button3,
1989
+ {
1990
+ variant: "secondary",
1991
+ size: "small",
1992
+ "data-testid": "product-create-form-cancel-button",
1993
+ children: t("actions.cancel")
1994
+ }
1995
+ ) }),
1996
+ /* @__PURE__ */ jsx11(
1997
+ Button3,
1998
+ {
1999
+ "data-name": SAVE_DRAFT_BUTTON,
2000
+ size: "small",
2001
+ type: "submit",
2002
+ isLoading,
2003
+ className: "whitespace-nowrap",
2004
+ "data-testid": "product-create-form-save-draft-button",
2005
+ children: t("actions.saveAsDraft")
2006
+ }
2007
+ ),
2008
+ isLastTab ? /* @__PURE__ */ jsx11(
2009
+ Button3,
2010
+ {
2011
+ "data-name": "publish-button",
2012
+ type: "submit",
2013
+ variant: "primary",
2014
+ size: "small",
2015
+ isLoading,
2016
+ "data-testid": "product-create-form-publish-button",
2017
+ children: t("actions.publish")
2018
+ },
2019
+ "submit-button"
2020
+ ) : /* @__PURE__ */ jsx11(
2021
+ Button3,
2022
+ {
2023
+ type: "button",
2024
+ variant: "primary",
2025
+ size: "small",
2026
+ onClick: () => onNext(),
2027
+ "data-testid": "product-create-form-continue-button",
2028
+ children: t("actions.continue")
2029
+ },
2030
+ "next-button"
2031
+ )
2032
+ ]
2033
+ }
2034
+ ),
2035
+ children: hasCustomChildren ? children : defaultTabs
2036
+ }
2037
+ );
2038
+ };
2039
+
2040
+ // src/pages/products/create/product-create.tsx
2041
+ import { jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
2042
+ var Root5 = ({ children }) => {
2043
+ const { t } = useTranslation10();
2044
+ return /* @__PURE__ */ jsxs10(RouteFocusModal, { children: [
2045
+ /* @__PURE__ */ jsx12(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx12("span", { className: "sr-only", children: t("products.create.title") }) }),
2046
+ /* @__PURE__ */ jsx12(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsx12("span", { className: "sr-only", children: t("products.create.description") }) }),
2047
+ Children2.count(children) > 0 ? children : /* @__PURE__ */ jsx12(ProductCreateForm, {})
2048
+ ] });
2049
+ };
2050
+ var ProductCreate = Root5;
2051
+ var ProductCreatePage = Object.assign(Root5, {
2052
+ Form: ProductCreateForm,
2053
+ DetailsTab: ProductCreateDetailsForm,
2054
+ OrganizeTab: ProductCreateOrganizeForm,
2055
+ AttributesTab: ProductCreateAttributesForm,
2056
+ VariantsTab: ProductCreateVariantsForm,
2057
+ Tab: TabbedForm.Tab
2058
+ });
2059
+
2060
+ export {
2061
+ ProductCreate,
2062
+ ProductCreatePage
2063
+ };