@medusajs/draft-order 2.20.1 → 2.20.2-preview-20260904113944

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.
@@ -5972,6 +5972,195 @@ const ID = () => {
5972
5972
  }
5973
5973
  );
5974
5974
  };
5975
+ const BillingAddress = () => {
5976
+ const { id } = useParams();
5977
+ const { order, isPending, isError, error } = useOrder(id, {
5978
+ fields: "+billing_address"
5979
+ });
5980
+ if (isError) {
5981
+ throw error;
5982
+ }
5983
+ const isReady = !isPending && !!order;
5984
+ return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
5985
+ /* @__PURE__ */ jsxs(RouteDrawer.Header, { children: [
5986
+ /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Billing Address" }) }),
5987
+ /* @__PURE__ */ jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Edit the billing address for the draft order" }) })
5988
+ ] }),
5989
+ isReady && /* @__PURE__ */ jsx(BillingAddressForm, { order })
5990
+ ] });
5991
+ };
5992
+ const BillingAddressForm = ({ order }) => {
5993
+ const form = useForm({
5994
+ defaultValues: {
5995
+ first_name: order.billing_address?.first_name ?? "",
5996
+ last_name: order.billing_address?.last_name ?? "",
5997
+ company: order.billing_address?.company ?? "",
5998
+ address_1: order.billing_address?.address_1 ?? "",
5999
+ address_2: order.billing_address?.address_2 ?? "",
6000
+ city: order.billing_address?.city ?? "",
6001
+ province: order.billing_address?.province ?? "",
6002
+ country_code: order.billing_address?.country_code ?? "",
6003
+ postal_code: order.billing_address?.postal_code ?? "",
6004
+ phone: order.billing_address?.phone ?? ""
6005
+ },
6006
+ resolver: zodResolver(schema$5)
6007
+ });
6008
+ const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
6009
+ const { handleSuccess } = useRouteModal();
6010
+ const onSubmit = form.handleSubmit(async (data) => {
6011
+ await mutateAsync(
6012
+ { billing_address: data },
6013
+ {
6014
+ onSuccess: () => {
6015
+ handleSuccess();
6016
+ },
6017
+ onError: (error) => {
6018
+ toast.error(error.message);
6019
+ }
6020
+ }
6021
+ );
6022
+ });
6023
+ return /* @__PURE__ */ jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxs(
6024
+ KeyboundForm,
6025
+ {
6026
+ className: "flex flex-1 flex-col overflow-hidden",
6027
+ onSubmit,
6028
+ children: [
6029
+ /* @__PURE__ */ jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-y-4", children: [
6030
+ /* @__PURE__ */ jsx(
6031
+ Form$2.Field,
6032
+ {
6033
+ control: form.control,
6034
+ name: "country_code",
6035
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
6036
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Country" }),
6037
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(CountrySelect, { ...field }) }),
6038
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
6039
+ ] })
6040
+ }
6041
+ ),
6042
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
6043
+ /* @__PURE__ */ jsx(
6044
+ Form$2.Field,
6045
+ {
6046
+ control: form.control,
6047
+ name: "first_name",
6048
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
6049
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "First name" }),
6050
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
6051
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
6052
+ ] })
6053
+ }
6054
+ ),
6055
+ /* @__PURE__ */ jsx(
6056
+ Form$2.Field,
6057
+ {
6058
+ control: form.control,
6059
+ name: "last_name",
6060
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
6061
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Last name" }),
6062
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
6063
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
6064
+ ] })
6065
+ }
6066
+ )
6067
+ ] }),
6068
+ /* @__PURE__ */ jsx(
6069
+ Form$2.Field,
6070
+ {
6071
+ control: form.control,
6072
+ name: "company",
6073
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
6074
+ /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Company" }),
6075
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
6076
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
6077
+ ] })
6078
+ }
6079
+ ),
6080
+ /* @__PURE__ */ jsx(
6081
+ Form$2.Field,
6082
+ {
6083
+ control: form.control,
6084
+ name: "address_1",
6085
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
6086
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Address" }),
6087
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
6088
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
6089
+ ] })
6090
+ }
6091
+ ),
6092
+ /* @__PURE__ */ jsx(
6093
+ Form$2.Field,
6094
+ {
6095
+ control: form.control,
6096
+ name: "address_2",
6097
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
6098
+ /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Apartment, suite, etc." }),
6099
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
6100
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
6101
+ ] })
6102
+ }
6103
+ ),
6104
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
6105
+ /* @__PURE__ */ jsx(
6106
+ Form$2.Field,
6107
+ {
6108
+ control: form.control,
6109
+ name: "postal_code",
6110
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
6111
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Postal code" }),
6112
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
6113
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
6114
+ ] })
6115
+ }
6116
+ ),
6117
+ /* @__PURE__ */ jsx(
6118
+ Form$2.Field,
6119
+ {
6120
+ control: form.control,
6121
+ name: "city",
6122
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
6123
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "City" }),
6124
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
6125
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
6126
+ ] })
6127
+ }
6128
+ )
6129
+ ] }),
6130
+ /* @__PURE__ */ jsx(
6131
+ Form$2.Field,
6132
+ {
6133
+ control: form.control,
6134
+ name: "province",
6135
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
6136
+ /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Province / State" }),
6137
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
6138
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
6139
+ ] })
6140
+ }
6141
+ ),
6142
+ /* @__PURE__ */ jsx(
6143
+ Form$2.Field,
6144
+ {
6145
+ control: form.control,
6146
+ name: "phone",
6147
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
6148
+ /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Phone" }),
6149
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
6150
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
6151
+ ] })
6152
+ }
6153
+ )
6154
+ ] }) }),
6155
+ /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
6156
+ /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
6157
+ /* @__PURE__ */ jsx(Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
6158
+ ] }) })
6159
+ ]
6160
+ }
6161
+ ) });
6162
+ };
6163
+ const schema$5 = addressSchema;
5975
6164
  const CustomItems = () => {
5976
6165
  return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
5977
6166
  /* @__PURE__ */ jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Custom Items" }) }) }),
@@ -5980,7 +6169,7 @@ const CustomItems = () => {
5980
6169
  };
5981
6170
  const CustomItemsForm = () => {
5982
6171
  const form = useForm({
5983
- resolver: zodResolver(schema$5)
6172
+ resolver: zodResolver(schema$4)
5984
6173
  });
5985
6174
  return /* @__PURE__ */ jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxs(KeyboundForm, { className: "flex flex-1 flex-col", children: [
5986
6175
  /* @__PURE__ */ jsx(RouteDrawer.Body, {}),
@@ -5990,7 +6179,7 @@ const CustomItemsForm = () => {
5990
6179
  ] }) })
5991
6180
  ] }) });
5992
6181
  };
5993
- const schema$5 = z.object({
6182
+ const schema$4 = z.object({
5994
6183
  email: z.string().email()
5995
6184
  });
5996
6185
  const Email = () => {
@@ -6015,7 +6204,7 @@ const EmailForm = ({ order }) => {
6015
6204
  defaultValues: {
6016
6205
  email: order.email ?? ""
6017
6206
  },
6018
- resolver: zodResolver(schema$4)
6207
+ resolver: zodResolver(schema$3)
6019
6208
  });
6020
6209
  const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
6021
6210
  const { handleSuccess } = useRouteModal();
@@ -6058,7 +6247,7 @@ const EmailForm = ({ order }) => {
6058
6247
  }
6059
6248
  ) });
6060
6249
  };
6061
- const schema$4 = z.object({
6250
+ const schema$3 = z.object({
6062
6251
  email: z.string().email()
6063
6252
  });
6064
6253
  const NumberInput = forwardRef(
@@ -7080,844 +7269,336 @@ const customItemSchema = z.object({
7080
7269
  quantity: z.number(),
7081
7270
  unit_price: z.union([z.number(), z.string()])
7082
7271
  });
7083
- const BillingAddress = () => {
7084
- const { id } = useParams();
7085
- const { order, isPending, isError, error } = useOrder(id, {
7086
- fields: "+billing_address"
7272
+ const PROMOTION_QUERY_KEY = "promotions";
7273
+ const promotionsQueryKeys = {
7274
+ list: (query2) => [
7275
+ PROMOTION_QUERY_KEY,
7276
+ query2 ? query2 : void 0
7277
+ ],
7278
+ detail: (id, query2) => [
7279
+ PROMOTION_QUERY_KEY,
7280
+ id,
7281
+ query2 ? query2 : void 0
7282
+ ]
7283
+ };
7284
+ const usePromotions = (query2, options) => {
7285
+ const { data, ...rest } = useQuery({
7286
+ queryKey: promotionsQueryKeys.list(query2),
7287
+ queryFn: async () => sdk.admin.promotion.list(query2),
7288
+ ...options
7087
7289
  });
7088
- if (isError) {
7089
- throw error;
7290
+ return { ...data, ...rest };
7291
+ };
7292
+ const Promotions = () => {
7293
+ const { id } = useParams();
7294
+ const {
7295
+ order: preview,
7296
+ isError: isPreviewError,
7297
+ error: previewError
7298
+ } = useOrderPreview(id, void 0);
7299
+ useInitiateOrderEdit({ preview });
7300
+ const { onCancel } = useCancelOrderEdit({ preview });
7301
+ if (isPreviewError) {
7302
+ throw previewError;
7090
7303
  }
7091
- const isReady = !isPending && !!order;
7092
- return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
7093
- /* @__PURE__ */ jsxs(RouteDrawer.Header, { children: [
7094
- /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Billing Address" }) }),
7095
- /* @__PURE__ */ jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Edit the billing address for the draft order" }) })
7096
- ] }),
7097
- isReady && /* @__PURE__ */ jsx(BillingAddressForm, { order })
7304
+ const isReady = !!preview;
7305
+ return /* @__PURE__ */ jsxs(RouteDrawer, { onClose: onCancel, children: [
7306
+ /* @__PURE__ */ jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Promotions" }) }) }),
7307
+ isReady && /* @__PURE__ */ jsx(PromotionForm, { preview })
7098
7308
  ] });
7099
7309
  };
7100
- const BillingAddressForm = ({ order }) => {
7101
- const form = useForm({
7102
- defaultValues: {
7103
- first_name: order.billing_address?.first_name ?? "",
7104
- last_name: order.billing_address?.last_name ?? "",
7105
- company: order.billing_address?.company ?? "",
7106
- address_1: order.billing_address?.address_1 ?? "",
7107
- address_2: order.billing_address?.address_2 ?? "",
7108
- city: order.billing_address?.city ?? "",
7109
- province: order.billing_address?.province ?? "",
7110
- country_code: order.billing_address?.country_code ?? "",
7111
- postal_code: order.billing_address?.postal_code ?? "",
7112
- phone: order.billing_address?.phone ?? ""
7113
- },
7114
- resolver: zodResolver(schema$3)
7115
- });
7116
- const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
7310
+ const PromotionForm = ({ preview }) => {
7311
+ const { items, shipping_methods } = preview;
7312
+ const [isSubmitting, setIsSubmitting] = useState(false);
7313
+ const [comboboxValue, setComboboxValue] = useState("");
7117
7314
  const { handleSuccess } = useRouteModal();
7118
- const onSubmit = form.handleSubmit(async (data) => {
7119
- await mutateAsync(
7120
- { billing_address: data },
7121
- {
7122
- onSuccess: () => {
7123
- handleSuccess();
7124
- },
7125
- onError: (error) => {
7126
- toast.error(error.message);
7127
- }
7128
- }
7129
- );
7130
- });
7131
- return /* @__PURE__ */ jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxs(
7132
- KeyboundForm,
7315
+ const { mutateAsync: addPromotions, isPending: isAddingPromotions } = useDraftOrderAddPromotions(preview.id);
7316
+ const promoIds = getPromotionIds(items, shipping_methods);
7317
+ const { promotions, isPending, isError, error } = usePromotions(
7133
7318
  {
7134
- className: "flex flex-1 flex-col overflow-hidden",
7135
- onSubmit,
7136
- children: [
7137
- /* @__PURE__ */ jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-y-4", children: [
7138
- /* @__PURE__ */ jsx(
7139
- Form$2.Field,
7140
- {
7141
- control: form.control,
7142
- name: "country_code",
7143
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
7144
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Country" }),
7145
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(CountrySelect, { ...field }) }),
7146
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
7147
- ] })
7148
- }
7149
- ),
7150
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
7151
- /* @__PURE__ */ jsx(
7152
- Form$2.Field,
7153
- {
7154
- control: form.control,
7155
- name: "first_name",
7156
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
7157
- /* @__PURE__ */ jsx(Form$2.Label, { children: "First name" }),
7158
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
7159
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
7160
- ] })
7161
- }
7162
- ),
7163
- /* @__PURE__ */ jsx(
7164
- Form$2.Field,
7165
- {
7166
- control: form.control,
7167
- name: "last_name",
7168
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
7169
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Last name" }),
7170
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
7171
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
7172
- ] })
7173
- }
7174
- )
7175
- ] }),
7176
- /* @__PURE__ */ jsx(
7177
- Form$2.Field,
7178
- {
7179
- control: form.control,
7180
- name: "company",
7181
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
7182
- /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Company" }),
7183
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
7184
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
7185
- ] })
7186
- }
7187
- ),
7188
- /* @__PURE__ */ jsx(
7189
- Form$2.Field,
7190
- {
7191
- control: form.control,
7192
- name: "address_1",
7193
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
7194
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Address" }),
7195
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
7196
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
7197
- ] })
7198
- }
7199
- ),
7200
- /* @__PURE__ */ jsx(
7201
- Form$2.Field,
7202
- {
7203
- control: form.control,
7204
- name: "address_2",
7205
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
7206
- /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Apartment, suite, etc." }),
7207
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
7208
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
7209
- ] })
7210
- }
7211
- ),
7212
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
7213
- /* @__PURE__ */ jsx(
7214
- Form$2.Field,
7215
- {
7216
- control: form.control,
7217
- name: "postal_code",
7218
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
7219
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Postal code" }),
7220
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
7221
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
7222
- ] })
7223
- }
7224
- ),
7225
- /* @__PURE__ */ jsx(
7226
- Form$2.Field,
7227
- {
7228
- control: form.control,
7229
- name: "city",
7230
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
7231
- /* @__PURE__ */ jsx(Form$2.Label, { children: "City" }),
7232
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
7233
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
7234
- ] })
7235
- }
7236
- )
7237
- ] }),
7238
- /* @__PURE__ */ jsx(
7239
- Form$2.Field,
7240
- {
7241
- control: form.control,
7242
- name: "province",
7243
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
7244
- /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Province / State" }),
7245
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
7246
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
7247
- ] })
7248
- }
7249
- ),
7250
- /* @__PURE__ */ jsx(
7251
- Form$2.Field,
7252
- {
7253
- control: form.control,
7254
- name: "phone",
7255
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
7256
- /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Phone" }),
7257
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
7258
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
7259
- ] })
7260
- }
7261
- )
7262
- ] }) }),
7263
- /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
7264
- /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
7265
- /* @__PURE__ */ jsx(Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
7266
- ] }) })
7267
- ]
7268
- }
7269
- ) });
7270
- };
7271
- const schema$3 = addressSchema;
7272
- const InlineTip = forwardRef(
7273
- ({ variant = "tip", label, className, children, ...props }, ref) => {
7274
- const labelValue = label || (variant === "warning" ? "Warning" : "Tip");
7275
- return /* @__PURE__ */ jsxs(
7276
- "div",
7277
- {
7278
- ref,
7279
- className: clx(
7280
- "bg-ui-bg-component txt-small text-ui-fg-subtle grid grid-cols-[4px_1fr] items-start gap-3 rounded-lg border p-3",
7281
- className
7282
- ),
7283
- ...props,
7284
- children: [
7285
- /* @__PURE__ */ jsx(
7286
- "div",
7287
- {
7288
- role: "presentation",
7289
- className: clx("w-4px bg-ui-tag-neutral-icon h-full rounded-full", {
7290
- "bg-ui-tag-orange-icon": variant === "warning"
7291
- })
7292
- }
7293
- ),
7294
- /* @__PURE__ */ jsxs("div", { className: "text-pretty", children: [
7295
- /* @__PURE__ */ jsxs("strong", { className: "txt-small-plus text-ui-fg-base", children: [
7296
- labelValue,
7297
- ":"
7298
- ] }),
7299
- " ",
7300
- children
7301
- ] })
7302
- ]
7303
- }
7304
- );
7305
- }
7306
- );
7307
- InlineTip.displayName = "InlineTip";
7308
- const MetadataFieldSchema = z.object({
7309
- key: z.string(),
7310
- disabled: z.boolean().optional(),
7311
- value: z.any()
7312
- });
7313
- const MetadataSchema = z.object({
7314
- metadata: z.array(MetadataFieldSchema)
7315
- });
7316
- const Metadata = () => {
7317
- const { id } = useParams();
7318
- const { order, isPending, isError, error } = useOrder(id, {
7319
- fields: "metadata"
7320
- });
7321
- if (isError) {
7322
- throw error;
7323
- }
7324
- const isReady = !isPending && !!order;
7325
- return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
7326
- /* @__PURE__ */ jsxs(RouteDrawer.Header, { children: [
7327
- /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Metadata" }) }),
7328
- /* @__PURE__ */ jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Add metadata to the draft order." }) })
7329
- ] }),
7330
- !isReady ? /* @__PURE__ */ jsx(PlaceholderInner, {}) : /* @__PURE__ */ jsx(MetadataForm, { orderId: id, metadata: order?.metadata })
7331
- ] });
7332
- };
7333
- const METADATA_KEY_LABEL_ID = "metadata-form-key-label";
7334
- const METADATA_VALUE_LABEL_ID = "metadata-form-value-label";
7335
- const MetadataForm = ({ orderId, metadata }) => {
7336
- const { handleSuccess } = useRouteModal();
7337
- const hasUneditableRows = getHasUneditableRows(metadata);
7338
- const { mutateAsync, isPending } = useUpdateDraftOrder(orderId);
7339
- const form = useForm({
7340
- defaultValues: {
7341
- metadata: getDefaultValues(metadata)
7319
+ id: promoIds
7342
7320
  },
7343
- resolver: zodResolver(MetadataSchema)
7344
- });
7345
- const handleSubmit = form.handleSubmit(async (data) => {
7346
- const parsedData = parseValues(data);
7347
- await mutateAsync(
7348
- {
7349
- metadata: parsedData
7350
- },
7351
- {
7352
- onSuccess: () => {
7353
- toast.success("Metadata updated");
7354
- handleSuccess();
7355
- },
7356
- onError: (error) => {
7357
- toast.error(error.message);
7358
- }
7359
- }
7360
- );
7361
- });
7362
- const { fields, insert, remove } = useFieldArray({
7363
- control: form.control,
7364
- name: "metadata"
7365
- });
7366
- function deleteRow(index) {
7367
- remove(index);
7368
- if (fields.length === 1) {
7369
- insert(0, {
7370
- key: "",
7371
- value: "",
7372
- disabled: false
7373
- });
7374
- }
7375
- }
7376
- function insertRow(index, position) {
7377
- insert(index + (position === "above" ? 0 : 1), {
7378
- key: "",
7379
- value: "",
7380
- disabled: false
7381
- });
7382
- }
7383
- return /* @__PURE__ */ jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxs(
7384
- KeyboundForm,
7385
- {
7386
- onSubmit: handleSubmit,
7387
- className: "flex flex-1 flex-col overflow-hidden",
7388
- children: [
7389
- /* @__PURE__ */ jsxs(RouteDrawer.Body, { className: "flex flex-1 flex-col gap-y-8 overflow-y-auto", children: [
7390
- /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest grid grid-cols-1 divide-y rounded-lg", children: [
7391
- /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-subtle grid grid-cols-2 divide-x rounded-t-lg", children: [
7392
- /* @__PURE__ */ jsx("div", { className: "txt-compact-small-plus text-ui-fg-subtle px-2 py-1.5", children: /* @__PURE__ */ jsx("label", { id: METADATA_KEY_LABEL_ID, children: "Key" }) }),
7393
- /* @__PURE__ */ jsx("div", { className: "txt-compact-small-plus text-ui-fg-subtle px-2 py-1.5", children: /* @__PURE__ */ jsx("label", { id: METADATA_VALUE_LABEL_ID, children: "Value" }) })
7394
- ] }),
7395
- fields.map((field, index) => {
7396
- const isDisabled = field.disabled || false;
7397
- let placeholder = "-";
7398
- if (typeof field.value === "object") {
7399
- placeholder = "{ ... }";
7400
- }
7401
- if (Array.isArray(field.value)) {
7402
- placeholder = "[ ... ]";
7403
- }
7404
- return /* @__PURE__ */ jsx(
7405
- ConditionalTooltip,
7406
- {
7407
- showTooltip: isDisabled,
7408
- content: "This row is disabled because it contains non-primitive data.",
7409
- children: /* @__PURE__ */ jsxs("div", { className: "group/table relative", children: [
7410
- /* @__PURE__ */ jsxs(
7411
- "div",
7412
- {
7413
- className: clx("grid grid-cols-2 divide-x", {
7414
- "overflow-hidden rounded-b-lg": index === fields.length - 1
7415
- }),
7416
- children: [
7417
- /* @__PURE__ */ jsx(
7418
- Form$2.Field,
7419
- {
7420
- control: form.control,
7421
- name: `metadata.${index}.key`,
7422
- render: ({ field: field2 }) => {
7423
- return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
7424
- GridInput,
7425
- {
7426
- "aria-labelledby": METADATA_KEY_LABEL_ID,
7427
- ...field2,
7428
- disabled: isDisabled,
7429
- placeholder: "Key"
7430
- }
7431
- ) }) });
7432
- }
7433
- }
7434
- ),
7435
- /* @__PURE__ */ jsx(
7436
- Form$2.Field,
7437
- {
7438
- control: form.control,
7439
- name: `metadata.${index}.value`,
7440
- render: ({ field: { value, ...field2 } }) => {
7441
- return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
7442
- GridInput,
7443
- {
7444
- "aria-labelledby": METADATA_VALUE_LABEL_ID,
7445
- ...field2,
7446
- value: isDisabled ? placeholder : value,
7447
- disabled: isDisabled,
7448
- placeholder: "Value"
7449
- }
7450
- ) }) });
7451
- }
7452
- }
7453
- )
7454
- ]
7455
- }
7456
- ),
7457
- /* @__PURE__ */ jsxs(DropdownMenu, { children: [
7458
- /* @__PURE__ */ jsx(
7459
- DropdownMenu.Trigger,
7460
- {
7461
- className: clx(
7462
- "invisible absolute inset-y-0 -right-2.5 my-auto group-hover/table:visible data-[state='open']:visible",
7463
- {
7464
- hidden: isDisabled
7465
- }
7466
- ),
7467
- disabled: isDisabled,
7468
- asChild: true,
7469
- children: /* @__PURE__ */ jsx(IconButton, { size: "2xsmall", children: /* @__PURE__ */ jsx(EllipsisVertical, {}) })
7470
- }
7471
- ),
7472
- /* @__PURE__ */ jsxs(DropdownMenu.Content, { children: [
7473
- /* @__PURE__ */ jsxs(
7474
- DropdownMenu.Item,
7475
- {
7476
- className: "gap-x-2",
7477
- onClick: () => insertRow(index, "above"),
7478
- children: [
7479
- /* @__PURE__ */ jsx(ArrowUpMini, { className: "text-ui-fg-subtle" }),
7480
- "Insert row above"
7481
- ]
7482
- }
7483
- ),
7484
- /* @__PURE__ */ jsxs(
7485
- DropdownMenu.Item,
7486
- {
7487
- className: "gap-x-2",
7488
- onClick: () => insertRow(index, "below"),
7489
- children: [
7490
- /* @__PURE__ */ jsx(ArrowDownMini, { className: "text-ui-fg-subtle" }),
7491
- "Insert row below"
7492
- ]
7493
- }
7494
- ),
7495
- /* @__PURE__ */ jsx(DropdownMenu.Separator, {}),
7496
- /* @__PURE__ */ jsxs(
7497
- DropdownMenu.Item,
7498
- {
7499
- className: "gap-x-2",
7500
- onClick: () => deleteRow(index),
7501
- children: [
7502
- /* @__PURE__ */ jsx(Trash, { className: "text-ui-fg-subtle" }),
7503
- "Delete row"
7504
- ]
7505
- }
7506
- )
7507
- ] })
7508
- ] })
7509
- ] })
7510
- },
7511
- field.id
7512
- );
7513
- })
7514
- ] }),
7515
- hasUneditableRows && /* @__PURE__ */ jsx(InlineTip, { variant: "warning", label: "Some rows are disabled", children: "This object contains non-primitive metadata, such as arrays or objects, that can't be edited here. To edit the disabled rows, use the API directly." })
7516
- ] }),
7517
- /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
7518
- /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
7519
- /* @__PURE__ */ jsx(Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
7520
- ] }) })
7521
- ]
7522
- }
7523
- ) });
7524
- };
7525
- const GridInput = forwardRef(({ className, ...props }, ref) => {
7526
- return /* @__PURE__ */ jsx(
7527
- "input",
7528
7321
  {
7529
- ref,
7530
- ...props,
7531
- autoComplete: "off",
7532
- className: clx(
7533
- "txt-compact-small text-ui-fg-base placeholder:text-ui-fg-muted disabled:text-ui-fg-disabled disabled:bg-ui-bg-base bg-transparent px-2 py-1.5 outline-none",
7534
- className
7535
- )
7536
- }
7537
- );
7538
- });
7539
- GridInput.displayName = "MetadataForm.GridInput";
7540
- const PlaceholderInner = () => {
7541
- return /* @__PURE__ */ jsxs("div", { className: "flex flex-1 flex-col overflow-hidden", children: [
7542
- /* @__PURE__ */ jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsx(Skeleton, { className: "h-[148ox] w-full rounded-lg" }) }),
7543
- /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
7544
- /* @__PURE__ */ jsx(Skeleton, { className: "h-7 w-12 rounded-md" }),
7545
- /* @__PURE__ */ jsx(Skeleton, { className: "h-7 w-12 rounded-md" })
7546
- ] }) })
7547
- ] });
7548
- };
7549
- const EDITABLE_TYPES = ["string", "number", "boolean"];
7550
- function getDefaultValues(metadata) {
7551
- if (!metadata || !Object.keys(metadata).length) {
7552
- return [
7553
- {
7554
- key: "",
7555
- value: "",
7556
- disabled: false
7557
- }
7558
- ];
7559
- }
7560
- return Object.entries(metadata).map(([key, value]) => {
7561
- if (!EDITABLE_TYPES.includes(typeof value)) {
7562
- return {
7563
- key,
7564
- value,
7565
- disabled: true
7566
- };
7322
+ enabled: !!promoIds.length
7567
7323
  }
7568
- let stringValue = value;
7569
- if (typeof value !== "string") {
7570
- stringValue = JSON.stringify(value);
7324
+ );
7325
+ const comboboxData = useComboboxData({
7326
+ queryKey: ["promotions", "combobox", promoIds],
7327
+ queryFn: async (params) => {
7328
+ return await sdk.admin.promotion.list({
7329
+ ...params,
7330
+ id: {
7331
+ $nin: promoIds
7332
+ }
7333
+ });
7334
+ },
7335
+ getOptions: (data) => {
7336
+ return data.promotions.map((promotion) => ({
7337
+ label: promotion.code,
7338
+ value: promotion.code
7339
+ }));
7571
7340
  }
7572
- return {
7573
- key,
7574
- value: stringValue,
7575
- original_key: key
7576
- };
7577
7341
  });
7578
- }
7579
- function parseValues(values) {
7580
- const metadata = values.metadata;
7581
- const isEmpty = !metadata.length || metadata.length === 1 && !metadata[0].key && !metadata[0].value;
7582
- if (isEmpty) {
7583
- return null;
7584
- }
7585
- const update = {};
7586
- metadata.forEach((field) => {
7587
- let key = field.key;
7588
- let value = field.value;
7589
- const disabled = field.disabled;
7590
- if (!key || !value) {
7342
+ const add = async (value) => {
7343
+ if (!value) {
7591
7344
  return;
7592
7345
  }
7593
- if (disabled) {
7594
- update[key] = value;
7346
+ addPromotions(
7347
+ {
7348
+ promo_codes: [value]
7349
+ },
7350
+ {
7351
+ onError: (e) => {
7352
+ toast.error(e.message);
7353
+ comboboxData.onSearchValueChange("");
7354
+ setComboboxValue("");
7355
+ },
7356
+ onSuccess: () => {
7357
+ comboboxData.onSearchValueChange("");
7358
+ setComboboxValue("");
7359
+ }
7360
+ }
7361
+ );
7362
+ };
7363
+ const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
7364
+ const { mutateAsync: requestOrderEdit } = useOrderEditRequest(preview.id);
7365
+ const onSubmit = async () => {
7366
+ setIsSubmitting(true);
7367
+ let requestSucceeded = false;
7368
+ await requestOrderEdit(void 0, {
7369
+ onError: (e) => {
7370
+ toast.error(e.message);
7371
+ },
7372
+ onSuccess: () => {
7373
+ requestSucceeded = true;
7374
+ }
7375
+ });
7376
+ if (!requestSucceeded) {
7377
+ setIsSubmitting(false);
7595
7378
  return;
7596
7379
  }
7597
- key = key.trim();
7598
- value = value.trim();
7599
- if (value === "true") {
7600
- update[key] = true;
7601
- } else if (value === "false") {
7602
- update[key] = false;
7603
- } else {
7604
- const parsedNumber = parseFloat(value);
7605
- if (!isNaN(parsedNumber)) {
7606
- update[key] = parsedNumber;
7607
- } else {
7608
- update[key] = value;
7380
+ await confirmOrderEdit(void 0, {
7381
+ onError: (e) => {
7382
+ toast.error(e.message);
7383
+ },
7384
+ onSuccess: () => {
7385
+ handleSuccess();
7386
+ },
7387
+ onSettled: () => {
7388
+ setIsSubmitting(false);
7609
7389
  }
7610
- }
7611
- });
7612
- return update;
7613
- }
7614
- function getHasUneditableRows(metadata) {
7615
- if (!metadata) {
7616
- return false;
7617
- }
7618
- return Object.values(metadata).some(
7619
- (value) => !EDITABLE_TYPES.includes(typeof value)
7620
- );
7621
- }
7622
- const SalesChannel = () => {
7623
- const { id } = useParams();
7624
- const { draft_order, isPending, isError, error } = useDraftOrder(
7625
- id,
7626
- {
7627
- fields: "+sales_channel_id"
7628
- },
7629
- {
7630
- enabled: !!id
7631
- }
7632
- );
7390
+ });
7391
+ };
7633
7392
  if (isError) {
7634
7393
  throw error;
7635
7394
  }
7636
- const ISrEADY = !!draft_order && !isPending;
7637
- return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
7638
- /* @__PURE__ */ jsxs(RouteDrawer.Header, { children: [
7639
- /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Sales Channel" }) }),
7640
- /* @__PURE__ */ jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Update which sales channel the draft order is associated with" }) })
7641
- ] }),
7642
- ISrEADY && /* @__PURE__ */ jsx(SalesChannelForm, { order: draft_order })
7395
+ return /* @__PURE__ */ jsxs(KeyboundForm, { className: "flex flex-1 flex-col", onSubmit, children: [
7396
+ /* @__PURE__ */ jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-4", children: [
7397
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3", children: [
7398
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
7399
+ /* @__PURE__ */ jsx(Label$1, { size: "small", weight: "plus", htmlFor: "promotion-combobox", children: "Apply promotions" }),
7400
+ /* @__PURE__ */ jsx(Hint$1, { id: "promotion-combobox-hint", children: "Manage promotions that should be applied to the order." })
7401
+ ] }),
7402
+ /* @__PURE__ */ jsx(
7403
+ Combobox,
7404
+ {
7405
+ id: "promotion-combobox",
7406
+ "aria-describedby": "promotion-combobox-hint",
7407
+ isFetchingNextPage: comboboxData.isFetchingNextPage,
7408
+ fetchNextPage: comboboxData.fetchNextPage,
7409
+ options: comboboxData.options,
7410
+ onSearchValueChange: comboboxData.onSearchValueChange,
7411
+ searchValue: comboboxData.searchValue,
7412
+ disabled: comboboxData.disabled || isAddingPromotions,
7413
+ onChange: add,
7414
+ value: comboboxValue
7415
+ }
7416
+ )
7417
+ ] }),
7418
+ /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
7419
+ /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-2", children: promotions?.map((promotion) => /* @__PURE__ */ jsx(
7420
+ PromotionItem,
7421
+ {
7422
+ promotion,
7423
+ orderId: preview.id,
7424
+ isLoading: isPending
7425
+ },
7426
+ promotion.id
7427
+ )) })
7428
+ ] }) }),
7429
+ /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
7430
+ /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
7431
+ /* @__PURE__ */ jsx(
7432
+ Button,
7433
+ {
7434
+ size: "small",
7435
+ type: "submit",
7436
+ isLoading: isSubmitting || isAddingPromotions,
7437
+ children: "Save"
7438
+ }
7439
+ )
7440
+ ] }) })
7643
7441
  ] });
7644
7442
  };
7645
- const SalesChannelForm = ({ order }) => {
7646
- const form = useForm({
7647
- defaultValues: {
7648
- sales_channel_id: order.sales_channel_id || ""
7649
- },
7650
- resolver: zodResolver(schema$2)
7651
- });
7652
- const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
7653
- const { handleSuccess } = useRouteModal();
7654
- const onSubmit = form.handleSubmit(async (data) => {
7655
- await mutateAsync(
7443
+ const PromotionItem = ({
7444
+ promotion,
7445
+ orderId,
7446
+ isLoading
7447
+ }) => {
7448
+ const { mutateAsync: removePromotions, isPending } = useDraftOrderRemovePromotions(orderId);
7449
+ const onRemove = async () => {
7450
+ removePromotions(
7656
7451
  {
7657
- sales_channel_id: data.sales_channel_id
7452
+ promo_codes: [promotion.code]
7658
7453
  },
7659
7454
  {
7660
- onSuccess: () => {
7661
- toast.success("Sales channel updated");
7662
- handleSuccess();
7663
- },
7664
- onError: (error) => {
7665
- toast.error(error.message);
7455
+ onError: (e) => {
7456
+ toast.error(e.message);
7666
7457
  }
7667
7458
  }
7668
7459
  );
7669
- });
7670
- return /* @__PURE__ */ jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxs(
7671
- KeyboundForm,
7460
+ };
7461
+ const displayValue = getDisplayValue(promotion);
7462
+ return /* @__PURE__ */ jsxs(
7463
+ "div",
7672
7464
  {
7673
- className: "flex flex-1 flex-col overflow-hidden",
7674
- onSubmit,
7465
+ className: clx(
7466
+ "bg-ui-bg-component shadow-elevation-card-rest flex items-center justify-between rounded-lg px-3 py-2",
7467
+ {
7468
+ "animate-pulse": isLoading
7469
+ }
7470
+ ),
7675
7471
  children: [
7676
- /* @__PURE__ */ jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsx(SalesChannelField, { control: form.control, order }) }),
7677
- /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
7678
- /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
7679
- /* @__PURE__ */ jsx(Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
7680
- ] }) })
7472
+ /* @__PURE__ */ jsxs("div", { children: [
7473
+ /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: promotion.code }),
7474
+ /* @__PURE__ */ jsxs("div", { className: "text-ui-fg-subtle flex items-center gap-1.5", children: [
7475
+ displayValue && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
7476
+ /* @__PURE__ */ jsx(Text, { size: "small", leading: "compact", children: displayValue }),
7477
+ /* @__PURE__ */ jsx(Text, { size: "small", leading: "compact", children: "·" })
7478
+ ] }),
7479
+ /* @__PURE__ */ jsx(Text, { size: "small", leading: "compact", className: "capitalize", children: promotion.application_method?.allocation })
7480
+ ] })
7481
+ ] }),
7482
+ /* @__PURE__ */ jsx(
7483
+ IconButton,
7484
+ {
7485
+ size: "small",
7486
+ type: "button",
7487
+ variant: "transparent",
7488
+ onClick: onRemove,
7489
+ isLoading: isPending || isLoading,
7490
+ children: /* @__PURE__ */ jsx(XMark, {})
7491
+ }
7492
+ )
7681
7493
  ]
7682
- }
7683
- ) });
7684
- };
7685
- const SalesChannelField = ({ control, order }) => {
7686
- const salesChannels = useComboboxData({
7687
- queryFn: async (params) => {
7688
- return await sdk.admin.salesChannel.list(params);
7689
- },
7690
- queryKey: ["sales-channels"],
7691
- getOptions: (data) => {
7692
- return data.sales_channels.map((salesChannel) => ({
7693
- label: salesChannel.name,
7694
- value: salesChannel.id
7695
- }));
7696
7494
  },
7697
- defaultValue: order.sales_channel_id || void 0
7698
- });
7699
- return /* @__PURE__ */ jsx(
7700
- Form$2.Field,
7701
- {
7702
- control,
7703
- name: "sales_channel_id",
7704
- render: ({ field }) => {
7705
- return /* @__PURE__ */ jsxs(Form$2.Item, { children: [
7706
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Sales Channel" }),
7707
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
7708
- Combobox,
7709
- {
7710
- options: salesChannels.options,
7711
- fetchNextPage: salesChannels.fetchNextPage,
7712
- isFetchingNextPage: salesChannels.isFetchingNextPage,
7713
- searchValue: salesChannels.searchValue,
7714
- onSearchValueChange: salesChannels.onSearchValueChange,
7715
- placeholder: "Select sales channel",
7716
- ...field
7717
- }
7718
- ) }),
7719
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
7720
- ] });
7721
- }
7722
- }
7495
+ promotion.id
7723
7496
  );
7724
7497
  };
7725
- const schema$2 = z.object({
7726
- sales_channel_id: z.string().min(1)
7498
+ function getDisplayValue(promotion) {
7499
+ const value = promotion.application_method?.value;
7500
+ if (!value) {
7501
+ return null;
7502
+ }
7503
+ if (promotion.application_method?.type === "fixed") {
7504
+ const currency = promotion.application_method?.currency_code;
7505
+ if (!currency) {
7506
+ return null;
7507
+ }
7508
+ return getLocaleAmount(value, currency);
7509
+ } else if (promotion.application_method?.type === "percentage") {
7510
+ return formatPercentage(value);
7511
+ }
7512
+ return null;
7513
+ }
7514
+ const formatter = new Intl.NumberFormat([], {
7515
+ style: "percent",
7516
+ minimumFractionDigits: 2
7727
7517
  });
7728
- const ShippingAddress = () => {
7729
- const { id } = useParams();
7730
- const { order, isPending, isError, error } = useOrder(id, {
7731
- fields: "+shipping_address"
7732
- });
7733
- if (isError) {
7734
- throw error;
7518
+ const formatPercentage = (value, isPercentageValue = false) => {
7519
+ let val = value || 0;
7520
+ if (!isPercentageValue) {
7521
+ val = val / 100;
7735
7522
  }
7736
- const isReady = !isPending && !!order;
7737
- return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
7738
- /* @__PURE__ */ jsxs(RouteDrawer.Header, { children: [
7739
- /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Shipping Address" }) }),
7740
- /* @__PURE__ */ jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Edit the shipping address for the draft order" }) })
7741
- ] }),
7742
- isReady && /* @__PURE__ */ jsx(ShippingAddressForm, { order })
7743
- ] });
7523
+ return formatter.format(val);
7744
7524
  };
7745
- const ShippingAddressForm = ({ order }) => {
7746
- const form = useForm({
7747
- defaultValues: {
7748
- first_name: order.shipping_address?.first_name ?? "",
7749
- last_name: order.shipping_address?.last_name ?? "",
7750
- company: order.shipping_address?.company ?? "",
7751
- address_1: order.shipping_address?.address_1 ?? "",
7752
- address_2: order.shipping_address?.address_2 ?? "",
7753
- city: order.shipping_address?.city ?? "",
7754
- province: order.shipping_address?.province ?? "",
7755
- country_code: order.shipping_address?.country_code ?? "",
7756
- postal_code: order.shipping_address?.postal_code ?? "",
7757
- phone: order.shipping_address?.phone ?? ""
7758
- },
7759
- resolver: zodResolver(schema$1)
7760
- });
7761
- const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
7762
- const { handleSuccess } = useRouteModal();
7763
- const onSubmit = form.handleSubmit(async (data) => {
7764
- await mutateAsync(
7765
- {
7766
- shipping_address: {
7767
- first_name: data.first_name,
7768
- last_name: data.last_name,
7769
- company: data.company,
7770
- address_1: data.address_1,
7771
- address_2: data.address_2,
7772
- city: data.city,
7773
- province: data.province,
7774
- country_code: data.country_code,
7775
- postal_code: data.postal_code,
7776
- phone: data.phone
7525
+ function getPromotionIds(items, shippingMethods) {
7526
+ const promotionIds = /* @__PURE__ */ new Set();
7527
+ for (const item of items) {
7528
+ if (item.adjustments) {
7529
+ for (const adjustment of item.adjustments) {
7530
+ if (adjustment.promotion_id) {
7531
+ promotionIds.add(adjustment.promotion_id);
7777
7532
  }
7778
- },
7779
- {
7780
- onSuccess: () => {
7781
- handleSuccess();
7782
- },
7783
- onError: (error) => {
7784
- toast.error(error.message);
7533
+ }
7534
+ }
7535
+ }
7536
+ for (const shippingMethod of shippingMethods) {
7537
+ if (shippingMethod.adjustments) {
7538
+ for (const adjustment of shippingMethod.adjustments) {
7539
+ if (adjustment.promotion_id) {
7540
+ promotionIds.add(adjustment.promotion_id);
7785
7541
  }
7786
7542
  }
7787
- );
7788
- });
7789
- return /* @__PURE__ */ jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxs(
7790
- KeyboundForm,
7791
- {
7792
- className: "flex flex-1 flex-col overflow-hidden",
7793
- onSubmit,
7794
- children: [
7795
- /* @__PURE__ */ jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-y-4", children: [
7796
- /* @__PURE__ */ jsx(
7797
- Form$2.Field,
7798
- {
7799
- control: form.control,
7800
- name: "country_code",
7801
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
7802
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Country" }),
7803
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(CountrySelect, { ...field }) }),
7804
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
7805
- ] })
7806
- }
7807
- ),
7808
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
7809
- /* @__PURE__ */ jsx(
7810
- Form$2.Field,
7811
- {
7812
- control: form.control,
7813
- name: "first_name",
7814
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
7815
- /* @__PURE__ */ jsx(Form$2.Label, { children: "First name" }),
7816
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
7817
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
7818
- ] })
7819
- }
7820
- ),
7821
- /* @__PURE__ */ jsx(
7822
- Form$2.Field,
7823
- {
7824
- control: form.control,
7825
- name: "last_name",
7826
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
7827
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Last name" }),
7828
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
7829
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
7830
- ] })
7831
- }
7832
- )
7833
- ] }),
7834
- /* @__PURE__ */ jsx(
7835
- Form$2.Field,
7836
- {
7837
- control: form.control,
7838
- name: "company",
7839
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
7840
- /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Company" }),
7841
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
7842
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
7843
- ] })
7844
- }
7845
- ),
7846
- /* @__PURE__ */ jsx(
7847
- Form$2.Field,
7848
- {
7849
- control: form.control,
7850
- name: "address_1",
7851
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
7852
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Address" }),
7853
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
7854
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
7855
- ] })
7856
- }
7857
- ),
7858
- /* @__PURE__ */ jsx(
7859
- Form$2.Field,
7860
- {
7861
- control: form.control,
7862
- name: "address_2",
7863
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
7864
- /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Apartment, suite, etc." }),
7865
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
7866
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
7867
- ] })
7868
- }
7869
- ),
7870
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
7871
- /* @__PURE__ */ jsx(
7872
- Form$2.Field,
7873
- {
7874
- control: form.control,
7875
- name: "postal_code",
7876
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
7877
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Postal code" }),
7878
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
7879
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
7880
- ] })
7881
- }
7882
- ),
7883
- /* @__PURE__ */ jsx(
7884
- Form$2.Field,
7885
- {
7886
- control: form.control,
7887
- name: "city",
7888
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
7889
- /* @__PURE__ */ jsx(Form$2.Label, { children: "City" }),
7890
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
7891
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
7892
- ] })
7893
- }
7894
- )
7895
- ] }),
7896
- /* @__PURE__ */ jsx(
7897
- Form$2.Field,
7898
- {
7899
- control: form.control,
7900
- name: "province",
7901
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
7902
- /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Province / State" }),
7903
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
7904
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
7905
- ] })
7906
- }
7907
- ),
7908
- /* @__PURE__ */ jsx(
7909
- Form$2.Field,
7910
- {
7911
- control: form.control,
7912
- name: "phone",
7913
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
7914
- /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Phone" }),
7915
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
7916
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
7917
- ] })
7918
- }
7919
- )
7920
- ] }) }),
7543
+ }
7544
+ }
7545
+ return Array.from(promotionIds);
7546
+ }
7547
+ const SalesChannel = () => {
7548
+ const { id } = useParams();
7549
+ const { draft_order, isPending, isError, error } = useDraftOrder(
7550
+ id,
7551
+ {
7552
+ fields: "+sales_channel_id"
7553
+ },
7554
+ {
7555
+ enabled: !!id
7556
+ }
7557
+ );
7558
+ if (isError) {
7559
+ throw error;
7560
+ }
7561
+ const ISrEADY = !!draft_order && !isPending;
7562
+ return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
7563
+ /* @__PURE__ */ jsxs(RouteDrawer.Header, { children: [
7564
+ /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Sales Channel" }) }),
7565
+ /* @__PURE__ */ jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Update which sales channel the draft order is associated with" }) })
7566
+ ] }),
7567
+ ISrEADY && /* @__PURE__ */ jsx(SalesChannelForm, { order: draft_order })
7568
+ ] });
7569
+ };
7570
+ const SalesChannelForm = ({ order }) => {
7571
+ const form = useForm({
7572
+ defaultValues: {
7573
+ sales_channel_id: order.sales_channel_id || ""
7574
+ },
7575
+ resolver: zodResolver(schema$2)
7576
+ });
7577
+ const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
7578
+ const { handleSuccess } = useRouteModal();
7579
+ const onSubmit = form.handleSubmit(async (data) => {
7580
+ await mutateAsync(
7581
+ {
7582
+ sales_channel_id: data.sales_channel_id
7583
+ },
7584
+ {
7585
+ onSuccess: () => {
7586
+ toast.success("Sales channel updated");
7587
+ handleSuccess();
7588
+ },
7589
+ onError: (error) => {
7590
+ toast.error(error.message);
7591
+ }
7592
+ }
7593
+ );
7594
+ });
7595
+ return /* @__PURE__ */ jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxs(
7596
+ KeyboundForm,
7597
+ {
7598
+ className: "flex flex-1 flex-col overflow-hidden",
7599
+ onSubmit,
7600
+ children: [
7601
+ /* @__PURE__ */ jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsx(SalesChannelField, { control: form.control, order }) }),
7921
7602
  /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
7922
7603
  /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
7923
7604
  /* @__PURE__ */ jsx(Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
@@ -7926,7 +7607,49 @@ const ShippingAddressForm = ({ order }) => {
7926
7607
  }
7927
7608
  ) });
7928
7609
  };
7929
- const schema$1 = addressSchema;
7610
+ const SalesChannelField = ({ control, order }) => {
7611
+ const salesChannels = useComboboxData({
7612
+ queryFn: async (params) => {
7613
+ return await sdk.admin.salesChannel.list(params);
7614
+ },
7615
+ queryKey: ["sales-channels"],
7616
+ getOptions: (data) => {
7617
+ return data.sales_channels.map((salesChannel) => ({
7618
+ label: salesChannel.name,
7619
+ value: salesChannel.id
7620
+ }));
7621
+ },
7622
+ defaultValue: order.sales_channel_id || void 0
7623
+ });
7624
+ return /* @__PURE__ */ jsx(
7625
+ Form$2.Field,
7626
+ {
7627
+ control,
7628
+ name: "sales_channel_id",
7629
+ render: ({ field }) => {
7630
+ return /* @__PURE__ */ jsxs(Form$2.Item, { children: [
7631
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Sales Channel" }),
7632
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
7633
+ Combobox,
7634
+ {
7635
+ options: salesChannels.options,
7636
+ fetchNextPage: salesChannels.fetchNextPage,
7637
+ isFetchingNextPage: salesChannels.isFetchingNextPage,
7638
+ searchValue: salesChannels.searchValue,
7639
+ onSearchValueChange: salesChannels.onSearchValueChange,
7640
+ placeholder: "Select sales channel",
7641
+ ...field
7642
+ }
7643
+ ) }),
7644
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
7645
+ ] });
7646
+ }
7647
+ }
7648
+ );
7649
+ };
7650
+ const schema$2 = z.object({
7651
+ sales_channel_id: z.string().min(1)
7652
+ });
7930
7653
  const STACKED_FOCUS_MODAL_ID = "shipping-form";
7931
7654
  const Shipping = () => {
7932
7655
  const { id } = useParams();
@@ -8670,332 +8393,259 @@ const ShippingOptionField = ({
8670
8393
  /* @__PURE__ */ jsx(
8671
8394
  ConditionalTooltip,
8672
8395
  {
8673
- content: tooltipContent,
8674
- showTooltip: !locationId || !shippingProfileId,
8675
- children: /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
8676
- Combobox,
8677
- {
8678
- options: shippingOptions.options,
8679
- fetchNextPage: shippingOptions.fetchNextPage,
8680
- isFetchingNextPage: shippingOptions.isFetchingNextPage,
8681
- searchValue: shippingOptions.searchValue,
8682
- onSearchValueChange: shippingOptions.onSearchValueChange,
8683
- placeholder: "Select shipping option",
8684
- ...field,
8685
- disabled: !locationId || !shippingProfileId
8686
- }
8687
- ) }) })
8688
- }
8689
- )
8690
- ] }) });
8691
- }
8692
- }
8693
- );
8694
- };
8695
- const CustomAmountField = ({
8696
- control,
8697
- currencyCode
8698
- }) => {
8699
- return /* @__PURE__ */ jsx(
8700
- Form$2.Field,
8701
- {
8702
- control,
8703
- name: "custom_amount",
8704
- render: ({ field: { onChange, ...field } }) => {
8705
- return /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
8706
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
8707
- /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Custom amount" }),
8708
- /* @__PURE__ */ jsx(Form$2.Hint, { children: "Set a custom amount for the shipping option." })
8709
- ] }),
8710
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
8711
- CurrencyInput,
8712
- {
8713
- ...field,
8714
- onValueChange: (value) => onChange(value),
8715
- symbol: getNativeSymbol(currencyCode),
8716
- code: currencyCode
8717
- }
8718
- ) })
8719
- ] });
8720
- }
8721
- }
8722
- );
8723
- };
8724
- const PROMOTION_QUERY_KEY = "promotions";
8725
- const promotionsQueryKeys = {
8726
- list: (query2) => [
8727
- PROMOTION_QUERY_KEY,
8728
- query2 ? query2 : void 0
8729
- ],
8730
- detail: (id, query2) => [
8731
- PROMOTION_QUERY_KEY,
8732
- id,
8733
- query2 ? query2 : void 0
8734
- ]
8735
- };
8736
- const usePromotions = (query2, options) => {
8737
- const { data, ...rest } = useQuery({
8738
- queryKey: promotionsQueryKeys.list(query2),
8739
- queryFn: async () => sdk.admin.promotion.list(query2),
8740
- ...options
8741
- });
8742
- return { ...data, ...rest };
8743
- };
8744
- const Promotions = () => {
8745
- const { id } = useParams();
8746
- const {
8747
- order: preview,
8748
- isError: isPreviewError,
8749
- error: previewError
8750
- } = useOrderPreview(id, void 0);
8751
- useInitiateOrderEdit({ preview });
8752
- const { onCancel } = useCancelOrderEdit({ preview });
8753
- if (isPreviewError) {
8754
- throw previewError;
8755
- }
8756
- const isReady = !!preview;
8757
- return /* @__PURE__ */ jsxs(RouteDrawer, { onClose: onCancel, children: [
8758
- /* @__PURE__ */ jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Promotions" }) }) }),
8759
- isReady && /* @__PURE__ */ jsx(PromotionForm, { preview })
8760
- ] });
8761
- };
8762
- const PromotionForm = ({ preview }) => {
8763
- const { items, shipping_methods } = preview;
8764
- const [isSubmitting, setIsSubmitting] = useState(false);
8765
- const [comboboxValue, setComboboxValue] = useState("");
8766
- const { handleSuccess } = useRouteModal();
8767
- const { mutateAsync: addPromotions, isPending: isAddingPromotions } = useDraftOrderAddPromotions(preview.id);
8768
- const promoIds = getPromotionIds(items, shipping_methods);
8769
- const { promotions, isPending, isError, error } = usePromotions(
8770
- {
8771
- id: promoIds
8772
- },
8773
- {
8774
- enabled: !!promoIds.length
8775
- }
8776
- );
8777
- const comboboxData = useComboboxData({
8778
- queryKey: ["promotions", "combobox", promoIds],
8779
- queryFn: async (params) => {
8780
- return await sdk.admin.promotion.list({
8781
- ...params,
8782
- id: {
8783
- $nin: promoIds
8784
- }
8785
- });
8786
- },
8787
- getOptions: (data) => {
8788
- return data.promotions.map((promotion) => ({
8789
- label: promotion.code,
8790
- value: promotion.code
8791
- }));
8792
- }
8793
- });
8794
- const add = async (value) => {
8795
- if (!value) {
8796
- return;
8797
- }
8798
- addPromotions(
8799
- {
8800
- promo_codes: [value]
8801
- },
8802
- {
8803
- onError: (e) => {
8804
- toast.error(e.message);
8805
- comboboxData.onSearchValueChange("");
8806
- setComboboxValue("");
8807
- },
8808
- onSuccess: () => {
8809
- comboboxData.onSearchValueChange("");
8810
- setComboboxValue("");
8811
- }
8812
- }
8813
- );
8814
- };
8815
- const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
8816
- const { mutateAsync: requestOrderEdit } = useOrderEditRequest(preview.id);
8817
- const onSubmit = async () => {
8818
- setIsSubmitting(true);
8819
- let requestSucceeded = false;
8820
- await requestOrderEdit(void 0, {
8821
- onError: (e) => {
8822
- toast.error(e.message);
8823
- },
8824
- onSuccess: () => {
8825
- requestSucceeded = true;
8396
+ content: tooltipContent,
8397
+ showTooltip: !locationId || !shippingProfileId,
8398
+ children: /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
8399
+ Combobox,
8400
+ {
8401
+ options: shippingOptions.options,
8402
+ fetchNextPage: shippingOptions.fetchNextPage,
8403
+ isFetchingNextPage: shippingOptions.isFetchingNextPage,
8404
+ searchValue: shippingOptions.searchValue,
8405
+ onSearchValueChange: shippingOptions.onSearchValueChange,
8406
+ placeholder: "Select shipping option",
8407
+ ...field,
8408
+ disabled: !locationId || !shippingProfileId
8409
+ }
8410
+ ) }) })
8411
+ }
8412
+ )
8413
+ ] }) });
8826
8414
  }
8827
- });
8828
- if (!requestSucceeded) {
8829
- setIsSubmitting(false);
8830
- return;
8831
8415
  }
8832
- await confirmOrderEdit(void 0, {
8833
- onError: (e) => {
8834
- toast.error(e.message);
8835
- },
8836
- onSuccess: () => {
8837
- handleSuccess();
8838
- },
8839
- onSettled: () => {
8840
- setIsSubmitting(false);
8416
+ );
8417
+ };
8418
+ const CustomAmountField = ({
8419
+ control,
8420
+ currencyCode
8421
+ }) => {
8422
+ return /* @__PURE__ */ jsx(
8423
+ Form$2.Field,
8424
+ {
8425
+ control,
8426
+ name: "custom_amount",
8427
+ render: ({ field: { onChange, ...field } }) => {
8428
+ return /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
8429
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
8430
+ /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Custom amount" }),
8431
+ /* @__PURE__ */ jsx(Form$2.Hint, { children: "Set a custom amount for the shipping option." })
8432
+ ] }),
8433
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
8434
+ CurrencyInput,
8435
+ {
8436
+ ...field,
8437
+ onValueChange: (value) => onChange(value),
8438
+ symbol: getNativeSymbol(currencyCode),
8439
+ code: currencyCode
8440
+ }
8441
+ ) })
8442
+ ] });
8841
8443
  }
8842
- });
8843
- };
8444
+ }
8445
+ );
8446
+ };
8447
+ const ShippingAddress = () => {
8448
+ const { id } = useParams();
8449
+ const { order, isPending, isError, error } = useOrder(id, {
8450
+ fields: "+shipping_address"
8451
+ });
8844
8452
  if (isError) {
8845
8453
  throw error;
8846
8454
  }
8847
- return /* @__PURE__ */ jsxs(KeyboundForm, { className: "flex flex-1 flex-col", onSubmit, children: [
8848
- /* @__PURE__ */ jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-4", children: [
8849
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3", children: [
8850
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
8851
- /* @__PURE__ */ jsx(Label$1, { size: "small", weight: "plus", htmlFor: "promotion-combobox", children: "Apply promotions" }),
8852
- /* @__PURE__ */ jsx(Hint$1, { id: "promotion-combobox-hint", children: "Manage promotions that should be applied to the order." })
8853
- ] }),
8854
- /* @__PURE__ */ jsx(
8855
- Combobox,
8856
- {
8857
- id: "promotion-combobox",
8858
- "aria-describedby": "promotion-combobox-hint",
8859
- isFetchingNextPage: comboboxData.isFetchingNextPage,
8860
- fetchNextPage: comboboxData.fetchNextPage,
8861
- options: comboboxData.options,
8862
- onSearchValueChange: comboboxData.onSearchValueChange,
8863
- searchValue: comboboxData.searchValue,
8864
- disabled: comboboxData.disabled || isAddingPromotions,
8865
- onChange: add,
8866
- value: comboboxValue
8867
- }
8868
- )
8869
- ] }),
8870
- /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
8871
- /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-2", children: promotions?.map((promotion) => /* @__PURE__ */ jsx(
8872
- PromotionItem,
8873
- {
8874
- promotion,
8875
- orderId: preview.id,
8876
- isLoading: isPending
8877
- },
8878
- promotion.id
8879
- )) })
8880
- ] }) }),
8881
- /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
8882
- /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
8883
- /* @__PURE__ */ jsx(
8884
- Button,
8885
- {
8886
- size: "small",
8887
- type: "submit",
8888
- isLoading: isSubmitting || isAddingPromotions,
8889
- children: "Save"
8890
- }
8891
- )
8892
- ] }) })
8455
+ const isReady = !isPending && !!order;
8456
+ return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
8457
+ /* @__PURE__ */ jsxs(RouteDrawer.Header, { children: [
8458
+ /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Shipping Address" }) }),
8459
+ /* @__PURE__ */ jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Edit the shipping address for the draft order" }) })
8460
+ ] }),
8461
+ isReady && /* @__PURE__ */ jsx(ShippingAddressForm, { order })
8893
8462
  ] });
8894
8463
  };
8895
- const PromotionItem = ({
8896
- promotion,
8897
- orderId,
8898
- isLoading
8899
- }) => {
8900
- const { mutateAsync: removePromotions, isPending } = useDraftOrderRemovePromotions(orderId);
8901
- const onRemove = async () => {
8902
- removePromotions(
8464
+ const ShippingAddressForm = ({ order }) => {
8465
+ const form = useForm({
8466
+ defaultValues: {
8467
+ first_name: order.shipping_address?.first_name ?? "",
8468
+ last_name: order.shipping_address?.last_name ?? "",
8469
+ company: order.shipping_address?.company ?? "",
8470
+ address_1: order.shipping_address?.address_1 ?? "",
8471
+ address_2: order.shipping_address?.address_2 ?? "",
8472
+ city: order.shipping_address?.city ?? "",
8473
+ province: order.shipping_address?.province ?? "",
8474
+ country_code: order.shipping_address?.country_code ?? "",
8475
+ postal_code: order.shipping_address?.postal_code ?? "",
8476
+ phone: order.shipping_address?.phone ?? ""
8477
+ },
8478
+ resolver: zodResolver(schema$1)
8479
+ });
8480
+ const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
8481
+ const { handleSuccess } = useRouteModal();
8482
+ const onSubmit = form.handleSubmit(async (data) => {
8483
+ await mutateAsync(
8903
8484
  {
8904
- promo_codes: [promotion.code]
8485
+ shipping_address: {
8486
+ first_name: data.first_name,
8487
+ last_name: data.last_name,
8488
+ company: data.company,
8489
+ address_1: data.address_1,
8490
+ address_2: data.address_2,
8491
+ city: data.city,
8492
+ province: data.province,
8493
+ country_code: data.country_code,
8494
+ postal_code: data.postal_code,
8495
+ phone: data.phone
8496
+ }
8905
8497
  },
8906
8498
  {
8907
- onError: (e) => {
8908
- toast.error(e.message);
8499
+ onSuccess: () => {
8500
+ handleSuccess();
8501
+ },
8502
+ onError: (error) => {
8503
+ toast.error(error.message);
8909
8504
  }
8910
8505
  }
8911
8506
  );
8912
- };
8913
- const displayValue = getDisplayValue(promotion);
8914
- return /* @__PURE__ */ jsxs(
8915
- "div",
8507
+ });
8508
+ return /* @__PURE__ */ jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxs(
8509
+ KeyboundForm,
8916
8510
  {
8917
- className: clx(
8918
- "bg-ui-bg-component shadow-elevation-card-rest flex items-center justify-between rounded-lg px-3 py-2",
8919
- {
8920
- "animate-pulse": isLoading
8921
- }
8922
- ),
8511
+ className: "flex flex-1 flex-col overflow-hidden",
8512
+ onSubmit,
8923
8513
  children: [
8924
- /* @__PURE__ */ jsxs("div", { children: [
8925
- /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: promotion.code }),
8926
- /* @__PURE__ */ jsxs("div", { className: "text-ui-fg-subtle flex items-center gap-1.5", children: [
8927
- displayValue && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
8928
- /* @__PURE__ */ jsx(Text, { size: "small", leading: "compact", children: displayValue }),
8929
- /* @__PURE__ */ jsx(Text, { size: "small", leading: "compact", children: "·" })
8930
- ] }),
8931
- /* @__PURE__ */ jsx(Text, { size: "small", leading: "compact", className: "capitalize", children: promotion.application_method?.allocation })
8932
- ] })
8933
- ] }),
8934
- /* @__PURE__ */ jsx(
8935
- IconButton,
8936
- {
8937
- size: "small",
8938
- type: "button",
8939
- variant: "transparent",
8940
- onClick: onRemove,
8941
- isLoading: isPending || isLoading,
8942
- children: /* @__PURE__ */ jsx(XMark, {})
8943
- }
8944
- )
8514
+ /* @__PURE__ */ jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-y-4", children: [
8515
+ /* @__PURE__ */ jsx(
8516
+ Form$2.Field,
8517
+ {
8518
+ control: form.control,
8519
+ name: "country_code",
8520
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
8521
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Country" }),
8522
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(CountrySelect, { ...field }) }),
8523
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
8524
+ ] })
8525
+ }
8526
+ ),
8527
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
8528
+ /* @__PURE__ */ jsx(
8529
+ Form$2.Field,
8530
+ {
8531
+ control: form.control,
8532
+ name: "first_name",
8533
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
8534
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "First name" }),
8535
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
8536
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
8537
+ ] })
8538
+ }
8539
+ ),
8540
+ /* @__PURE__ */ jsx(
8541
+ Form$2.Field,
8542
+ {
8543
+ control: form.control,
8544
+ name: "last_name",
8545
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
8546
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Last name" }),
8547
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
8548
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
8549
+ ] })
8550
+ }
8551
+ )
8552
+ ] }),
8553
+ /* @__PURE__ */ jsx(
8554
+ Form$2.Field,
8555
+ {
8556
+ control: form.control,
8557
+ name: "company",
8558
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
8559
+ /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Company" }),
8560
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
8561
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
8562
+ ] })
8563
+ }
8564
+ ),
8565
+ /* @__PURE__ */ jsx(
8566
+ Form$2.Field,
8567
+ {
8568
+ control: form.control,
8569
+ name: "address_1",
8570
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
8571
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Address" }),
8572
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
8573
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
8574
+ ] })
8575
+ }
8576
+ ),
8577
+ /* @__PURE__ */ jsx(
8578
+ Form$2.Field,
8579
+ {
8580
+ control: form.control,
8581
+ name: "address_2",
8582
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
8583
+ /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Apartment, suite, etc." }),
8584
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
8585
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
8586
+ ] })
8587
+ }
8588
+ ),
8589
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
8590
+ /* @__PURE__ */ jsx(
8591
+ Form$2.Field,
8592
+ {
8593
+ control: form.control,
8594
+ name: "postal_code",
8595
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
8596
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Postal code" }),
8597
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
8598
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
8599
+ ] })
8600
+ }
8601
+ ),
8602
+ /* @__PURE__ */ jsx(
8603
+ Form$2.Field,
8604
+ {
8605
+ control: form.control,
8606
+ name: "city",
8607
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
8608
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "City" }),
8609
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
8610
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
8611
+ ] })
8612
+ }
8613
+ )
8614
+ ] }),
8615
+ /* @__PURE__ */ jsx(
8616
+ Form$2.Field,
8617
+ {
8618
+ control: form.control,
8619
+ name: "province",
8620
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
8621
+ /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Province / State" }),
8622
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
8623
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
8624
+ ] })
8625
+ }
8626
+ ),
8627
+ /* @__PURE__ */ jsx(
8628
+ Form$2.Field,
8629
+ {
8630
+ control: form.control,
8631
+ name: "phone",
8632
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
8633
+ /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Phone" }),
8634
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
8635
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
8636
+ ] })
8637
+ }
8638
+ )
8639
+ ] }) }),
8640
+ /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
8641
+ /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
8642
+ /* @__PURE__ */ jsx(Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
8643
+ ] }) })
8945
8644
  ]
8946
- },
8947
- promotion.id
8948
- );
8949
- };
8950
- function getDisplayValue(promotion) {
8951
- const value = promotion.application_method?.value;
8952
- if (!value) {
8953
- return null;
8954
- }
8955
- if (promotion.application_method?.type === "fixed") {
8956
- const currency = promotion.application_method?.currency_code;
8957
- if (!currency) {
8958
- return null;
8959
8645
  }
8960
- return getLocaleAmount(value, currency);
8961
- } else if (promotion.application_method?.type === "percentage") {
8962
- return formatPercentage(value);
8963
- }
8964
- return null;
8965
- }
8966
- const formatter = new Intl.NumberFormat([], {
8967
- style: "percent",
8968
- minimumFractionDigits: 2
8969
- });
8970
- const formatPercentage = (value, isPercentageValue = false) => {
8971
- let val = value || 0;
8972
- if (!isPercentageValue) {
8973
- val = val / 100;
8974
- }
8975
- return formatter.format(val);
8646
+ ) });
8976
8647
  };
8977
- function getPromotionIds(items, shippingMethods) {
8978
- const promotionIds = /* @__PURE__ */ new Set();
8979
- for (const item of items) {
8980
- if (item.adjustments) {
8981
- for (const adjustment of item.adjustments) {
8982
- if (adjustment.promotion_id) {
8983
- promotionIds.add(adjustment.promotion_id);
8984
- }
8985
- }
8986
- }
8987
- }
8988
- for (const shippingMethod of shippingMethods) {
8989
- if (shippingMethod.adjustments) {
8990
- for (const adjustment of shippingMethod.adjustments) {
8991
- if (adjustment.promotion_id) {
8992
- promotionIds.add(adjustment.promotion_id);
8993
- }
8994
- }
8995
- }
8996
- }
8997
- return Array.from(promotionIds);
8998
- }
8648
+ const schema$1 = addressSchema;
8999
8649
  const TransferOwnership = () => {
9000
8650
  const { id } = useParams();
9001
8651
  const { draft_order, isPending, isError, error } = useDraftOrder(id, {
@@ -9466,11 +9116,361 @@ const Illustration = () => {
9466
9116
  ] })
9467
9117
  ]
9468
9118
  }
9469
- );
9119
+ );
9120
+ };
9121
+ const schema = z.object({
9122
+ customer_id: z.string().min(1)
9123
+ });
9124
+ const InlineTip = forwardRef(
9125
+ ({ variant = "tip", label, className, children, ...props }, ref) => {
9126
+ const labelValue = label || (variant === "warning" ? "Warning" : "Tip");
9127
+ return /* @__PURE__ */ jsxs(
9128
+ "div",
9129
+ {
9130
+ ref,
9131
+ className: clx(
9132
+ "bg-ui-bg-component txt-small text-ui-fg-subtle grid grid-cols-[4px_1fr] items-start gap-3 rounded-lg border p-3",
9133
+ className
9134
+ ),
9135
+ ...props,
9136
+ children: [
9137
+ /* @__PURE__ */ jsx(
9138
+ "div",
9139
+ {
9140
+ role: "presentation",
9141
+ className: clx("w-4px bg-ui-tag-neutral-icon h-full rounded-full", {
9142
+ "bg-ui-tag-orange-icon": variant === "warning"
9143
+ })
9144
+ }
9145
+ ),
9146
+ /* @__PURE__ */ jsxs("div", { className: "text-pretty", children: [
9147
+ /* @__PURE__ */ jsxs("strong", { className: "txt-small-plus text-ui-fg-base", children: [
9148
+ labelValue,
9149
+ ":"
9150
+ ] }),
9151
+ " ",
9152
+ children
9153
+ ] })
9154
+ ]
9155
+ }
9156
+ );
9157
+ }
9158
+ );
9159
+ InlineTip.displayName = "InlineTip";
9160
+ const MetadataFieldSchema = z.object({
9161
+ key: z.string(),
9162
+ disabled: z.boolean().optional(),
9163
+ value: z.any()
9164
+ });
9165
+ const MetadataSchema = z.object({
9166
+ metadata: z.array(MetadataFieldSchema)
9167
+ });
9168
+ const Metadata = () => {
9169
+ const { id } = useParams();
9170
+ const { order, isPending, isError, error } = useOrder(id, {
9171
+ fields: "metadata"
9172
+ });
9173
+ if (isError) {
9174
+ throw error;
9175
+ }
9176
+ const isReady = !isPending && !!order;
9177
+ return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
9178
+ /* @__PURE__ */ jsxs(RouteDrawer.Header, { children: [
9179
+ /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Metadata" }) }),
9180
+ /* @__PURE__ */ jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Add metadata to the draft order." }) })
9181
+ ] }),
9182
+ !isReady ? /* @__PURE__ */ jsx(PlaceholderInner, {}) : /* @__PURE__ */ jsx(MetadataForm, { orderId: id, metadata: order?.metadata })
9183
+ ] });
9184
+ };
9185
+ const METADATA_KEY_LABEL_ID = "metadata-form-key-label";
9186
+ const METADATA_VALUE_LABEL_ID = "metadata-form-value-label";
9187
+ const MetadataForm = ({ orderId, metadata }) => {
9188
+ const { handleSuccess } = useRouteModal();
9189
+ const hasUneditableRows = getHasUneditableRows(metadata);
9190
+ const { mutateAsync, isPending } = useUpdateDraftOrder(orderId);
9191
+ const form = useForm({
9192
+ defaultValues: {
9193
+ metadata: getDefaultValues(metadata)
9194
+ },
9195
+ resolver: zodResolver(MetadataSchema)
9196
+ });
9197
+ const handleSubmit = form.handleSubmit(async (data) => {
9198
+ const parsedData = parseValues(data);
9199
+ await mutateAsync(
9200
+ {
9201
+ metadata: parsedData
9202
+ },
9203
+ {
9204
+ onSuccess: () => {
9205
+ toast.success("Metadata updated");
9206
+ handleSuccess();
9207
+ },
9208
+ onError: (error) => {
9209
+ toast.error(error.message);
9210
+ }
9211
+ }
9212
+ );
9213
+ });
9214
+ const { fields, insert, remove } = useFieldArray({
9215
+ control: form.control,
9216
+ name: "metadata"
9217
+ });
9218
+ function deleteRow(index) {
9219
+ remove(index);
9220
+ if (fields.length === 1) {
9221
+ insert(0, {
9222
+ key: "",
9223
+ value: "",
9224
+ disabled: false
9225
+ });
9226
+ }
9227
+ }
9228
+ function insertRow(index, position) {
9229
+ insert(index + (position === "above" ? 0 : 1), {
9230
+ key: "",
9231
+ value: "",
9232
+ disabled: false
9233
+ });
9234
+ }
9235
+ return /* @__PURE__ */ jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxs(
9236
+ KeyboundForm,
9237
+ {
9238
+ onSubmit: handleSubmit,
9239
+ className: "flex flex-1 flex-col overflow-hidden",
9240
+ children: [
9241
+ /* @__PURE__ */ jsxs(RouteDrawer.Body, { className: "flex flex-1 flex-col gap-y-8 overflow-y-auto", children: [
9242
+ /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest grid grid-cols-1 divide-y rounded-lg", children: [
9243
+ /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-subtle grid grid-cols-2 divide-x rounded-t-lg", children: [
9244
+ /* @__PURE__ */ jsx("div", { className: "txt-compact-small-plus text-ui-fg-subtle px-2 py-1.5", children: /* @__PURE__ */ jsx("label", { id: METADATA_KEY_LABEL_ID, children: "Key" }) }),
9245
+ /* @__PURE__ */ jsx("div", { className: "txt-compact-small-plus text-ui-fg-subtle px-2 py-1.5", children: /* @__PURE__ */ jsx("label", { id: METADATA_VALUE_LABEL_ID, children: "Value" }) })
9246
+ ] }),
9247
+ fields.map((field, index) => {
9248
+ const isDisabled = field.disabled || false;
9249
+ let placeholder = "-";
9250
+ if (typeof field.value === "object") {
9251
+ placeholder = "{ ... }";
9252
+ }
9253
+ if (Array.isArray(field.value)) {
9254
+ placeholder = "[ ... ]";
9255
+ }
9256
+ return /* @__PURE__ */ jsx(
9257
+ ConditionalTooltip,
9258
+ {
9259
+ showTooltip: isDisabled,
9260
+ content: "This row is disabled because it contains non-primitive data.",
9261
+ children: /* @__PURE__ */ jsxs("div", { className: "group/table relative", children: [
9262
+ /* @__PURE__ */ jsxs(
9263
+ "div",
9264
+ {
9265
+ className: clx("grid grid-cols-2 divide-x", {
9266
+ "overflow-hidden rounded-b-lg": index === fields.length - 1
9267
+ }),
9268
+ children: [
9269
+ /* @__PURE__ */ jsx(
9270
+ Form$2.Field,
9271
+ {
9272
+ control: form.control,
9273
+ name: `metadata.${index}.key`,
9274
+ render: ({ field: field2 }) => {
9275
+ return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
9276
+ GridInput,
9277
+ {
9278
+ "aria-labelledby": METADATA_KEY_LABEL_ID,
9279
+ ...field2,
9280
+ disabled: isDisabled,
9281
+ placeholder: "Key"
9282
+ }
9283
+ ) }) });
9284
+ }
9285
+ }
9286
+ ),
9287
+ /* @__PURE__ */ jsx(
9288
+ Form$2.Field,
9289
+ {
9290
+ control: form.control,
9291
+ name: `metadata.${index}.value`,
9292
+ render: ({ field: { value, ...field2 } }) => {
9293
+ return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
9294
+ GridInput,
9295
+ {
9296
+ "aria-labelledby": METADATA_VALUE_LABEL_ID,
9297
+ ...field2,
9298
+ value: isDisabled ? placeholder : value,
9299
+ disabled: isDisabled,
9300
+ placeholder: "Value"
9301
+ }
9302
+ ) }) });
9303
+ }
9304
+ }
9305
+ )
9306
+ ]
9307
+ }
9308
+ ),
9309
+ /* @__PURE__ */ jsxs(DropdownMenu, { children: [
9310
+ /* @__PURE__ */ jsx(
9311
+ DropdownMenu.Trigger,
9312
+ {
9313
+ className: clx(
9314
+ "invisible absolute inset-y-0 -right-2.5 my-auto group-hover/table:visible data-[state='open']:visible",
9315
+ {
9316
+ hidden: isDisabled
9317
+ }
9318
+ ),
9319
+ disabled: isDisabled,
9320
+ asChild: true,
9321
+ children: /* @__PURE__ */ jsx(IconButton, { size: "2xsmall", children: /* @__PURE__ */ jsx(EllipsisVertical, {}) })
9322
+ }
9323
+ ),
9324
+ /* @__PURE__ */ jsxs(DropdownMenu.Content, { children: [
9325
+ /* @__PURE__ */ jsxs(
9326
+ DropdownMenu.Item,
9327
+ {
9328
+ className: "gap-x-2",
9329
+ onClick: () => insertRow(index, "above"),
9330
+ children: [
9331
+ /* @__PURE__ */ jsx(ArrowUpMini, { className: "text-ui-fg-subtle" }),
9332
+ "Insert row above"
9333
+ ]
9334
+ }
9335
+ ),
9336
+ /* @__PURE__ */ jsxs(
9337
+ DropdownMenu.Item,
9338
+ {
9339
+ className: "gap-x-2",
9340
+ onClick: () => insertRow(index, "below"),
9341
+ children: [
9342
+ /* @__PURE__ */ jsx(ArrowDownMini, { className: "text-ui-fg-subtle" }),
9343
+ "Insert row below"
9344
+ ]
9345
+ }
9346
+ ),
9347
+ /* @__PURE__ */ jsx(DropdownMenu.Separator, {}),
9348
+ /* @__PURE__ */ jsxs(
9349
+ DropdownMenu.Item,
9350
+ {
9351
+ className: "gap-x-2",
9352
+ onClick: () => deleteRow(index),
9353
+ children: [
9354
+ /* @__PURE__ */ jsx(Trash, { className: "text-ui-fg-subtle" }),
9355
+ "Delete row"
9356
+ ]
9357
+ }
9358
+ )
9359
+ ] })
9360
+ ] })
9361
+ ] })
9362
+ },
9363
+ field.id
9364
+ );
9365
+ })
9366
+ ] }),
9367
+ hasUneditableRows && /* @__PURE__ */ jsx(InlineTip, { variant: "warning", label: "Some rows are disabled", children: "This object contains non-primitive metadata, such as arrays or objects, that can't be edited here. To edit the disabled rows, use the API directly." })
9368
+ ] }),
9369
+ /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
9370
+ /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
9371
+ /* @__PURE__ */ jsx(Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
9372
+ ] }) })
9373
+ ]
9374
+ }
9375
+ ) });
9470
9376
  };
9471
- const schema = z.object({
9472
- customer_id: z.string().min(1)
9377
+ const GridInput = forwardRef(({ className, ...props }, ref) => {
9378
+ return /* @__PURE__ */ jsx(
9379
+ "input",
9380
+ {
9381
+ ref,
9382
+ ...props,
9383
+ autoComplete: "off",
9384
+ className: clx(
9385
+ "txt-compact-small text-ui-fg-base placeholder:text-ui-fg-muted disabled:text-ui-fg-disabled disabled:bg-ui-bg-base bg-transparent px-2 py-1.5 outline-none",
9386
+ className
9387
+ )
9388
+ }
9389
+ );
9473
9390
  });
9391
+ GridInput.displayName = "MetadataForm.GridInput";
9392
+ const PlaceholderInner = () => {
9393
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-1 flex-col overflow-hidden", children: [
9394
+ /* @__PURE__ */ jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsx(Skeleton, { className: "h-[148ox] w-full rounded-lg" }) }),
9395
+ /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
9396
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-7 w-12 rounded-md" }),
9397
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-7 w-12 rounded-md" })
9398
+ ] }) })
9399
+ ] });
9400
+ };
9401
+ const EDITABLE_TYPES = ["string", "number", "boolean"];
9402
+ function getDefaultValues(metadata) {
9403
+ if (!metadata || !Object.keys(metadata).length) {
9404
+ return [
9405
+ {
9406
+ key: "",
9407
+ value: "",
9408
+ disabled: false
9409
+ }
9410
+ ];
9411
+ }
9412
+ return Object.entries(metadata).map(([key, value]) => {
9413
+ if (!EDITABLE_TYPES.includes(typeof value)) {
9414
+ return {
9415
+ key,
9416
+ value,
9417
+ disabled: true
9418
+ };
9419
+ }
9420
+ let stringValue = value;
9421
+ if (typeof value !== "string") {
9422
+ stringValue = JSON.stringify(value);
9423
+ }
9424
+ return {
9425
+ key,
9426
+ value: stringValue,
9427
+ original_key: key
9428
+ };
9429
+ });
9430
+ }
9431
+ function parseValues(values) {
9432
+ const metadata = values.metadata;
9433
+ const isEmpty = !metadata.length || metadata.length === 1 && !metadata[0].key && !metadata[0].value;
9434
+ if (isEmpty) {
9435
+ return null;
9436
+ }
9437
+ const update = {};
9438
+ metadata.forEach((field) => {
9439
+ let key = field.key;
9440
+ let value = field.value;
9441
+ const disabled = field.disabled;
9442
+ if (!key || !value) {
9443
+ return;
9444
+ }
9445
+ if (disabled) {
9446
+ update[key] = value;
9447
+ return;
9448
+ }
9449
+ key = key.trim();
9450
+ value = value.trim();
9451
+ if (value === "true") {
9452
+ update[key] = true;
9453
+ } else if (value === "false") {
9454
+ update[key] = false;
9455
+ } else {
9456
+ const parsedNumber = parseFloat(value);
9457
+ if (!isNaN(parsedNumber)) {
9458
+ update[key] = parsedNumber;
9459
+ } else {
9460
+ update[key] = value;
9461
+ }
9462
+ }
9463
+ });
9464
+ return update;
9465
+ }
9466
+ function getHasUneditableRows(metadata) {
9467
+ if (!metadata) {
9468
+ return false;
9469
+ }
9470
+ return Object.values(metadata).some(
9471
+ (value) => !EDITABLE_TYPES.includes(typeof value)
9472
+ );
9473
+ }
9474
9474
  const widgetModule = { widgets: [] };
9475
9475
  const routeModule = {
9476
9476
  routes: [
@@ -9491,6 +9491,10 @@ const routeModule = {
9491
9491
  handle,
9492
9492
  loader,
9493
9493
  children: [
9494
+ {
9495
+ Component: BillingAddress,
9496
+ path: "/draft-orders/:id/billing-address"
9497
+ },
9494
9498
  {
9495
9499
  Component: CustomItems,
9496
9500
  path: "/draft-orders/:id/custom-items"
@@ -9504,32 +9508,28 @@ const routeModule = {
9504
9508
  path: "/draft-orders/:id/items"
9505
9509
  },
9506
9510
  {
9507
- Component: BillingAddress,
9508
- path: "/draft-orders/:id/billing-address"
9509
- },
9510
- {
9511
- Component: Metadata,
9512
- path: "/draft-orders/:id/metadata"
9511
+ Component: Promotions,
9512
+ path: "/draft-orders/:id/promotions"
9513
9513
  },
9514
9514
  {
9515
9515
  Component: SalesChannel,
9516
9516
  path: "/draft-orders/:id/sales-channel"
9517
9517
  },
9518
- {
9519
- Component: ShippingAddress,
9520
- path: "/draft-orders/:id/shipping-address"
9521
- },
9522
9518
  {
9523
9519
  Component: Shipping,
9524
9520
  path: "/draft-orders/:id/shipping"
9525
9521
  },
9526
9522
  {
9527
- Component: Promotions,
9528
- path: "/draft-orders/:id/promotions"
9523
+ Component: ShippingAddress,
9524
+ path: "/draft-orders/:id/shipping-address"
9529
9525
  },
9530
9526
  {
9531
9527
  Component: TransferOwnership,
9532
9528
  path: "/draft-orders/:id/transfer-ownership"
9529
+ },
9530
+ {
9531
+ Component: Metadata,
9532
+ path: "/draft-orders/:id/metadata"
9533
9533
  }
9534
9534
  ]
9535
9535
  }