@medusajs/dashboard 3.0.0-snapshot-20251114155958 → 3.0.0-snapshot-20251126221441

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 (253) hide show
  1. package/dist/{adjust-inventory-ZB3AVET7.mjs → adjust-inventory-WZOCLB5V.mjs} +1 -1
  2. package/dist/{api-key-management-create-U6VGZK7R.mjs → api-key-management-create-W7NL2IYN.mjs} +3 -3
  3. package/dist/{api-key-management-detail-B5XNEGKF.mjs → api-key-management-detail-3F77JKQT.mjs} +13 -13
  4. package/dist/{api-key-management-edit-TJM737A7.mjs → api-key-management-edit-TLVLXAVK.mjs} +3 -3
  5. package/dist/{api-key-management-list-ZRYMMTF5.mjs → api-key-management-list-FTLC3ELT.mjs} +3 -3
  6. package/dist/{api-key-management-sales-channels-D2RAHI7W.mjs → api-key-management-sales-channels-NYY3NZOE.mjs} +4 -4
  7. package/dist/app.css +3 -3
  8. package/dist/app.js +16021 -17376
  9. package/dist/app.mjs +11 -11
  10. package/dist/{campaign-create-IXOWJQ4L.mjs → campaign-create-LHL7FKQK.mjs} +3 -3
  11. package/dist/{campaign-detail-RCA3TBE4.mjs → campaign-detail-G2FIHVM2.mjs} +10 -10
  12. package/dist/{categories-metadata-5NBC7HX4.mjs → categories-metadata-YEF2WFML.mjs} +10 -10
  13. package/dist/{category-create-BTMZYQ5R.mjs → category-create-ELMCLH4J.mjs} +5 -5
  14. package/dist/{category-detail-RBUJVFPN.mjs → category-detail-ORXA4DBA.mjs} +14 -14
  15. package/dist/{category-edit-Q3KEELHO.mjs → category-edit-TYKLEYGE.mjs} +2 -2
  16. package/dist/{category-list-Z6HS6N75.mjs → category-list-IJ3DLPYQ.mjs} +5 -5
  17. package/dist/{category-organize-45NPSRNG.mjs → category-organize-PDLC54E2.mjs} +2 -2
  18. package/dist/{category-products-KREOO2KQ.mjs → category-products-GXTUJNT6.mjs} +13 -13
  19. package/dist/{chunk-SAZHCRHS.mjs → chunk-2PZVZSZW.mjs} +1 -1
  20. package/dist/{chunk-NFEW5CVI.mjs → chunk-3C6WQ7NH.mjs} +3 -37
  21. package/dist/{chunk-KF22R23X.mjs → chunk-3UOOSL7Y.mjs} +1 -1
  22. package/dist/{chunk-BYZSMXJ7.mjs → chunk-4DDI2KIE.mjs} +1 -1
  23. package/dist/{chunk-5N33TBBX.mjs → chunk-56TDUOXV.mjs} +1 -1
  24. package/dist/{chunk-67RC6SEX.mjs → chunk-5LGRZSEH.mjs} +1 -1
  25. package/dist/{chunk-W4TIFG3A.mjs → chunk-6KMZSZIA.mjs} +5 -5
  26. package/dist/{chunk-P23S5LDK.mjs → chunk-7V2JZU2B.mjs} +2 -2
  27. package/dist/{chunk-GHBURGZC.mjs → chunk-A6PWH2CK.mjs} +1 -1
  28. package/dist/{chunk-KJU3T6BK.mjs → chunk-AEMKNDRM.mjs} +2 -2
  29. package/dist/{chunk-QW4SQVMT.mjs → chunk-AENRV3N7.mjs} +50 -109
  30. package/dist/{chunk-O5DGX2NZ.mjs → chunk-AF7A24XI.mjs} +1 -1
  31. package/dist/{chunk-F7LJJHQT.mjs → chunk-C7F7MMXS.mjs} +1 -0
  32. package/dist/{chunk-CWIMWR6L.mjs → chunk-D6DIMX3W.mjs} +15 -15
  33. package/dist/{chunk-3RRA56WC.mjs → chunk-DODQ3KJT.mjs} +3 -8
  34. package/dist/{chunk-FJHAGJ5G.mjs → chunk-ETOJCN3Q.mjs} +1 -1
  35. package/dist/{chunk-YVQIO3JS.mjs → chunk-GYHQTVXN.mjs} +236 -318
  36. package/dist/{chunk-FNQ227BC.mjs → chunk-K5QWNI6V.mjs} +1 -1
  37. package/dist/{chunk-ZOJRDXH3.mjs → chunk-KC64IT2X.mjs} +1 -1
  38. package/dist/{chunk-K75OQ7QA.mjs → chunk-KHNOLBMA.mjs} +2 -2
  39. package/dist/{chunk-MOGV3UZD.mjs → chunk-KLNRCI3K.mjs} +1 -1
  40. package/dist/{chunk-YGEJFHC3.mjs → chunk-M3CKVBZC.mjs} +1 -1
  41. package/dist/{chunk-VW34SZWE.mjs → chunk-MDVO5GXZ.mjs} +2 -2
  42. package/dist/{chunk-7H6DB666.mjs → chunk-O4RZ3Y65.mjs} +1 -1
  43. package/dist/{chunk-5AM254NB.mjs → chunk-OFN7DIZA.mjs} +3 -83
  44. package/dist/{chunk-42TMWI76.mjs → chunk-OXPE5TAY.mjs} +1 -1
  45. package/dist/{chunk-NZNJSGGE.mjs → chunk-SIR4PJ4E.mjs} +3 -3
  46. package/dist/{chunk-QPJUVTKW.mjs → chunk-SWS2BE3M.mjs} +1 -1
  47. package/dist/{chunk-OMRGW7JS.mjs → chunk-T2ANPJ36.mjs} +3 -3
  48. package/dist/{chunk-ZE34KAKV.mjs → chunk-U63NCO35.mjs} +2 -2
  49. package/dist/{chunk-2WLOIS3L.mjs → chunk-WGRVE7KY.mjs} +21 -2
  50. package/dist/{chunk-BKJMQ6RP.mjs → chunk-WYITLR2E.mjs} +1 -1
  51. package/dist/{chunk-Y5TTJDGO.mjs → chunk-ZT7CR32D.mjs} +1 -1
  52. package/dist/{collection-add-products-KM4VO5G5.mjs → collection-add-products-D2KOVZPZ.mjs} +14 -14
  53. package/dist/{collection-create-RIGJHEX5.mjs → collection-create-I2A2X4VK.mjs} +2 -2
  54. package/dist/{collection-detail-MLVNULUS.mjs → collection-detail-ZT535E5T.mjs} +14 -14
  55. package/dist/{collection-edit-WX5G3FHR.mjs → collection-edit-RGH7NCUE.mjs} +2 -2
  56. package/dist/{collection-list-KWAHQGFE.mjs → collection-list-53JPFHPN.mjs} +23 -24
  57. package/dist/{collection-metadata-OMFOP3LA.mjs → collection-metadata-SQCA35II.mjs} +11 -11
  58. package/dist/{customer-detail-SVDGB2QD.mjs → customer-detail-W55EJ6LX.mjs} +14 -14
  59. package/dist/{customer-group-detail-OCQTI4GG.mjs → customer-group-detail-2WFTU5KU.mjs} +13 -13
  60. package/dist/{customer-group-list-K5MTMFLG.mjs → customer-group-list-GLF37WEN.mjs} +13 -13
  61. package/dist/{customers-add-customer-group-2LLBHTX3.mjs → customers-add-customer-group-KXT7RDV3.mjs} +13 -13
  62. package/dist/{edit-inventory-item-O6JLGZE4.mjs → edit-inventory-item-LMDNUI6M.mjs} +1 -1
  63. package/dist/{edit-inventory-item-attributes-AUVR3GYY.mjs → edit-inventory-item-attributes-DPJIHBP3.mjs} +1 -1
  64. package/dist/{edit-reservation-GQ6R6GVA.mjs → edit-reservation-IOOZBJ2T.mjs} +2 -2
  65. package/dist/{edit-rules-G7YMD5RC.mjs → edit-rules-7TG76PR3.mjs} +12 -12
  66. package/dist/en.json +3 -49
  67. package/dist/{inventory-create-GMFEGLE4.mjs → inventory-create-NQUETR3V.mjs} +10 -10
  68. package/dist/{inventory-detail-3BTAVXLJ.mjs → inventory-detail-ADLVUQJM.mjs} +10 -10
  69. package/dist/{inventory-list-ADJQDNX5.mjs → inventory-list-RQBI7UJX.mjs} +1 -1
  70. package/dist/{inventory-metadata-JJBXLQJG.mjs → inventory-metadata-45YATS7H.mjs} +10 -10
  71. package/dist/{inventory-stock-RHLN6ARK.mjs → inventory-stock-UG3CW3TM.mjs} +10 -10
  72. package/dist/{location-detail-F5QYFPUH.mjs → location-detail-BBPTVSP5.mjs} +15 -15
  73. package/dist/{location-fulfillment-providers-7JXNE6YT.mjs → location-fulfillment-providers-6AHWONY4.mjs} +14 -15
  74. package/dist/{location-sales-channels-JPH5BTUY.mjs → location-sales-channels-UVYT52SH.mjs} +3 -3
  75. package/dist/{location-service-zone-shipping-option-create-7VTPJAPA.mjs → location-service-zone-shipping-option-create-WEIDYZZT.mjs} +11 -11
  76. package/dist/{location-service-zone-shipping-option-edit-OYTEZGGC.mjs → location-service-zone-shipping-option-edit-TQNTCYII.mjs} +4 -4
  77. package/dist/{login-BGH5LSM4.mjs → login-VQ7YFW6V.mjs} +10 -10
  78. package/dist/{manage-locations-ATCDVTSR.mjs → manage-locations-2VDQ3ILT.mjs} +1 -1
  79. package/dist/{order-allocate-items-PHIW64XK.mjs → order-allocate-items-SSDLHV7A.mjs} +3 -3
  80. package/dist/{order-create-claim-NPQ6E5DR.mjs → order-create-claim-RAGNQ2RR.mjs} +18 -18
  81. package/dist/{order-create-edit-R4ZITC5I.mjs → order-create-edit-PRJWTWWE.mjs} +31 -16
  82. package/dist/{order-create-exchange-6XPYKVYN.mjs → order-create-exchange-DRSFEEL3.mjs} +60 -34
  83. package/dist/{order-create-fulfillment-7DVPBUES.mjs → order-create-fulfillment-URKHLFR7.mjs} +14 -14
  84. package/dist/{order-create-refund-7KEOYZTF.mjs → order-create-refund-VZG3UXLV.mjs} +15 -15
  85. package/dist/{order-create-return-J23AFCKP.mjs → order-create-return-P3OCXJSI.mjs} +6 -6
  86. package/dist/{order-create-shipment-KNXCANID.mjs → order-create-shipment-QZBUE342.mjs} +10 -10
  87. package/dist/{order-detail-7ATBL7GN.mjs → order-detail-32Y6JK42.mjs} +31 -31
  88. package/dist/{order-edit-billing-address-VS75YMUY.mjs → order-edit-billing-address-MUICLYNN.mjs} +11 -11
  89. package/dist/{order-edit-email-GEE7SF2E.mjs → order-edit-email-ADNCGCS3.mjs} +11 -11
  90. package/dist/{order-edit-shipping-address-HSRXSRLU.mjs → order-edit-shipping-address-NZF3KMVV.mjs} +11 -11
  91. package/dist/{order-list-GJTJHLZF.mjs → order-list-33SMDKZD.mjs} +5 -4
  92. package/dist/{order-metadata-LUBKP5Y4.mjs → order-metadata-UEKHMTAD.mjs} +10 -10
  93. package/dist/{order-receive-return-FLI44JN2.mjs → order-receive-return-5SB26KCQ.mjs} +11 -11
  94. package/dist/{order-request-transfer-NH2XCHMV.mjs → order-request-transfer-QS3LMEBW.mjs} +12 -12
  95. package/dist/{price-list-configuration-SS2VMD4N.mjs → price-list-configuration-CZPMKLNL.mjs} +4 -4
  96. package/dist/{price-list-create-DZR7JCDG.mjs → price-list-create-2YZRNBRI.mjs} +17 -17
  97. package/dist/{price-list-detail-4INABJQQ.mjs → price-list-detail-EGGLDH5B.mjs} +24 -20
  98. package/dist/{price-list-edit-VRI5T4W3.mjs → price-list-edit-3VNSZH4F.mjs} +2 -2
  99. package/dist/{price-list-list-S2HWTXKV.mjs → price-list-list-AU4IVCQN.mjs} +34 -18
  100. package/dist/{price-list-prices-add-DO43IEAD.mjs → price-list-prices-add-YRXYOXUG.mjs} +16 -14
  101. package/dist/{price-list-prices-edit-TRCLLGU4.mjs → price-list-prices-edit-UHOZKA75.mjs} +5 -3
  102. package/dist/{product-attributes-D6MNCAJB.mjs → product-attributes-W2PIZ6AU.mjs} +12 -12
  103. package/dist/{product-create-JQQTUEQL.mjs → product-create-UY3QXGNY.mjs} +554 -377
  104. package/dist/product-create-option-GAEPSU6J.mjs +145 -0
  105. package/dist/{product-create-variant-6UQRMACE.mjs → product-create-variant-RQEPRPG5.mjs} +11 -11
  106. package/dist/{product-detail-JMOULY3O.mjs → product-detail-FOLQUXCM.mjs} +54 -38
  107. package/dist/{product-edit-CC4OUBEC.mjs → product-edit-WRONAZ5F.mjs} +12 -12
  108. package/dist/product-edit-option-VIU3ZICO.mjs +150 -0
  109. package/dist/{product-export-BVREOXJT.mjs → product-export-ITQPBLG7.mjs} +22 -23
  110. package/dist/{product-image-variants-edit-7BBTFZO7.mjs → product-image-variants-edit-P2ZWO6DN.mjs} +10 -10
  111. package/dist/{product-import-UEXWOHOZ.mjs → product-import-WEHFNQXM.mjs} +10 -10
  112. package/dist/{product-list-RHHY3NAS.mjs → product-list-7QL2GZEA.mjs} +17 -17
  113. package/dist/{product-media-EKXMOSO4.mjs → product-media-WCLPCVR3.mjs} +2 -2
  114. package/dist/{product-metadata-DU2CNDKQ.mjs → product-metadata-LP3B3LXR.mjs} +10 -10
  115. package/dist/{product-organization-HU6YVPPV.mjs → product-organization-GKKUOJQV.mjs} +14 -14
  116. package/dist/{product-prices-UMEIS5AZ.mjs → product-prices-MKMKBH6P.mjs} +1 -1
  117. package/dist/{product-sales-channels-2SALTLTF.mjs → product-sales-channels-5YIO22UW.mjs} +3 -3
  118. package/dist/{product-shipping-profile-T4ZKHINJ.mjs → product-shipping-profile-GOESXQYV.mjs} +13 -13
  119. package/dist/{product-stock-CKBS4YDA.mjs → product-stock-KZ5NJINL.mjs} +10 -10
  120. package/dist/{product-tag-create-GFGPI7ML.mjs → product-tag-create-KOTNIDPO.mjs} +10 -10
  121. package/dist/{product-tag-detail-TTEWVF3I.mjs → product-tag-detail-4NEU4CQ4.mjs} +27 -28
  122. package/dist/{product-tag-edit-3XNTLATZ.mjs → product-tag-edit-UBVJB75M.mjs} +10 -10
  123. package/dist/{product-tag-list-24IJRVFR.mjs → product-tag-list-2JDK7DBC.mjs} +25 -26
  124. package/dist/{product-tag-metadata-JANWHZ3K.mjs → product-tag-metadata-H4QYJB5I.mjs} +10 -10
  125. package/dist/{product-type-detail-MAUHCM3C.mjs → product-type-detail-QSKBQZOO.mjs} +13 -13
  126. package/dist/{product-type-metadata-FAKUWQQF.mjs → product-type-metadata-OSGO33SD.mjs} +10 -10
  127. package/dist/{product-variant-detail-WHPECDUY.mjs → product-variant-detail-ATHRI3BX.mjs} +10 -10
  128. package/dist/{product-variant-edit-GR4RNE5G.mjs → product-variant-edit-457GNHH5.mjs} +11 -11
  129. package/dist/{product-variant-manage-inventory-items-IGDCLZQE.mjs → product-variant-manage-inventory-items-B7TUBSD5.mjs} +2 -2
  130. package/dist/{product-variant-media-EKI4BTEV.mjs → product-variant-media-6WWLRINP.mjs} +1 -1
  131. package/dist/{product-variant-metadata-DA2HKXXB.mjs → product-variant-metadata-GOUTYBDT.mjs} +10 -10
  132. package/dist/{promotion-add-campaign-DOALJUKJ.mjs → promotion-add-campaign-MKDYE7MW.mjs} +3 -3
  133. package/dist/{promotion-create-GGZULF2B.mjs → promotion-create-WCECPK2G.mjs} +18 -18
  134. package/dist/{promotion-detail-XK7U73XH.mjs → promotion-detail-JBM2LBZ4.mjs} +10 -10
  135. package/dist/{refund-reason-create-H7MHJ5C5.mjs → refund-reason-create-IAOKE37M.mjs} +10 -10
  136. package/dist/{refund-reason-edit-QY36CQVS.mjs → refund-reason-edit-D2VDINGV.mjs} +10 -10
  137. package/dist/{refund-reason-list-KSQW33QC.mjs → refund-reason-list-Q4TU7OVA.mjs} +13 -13
  138. package/dist/{region-create-UVJICJRX.mjs → region-create-QLPSK6TX.mjs} +1 -1
  139. package/dist/{region-edit-3NVXQECN.mjs → region-edit-JCJHA6TY.mjs} +1 -1
  140. package/dist/{region-metadata-4KQG6UL6.mjs → region-metadata-YLNPW7CL.mjs} +10 -10
  141. package/dist/{reservation-create-Z7TWUE2L.mjs → reservation-create-BW4CDTWR.mjs} +3 -3
  142. package/dist/{reservation-detail-W3FULMXT.mjs → reservation-detail-SMO3C2R5.mjs} +10 -10
  143. package/dist/{reservation-list-MN22JYAW.mjs → reservation-list-RGL67CIU.mjs} +2 -2
  144. package/dist/{reservation-metadata-AKAN5XNE.mjs → reservation-metadata-KU5AJF7S.mjs} +10 -10
  145. package/dist/{sales-channel-add-products-POHTQHMV.mjs → sales-channel-add-products-WGRIVVJA.mjs} +13 -13
  146. package/dist/{sales-channel-create-UFFXX5HK.mjs → sales-channel-create-TOBEDYFD.mjs} +2 -2
  147. package/dist/{sales-channel-detail-AACIFU2E.mjs → sales-channel-detail-VSTGXEZD.mjs} +13 -13
  148. package/dist/{sales-channel-edit-SP2HF4E3.mjs → sales-channel-edit-XUTE5GB5.mjs} +2 -2
  149. package/dist/{sales-channel-list-BY3KTVV6.mjs → sales-channel-list-2LXIRNZP.mjs} +11 -11
  150. package/dist/{sales-channel-metadata-KGOLI4BZ.mjs → sales-channel-metadata-RZMQYG4F.mjs} +10 -10
  151. package/dist/{shipping-option-type-create-PSQZW3RN.mjs → shipping-option-type-create-EQPBH6EA.mjs} +10 -10
  152. package/dist/{shipping-option-type-detail-WAW6TKJU.mjs → shipping-option-type-detail-BCCCVIIJ.mjs} +11 -11
  153. package/dist/{shipping-option-type-edit-2I44YHND.mjs → shipping-option-type-edit-CGTJ3HAR.mjs} +10 -10
  154. package/dist/{shipping-option-type-list-F4FRLW3P.mjs → shipping-option-type-list-3TLR4QZF.mjs} +11 -11
  155. package/dist/{shipping-profile-metadata-AZXPMPHG.mjs → shipping-profile-metadata-JSRQPOAD.mjs} +10 -10
  156. package/dist/{store-detail-AKRR64I6.mjs → store-detail-H53F5ESM.mjs} +10 -10
  157. package/dist/{store-edit-Q25HCMCQ.mjs → store-edit-3XS6IC2Z.mjs} +1 -1
  158. package/dist/{store-metadata-VLEDLAIJ.mjs → store-metadata-GHSJRHAV.mjs} +10 -10
  159. package/dist/{tax-region-create-JTM53LCS.mjs → tax-region-create-HYT3EOQO.mjs} +11 -11
  160. package/dist/{tax-region-detail-XBFYCVSH.mjs → tax-region-detail-TQS5425G.mjs} +28 -29
  161. package/dist/{tax-region-edit-2RRF7C7P.mjs → tax-region-edit-ZB36A456.mjs} +11 -11
  162. package/dist/{tax-region-province-detail-LGCYSFKE.mjs → tax-region-province-detail-CABVSQRU.mjs} +28 -29
  163. package/dist/{tax-region-tax-override-create-2W25EZNZ.mjs → tax-region-tax-override-create-ROK47GNE.mjs} +27 -28
  164. package/dist/{tax-region-tax-override-edit-ZSYNTYUG.mjs → tax-region-tax-override-edit-WRODO4LC.mjs} +26 -27
  165. package/dist/{user-detail-K5UMPO2L.mjs → user-detail-N6PT3KRP.mjs} +1 -1
  166. package/dist/{user-metadata-KOGHOQTW.mjs → user-metadata-DKZHLCPN.mjs} +10 -10
  167. package/dist/{workflow-execution-detail-4QAQ44YB.mjs → workflow-execution-detail-BQEMJSH6.mjs} +10 -10
  168. package/package.json +11 -11
  169. package/src/components/inputs/combobox/combobox.tsx +92 -173
  170. package/src/components/layout/main-layout/main-layout.tsx +4 -7
  171. package/src/dashboard-app/routes/get-route.map.tsx +12 -64
  172. package/src/hooks/api/index.ts +0 -1
  173. package/src/hooks/api/price-lists.tsx +32 -1
  174. package/src/hooks/api/products.tsx +66 -26
  175. package/src/hooks/table/filters/index.ts +0 -1
  176. package/src/i18n/translations/$schema.json +4 -172
  177. package/src/i18n/translations/en.json +3 -49
  178. package/src/routes/orders/order-create-edit/components/order-edit-create-form/order-edit-item.tsx +28 -3
  179. package/src/routes/orders/order-create-exchange/components/exchange-create-form/exchange-inbound-item.tsx +29 -4
  180. package/src/routes/orders/order-create-exchange/components/exchange-create-form/exchange-outbound-item.tsx +23 -4
  181. package/src/routes/orders/order-detail/constants.ts +1 -0
  182. package/src/routes/orders/order-list/const.ts +1 -0
  183. package/src/routes/price-lists/price-list-detail/components/price-list-general-section/price-list-general-section.tsx +10 -4
  184. package/src/routes/price-lists/price-list-list/components/price-list-list-table/price-count-cell.tsx +19 -0
  185. package/src/routes/price-lists/price-list-list/components/price-list-list-table/use-pricing-table-columns.tsx +5 -6
  186. package/src/routes/price-lists/price-list-prices-add/price-list-prices-add.tsx +4 -1
  187. package/src/routes/price-lists/price-list-prices-edit/price-list-prices-edit.tsx +3 -1
  188. package/src/routes/products/product-create/components/product-create-details-form/components/product-create-details-general-section/product-create-general-section.tsx +4 -16
  189. package/src/routes/products/product-create/components/product-create-details-form/components/product-create-details-variant-section/product-create-details-variant-section.tsx +198 -220
  190. package/src/routes/products/product-create/components/product-create-form/product-create-form.tsx +7 -4
  191. package/src/routes/products/product-create/constants.ts +0 -2
  192. package/src/routes/products/product-create/utils.ts +1 -6
  193. package/src/routes/products/product-create-option/components/create-product-option-form/create-product-option-form.tsx +122 -0
  194. package/src/routes/products/product-create-option/components/create-product-option-form/index.ts +1 -0
  195. package/src/routes/products/product-create-option/index.ts +1 -0
  196. package/src/routes/products/product-create-option/product-create-option.tsx +26 -0
  197. package/src/routes/products/product-detail/components/product-option-section/product-option-section.tsx +49 -31
  198. package/src/routes/products/product-edit-option/components/edit-product-option-form/edit-product-option-form.tsx +123 -0
  199. package/src/routes/products/product-edit-option/components/edit-product-option-form/index.ts +1 -0
  200. package/src/routes/products/product-edit-option/index.ts +1 -0
  201. package/src/routes/products/product-edit-option/product-edit-option.tsx +32 -0
  202. package/dist/chunk-ZHH3W7CN.mjs +0 -171
  203. package/dist/product-option-create-ML66ZKF3.mjs +0 -336
  204. package/dist/product-option-detail-DT7HJF5Q.mjs +0 -322
  205. package/dist/product-option-edit-GUKWRQQH.mjs +0 -324
  206. package/dist/product-option-list-KF3JSQ6Y.mjs +0 -262
  207. package/dist/product-option-metadata-BWWRRSAW.mjs +0 -71
  208. package/dist/product-options-manage-QYWBIHJA.mjs +0 -304
  209. package/src/hooks/api/product-options.tsx +0 -151
  210. package/src/hooks/table/columns/use-product-option-table-columns.tsx +0 -44
  211. package/src/hooks/table/filters/use-product-option-table-filters.tsx +0 -33
  212. package/src/hooks/table/query/use-product-option-table-query.tsx +0 -34
  213. package/src/routes/product-options/common/hooks/use-delete-product-option-action.tsx +0 -41
  214. package/src/routes/product-options/product-option-create/components/create-product-option-form/create-product-option-details.tsx +0 -71
  215. package/src/routes/product-options/product-option-create/components/create-product-option-form/create-product-option-form.tsx +0 -192
  216. package/src/routes/product-options/product-option-create/components/create-product-option-form/create-product-option-organize.tsx +0 -77
  217. package/src/routes/product-options/product-option-create/components/create-product-option-form/index.ts +0 -1
  218. package/src/routes/product-options/product-option-create/components/create-product-option-form/schema.ts +0 -15
  219. package/src/routes/product-options/product-option-create/index.ts +0 -1
  220. package/src/routes/product-options/product-option-create/product-option-create.tsx +0 -10
  221. package/src/routes/product-options/product-option-detail/breadcrumb.tsx +0 -14
  222. package/src/routes/product-options/product-option-detail/components/product-option-general-section/index.ts +0 -1
  223. package/src/routes/product-options/product-option-detail/components/product-option-general-section/product-option-general-section.tsx +0 -81
  224. package/src/routes/product-options/product-option-detail/components/product-option-product-section/index.ts +0 -1
  225. package/src/routes/product-options/product-option-detail/components/product-option-product-section/product-option-product-section.tsx +0 -74
  226. package/src/routes/product-options/product-option-detail/index.ts +0 -3
  227. package/src/routes/product-options/product-option-detail/loader.ts +0 -17
  228. package/src/routes/product-options/product-option-detail/product-option-detail.tsx +0 -50
  229. package/src/routes/product-options/product-option-edit/components/edit-product-option-form/edit-product-option-details.tsx +0 -94
  230. package/src/routes/product-options/product-option-edit/components/edit-product-option-form/edit-product-option-form.tsx +0 -116
  231. package/src/routes/product-options/product-option-edit/components/edit-product-option-form/edit-product-option-organize.tsx +0 -77
  232. package/src/routes/product-options/product-option-edit/components/edit-product-option-form/index.ts +0 -1
  233. package/src/routes/product-options/product-option-edit/components/edit-product-option-form/schema.ts +0 -13
  234. package/src/routes/product-options/product-option-edit/index.ts +0 -1
  235. package/src/routes/product-options/product-option-edit/product-option-edit.tsx +0 -34
  236. package/src/routes/product-options/product-option-list/components/product-option-list-table/index.ts +0 -1
  237. package/src/routes/product-options/product-option-list/components/product-option-list-table/product-option-list-table.tsx +0 -131
  238. package/src/routes/product-options/product-option-list/index.ts +0 -1
  239. package/src/routes/product-options/product-option-list/product-option-list.tsx +0 -19
  240. package/src/routes/product-options/product-option-metadata/index.ts +0 -1
  241. package/src/routes/product-options/product-option-metadata/product-option-metadata.tsx +0 -27
  242. package/src/routes/products/product-options-manage/components/product-options-manage-form/index.ts +0 -1
  243. package/src/routes/products/product-options-manage/components/product-options-manage-form/product-options-manage-form.tsx +0 -284
  244. package/src/routes/products/product-options-manage/index.ts +0 -1
  245. package/src/routes/products/product-options-manage/product-options-manage.tsx +0 -35
  246. package/dist/{chunk-2QH2TBJ2.mjs → chunk-ACJ3PPQJ.mjs} +3 -3
  247. package/dist/{customer-group-add-customers-2Y2GVCDV.mjs → customer-group-add-customers-QU4Q56SS.mjs} +3 -3
  248. package/dist/{customer-list-TG4D4QOT.mjs → customer-list-ZXCGIXJC.mjs} +3 -3
  249. package/dist/{location-list-ZJMZZ6T3.mjs → location-list-OYBI7EGV.mjs} +1 -1
  250. package/dist/{product-type-list-7WQ5D2KV.mjs → product-type-list-QX7QC6RI.mjs} +3 -3
  251. package/dist/{region-list-JAQXIBYD.mjs → region-list-XQRIBDMF.mjs} +3 -3
  252. package/dist/{return-reason-list-ATE2XU4H.mjs → return-reason-list-VYLLXDG4.mjs} +3 -3
  253. package/dist/{user-list-KPI3BTOA.mjs → user-list-6KATHOTJ.mjs} +3 -3
@@ -1,30 +1,32 @@
1
+ import { XMarkMini } from "@medusajs/icons"
1
2
  import {
2
3
  Alert,
4
+ Button,
3
5
  Checkbox,
4
6
  clx,
5
7
  Heading,
6
8
  Hint,
9
+ IconButton,
7
10
  InlineTip,
11
+ Input,
8
12
  Label,
9
13
  Text,
10
14
  } from "@medusajs/ui"
11
15
  import {
16
+ Controller,
12
17
  FieldArrayWithId,
13
18
  useFieldArray,
14
19
  UseFormReturn,
15
20
  useWatch,
16
21
  } from "react-hook-form"
17
22
  import { useTranslation } from "react-i18next"
18
- import { useMemo, useState } from "react"
19
23
 
20
24
  import { Form } from "../../../../../../../components/common/form"
21
25
  import { SortableList } from "../../../../../../../components/common/sortable-list"
22
26
  import { SwitchBox } from "../../../../../../../components/common/switch-box"
23
- import { Combobox } from "../../../../../../../components/inputs/combobox"
27
+ import { ChipInput } from "../../../../../../../components/inputs/chip-input"
24
28
  import { ProductCreateSchemaType } from "../../../../types"
25
29
  import { decorateVariantsWithDefaultValues } from "../../../../utils"
26
- import { useProductOptions } from "../../../../../../../hooks/api"
27
- import { AdminProductOption } from "@medusajs/types"
28
30
 
29
31
  type ProductCreateVariantsSectionProps = {
30
32
  form: UseFormReturn<ProductCreateSchemaType>
@@ -63,6 +65,11 @@ export const ProductCreateVariantsSection = ({
63
65
  }: ProductCreateVariantsSectionProps) => {
64
66
  const { t } = useTranslation()
65
67
 
68
+ const options = useFieldArray({
69
+ control: form.control,
70
+ name: "options",
71
+ })
72
+
66
73
  const variants = useFieldArray({
67
74
  control: form.control,
68
75
  name: "variants",
@@ -90,173 +97,90 @@ export const ProductCreateVariantsSection = ({
90
97
  const showInvalidVariantsMessage =
91
98
  form.formState.errors.variants?.root?.message === "invalid_length"
92
99
 
93
- const { product_options = [], isLoading } = useProductOptions({
94
- is_exclusive: false,
95
- })
96
-
97
- const productOptionChoices = useMemo(() => {
98
- return product_options.map((option) => ({
99
- value: option.id,
100
- label: option.title,
101
- }))
102
- }, [product_options])
103
-
104
- const [selectedOptionIds, setSelectedOptionIds] = useState<string[]>([])
105
- const [selectedOptionValues, setSelectedOptionValues] = useState<
106
- Record<string, string[]>
107
- >({})
108
- const [customValues, setCustomValues] = useState<
109
- Record<string, Array<{ id: string; value: string; rank: number }>>
110
- >({})
111
-
112
- const handleProductOptionSelect = (optionIds: string[]) => {
113
- setSelectedOptionIds(optionIds)
114
-
115
- // Initialize selected values for new options (select all by default)
116
- const newSelectedValues: Record<string, string[]> = {}
117
- const selectedProductOptions = product_options.filter((option) =>
118
- optionIds.includes(option.id)
119
- )
100
+ const handleOptionValueUpdate = (index: number, value: string[]) => {
101
+ const { isTouched: hasUserSelectedVariants } =
102
+ form.getFieldState("variants")
120
103
 
121
- selectedProductOptions.forEach((option) => {
122
- // If option was already selected, keep its current value selection
123
- if (selectedOptionValues[option.id]) {
124
- newSelectedValues[option.id] = selectedOptionValues[option.id]
125
- } else {
126
- // New option - select all values by default
127
- newSelectedValues[option.id] = option.values?.map((v) => v.id) || []
128
- }
129
- })
104
+ const newOptions = [...watchedOptions]
105
+ newOptions[index].values = value
130
106
 
131
- setSelectedOptionValues(newSelectedValues)
132
- updateFormWithSelectedValues(selectedProductOptions, newSelectedValues)
133
- }
107
+ const permutations = getPermutations(
108
+ newOptions.filter(({ values }) => values.length)
109
+ )
110
+ const oldVariants = [...watchedVariants]
134
111
 
135
- const handleValueChange = (optionId: string, valueIds: string[]) => {
136
- // Ensure at least one value is selected
137
- if (valueIds.length === 0) {
138
- return
112
+ const findMatchingPermutation = (options: Record<string, string>) => {
113
+ return permutations.find((permutation) =>
114
+ Object.keys(options).every((key) => options[key] === permutation[key])
115
+ )
139
116
  }
140
117
 
141
- // Detect new custom values that aren't in the options yet
142
- const allValues = getAllValuesForOption(optionId)
143
- const existingValueIds = new Set(allValues.map((v) => v.id))
144
-
145
- const validValueIds: string[] = []
146
- const newCustomValues: string[] = []
147
- valueIds.forEach((id) => {
148
- if (existingValueIds.has(id)) {
149
- validValueIds.push(id)
150
- } else {
151
- newCustomValues.push(id)
152
- }
153
- })
154
-
155
- let updatedCustomValues = customValues
156
- const updatedValidValueIds = [...validValueIds]
157
- newCustomValues.forEach((newValue) => {
158
- const tempId = `custom-${Date.now()}-${Math.random()}-${newValue}`
159
-
160
- const existingCustom = updatedCustomValues[optionId] || []
161
- const option = product_options.find((opt) => opt.id === optionId)
162
- const existingValuesCount =
163
- (option?.values?.length || 0) + existingCustom.length
118
+ const newVariants = oldVariants.reduce((variants, variant) => {
119
+ const match = findMatchingPermutation(variant.options)
164
120
 
165
- const newCustomValue = {
166
- id: tempId,
167
- value: newValue,
168
- rank: existingValuesCount + newCustomValues.indexOf(newValue),
121
+ if (match) {
122
+ variants.push({
123
+ ...variant,
124
+ title: getVariantName(match),
125
+ options: match,
126
+ })
169
127
  }
170
128
 
171
- updatedCustomValues = {
172
- ...updatedCustomValues,
173
- [optionId]: [...(updatedCustomValues[optionId] || []), newCustomValue],
174
- }
129
+ return variants
130
+ }, [] as typeof oldVariants)
131
+
132
+ const usedPermutations = new Set(
133
+ newVariants.map((variant) => variant.options)
134
+ )
135
+ const unusedPermutations = permutations.filter(
136
+ (permutation) => !usedPermutations.has(permutation)
137
+ )
175
138
 
176
- updatedValidValueIds.push(tempId)
139
+ unusedPermutations.forEach((permutation) => {
140
+ newVariants.push({
141
+ title: getVariantName(permutation),
142
+ options: permutation,
143
+ should_create: hasUserSelectedVariants ? false : true,
144
+ variant_rank: newVariants.length,
145
+ // NOTE - prepare inventory array here for now so we prevent rendering issue if we append the items later
146
+ inventory: [{ inventory_item_id: "", required_quantity: "" }],
147
+ })
177
148
  })
178
149
 
179
- if (newCustomValues.length > 0) {
180
- setCustomValues(updatedCustomValues)
181
- }
150
+ form.setValue("variants", newVariants)
151
+ }
182
152
 
183
- const updatedSelectedValues = {
184
- ...selectedOptionValues,
185
- [optionId]: updatedValidValueIds,
153
+ const handleRemoveOption = (index: number) => {
154
+ if (index === 0) {
155
+ return
186
156
  }
187
157
 
188
- setSelectedOptionValues(updatedSelectedValues)
158
+ options.remove(index)
189
159
 
190
- const selectedProductOptions = product_options.filter((option) =>
191
- selectedOptionIds.includes(option.id)
192
- )
193
- updateFormWithSelectedValues(
194
- selectedProductOptions,
195
- updatedSelectedValues,
196
- newCustomValues.length > 0 ? updatedCustomValues : undefined
197
- )
198
- }
160
+ const newOptions = [...watchedOptions]
161
+ newOptions.splice(index, 1)
162
+ const validOptionTitles = new Set(newOptions.map((option) => option.title))
199
163
 
200
- const getAllValuesForOption = (
201
- optionId: string,
202
- customVals?: Record<
203
- string,
204
- Array<{ id: string; value: string; rank: number }>
205
- >
206
- ) => {
207
- const option = product_options.find((opt) => opt.id === optionId)
208
- const existingValues = option?.values || []
209
- const customForOption = (customVals || customValues)[optionId] || []
164
+ const permutations = getPermutations(newOptions)
165
+ const oldVariants = [...watchedVariants]
210
166
 
211
- return [...existingValues, ...customForOption]
212
- }
167
+ const newVariants = permutations.reduce((variants, permutation) => {
168
+ const variant = oldVariants.find(({ options }) =>
169
+ Object.keys(options)
170
+ .filter((option) => validOptionTitles.has(option))
171
+ .every((key) => options[key] === permutation[key])
172
+ )
213
173
 
214
- const updateFormWithSelectedValues = (
215
- selectedProductOptions: AdminProductOption[],
216
- valueSelections: Record<string, string[]>,
217
- customVals?: Record<
218
- string,
219
- Array<{
220
- id: string
221
- value: string
222
- rank: number
223
- }>
224
- >
225
- ) => {
226
- const newOptions = selectedProductOptions.map((option) => {
227
- const selectedValueIds = valueSelections[option.id] || []
228
- const allValues = getAllValuesForOption(option.id, customVals)
229
-
230
- const selectedValues = allValues
231
- .filter((v) => selectedValueIds.includes(v.id))
232
- .sort((a, b) => {
233
- const rankA = a.rank ?? Number.MAX_VALUE
234
- const rankB = b.rank ?? Number.MAX_VALUE
235
- return rankA - rankB
174
+ if (variant) {
175
+ variants.push({
176
+ ...variant,
177
+ title: variant.title,
178
+ options: permutation,
236
179
  })
237
- .map((v) => v.value)
238
-
239
- return {
240
- id: option.id,
241
- title: option.title,
242
- values: selectedValues,
243
- value_ids: selectedValueIds,
244
180
  }
245
- })
246
181
 
247
- form.setValue("options", newOptions)
248
-
249
- const permutations = getPermutations(
250
- newOptions.filter(({ values }) => values.length)
251
- )
252
-
253
- const newVariants = permutations.map((permutation, index) => ({
254
- title: getVariantName(permutation),
255
- options: permutation,
256
- should_create: true,
257
- variant_rank: index,
258
- inventory: [{ inventory_item_id: "", required_quantity: "" }],
259
- }))
182
+ return variants
183
+ }, [] as typeof oldVariants)
260
184
 
261
185
  form.setValue("variants", newVariants)
262
186
  }
@@ -365,84 +289,138 @@ export const ProductCreateVariantsSection = ({
365
289
  } else {
366
290
  createDefaultOptionAndVariant()
367
291
  }
368
- setSelectedOptionIds([])
369
- setSelectedOptionValues({})
370
- setCustomValues({})
371
292
  }}
372
293
  />
373
294
  </div>
374
295
  {watchedAreVariantsEnabled && (
375
296
  <>
376
297
  <div className="flex flex-col gap-y-6">
377
- <div className="flex flex-col">
378
- <Label weight="plus">
379
- {t("products.create.variants.productOptions.label")}
380
- </Label>
381
- <Hint>{t("products.create.variants.productOptions.hint")}</Hint>
382
- </div>
383
- {showInvalidOptionsMessage && (
384
- <Alert dismissible variant="error">
385
- {t("products.create.errors.options")}
386
- </Alert>
387
- )}
388
- <Combobox
389
- value={selectedOptionIds}
390
- onChange={(value) => handleProductOptionSelect(value as string[])}
391
- options={productOptionChoices}
392
- placeholder={t("products.fields.options.optionTitlePlaceholder")}
393
- disabled={isLoading}
394
- displayMode="chips"
395
- />
396
- </div>
397
- {selectedOptionIds.length > 0 && (
398
- <div className="flex flex-col gap-y-4">
399
- <div className="flex flex-col">
400
- <Label weight="plus">{t("fields.values")}</Label>
401
- <Hint>{t("products.create.variants.selectValuesHint")}</Hint>
402
- </div>
403
- <div className="flex flex-col gap-y-3">
404
- {product_options
405
- .filter((option) => selectedOptionIds.includes(option.id))
406
- .map((option) => {
407
- // Get all values (existing + custom) for this option
408
- const allValues = getAllValuesForOption(option.id)
409
-
410
- const valueOptions = allValues
411
- .sort((a, b) => {
412
- const rankA = a.rank ?? Number.MAX_VALUE
413
- const rankB = b.rank ?? Number.MAX_VALUE
414
- return rankA - rankB
415
- })
416
- .map((v) => ({
417
- value: v.id,
418
- label: v.value,
419
- }))
420
-
421
- return (
422
- <div key={option.id} className="flex flex-col gap-y-2">
423
- <Label size="small" weight="plus">
424
- {option.title}
425
- </Label>
426
- <Combobox
427
- value={selectedOptionValues[option.id] || []}
428
- onChange={(value) =>
429
- handleValueChange(option.id, value as string[])
430
- }
431
- onCreateOption={(_) => {
432
- // Todo
298
+ <Form.Field
299
+ control={form.control}
300
+ name="options"
301
+ render={() => {
302
+ return (
303
+ <Form.Item>
304
+ <div className="flex flex-col gap-y-6">
305
+ <div className="flex items-start justify-between gap-x-4">
306
+ <div className="flex flex-col">
307
+ <Form.Label>
308
+ {t("products.create.variants.productOptions.label")}
309
+ </Form.Label>
310
+ <Form.Hint>
311
+ {t("products.create.variants.productOptions.hint")}
312
+ </Form.Hint>
313
+ </div>
314
+ <Button
315
+ size="small"
316
+ variant="secondary"
317
+ type="button"
318
+ onClick={() => {
319
+ options.append({
320
+ title: "",
321
+ values: [],
322
+ })
433
323
  }}
434
- options={valueOptions}
435
- placeholder={t(
436
- "products.fields.options.variantionsPlaceholder"
437
- )}
438
- displayMode="chips"
439
- />
324
+ >
325
+ {t("actions.add")}
326
+ </Button>
440
327
  </div>
441
- )
442
- })}
443
- </div>
444
- </div>
445
- )}
328
+ {showInvalidOptionsMessage && (
329
+ <Alert dismissible variant="error">
330
+ {t("products.create.errors.options")}
331
+ </Alert>
332
+ )}
333
+ <ul className="flex flex-col gap-y-4">
334
+ {options.fields.map((option, index) => {
335
+ const hasError =
336
+ !!form.formState.errors.options?.[index]
337
+ return (
338
+ <li
339
+ key={option.id}
340
+ className={clx(
341
+ "bg-ui-bg-component shadow-elevation-card-rest grid grid-cols-[1fr_28px] items-center gap-1.5 rounded-xl p-1.5",
342
+ {
343
+ "border-ui-border-error shadow-borders-error":
344
+ hasError,
345
+ }
346
+ )}
347
+ >
348
+ <div className="grid grid-cols-[min-content,1fr] items-center gap-1.5">
349
+ <div className="flex items-center px-2 py-1.5">
350
+ <Label
351
+ size="xsmall"
352
+ weight="plus"
353
+ className="text-ui-fg-subtle"
354
+ htmlFor={`options.${index}.title`}
355
+ >
356
+ {t("fields.title")}
357
+ </Label>
358
+ </div>
359
+ <Input
360
+ className="bg-ui-bg-field-component hover:bg-ui-bg-field-component-hover"
361
+ {...form.register(
362
+ `options.${index}.title` as const
363
+ )}
364
+ placeholder={t(
365
+ "products.fields.options.optionTitlePlaceholder"
366
+ )}
367
+ />
368
+ <div className="flex items-center px-2 py-1.5">
369
+ <Label
370
+ size="xsmall"
371
+ weight="plus"
372
+ className="text-ui-fg-subtle"
373
+ htmlFor={`options.${index}.values`}
374
+ >
375
+ {t("fields.values")}
376
+ </Label>
377
+ </div>
378
+ <Controller
379
+ control={form.control}
380
+ name={`options.${index}.values` as const}
381
+ render={({
382
+ field: { onChange, ...field },
383
+ }) => {
384
+ const handleValueChange = (
385
+ value: string[]
386
+ ) => {
387
+ handleOptionValueUpdate(index, value)
388
+ onChange(value)
389
+ }
390
+
391
+ return (
392
+ <ChipInput
393
+ {...field}
394
+ variant="contrast"
395
+ onChange={handleValueChange}
396
+ placeholder={t(
397
+ "products.fields.options.variantionsPlaceholder"
398
+ )}
399
+ />
400
+ )
401
+ }}
402
+ />
403
+ </div>
404
+ <IconButton
405
+ type="button"
406
+ size="small"
407
+ variant="transparent"
408
+ className="text-ui-fg-muted"
409
+ disabled={index === 0}
410
+ onClick={() => handleRemoveOption(index)}
411
+ >
412
+ <XMarkMini />
413
+ </IconButton>
414
+ </li>
415
+ )
416
+ })}
417
+ </ul>
418
+ </div>
419
+ </Form.Item>
420
+ )
421
+ }}
422
+ />
423
+ </div>
446
424
  <div className="grid grid-cols-1 gap-x-4 gap-y-8">
447
425
  <div className="flex flex-col gap-y-6">
448
426
  <div className="flex flex-col">
@@ -78,10 +78,13 @@ export const ProductCreateForm = ({
78
78
  return {}
79
79
  }
80
80
 
81
- return regions.reduce((acc, reg) => {
82
- acc[reg.id] = reg.currency_code
83
- return acc
84
- }, {} as Record<string, string>)
81
+ return regions.reduce(
82
+ (acc, reg) => {
83
+ acc[reg.id] = reg.currency_code
84
+ return acc
85
+ },
86
+ {} as Record<string, string>
87
+ )
85
88
  }, [regions])
86
89
 
87
90
  /**
@@ -47,10 +47,8 @@ export type ProductCreateVariantSchema = z.infer<
47
47
  >
48
48
 
49
49
  const ProductCreateOptionSchema = z.object({
50
- id: z.string().optional(),
51
50
  title: z.string(),
52
51
  values: z.array(z.string()).min(1),
53
- value_ids: z.array(z.string()).optional(),
54
52
  })
55
53
 
56
54
  export type ProductCreateOptionSchema = z.infer<
@@ -13,8 +13,6 @@ export const normalizeProductFormValues = (
13
13
  ?.filter((media) => !media.isThumbnail)
14
14
  .map((media) => ({ url: media.url }))
15
15
 
16
- const options = values.options.filter((o) => o.title) // clean temp. values
17
-
18
16
  return {
19
17
  status: values.status,
20
18
  is_giftcard: false,
@@ -43,10 +41,7 @@ export const normalizeProductFormValues = (
43
41
  length: values.length ? parseFloat(values.length) : undefined,
44
42
  height: values.height ? parseFloat(values.height) : undefined,
45
43
  weight: values.weight ? parseFloat(values.weight) : undefined,
46
- options: options.map((option) => {
47
- const { id, value_ids, ...rest } = option
48
- return id ? { id, value_ids } : { ...rest, is_exclusive: true }
49
- }),
44
+ options: values.options.filter((o) => o.title), // clean temp. values
50
45
  variants: normalizeVariants(
51
46
  values.variants.filter((variant) => variant.should_create),
52
47
  values.regionsCurrencyMap
@@ -0,0 +1,122 @@
1
+ import { zodResolver } from "@hookform/resolvers/zod"
2
+ import { Button, Input, toast } from "@medusajs/ui"
3
+ import { useForm } from "react-hook-form"
4
+ import { useTranslation } from "react-i18next"
5
+ import { z } from "zod"
6
+
7
+ import { HttpTypes } from "@medusajs/types"
8
+ import { Form } from "../../../../../components/common/form"
9
+ import { ChipInput } from "../../../../../components/inputs/chip-input"
10
+ import { RouteDrawer, useRouteModal } from "../../../../../components/modals"
11
+ import { KeyboundForm } from "../../../../../components/utilities/keybound-form"
12
+ import { useCreateProductOption } from "../../../../../hooks/api/products"
13
+
14
+ type EditProductOptionsFormProps = {
15
+ product: HttpTypes.AdminProduct
16
+ }
17
+
18
+ const CreateProductOptionSchema = z.object({
19
+ title: z.string().min(1),
20
+ values: z.array(z.string()).optional(),
21
+ })
22
+
23
+ export const CreateProductOptionForm = ({
24
+ product,
25
+ }: EditProductOptionsFormProps) => {
26
+ const { t } = useTranslation()
27
+ const { handleSuccess } = useRouteModal()
28
+
29
+ const form = useForm<z.infer<typeof CreateProductOptionSchema>>({
30
+ defaultValues: {
31
+ title: "",
32
+ values: [],
33
+ },
34
+ resolver: zodResolver(CreateProductOptionSchema),
35
+ })
36
+
37
+ const { mutateAsync, isPending } = useCreateProductOption(product.id)
38
+
39
+ const handleSubmit = form.handleSubmit(async (values) => {
40
+ mutateAsync(values, {
41
+ onSuccess: () => {
42
+ toast.success(
43
+ t("products.options.create.successToast", {
44
+ title: values.title,
45
+ })
46
+ )
47
+ handleSuccess()
48
+ },
49
+ onError: async (err) => {
50
+ toast.error(err.message)
51
+ },
52
+ })
53
+ })
54
+
55
+ return (
56
+ <RouteDrawer.Form form={form}>
57
+ <KeyboundForm
58
+ onSubmit={handleSubmit}
59
+ className="flex flex-1 flex-col overflow-hidden"
60
+ >
61
+ <RouteDrawer.Body className="flex flex-1 flex-col gap-y-4 overflow-auto">
62
+ <Form.Field
63
+ control={form.control}
64
+ name="title"
65
+ render={({ field }) => {
66
+ return (
67
+ <Form.Item>
68
+ <Form.Label>
69
+ {t("products.fields.options.optionTitle")}
70
+ </Form.Label>
71
+ <Form.Control>
72
+ <Input
73
+ {...field}
74
+ placeholder={t(
75
+ "products.fields.options.optionTitlePlaceholder"
76
+ )}
77
+ />
78
+ </Form.Control>
79
+ <Form.ErrorMessage />
80
+ </Form.Item>
81
+ )
82
+ }}
83
+ />
84
+ <Form.Field
85
+ control={form.control}
86
+ name="values"
87
+ render={({ field }) => {
88
+ return (
89
+ <Form.Item>
90
+ <Form.Label>
91
+ {t("products.fields.options.variations")}
92
+ </Form.Label>
93
+ <Form.Control>
94
+ <ChipInput
95
+ {...field}
96
+ placeholder={t(
97
+ "products.fields.options.variantionsPlaceholder"
98
+ )}
99
+ />
100
+ </Form.Control>
101
+ <Form.ErrorMessage />
102
+ </Form.Item>
103
+ )
104
+ }}
105
+ />
106
+ </RouteDrawer.Body>
107
+ <RouteDrawer.Footer>
108
+ <div className="flex items-center justify-end gap-x-2">
109
+ <RouteDrawer.Close asChild>
110
+ <Button variant="secondary" size="small">
111
+ {t("actions.cancel")}
112
+ </Button>
113
+ </RouteDrawer.Close>
114
+ <Button type="submit" size="small" isLoading={isPending}>
115
+ {t("actions.save")}
116
+ </Button>
117
+ </div>
118
+ </RouteDrawer.Footer>
119
+ </KeyboundForm>
120
+ </RouteDrawer.Form>
121
+ )
122
+ }
@@ -0,0 +1 @@
1
+ export * from "./create-product-option-form"
@@ -0,0 +1 @@
1
+ export { ProductCreateOption as Component } from "./product-create-option"