@medusajs/draft-order 2.11.0-preview-20251020141229 → 2.11.0-preview-20251020150157

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.
@@ -9571,95 +9571,6 @@ const ID = () => {
9571
9571
  /* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Outlet, {})
9572
9572
  ] });
9573
9573
  };
9574
- const Email = () => {
9575
- const { id } = reactRouterDom.useParams();
9576
- const { order, isPending, isError, error } = useOrder(id, {
9577
- fields: "+email"
9578
- });
9579
- if (isError) {
9580
- throw error;
9581
- }
9582
- const isReady = !isPending && !!order;
9583
- return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
9584
- /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Header, { children: [
9585
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Email" }) }),
9586
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Edit the email for the draft order" }) })
9587
- ] }),
9588
- isReady && /* @__PURE__ */ jsxRuntime.jsx(EmailForm, { order })
9589
- ] });
9590
- };
9591
- const EmailForm = ({ order }) => {
9592
- const form = reactHookForm.useForm({
9593
- defaultValues: {
9594
- email: order.email ?? ""
9595
- },
9596
- resolver: zod.zodResolver(schema$5)
9597
- });
9598
- const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
9599
- const { handleSuccess } = useRouteModal();
9600
- const onSubmit = form.handleSubmit(async (data) => {
9601
- await mutateAsync(
9602
- { email: data.email },
9603
- {
9604
- onSuccess: () => {
9605
- handleSuccess();
9606
- },
9607
- onError: (error) => {
9608
- ui.toast.error(error.message);
9609
- }
9610
- }
9611
- );
9612
- });
9613
- return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(
9614
- KeyboundForm,
9615
- {
9616
- className: "flex flex-1 flex-col overflow-hidden",
9617
- onSubmit,
9618
- children: [
9619
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsx(
9620
- Form$2.Field,
9621
- {
9622
- control: form.control,
9623
- name: "email",
9624
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
9625
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Email" }),
9626
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
9627
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
9628
- ] })
9629
- }
9630
- ) }),
9631
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
9632
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
9633
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
9634
- ] }) })
9635
- ]
9636
- }
9637
- ) });
9638
- };
9639
- const schema$5 = objectType({
9640
- email: stringType().email()
9641
- });
9642
- const CustomItems = () => {
9643
- return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
9644
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Custom Items" }) }) }),
9645
- /* @__PURE__ */ jsxRuntime.jsx(CustomItemsForm, {})
9646
- ] });
9647
- };
9648
- const CustomItemsForm = () => {
9649
- const form = reactHookForm.useForm({
9650
- resolver: zod.zodResolver(schema$4)
9651
- });
9652
- return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(KeyboundForm, { className: "flex flex-1 flex-col", children: [
9653
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, {}),
9654
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
9655
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
9656
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", children: "Save" })
9657
- ] }) })
9658
- ] }) });
9659
- };
9660
- const schema$4 = objectType({
9661
- email: stringType().email()
9662
- });
9663
9574
  const BillingAddress = () => {
9664
9575
  const { id } = reactRouterDom.useParams();
9665
9576
  const { order, isPending, isError, error } = useOrder(id, {
@@ -9692,7 +9603,7 @@ const BillingAddressForm = ({ order }) => {
9692
9603
  postal_code: ((_i = order.billing_address) == null ? void 0 : _i.postal_code) ?? "",
9693
9604
  phone: ((_j = order.billing_address) == null ? void 0 : _j.phone) ?? ""
9694
9605
  },
9695
- resolver: zod.zodResolver(schema$3)
9606
+ resolver: zod.zodResolver(schema$5)
9696
9607
  });
9697
9608
  const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
9698
9609
  const { handleSuccess } = useRouteModal();
@@ -9849,55 +9760,32 @@ const BillingAddressForm = ({ order }) => {
9849
9760
  }
9850
9761
  ) });
9851
9762
  };
9852
- const schema$3 = addressSchema;
9853
- const InlineTip = React.forwardRef(
9854
- ({ variant = "tip", label, className, children, ...props }, ref) => {
9855
- const labelValue = label || (variant === "warning" ? "Warning" : "Tip");
9856
- return /* @__PURE__ */ jsxRuntime.jsxs(
9857
- "div",
9858
- {
9859
- ref,
9860
- className: ui.clx(
9861
- "bg-ui-bg-component txt-small text-ui-fg-subtle grid grid-cols-[4px_1fr] items-start gap-3 rounded-lg border p-3",
9862
- className
9863
- ),
9864
- ...props,
9865
- children: [
9866
- /* @__PURE__ */ jsxRuntime.jsx(
9867
- "div",
9868
- {
9869
- role: "presentation",
9870
- className: ui.clx("w-4px bg-ui-tag-neutral-icon h-full rounded-full", {
9871
- "bg-ui-tag-orange-icon": variant === "warning"
9872
- })
9873
- }
9874
- ),
9875
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-pretty", children: [
9876
- /* @__PURE__ */ jsxRuntime.jsxs("strong", { className: "txt-small-plus text-ui-fg-base", children: [
9877
- labelValue,
9878
- ":"
9879
- ] }),
9880
- " ",
9881
- children
9882
- ] })
9883
- ]
9884
- }
9885
- );
9886
- }
9887
- );
9888
- InlineTip.displayName = "InlineTip";
9889
- const MetadataFieldSchema = objectType({
9890
- key: stringType(),
9891
- disabled: booleanType().optional(),
9892
- value: anyType()
9893
- });
9894
- const MetadataSchema = objectType({
9895
- metadata: arrayType(MetadataFieldSchema)
9763
+ const schema$5 = addressSchema;
9764
+ const CustomItems = () => {
9765
+ return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
9766
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Custom Items" }) }) }),
9767
+ /* @__PURE__ */ jsxRuntime.jsx(CustomItemsForm, {})
9768
+ ] });
9769
+ };
9770
+ const CustomItemsForm = () => {
9771
+ const form = reactHookForm.useForm({
9772
+ resolver: zod.zodResolver(schema$4)
9773
+ });
9774
+ return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(KeyboundForm, { className: "flex flex-1 flex-col", children: [
9775
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, {}),
9776
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
9777
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
9778
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", children: "Save" })
9779
+ ] }) })
9780
+ ] }) });
9781
+ };
9782
+ const schema$4 = objectType({
9783
+ email: stringType().email()
9896
9784
  });
9897
- const Metadata = () => {
9785
+ const Email = () => {
9898
9786
  const { id } = reactRouterDom.useParams();
9899
9787
  const { order, isPending, isError, error } = useOrder(id, {
9900
- fields: "metadata"
9788
+ fields: "+email"
9901
9789
  });
9902
9790
  if (isError) {
9903
9791
  throw error;
@@ -9905,33 +9793,26 @@ const Metadata = () => {
9905
9793
  const isReady = !isPending && !!order;
9906
9794
  return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
9907
9795
  /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Header, { children: [
9908
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Metadata" }) }),
9909
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Add metadata to the draft order." }) })
9796
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Email" }) }),
9797
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Edit the email for the draft order" }) })
9910
9798
  ] }),
9911
- !isReady ? /* @__PURE__ */ jsxRuntime.jsx(PlaceholderInner, {}) : /* @__PURE__ */ jsxRuntime.jsx(MetadataForm, { orderId: id, metadata: order == null ? void 0 : order.metadata })
9799
+ isReady && /* @__PURE__ */ jsxRuntime.jsx(EmailForm, { order })
9912
9800
  ] });
9913
9801
  };
9914
- const METADATA_KEY_LABEL_ID = "metadata-form-key-label";
9915
- const METADATA_VALUE_LABEL_ID = "metadata-form-value-label";
9916
- const MetadataForm = ({ orderId, metadata }) => {
9917
- const { handleSuccess } = useRouteModal();
9918
- const hasUneditableRows = getHasUneditableRows(metadata);
9919
- const { mutateAsync, isPending } = useUpdateDraftOrder(orderId);
9802
+ const EmailForm = ({ order }) => {
9920
9803
  const form = reactHookForm.useForm({
9921
9804
  defaultValues: {
9922
- metadata: getDefaultValues(metadata)
9805
+ email: order.email ?? ""
9923
9806
  },
9924
- resolver: zod.zodResolver(MetadataSchema)
9807
+ resolver: zod.zodResolver(schema$3)
9925
9808
  });
9926
- const handleSubmit = form.handleSubmit(async (data) => {
9927
- const parsedData = parseValues(data);
9809
+ const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
9810
+ const { handleSuccess } = useRouteModal();
9811
+ const onSubmit = form.handleSubmit(async (data) => {
9928
9812
  await mutateAsync(
9929
- {
9930
- metadata: parsedData
9931
- },
9813
+ { email: data.email },
9932
9814
  {
9933
9815
  onSuccess: () => {
9934
- ui.toast.success("Metadata updated");
9935
9816
  handleSuccess();
9936
9817
  },
9937
9818
  onError: (error) => {
@@ -9940,266 +9821,35 @@ const MetadataForm = ({ orderId, metadata }) => {
9940
9821
  }
9941
9822
  );
9942
9823
  });
9943
- const { fields, insert, remove } = reactHookForm.useFieldArray({
9944
- control: form.control,
9945
- name: "metadata"
9946
- });
9947
- function deleteRow(index) {
9948
- remove(index);
9949
- if (fields.length === 1) {
9950
- insert(0, {
9951
- key: "",
9952
- value: "",
9953
- disabled: false
9954
- });
9955
- }
9956
- }
9957
- function insertRow(index, position) {
9958
- insert(index + (position === "above" ? 0 : 1), {
9959
- key: "",
9960
- value: "",
9961
- disabled: false
9962
- });
9963
- }
9964
9824
  return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(
9965
9825
  KeyboundForm,
9966
9826
  {
9967
- onSubmit: handleSubmit,
9968
9827
  className: "flex flex-1 flex-col overflow-hidden",
9828
+ onSubmit,
9969
9829
  children: [
9970
- /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Body, { className: "flex flex-1 flex-col gap-y-8 overflow-y-auto", children: [
9971
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest grid grid-cols-1 divide-y rounded-lg", children: [
9972
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-subtle grid grid-cols-2 divide-x rounded-t-lg", children: [
9973
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "txt-compact-small-plus text-ui-fg-subtle px-2 py-1.5", children: /* @__PURE__ */ jsxRuntime.jsx("label", { id: METADATA_KEY_LABEL_ID, children: "Key" }) }),
9974
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "txt-compact-small-plus text-ui-fg-subtle px-2 py-1.5", children: /* @__PURE__ */ jsxRuntime.jsx("label", { id: METADATA_VALUE_LABEL_ID, children: "Value" }) })
9975
- ] }),
9976
- fields.map((field, index) => {
9977
- const isDisabled = field.disabled || false;
9978
- let placeholder = "-";
9979
- if (typeof field.value === "object") {
9980
- placeholder = "{ ... }";
9981
- }
9982
- if (Array.isArray(field.value)) {
9983
- placeholder = "[ ... ]";
9984
- }
9985
- return /* @__PURE__ */ jsxRuntime.jsx(
9986
- ConditionalTooltip,
9987
- {
9988
- showTooltip: isDisabled,
9989
- content: "This row is disabled because it contains non-primitive data.",
9990
- children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "group/table relative", children: [
9991
- /* @__PURE__ */ jsxRuntime.jsxs(
9992
- "div",
9993
- {
9994
- className: ui.clx("grid grid-cols-2 divide-x", {
9995
- "overflow-hidden rounded-b-lg": index === fields.length - 1
9996
- }),
9997
- children: [
9998
- /* @__PURE__ */ jsxRuntime.jsx(
9999
- Form$2.Field,
10000
- {
10001
- control: form.control,
10002
- name: `metadata.${index}.key`,
10003
- render: ({ field: field2 }) => {
10004
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
10005
- GridInput,
10006
- {
10007
- "aria-labelledby": METADATA_KEY_LABEL_ID,
10008
- ...field2,
10009
- disabled: isDisabled,
10010
- placeholder: "Key"
10011
- }
10012
- ) }) });
10013
- }
10014
- }
10015
- ),
10016
- /* @__PURE__ */ jsxRuntime.jsx(
10017
- Form$2.Field,
10018
- {
10019
- control: form.control,
10020
- name: `metadata.${index}.value`,
10021
- render: ({ field: { value, ...field2 } }) => {
10022
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
10023
- GridInput,
10024
- {
10025
- "aria-labelledby": METADATA_VALUE_LABEL_ID,
10026
- ...field2,
10027
- value: isDisabled ? placeholder : value,
10028
- disabled: isDisabled,
10029
- placeholder: "Value"
10030
- }
10031
- ) }) });
10032
- }
10033
- }
10034
- )
10035
- ]
10036
- }
10037
- ),
10038
- /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu, { children: [
10039
- /* @__PURE__ */ jsxRuntime.jsx(
10040
- ui.DropdownMenu.Trigger,
10041
- {
10042
- className: ui.clx(
10043
- "invisible absolute inset-y-0 -right-2.5 my-auto group-hover/table:visible data-[state='open']:visible",
10044
- {
10045
- hidden: isDisabled
10046
- }
10047
- ),
10048
- disabled: isDisabled,
10049
- asChild: true,
10050
- children: /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { size: "2xsmall", children: /* @__PURE__ */ jsxRuntime.jsx(icons.EllipsisVertical, {}) })
10051
- }
10052
- ),
10053
- /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu.Content, { children: [
10054
- /* @__PURE__ */ jsxRuntime.jsxs(
10055
- ui.DropdownMenu.Item,
10056
- {
10057
- className: "gap-x-2",
10058
- onClick: () => insertRow(index, "above"),
10059
- children: [
10060
- /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowUpMini, { className: "text-ui-fg-subtle" }),
10061
- "Insert row above"
10062
- ]
10063
- }
10064
- ),
10065
- /* @__PURE__ */ jsxRuntime.jsxs(
10066
- ui.DropdownMenu.Item,
10067
- {
10068
- className: "gap-x-2",
10069
- onClick: () => insertRow(index, "below"),
10070
- children: [
10071
- /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowDownMini, { className: "text-ui-fg-subtle" }),
10072
- "Insert row below"
10073
- ]
10074
- }
10075
- ),
10076
- /* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenu.Separator, {}),
10077
- /* @__PURE__ */ jsxRuntime.jsxs(
10078
- ui.DropdownMenu.Item,
10079
- {
10080
- className: "gap-x-2",
10081
- onClick: () => deleteRow(index),
10082
- children: [
10083
- /* @__PURE__ */ jsxRuntime.jsx(icons.Trash, { className: "text-ui-fg-subtle" }),
10084
- "Delete row"
10085
- ]
10086
- }
10087
- )
10088
- ] })
10089
- ] })
10090
- ] })
10091
- },
10092
- field.id
10093
- );
10094
- })
10095
- ] }),
10096
- hasUneditableRows && /* @__PURE__ */ jsxRuntime.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." })
10097
- ] }),
10098
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
10099
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
9830
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsx(
9831
+ Form$2.Field,
9832
+ {
9833
+ control: form.control,
9834
+ name: "email",
9835
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
9836
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Email" }),
9837
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
9838
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
9839
+ ] })
9840
+ }
9841
+ ) }),
9842
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
9843
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
10100
9844
  /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
10101
9845
  ] }) })
10102
9846
  ]
10103
9847
  }
10104
9848
  ) });
10105
9849
  };
10106
- const GridInput = React.forwardRef(({ className, ...props }, ref) => {
10107
- return /* @__PURE__ */ jsxRuntime.jsx(
10108
- "input",
10109
- {
10110
- ref,
10111
- ...props,
10112
- autoComplete: "off",
10113
- className: ui.clx(
10114
- "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",
10115
- className
10116
- )
10117
- }
10118
- );
9850
+ const schema$3 = objectType({
9851
+ email: stringType().email()
10119
9852
  });
10120
- GridInput.displayName = "MetadataForm.GridInput";
10121
- const PlaceholderInner = () => {
10122
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-1 flex-col overflow-hidden", children: [
10123
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-[148ox] w-full rounded-lg" }) }),
10124
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
10125
- /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-7 w-12 rounded-md" }),
10126
- /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-7 w-12 rounded-md" })
10127
- ] }) })
10128
- ] });
10129
- };
10130
- const EDITABLE_TYPES = ["string", "number", "boolean"];
10131
- function getDefaultValues(metadata) {
10132
- if (!metadata || !Object.keys(metadata).length) {
10133
- return [
10134
- {
10135
- key: "",
10136
- value: "",
10137
- disabled: false
10138
- }
10139
- ];
10140
- }
10141
- return Object.entries(metadata).map(([key, value]) => {
10142
- if (!EDITABLE_TYPES.includes(typeof value)) {
10143
- return {
10144
- key,
10145
- value,
10146
- disabled: true
10147
- };
10148
- }
10149
- let stringValue = value;
10150
- if (typeof value !== "string") {
10151
- stringValue = JSON.stringify(value);
10152
- }
10153
- return {
10154
- key,
10155
- value: stringValue,
10156
- original_key: key
10157
- };
10158
- });
10159
- }
10160
- function parseValues(values) {
10161
- const metadata = values.metadata;
10162
- const isEmpty = !metadata.length || metadata.length === 1 && !metadata[0].key && !metadata[0].value;
10163
- if (isEmpty) {
10164
- return null;
10165
- }
10166
- const update = {};
10167
- metadata.forEach((field) => {
10168
- let key = field.key;
10169
- let value = field.value;
10170
- const disabled = field.disabled;
10171
- if (!key || !value) {
10172
- return;
10173
- }
10174
- if (disabled) {
10175
- update[key] = value;
10176
- return;
10177
- }
10178
- key = key.trim();
10179
- value = value.trim();
10180
- if (value === "true") {
10181
- update[key] = true;
10182
- } else if (value === "false") {
10183
- update[key] = false;
10184
- } else {
10185
- const parsedNumber = parseFloat(value);
10186
- if (!isNaN(parsedNumber)) {
10187
- update[key] = parsedNumber;
10188
- } else {
10189
- update[key] = value;
10190
- }
10191
- }
10192
- });
10193
- return update;
10194
- }
10195
- function getHasUneditableRows(metadata) {
10196
- if (!metadata) {
10197
- return false;
10198
- }
10199
- return Object.values(metadata).some(
10200
- (value) => !EDITABLE_TYPES.includes(typeof value)
10201
- );
10202
- }
10203
9853
  const NumberInput = React.forwardRef(
10204
9854
  ({
10205
9855
  value,
@@ -11174,10 +10824,54 @@ const customItemSchema = objectType({
11174
10824
  quantity: numberType(),
11175
10825
  unit_price: unionType([numberType(), stringType()])
11176
10826
  });
11177
- const ShippingAddress = () => {
10827
+ const InlineTip = React.forwardRef(
10828
+ ({ variant = "tip", label, className, children, ...props }, ref) => {
10829
+ const labelValue = label || (variant === "warning" ? "Warning" : "Tip");
10830
+ return /* @__PURE__ */ jsxRuntime.jsxs(
10831
+ "div",
10832
+ {
10833
+ ref,
10834
+ className: ui.clx(
10835
+ "bg-ui-bg-component txt-small text-ui-fg-subtle grid grid-cols-[4px_1fr] items-start gap-3 rounded-lg border p-3",
10836
+ className
10837
+ ),
10838
+ ...props,
10839
+ children: [
10840
+ /* @__PURE__ */ jsxRuntime.jsx(
10841
+ "div",
10842
+ {
10843
+ role: "presentation",
10844
+ className: ui.clx("w-4px bg-ui-tag-neutral-icon h-full rounded-full", {
10845
+ "bg-ui-tag-orange-icon": variant === "warning"
10846
+ })
10847
+ }
10848
+ ),
10849
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-pretty", children: [
10850
+ /* @__PURE__ */ jsxRuntime.jsxs("strong", { className: "txt-small-plus text-ui-fg-base", children: [
10851
+ labelValue,
10852
+ ":"
10853
+ ] }),
10854
+ " ",
10855
+ children
10856
+ ] })
10857
+ ]
10858
+ }
10859
+ );
10860
+ }
10861
+ );
10862
+ InlineTip.displayName = "InlineTip";
10863
+ const MetadataFieldSchema = objectType({
10864
+ key: stringType(),
10865
+ disabled: booleanType().optional(),
10866
+ value: anyType()
10867
+ });
10868
+ const MetadataSchema = objectType({
10869
+ metadata: arrayType(MetadataFieldSchema)
10870
+ });
10871
+ const Metadata = () => {
11178
10872
  const { id } = reactRouterDom.useParams();
11179
10873
  const { order, isPending, isError, error } = useOrder(id, {
11180
- fields: "+shipping_address"
10874
+ fields: "metadata"
11181
10875
  });
11182
10876
  if (isError) {
11183
10877
  throw error;
@@ -11185,49 +10879,33 @@ const ShippingAddress = () => {
11185
10879
  const isReady = !isPending && !!order;
11186
10880
  return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
11187
10881
  /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Header, { children: [
11188
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Shipping Address" }) }),
11189
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Edit the shipping address for the draft order" }) })
10882
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Metadata" }) }),
10883
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Add metadata to the draft order." }) })
11190
10884
  ] }),
11191
- isReady && /* @__PURE__ */ jsxRuntime.jsx(ShippingAddressForm, { order })
10885
+ !isReady ? /* @__PURE__ */ jsxRuntime.jsx(PlaceholderInner, {}) : /* @__PURE__ */ jsxRuntime.jsx(MetadataForm, { orderId: id, metadata: order == null ? void 0 : order.metadata })
11192
10886
  ] });
11193
10887
  };
11194
- const ShippingAddressForm = ({ order }) => {
11195
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
10888
+ const METADATA_KEY_LABEL_ID = "metadata-form-key-label";
10889
+ const METADATA_VALUE_LABEL_ID = "metadata-form-value-label";
10890
+ const MetadataForm = ({ orderId, metadata }) => {
10891
+ const { handleSuccess } = useRouteModal();
10892
+ const hasUneditableRows = getHasUneditableRows(metadata);
10893
+ const { mutateAsync, isPending } = useUpdateDraftOrder(orderId);
11196
10894
  const form = reactHookForm.useForm({
11197
10895
  defaultValues: {
11198
- first_name: ((_a = order.shipping_address) == null ? void 0 : _a.first_name) ?? "",
11199
- last_name: ((_b = order.shipping_address) == null ? void 0 : _b.last_name) ?? "",
11200
- company: ((_c = order.shipping_address) == null ? void 0 : _c.company) ?? "",
11201
- address_1: ((_d = order.shipping_address) == null ? void 0 : _d.address_1) ?? "",
11202
- address_2: ((_e = order.shipping_address) == null ? void 0 : _e.address_2) ?? "",
11203
- city: ((_f = order.shipping_address) == null ? void 0 : _f.city) ?? "",
11204
- province: ((_g = order.shipping_address) == null ? void 0 : _g.province) ?? "",
11205
- country_code: ((_h = order.shipping_address) == null ? void 0 : _h.country_code) ?? "",
11206
- postal_code: ((_i = order.shipping_address) == null ? void 0 : _i.postal_code) ?? "",
11207
- phone: ((_j = order.shipping_address) == null ? void 0 : _j.phone) ?? ""
10896
+ metadata: getDefaultValues(metadata)
11208
10897
  },
11209
- resolver: zod.zodResolver(schema$2)
10898
+ resolver: zod.zodResolver(MetadataSchema)
11210
10899
  });
11211
- const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
11212
- const { handleSuccess } = useRouteModal();
11213
- const onSubmit = form.handleSubmit(async (data) => {
10900
+ const handleSubmit = form.handleSubmit(async (data) => {
10901
+ const parsedData = parseValues(data);
11214
10902
  await mutateAsync(
11215
10903
  {
11216
- shipping_address: {
11217
- first_name: data.first_name,
11218
- last_name: data.last_name,
11219
- company: data.company,
11220
- address_1: data.address_1,
11221
- address_2: data.address_2,
11222
- city: data.city,
11223
- province: data.province,
11224
- country_code: data.country_code,
11225
- postal_code: data.postal_code,
11226
- phone: data.phone
11227
- }
10904
+ metadata: parsedData
11228
10905
  },
11229
10906
  {
11230
10907
  onSuccess: () => {
10908
+ ui.toast.success("Metadata updated");
11231
10909
  handleSuccess();
11232
10910
  },
11233
10911
  onError: (error) => {
@@ -11236,238 +10914,740 @@ const ShippingAddressForm = ({ order }) => {
11236
10914
  }
11237
10915
  );
11238
10916
  });
10917
+ const { fields, insert, remove } = reactHookForm.useFieldArray({
10918
+ control: form.control,
10919
+ name: "metadata"
10920
+ });
10921
+ function deleteRow(index) {
10922
+ remove(index);
10923
+ if (fields.length === 1) {
10924
+ insert(0, {
10925
+ key: "",
10926
+ value: "",
10927
+ disabled: false
10928
+ });
10929
+ }
10930
+ }
10931
+ function insertRow(index, position) {
10932
+ insert(index + (position === "above" ? 0 : 1), {
10933
+ key: "",
10934
+ value: "",
10935
+ disabled: false
10936
+ });
10937
+ }
11239
10938
  return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(
11240
10939
  KeyboundForm,
11241
10940
  {
10941
+ onSubmit: handleSubmit,
11242
10942
  className: "flex flex-1 flex-col overflow-hidden",
11243
- onSubmit,
11244
10943
  children: [
11245
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-4", children: [
11246
- /* @__PURE__ */ jsxRuntime.jsx(
11247
- Form$2.Field,
11248
- {
11249
- control: form.control,
11250
- name: "country_code",
11251
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
11252
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Country" }),
11253
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(CountrySelect, { ...field }) }),
11254
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
11255
- ] })
11256
- }
11257
- ),
11258
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
11259
- /* @__PURE__ */ jsxRuntime.jsx(
11260
- Form$2.Field,
11261
- {
11262
- control: form.control,
11263
- name: "first_name",
11264
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
11265
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "First name" }),
11266
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
11267
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
11268
- ] })
10944
+ /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Body, { className: "flex flex-1 flex-col gap-y-8 overflow-y-auto", children: [
10945
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest grid grid-cols-1 divide-y rounded-lg", children: [
10946
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-subtle grid grid-cols-2 divide-x rounded-t-lg", children: [
10947
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "txt-compact-small-plus text-ui-fg-subtle px-2 py-1.5", children: /* @__PURE__ */ jsxRuntime.jsx("label", { id: METADATA_KEY_LABEL_ID, children: "Key" }) }),
10948
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "txt-compact-small-plus text-ui-fg-subtle px-2 py-1.5", children: /* @__PURE__ */ jsxRuntime.jsx("label", { id: METADATA_VALUE_LABEL_ID, children: "Value" }) })
10949
+ ] }),
10950
+ fields.map((field, index) => {
10951
+ const isDisabled = field.disabled || false;
10952
+ let placeholder = "-";
10953
+ if (typeof field.value === "object") {
10954
+ placeholder = "{ ... }";
11269
10955
  }
11270
- ),
11271
- /* @__PURE__ */ jsxRuntime.jsx(
11272
- Form$2.Field,
11273
- {
11274
- control: form.control,
11275
- name: "last_name",
11276
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
11277
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Last name" }),
11278
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
11279
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
11280
- ] })
10956
+ if (Array.isArray(field.value)) {
10957
+ placeholder = "[ ... ]";
11281
10958
  }
11282
- )
10959
+ return /* @__PURE__ */ jsxRuntime.jsx(
10960
+ ConditionalTooltip,
10961
+ {
10962
+ showTooltip: isDisabled,
10963
+ content: "This row is disabled because it contains non-primitive data.",
10964
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "group/table relative", children: [
10965
+ /* @__PURE__ */ jsxRuntime.jsxs(
10966
+ "div",
10967
+ {
10968
+ className: ui.clx("grid grid-cols-2 divide-x", {
10969
+ "overflow-hidden rounded-b-lg": index === fields.length - 1
10970
+ }),
10971
+ children: [
10972
+ /* @__PURE__ */ jsxRuntime.jsx(
10973
+ Form$2.Field,
10974
+ {
10975
+ control: form.control,
10976
+ name: `metadata.${index}.key`,
10977
+ render: ({ field: field2 }) => {
10978
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
10979
+ GridInput,
10980
+ {
10981
+ "aria-labelledby": METADATA_KEY_LABEL_ID,
10982
+ ...field2,
10983
+ disabled: isDisabled,
10984
+ placeholder: "Key"
10985
+ }
10986
+ ) }) });
10987
+ }
10988
+ }
10989
+ ),
10990
+ /* @__PURE__ */ jsxRuntime.jsx(
10991
+ Form$2.Field,
10992
+ {
10993
+ control: form.control,
10994
+ name: `metadata.${index}.value`,
10995
+ render: ({ field: { value, ...field2 } }) => {
10996
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
10997
+ GridInput,
10998
+ {
10999
+ "aria-labelledby": METADATA_VALUE_LABEL_ID,
11000
+ ...field2,
11001
+ value: isDisabled ? placeholder : value,
11002
+ disabled: isDisabled,
11003
+ placeholder: "Value"
11004
+ }
11005
+ ) }) });
11006
+ }
11007
+ }
11008
+ )
11009
+ ]
11010
+ }
11011
+ ),
11012
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu, { children: [
11013
+ /* @__PURE__ */ jsxRuntime.jsx(
11014
+ ui.DropdownMenu.Trigger,
11015
+ {
11016
+ className: ui.clx(
11017
+ "invisible absolute inset-y-0 -right-2.5 my-auto group-hover/table:visible data-[state='open']:visible",
11018
+ {
11019
+ hidden: isDisabled
11020
+ }
11021
+ ),
11022
+ disabled: isDisabled,
11023
+ asChild: true,
11024
+ children: /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { size: "2xsmall", children: /* @__PURE__ */ jsxRuntime.jsx(icons.EllipsisVertical, {}) })
11025
+ }
11026
+ ),
11027
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu.Content, { children: [
11028
+ /* @__PURE__ */ jsxRuntime.jsxs(
11029
+ ui.DropdownMenu.Item,
11030
+ {
11031
+ className: "gap-x-2",
11032
+ onClick: () => insertRow(index, "above"),
11033
+ children: [
11034
+ /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowUpMini, { className: "text-ui-fg-subtle" }),
11035
+ "Insert row above"
11036
+ ]
11037
+ }
11038
+ ),
11039
+ /* @__PURE__ */ jsxRuntime.jsxs(
11040
+ ui.DropdownMenu.Item,
11041
+ {
11042
+ className: "gap-x-2",
11043
+ onClick: () => insertRow(index, "below"),
11044
+ children: [
11045
+ /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowDownMini, { className: "text-ui-fg-subtle" }),
11046
+ "Insert row below"
11047
+ ]
11048
+ }
11049
+ ),
11050
+ /* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenu.Separator, {}),
11051
+ /* @__PURE__ */ jsxRuntime.jsxs(
11052
+ ui.DropdownMenu.Item,
11053
+ {
11054
+ className: "gap-x-2",
11055
+ onClick: () => deleteRow(index),
11056
+ children: [
11057
+ /* @__PURE__ */ jsxRuntime.jsx(icons.Trash, { className: "text-ui-fg-subtle" }),
11058
+ "Delete row"
11059
+ ]
11060
+ }
11061
+ )
11062
+ ] })
11063
+ ] })
11064
+ ] })
11065
+ },
11066
+ field.id
11067
+ );
11068
+ })
11283
11069
  ] }),
11284
- /* @__PURE__ */ jsxRuntime.jsx(
11285
- Form$2.Field,
11286
- {
11287
- control: form.control,
11288
- name: "company",
11289
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
11290
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { optional: true, children: "Company" }),
11291
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
11292
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
11293
- ] })
11294
- }
11295
- ),
11296
- /* @__PURE__ */ jsxRuntime.jsx(
11297
- Form$2.Field,
11298
- {
11299
- control: form.control,
11300
- name: "address_1",
11301
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
11302
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Address" }),
11303
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
11304
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
11305
- ] })
11306
- }
11307
- ),
11308
- /* @__PURE__ */ jsxRuntime.jsx(
11309
- Form$2.Field,
11310
- {
11311
- control: form.control,
11312
- name: "address_2",
11313
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
11314
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { optional: true, children: "Apartment, suite, etc." }),
11315
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
11316
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
11317
- ] })
11318
- }
11319
- ),
11320
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
11321
- /* @__PURE__ */ jsxRuntime.jsx(
11322
- Form$2.Field,
11323
- {
11324
- control: form.control,
11325
- name: "postal_code",
11326
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
11327
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Postal code" }),
11328
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
11329
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
11330
- ] })
11331
- }
11332
- ),
11333
- /* @__PURE__ */ jsxRuntime.jsx(
11334
- Form$2.Field,
11335
- {
11336
- control: form.control,
11337
- name: "city",
11338
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
11339
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "City" }),
11340
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
11341
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
11342
- ] })
11343
- }
11344
- )
11345
- ] }),
11346
- /* @__PURE__ */ jsxRuntime.jsx(
11347
- Form$2.Field,
11348
- {
11349
- control: form.control,
11350
- name: "province",
11351
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
11352
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { optional: true, children: "Province / State" }),
11353
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
11354
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
11355
- ] })
11356
- }
11357
- ),
11358
- /* @__PURE__ */ jsxRuntime.jsx(
11359
- Form$2.Field,
11360
- {
11361
- control: form.control,
11362
- name: "phone",
11363
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
11364
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { optional: true, children: "Phone" }),
11365
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
11366
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
11367
- ] })
11368
- }
11369
- )
11370
- ] }) }),
11371
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
11372
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
11070
+ hasUneditableRows && /* @__PURE__ */ jsxRuntime.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." })
11071
+ ] }),
11072
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
11073
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
11373
11074
  /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
11374
11075
  ] }) })
11375
11076
  ]
11376
11077
  }
11377
11078
  ) });
11378
11079
  };
11379
- const schema$2 = addressSchema;
11380
- const STACKED_FOCUS_MODAL_ID = "shipping-form";
11381
- const Shipping = () => {
11382
- var _a;
11383
- const { id } = reactRouterDom.useParams();
11384
- const { order, isPending, isError, error } = useOrder(id, {
11385
- fields: "+items.*,+items.variant.*,+items.variant.product.*,+items.variant.product.shipping_profile.*,+currency_code"
11080
+ const GridInput = React.forwardRef(({ className, ...props }, ref) => {
11081
+ return /* @__PURE__ */ jsxRuntime.jsx(
11082
+ "input",
11083
+ {
11084
+ ref,
11085
+ ...props,
11086
+ autoComplete: "off",
11087
+ className: ui.clx(
11088
+ "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",
11089
+ className
11090
+ )
11091
+ }
11092
+ );
11093
+ });
11094
+ GridInput.displayName = "MetadataForm.GridInput";
11095
+ const PlaceholderInner = () => {
11096
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-1 flex-col overflow-hidden", children: [
11097
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-[148ox] w-full rounded-lg" }) }),
11098
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
11099
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-7 w-12 rounded-md" }),
11100
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-7 w-12 rounded-md" })
11101
+ ] }) })
11102
+ ] });
11103
+ };
11104
+ const EDITABLE_TYPES = ["string", "number", "boolean"];
11105
+ function getDefaultValues(metadata) {
11106
+ if (!metadata || !Object.keys(metadata).length) {
11107
+ return [
11108
+ {
11109
+ key: "",
11110
+ value: "",
11111
+ disabled: false
11112
+ }
11113
+ ];
11114
+ }
11115
+ return Object.entries(metadata).map(([key, value]) => {
11116
+ if (!EDITABLE_TYPES.includes(typeof value)) {
11117
+ return {
11118
+ key,
11119
+ value,
11120
+ disabled: true
11121
+ };
11122
+ }
11123
+ let stringValue = value;
11124
+ if (typeof value !== "string") {
11125
+ stringValue = JSON.stringify(value);
11126
+ }
11127
+ return {
11128
+ key,
11129
+ value: stringValue,
11130
+ original_key: key
11131
+ };
11132
+ });
11133
+ }
11134
+ function parseValues(values) {
11135
+ const metadata = values.metadata;
11136
+ const isEmpty = !metadata.length || metadata.length === 1 && !metadata[0].key && !metadata[0].value;
11137
+ if (isEmpty) {
11138
+ return null;
11139
+ }
11140
+ const update = {};
11141
+ metadata.forEach((field) => {
11142
+ let key = field.key;
11143
+ let value = field.value;
11144
+ const disabled = field.disabled;
11145
+ if (!key || !value) {
11146
+ return;
11147
+ }
11148
+ if (disabled) {
11149
+ update[key] = value;
11150
+ return;
11151
+ }
11152
+ key = key.trim();
11153
+ value = value.trim();
11154
+ if (value === "true") {
11155
+ update[key] = true;
11156
+ } else if (value === "false") {
11157
+ update[key] = false;
11158
+ } else {
11159
+ const parsedNumber = parseFloat(value);
11160
+ if (!isNaN(parsedNumber)) {
11161
+ update[key] = parsedNumber;
11162
+ } else {
11163
+ update[key] = value;
11164
+ }
11165
+ }
11166
+ });
11167
+ return update;
11168
+ }
11169
+ function getHasUneditableRows(metadata) {
11170
+ if (!metadata) {
11171
+ return false;
11172
+ }
11173
+ return Object.values(metadata).some(
11174
+ (value) => !EDITABLE_TYPES.includes(typeof value)
11175
+ );
11176
+ }
11177
+ const PROMOTION_QUERY_KEY = "promotions";
11178
+ const promotionsQueryKeys = {
11179
+ list: (query2) => [
11180
+ PROMOTION_QUERY_KEY,
11181
+ query2 ? query2 : void 0
11182
+ ],
11183
+ detail: (id, query2) => [
11184
+ PROMOTION_QUERY_KEY,
11185
+ id,
11186
+ query2 ? query2 : void 0
11187
+ ]
11188
+ };
11189
+ const usePromotions = (query2, options) => {
11190
+ const { data, ...rest } = reactQuery.useQuery({
11191
+ queryKey: promotionsQueryKeys.list(query2),
11192
+ queryFn: async () => sdk.admin.promotion.list(query2),
11193
+ ...options
11386
11194
  });
11195
+ return { ...data, ...rest };
11196
+ };
11197
+ const Promotions = () => {
11198
+ const { id } = reactRouterDom.useParams();
11387
11199
  const {
11388
11200
  order: preview,
11389
- isPending: isPreviewPending,
11390
11201
  isError: isPreviewError,
11391
11202
  error: previewError
11392
- } = useOrderPreview(id);
11203
+ } = useOrderPreview(id, void 0);
11393
11204
  useInitiateOrderEdit({ preview });
11394
11205
  const { onCancel } = useCancelOrderEdit({ preview });
11395
- if (isError) {
11396
- throw error;
11397
- }
11398
11206
  if (isPreviewError) {
11399
11207
  throw previewError;
11400
11208
  }
11401
- const orderHasItems = (((_a = order == null ? void 0 : order.items) == null ? void 0 : _a.length) || 0) > 0;
11402
- const isReady = preview && !isPreviewPending && order && !isPending;
11403
- return /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal, { onClose: onCancel, children: !orderHasItems ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-full flex-col overflow-hidden ", children: [
11404
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Header, {}),
11405
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Body, { className: "flex flex-1 flex-col overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-1 flex-col items-center overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full max-w-[720px] flex-col gap-y-6 py-16 px-6", children: [
11406
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Shipping" }) }),
11407
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "This draft order currently has no items. Add items to the order before adding shipping." }) })
11408
- ] }) }) }),
11409
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Footer, { children: /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }) })
11410
- ] }) : isReady ? /* @__PURE__ */ jsxRuntime.jsx(ShippingForm, { preview, order }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
11411
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Edit Shipping" }) }),
11412
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Loading data for the draft order, please wait..." }) })
11413
- ] }) });
11209
+ const isReady = !!preview;
11210
+ return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { onClose: onCancel, children: [
11211
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Promotions" }) }) }),
11212
+ isReady && /* @__PURE__ */ jsxRuntime.jsx(PromotionForm, { preview })
11213
+ ] });
11414
11214
  };
11415
- const ShippingForm = ({ preview, order }) => {
11416
- var _a;
11417
- const { setIsOpen } = useStackedModal();
11215
+ const PromotionForm = ({ preview }) => {
11216
+ const { items, shipping_methods } = preview;
11418
11217
  const [isSubmitting, setIsSubmitting] = React.useState(false);
11419
- const [data, setData] = React.useState(null);
11420
- const appliedShippingOptionIds = (_a = preview.shipping_methods) == null ? void 0 : _a.map((method) => method.shipping_option_id).filter(Boolean);
11421
- const { shipping_options } = useShippingOptions(
11218
+ const [comboboxValue, setComboboxValue] = React.useState("");
11219
+ const { handleSuccess } = useRouteModal();
11220
+ const { mutateAsync: addPromotions, isPending: isAddingPromotions } = useDraftOrderAddPromotions(preview.id);
11221
+ const promoIds = getPromotionIds(items, shipping_methods);
11222
+ const { promotions, isPending, isError, error } = usePromotions(
11422
11223
  {
11423
- id: appliedShippingOptionIds,
11424
- fields: "+service_zone.*,+service_zone.fulfillment_set.*,+service_zone.fulfillment_set.location.*"
11224
+ id: promoIds
11425
11225
  },
11426
11226
  {
11427
- enabled: appliedShippingOptionIds.length > 0
11227
+ enabled: !!promoIds.length
11428
11228
  }
11429
11229
  );
11430
- const uniqueShippingProfiles = React.useMemo(() => {
11431
- const profiles = /* @__PURE__ */ new Map();
11432
- getUniqueShippingProfiles(order.items).forEach((profile) => {
11433
- profiles.set(profile.id, profile);
11434
- });
11435
- shipping_options == null ? void 0 : shipping_options.forEach((option) => {
11436
- profiles.set(option.shipping_profile_id, option.shipping_profile);
11437
- });
11438
- return Array.from(profiles.values());
11439
- }, [order.items, shipping_options]);
11440
- const { handleSuccess } = useRouteModal();
11441
- const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
11442
- const { mutateAsync: requestOrderEdit } = useDraftOrderRequestEdit(preview.id);
11443
- const { mutateAsync: removeShippingMethod } = useDraftOrderRemoveShippingMethod(preview.id);
11444
- const { mutateAsync: removeActionShippingMethod } = useDraftOrderRemoveActionShippingMethod(preview.id);
11445
- const onSubmit = async () => {
11446
- setIsSubmitting(true);
11447
- let requestSucceeded = false;
11448
- await requestOrderEdit(void 0, {
11449
- onError: (e) => {
11450
- ui.toast.error(`Failed to request order edit: ${e.message}`);
11451
- },
11452
- onSuccess: () => {
11453
- requestSucceeded = true;
11454
- }
11455
- });
11456
- if (!requestSucceeded) {
11457
- setIsSubmitting(false);
11458
- return;
11459
- }
11460
- await confirmOrderEdit(void 0, {
11461
- onError: (e) => {
11462
- ui.toast.error(`Failed to confirm order edit: ${e.message}`);
11463
- },
11464
- onSuccess: () => {
11465
- handleSuccess();
11466
- },
11467
- onSettled: () => {
11468
- setIsSubmitting(false);
11469
- }
11470
- });
11230
+ const comboboxData = useComboboxData({
11231
+ queryKey: ["promotions", "combobox", promoIds],
11232
+ queryFn: async (params) => {
11233
+ return await sdk.admin.promotion.list({
11234
+ ...params,
11235
+ id: {
11236
+ $nin: promoIds
11237
+ }
11238
+ });
11239
+ },
11240
+ getOptions: (data) => {
11241
+ return data.promotions.map((promotion) => ({
11242
+ label: promotion.code,
11243
+ value: promotion.code
11244
+ }));
11245
+ }
11246
+ });
11247
+ const add = async (value) => {
11248
+ if (!value) {
11249
+ return;
11250
+ }
11251
+ addPromotions(
11252
+ {
11253
+ promo_codes: [value]
11254
+ },
11255
+ {
11256
+ onError: (e) => {
11257
+ ui.toast.error(e.message);
11258
+ comboboxData.onSearchValueChange("");
11259
+ setComboboxValue("");
11260
+ },
11261
+ onSuccess: () => {
11262
+ comboboxData.onSearchValueChange("");
11263
+ setComboboxValue("");
11264
+ }
11265
+ }
11266
+ );
11267
+ };
11268
+ const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
11269
+ const { mutateAsync: requestOrderEdit } = useOrderEditRequest(preview.id);
11270
+ const onSubmit = async () => {
11271
+ setIsSubmitting(true);
11272
+ let requestSucceeded = false;
11273
+ await requestOrderEdit(void 0, {
11274
+ onError: (e) => {
11275
+ ui.toast.error(e.message);
11276
+ },
11277
+ onSuccess: () => {
11278
+ requestSucceeded = true;
11279
+ }
11280
+ });
11281
+ if (!requestSucceeded) {
11282
+ setIsSubmitting(false);
11283
+ return;
11284
+ }
11285
+ await confirmOrderEdit(void 0, {
11286
+ onError: (e) => {
11287
+ ui.toast.error(e.message);
11288
+ },
11289
+ onSuccess: () => {
11290
+ handleSuccess();
11291
+ },
11292
+ onSettled: () => {
11293
+ setIsSubmitting(false);
11294
+ }
11295
+ });
11296
+ };
11297
+ if (isError) {
11298
+ throw error;
11299
+ }
11300
+ return /* @__PURE__ */ jsxRuntime.jsxs(KeyboundForm, { className: "flex flex-1 flex-col", onSubmit, children: [
11301
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-4", children: [
11302
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
11303
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
11304
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Label, { size: "small", weight: "plus", htmlFor: "promotion-combobox", children: "Apply promotions" }),
11305
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Hint, { id: "promotion-combobox-hint", children: "Manage promotions that should be applied to the order." })
11306
+ ] }),
11307
+ /* @__PURE__ */ jsxRuntime.jsx(
11308
+ Combobox,
11309
+ {
11310
+ id: "promotion-combobox",
11311
+ "aria-describedby": "promotion-combobox-hint",
11312
+ isFetchingNextPage: comboboxData.isFetchingNextPage,
11313
+ fetchNextPage: comboboxData.fetchNextPage,
11314
+ options: comboboxData.options,
11315
+ onSearchValueChange: comboboxData.onSearchValueChange,
11316
+ searchValue: comboboxData.searchValue,
11317
+ disabled: comboboxData.disabled || isAddingPromotions,
11318
+ onChange: add,
11319
+ value: comboboxValue
11320
+ }
11321
+ )
11322
+ ] }),
11323
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
11324
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-2", children: promotions == null ? void 0 : promotions.map((promotion) => /* @__PURE__ */ jsxRuntime.jsx(
11325
+ PromotionItem,
11326
+ {
11327
+ promotion,
11328
+ orderId: preview.id,
11329
+ isLoading: isPending
11330
+ },
11331
+ promotion.id
11332
+ )) })
11333
+ ] }) }),
11334
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
11335
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
11336
+ /* @__PURE__ */ jsxRuntime.jsx(
11337
+ ui.Button,
11338
+ {
11339
+ size: "small",
11340
+ type: "submit",
11341
+ isLoading: isSubmitting || isAddingPromotions,
11342
+ children: "Save"
11343
+ }
11344
+ )
11345
+ ] }) })
11346
+ ] });
11347
+ };
11348
+ const PromotionItem = ({
11349
+ promotion,
11350
+ orderId,
11351
+ isLoading
11352
+ }) => {
11353
+ var _a;
11354
+ const { mutateAsync: removePromotions, isPending } = useDraftOrderRemovePromotions(orderId);
11355
+ const onRemove = async () => {
11356
+ removePromotions(
11357
+ {
11358
+ promo_codes: [promotion.code]
11359
+ },
11360
+ {
11361
+ onError: (e) => {
11362
+ ui.toast.error(e.message);
11363
+ }
11364
+ }
11365
+ );
11366
+ };
11367
+ const displayValue = getDisplayValue(promotion);
11368
+ return /* @__PURE__ */ jsxRuntime.jsxs(
11369
+ "div",
11370
+ {
11371
+ className: ui.clx(
11372
+ "bg-ui-bg-component shadow-elevation-card-rest flex items-center justify-between rounded-lg px-3 py-2",
11373
+ {
11374
+ "animate-pulse": isLoading
11375
+ }
11376
+ ),
11377
+ children: [
11378
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
11379
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: promotion.code }),
11380
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-ui-fg-subtle flex items-center gap-1.5", children: [
11381
+ displayValue && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
11382
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", children: displayValue }),
11383
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", children: "·" })
11384
+ ] }),
11385
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", className: "capitalize", children: (_a = promotion.application_method) == null ? void 0 : _a.allocation })
11386
+ ] })
11387
+ ] }),
11388
+ /* @__PURE__ */ jsxRuntime.jsx(
11389
+ ui.IconButton,
11390
+ {
11391
+ size: "small",
11392
+ type: "button",
11393
+ variant: "transparent",
11394
+ onClick: onRemove,
11395
+ isLoading: isPending || isLoading,
11396
+ children: /* @__PURE__ */ jsxRuntime.jsx(icons.XMark, {})
11397
+ }
11398
+ )
11399
+ ]
11400
+ },
11401
+ promotion.id
11402
+ );
11403
+ };
11404
+ function getDisplayValue(promotion) {
11405
+ var _a, _b, _c, _d;
11406
+ const value = (_a = promotion.application_method) == null ? void 0 : _a.value;
11407
+ if (!value) {
11408
+ return null;
11409
+ }
11410
+ if (((_b = promotion.application_method) == null ? void 0 : _b.type) === "fixed") {
11411
+ const currency = (_c = promotion.application_method) == null ? void 0 : _c.currency_code;
11412
+ if (!currency) {
11413
+ return null;
11414
+ }
11415
+ return getLocaleAmount(value, currency);
11416
+ } else if (((_d = promotion.application_method) == null ? void 0 : _d.type) === "percentage") {
11417
+ return formatPercentage(value);
11418
+ }
11419
+ return null;
11420
+ }
11421
+ const formatter = new Intl.NumberFormat([], {
11422
+ style: "percent",
11423
+ minimumFractionDigits: 2
11424
+ });
11425
+ const formatPercentage = (value, isPercentageValue = false) => {
11426
+ let val = value || 0;
11427
+ if (!isPercentageValue) {
11428
+ val = val / 100;
11429
+ }
11430
+ return formatter.format(val);
11431
+ };
11432
+ function getPromotionIds(items, shippingMethods) {
11433
+ const promotionIds = /* @__PURE__ */ new Set();
11434
+ for (const item of items) {
11435
+ if (item.adjustments) {
11436
+ for (const adjustment of item.adjustments) {
11437
+ if (adjustment.promotion_id) {
11438
+ promotionIds.add(adjustment.promotion_id);
11439
+ }
11440
+ }
11441
+ }
11442
+ }
11443
+ for (const shippingMethod of shippingMethods) {
11444
+ if (shippingMethod.adjustments) {
11445
+ for (const adjustment of shippingMethod.adjustments) {
11446
+ if (adjustment.promotion_id) {
11447
+ promotionIds.add(adjustment.promotion_id);
11448
+ }
11449
+ }
11450
+ }
11451
+ }
11452
+ return Array.from(promotionIds);
11453
+ }
11454
+ const SalesChannel = () => {
11455
+ const { id } = reactRouterDom.useParams();
11456
+ const { draft_order, isPending, isError, error } = useDraftOrder(
11457
+ id,
11458
+ {
11459
+ fields: "+sales_channel_id"
11460
+ },
11461
+ {
11462
+ enabled: !!id
11463
+ }
11464
+ );
11465
+ if (isError) {
11466
+ throw error;
11467
+ }
11468
+ const ISrEADY = !!draft_order && !isPending;
11469
+ return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
11470
+ /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Header, { children: [
11471
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Sales Channel" }) }),
11472
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Update which sales channel the draft order is associated with" }) })
11473
+ ] }),
11474
+ ISrEADY && /* @__PURE__ */ jsxRuntime.jsx(SalesChannelForm, { order: draft_order })
11475
+ ] });
11476
+ };
11477
+ const SalesChannelForm = ({ order }) => {
11478
+ const form = reactHookForm.useForm({
11479
+ defaultValues: {
11480
+ sales_channel_id: order.sales_channel_id || ""
11481
+ },
11482
+ resolver: zod.zodResolver(schema$2)
11483
+ });
11484
+ const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
11485
+ const { handleSuccess } = useRouteModal();
11486
+ const onSubmit = form.handleSubmit(async (data) => {
11487
+ await mutateAsync(
11488
+ {
11489
+ sales_channel_id: data.sales_channel_id
11490
+ },
11491
+ {
11492
+ onSuccess: () => {
11493
+ ui.toast.success("Sales channel updated");
11494
+ handleSuccess();
11495
+ },
11496
+ onError: (error) => {
11497
+ ui.toast.error(error.message);
11498
+ }
11499
+ }
11500
+ );
11501
+ });
11502
+ return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(
11503
+ KeyboundForm,
11504
+ {
11505
+ className: "flex flex-1 flex-col overflow-hidden",
11506
+ onSubmit,
11507
+ children: [
11508
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsx(SalesChannelField, { control: form.control, order }) }),
11509
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
11510
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
11511
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
11512
+ ] }) })
11513
+ ]
11514
+ }
11515
+ ) });
11516
+ };
11517
+ const SalesChannelField = ({ control, order }) => {
11518
+ const salesChannels = useComboboxData({
11519
+ queryFn: async (params) => {
11520
+ return await sdk.admin.salesChannel.list(params);
11521
+ },
11522
+ queryKey: ["sales-channels"],
11523
+ getOptions: (data) => {
11524
+ return data.sales_channels.map((salesChannel) => ({
11525
+ label: salesChannel.name,
11526
+ value: salesChannel.id
11527
+ }));
11528
+ },
11529
+ defaultValue: order.sales_channel_id || void 0
11530
+ });
11531
+ return /* @__PURE__ */ jsxRuntime.jsx(
11532
+ Form$2.Field,
11533
+ {
11534
+ control,
11535
+ name: "sales_channel_id",
11536
+ render: ({ field }) => {
11537
+ return /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
11538
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Sales Channel" }),
11539
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
11540
+ Combobox,
11541
+ {
11542
+ options: salesChannels.options,
11543
+ fetchNextPage: salesChannels.fetchNextPage,
11544
+ isFetchingNextPage: salesChannels.isFetchingNextPage,
11545
+ searchValue: salesChannels.searchValue,
11546
+ onSearchValueChange: salesChannels.onSearchValueChange,
11547
+ placeholder: "Select sales channel",
11548
+ ...field
11549
+ }
11550
+ ) }),
11551
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
11552
+ ] });
11553
+ }
11554
+ }
11555
+ );
11556
+ };
11557
+ const schema$2 = objectType({
11558
+ sales_channel_id: stringType().min(1)
11559
+ });
11560
+ const STACKED_FOCUS_MODAL_ID = "shipping-form";
11561
+ const Shipping = () => {
11562
+ var _a;
11563
+ const { id } = reactRouterDom.useParams();
11564
+ const { order, isPending, isError, error } = useOrder(id, {
11565
+ fields: "+items.*,+items.variant.*,+items.variant.product.*,+items.variant.product.shipping_profile.*,+currency_code"
11566
+ });
11567
+ const {
11568
+ order: preview,
11569
+ isPending: isPreviewPending,
11570
+ isError: isPreviewError,
11571
+ error: previewError
11572
+ } = useOrderPreview(id);
11573
+ useInitiateOrderEdit({ preview });
11574
+ const { onCancel } = useCancelOrderEdit({ preview });
11575
+ if (isError) {
11576
+ throw error;
11577
+ }
11578
+ if (isPreviewError) {
11579
+ throw previewError;
11580
+ }
11581
+ const orderHasItems = (((_a = order == null ? void 0 : order.items) == null ? void 0 : _a.length) || 0) > 0;
11582
+ const isReady = preview && !isPreviewPending && order && !isPending;
11583
+ return /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal, { onClose: onCancel, children: !orderHasItems ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-full flex-col overflow-hidden ", children: [
11584
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Header, {}),
11585
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Body, { className: "flex flex-1 flex-col overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-1 flex-col items-center overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full max-w-[720px] flex-col gap-y-6 py-16 px-6", children: [
11586
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Shipping" }) }),
11587
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "This draft order currently has no items. Add items to the order before adding shipping." }) })
11588
+ ] }) }) }),
11589
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Footer, { children: /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }) })
11590
+ ] }) : isReady ? /* @__PURE__ */ jsxRuntime.jsx(ShippingForm, { preview, order }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
11591
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Edit Shipping" }) }),
11592
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Loading data for the draft order, please wait..." }) })
11593
+ ] }) });
11594
+ };
11595
+ const ShippingForm = ({ preview, order }) => {
11596
+ var _a;
11597
+ const { setIsOpen } = useStackedModal();
11598
+ const [isSubmitting, setIsSubmitting] = React.useState(false);
11599
+ const [data, setData] = React.useState(null);
11600
+ const appliedShippingOptionIds = (_a = preview.shipping_methods) == null ? void 0 : _a.map((method) => method.shipping_option_id).filter(Boolean);
11601
+ const { shipping_options } = useShippingOptions(
11602
+ {
11603
+ id: appliedShippingOptionIds,
11604
+ fields: "+service_zone.*,+service_zone.fulfillment_set.*,+service_zone.fulfillment_set.location.*"
11605
+ },
11606
+ {
11607
+ enabled: appliedShippingOptionIds.length > 0
11608
+ }
11609
+ );
11610
+ const uniqueShippingProfiles = React.useMemo(() => {
11611
+ const profiles = /* @__PURE__ */ new Map();
11612
+ getUniqueShippingProfiles(order.items).forEach((profile) => {
11613
+ profiles.set(profile.id, profile);
11614
+ });
11615
+ shipping_options == null ? void 0 : shipping_options.forEach((option) => {
11616
+ profiles.set(option.shipping_profile_id, option.shipping_profile);
11617
+ });
11618
+ return Array.from(profiles.values());
11619
+ }, [order.items, shipping_options]);
11620
+ const { handleSuccess } = useRouteModal();
11621
+ const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
11622
+ const { mutateAsync: requestOrderEdit } = useDraftOrderRequestEdit(preview.id);
11623
+ const { mutateAsync: removeShippingMethod } = useDraftOrderRemoveShippingMethod(preview.id);
11624
+ const { mutateAsync: removeActionShippingMethod } = useDraftOrderRemoveActionShippingMethod(preview.id);
11625
+ const onSubmit = async () => {
11626
+ setIsSubmitting(true);
11627
+ let requestSucceeded = false;
11628
+ await requestOrderEdit(void 0, {
11629
+ onError: (e) => {
11630
+ ui.toast.error(`Failed to request order edit: ${e.message}`);
11631
+ },
11632
+ onSuccess: () => {
11633
+ requestSucceeded = true;
11634
+ }
11635
+ });
11636
+ if (!requestSucceeded) {
11637
+ setIsSubmitting(false);
11638
+ return;
11639
+ }
11640
+ await confirmOrderEdit(void 0, {
11641
+ onError: (e) => {
11642
+ ui.toast.error(`Failed to confirm order edit: ${e.message}`);
11643
+ },
11644
+ onSuccess: () => {
11645
+ handleSuccess();
11646
+ },
11647
+ onSettled: () => {
11648
+ setIsSubmitting(false);
11649
+ }
11650
+ });
11471
11651
  };
11472
11652
  const onKeydown = React.useCallback(
11473
11653
  (e) => {
@@ -12147,426 +12327,246 @@ const ShippingOptionField = ({
12147
12327
  ...field,
12148
12328
  disabled: !locationId || !shippingProfileId
12149
12329
  }
12150
- ) }) })
12151
- }
12152
- )
12153
- ] }) });
12154
- }
12155
- }
12156
- );
12157
- };
12158
- const CustomAmountField = ({
12159
- control,
12160
- currencyCode
12161
- }) => {
12162
- return /* @__PURE__ */ jsxRuntime.jsx(
12163
- Form$2.Field,
12164
- {
12165
- control,
12166
- name: "custom_amount",
12167
- render: ({ field: { onChange, ...field } }) => {
12168
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
12169
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
12170
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { optional: true, children: "Custom amount" }),
12171
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Set a custom amount for the shipping option." })
12172
- ] }),
12173
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
12174
- ui.CurrencyInput,
12175
- {
12176
- ...field,
12177
- onValueChange: (value) => onChange(value),
12178
- symbol: getNativeSymbol(currencyCode),
12179
- code: currencyCode
12180
- }
12181
- ) })
12182
- ] });
12183
- }
12184
- }
12185
- );
12186
- };
12187
- const SalesChannel = () => {
12188
- const { id } = reactRouterDom.useParams();
12189
- const { draft_order, isPending, isError, error } = useDraftOrder(
12190
- id,
12191
- {
12192
- fields: "+sales_channel_id"
12193
- },
12194
- {
12195
- enabled: !!id
12196
- }
12197
- );
12198
- if (isError) {
12199
- throw error;
12200
- }
12201
- const ISrEADY = !!draft_order && !isPending;
12202
- return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
12203
- /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Header, { children: [
12204
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Sales Channel" }) }),
12205
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Update which sales channel the draft order is associated with" }) })
12206
- ] }),
12207
- ISrEADY && /* @__PURE__ */ jsxRuntime.jsx(SalesChannelForm, { order: draft_order })
12208
- ] });
12209
- };
12210
- const SalesChannelForm = ({ order }) => {
12211
- const form = reactHookForm.useForm({
12212
- defaultValues: {
12213
- sales_channel_id: order.sales_channel_id || ""
12214
- },
12215
- resolver: zod.zodResolver(schema$1)
12216
- });
12217
- const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
12218
- const { handleSuccess } = useRouteModal();
12219
- const onSubmit = form.handleSubmit(async (data) => {
12220
- await mutateAsync(
12221
- {
12222
- sales_channel_id: data.sales_channel_id
12223
- },
12224
- {
12225
- onSuccess: () => {
12226
- ui.toast.success("Sales channel updated");
12227
- handleSuccess();
12228
- },
12229
- onError: (error) => {
12230
- ui.toast.error(error.message);
12231
- }
12232
- }
12233
- );
12234
- });
12235
- return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(
12236
- KeyboundForm,
12237
- {
12238
- className: "flex flex-1 flex-col overflow-hidden",
12239
- onSubmit,
12240
- children: [
12241
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsx(SalesChannelField, { control: form.control, order }) }),
12242
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
12243
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
12244
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
12245
- ] }) })
12246
- ]
12247
- }
12248
- ) });
12249
- };
12250
- const SalesChannelField = ({ control, order }) => {
12251
- const salesChannels = useComboboxData({
12252
- queryFn: async (params) => {
12253
- return await sdk.admin.salesChannel.list(params);
12254
- },
12255
- queryKey: ["sales-channels"],
12256
- getOptions: (data) => {
12257
- return data.sales_channels.map((salesChannel) => ({
12258
- label: salesChannel.name,
12259
- value: salesChannel.id
12260
- }));
12261
- },
12262
- defaultValue: order.sales_channel_id || void 0
12263
- });
12330
+ ) }) })
12331
+ }
12332
+ )
12333
+ ] }) });
12334
+ }
12335
+ }
12336
+ );
12337
+ };
12338
+ const CustomAmountField = ({
12339
+ control,
12340
+ currencyCode
12341
+ }) => {
12264
12342
  return /* @__PURE__ */ jsxRuntime.jsx(
12265
12343
  Form$2.Field,
12266
12344
  {
12267
12345
  control,
12268
- name: "sales_channel_id",
12269
- render: ({ field }) => {
12270
- return /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
12271
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Sales Channel" }),
12346
+ name: "custom_amount",
12347
+ render: ({ field: { onChange, ...field } }) => {
12348
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
12349
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
12350
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { optional: true, children: "Custom amount" }),
12351
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Set a custom amount for the shipping option." })
12352
+ ] }),
12272
12353
  /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
12273
- Combobox,
12354
+ ui.CurrencyInput,
12274
12355
  {
12275
- options: salesChannels.options,
12276
- fetchNextPage: salesChannels.fetchNextPage,
12277
- isFetchingNextPage: salesChannels.isFetchingNextPage,
12278
- searchValue: salesChannels.searchValue,
12279
- onSearchValueChange: salesChannels.onSearchValueChange,
12280
- placeholder: "Select sales channel",
12281
- ...field
12356
+ ...field,
12357
+ onValueChange: (value) => onChange(value),
12358
+ symbol: getNativeSymbol(currencyCode),
12359
+ code: currencyCode
12282
12360
  }
12283
- ) }),
12284
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12361
+ ) })
12285
12362
  ] });
12286
12363
  }
12287
12364
  }
12288
12365
  );
12289
12366
  };
12290
- const schema$1 = objectType({
12291
- sales_channel_id: stringType().min(1)
12292
- });
12293
- const PROMOTION_QUERY_KEY = "promotions";
12294
- const promotionsQueryKeys = {
12295
- list: (query2) => [
12296
- PROMOTION_QUERY_KEY,
12297
- query2 ? query2 : void 0
12298
- ],
12299
- detail: (id, query2) => [
12300
- PROMOTION_QUERY_KEY,
12301
- id,
12302
- query2 ? query2 : void 0
12303
- ]
12304
- };
12305
- const usePromotions = (query2, options) => {
12306
- const { data, ...rest } = reactQuery.useQuery({
12307
- queryKey: promotionsQueryKeys.list(query2),
12308
- queryFn: async () => sdk.admin.promotion.list(query2),
12309
- ...options
12310
- });
12311
- return { ...data, ...rest };
12312
- };
12313
- const Promotions = () => {
12367
+ const ShippingAddress = () => {
12314
12368
  const { id } = reactRouterDom.useParams();
12315
- const {
12316
- order: preview,
12317
- isError: isPreviewError,
12318
- error: previewError
12319
- } = useOrderPreview(id, void 0);
12320
- useInitiateOrderEdit({ preview });
12321
- const { onCancel } = useCancelOrderEdit({ preview });
12322
- if (isPreviewError) {
12323
- throw previewError;
12324
- }
12325
- const isReady = !!preview;
12326
- return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { onClose: onCancel, children: [
12327
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Promotions" }) }) }),
12328
- isReady && /* @__PURE__ */ jsxRuntime.jsx(PromotionForm, { preview })
12329
- ] });
12330
- };
12331
- const PromotionForm = ({ preview }) => {
12332
- const { items, shipping_methods } = preview;
12333
- const [isSubmitting, setIsSubmitting] = React.useState(false);
12334
- const [comboboxValue, setComboboxValue] = React.useState("");
12335
- const { handleSuccess } = useRouteModal();
12336
- const { mutateAsync: addPromotions, isPending: isAddingPromotions } = useDraftOrderAddPromotions(preview.id);
12337
- const promoIds = getPromotionIds(items, shipping_methods);
12338
- const { promotions, isPending, isError, error } = usePromotions(
12339
- {
12340
- id: promoIds
12341
- },
12342
- {
12343
- enabled: !!promoIds.length
12344
- }
12345
- );
12346
- const comboboxData = useComboboxData({
12347
- queryKey: ["promotions", "combobox", promoIds],
12348
- queryFn: async (params) => {
12349
- return await sdk.admin.promotion.list({
12350
- ...params,
12351
- id: {
12352
- $nin: promoIds
12353
- }
12354
- });
12355
- },
12356
- getOptions: (data) => {
12357
- return data.promotions.map((promotion) => ({
12358
- label: promotion.code,
12359
- value: promotion.code
12360
- }));
12361
- }
12369
+ const { order, isPending, isError, error } = useOrder(id, {
12370
+ fields: "+shipping_address"
12362
12371
  });
12363
- const add = async (value) => {
12364
- if (!value) {
12365
- return;
12366
- }
12367
- addPromotions(
12368
- {
12369
- promo_codes: [value]
12370
- },
12371
- {
12372
- onError: (e) => {
12373
- ui.toast.error(e.message);
12374
- comboboxData.onSearchValueChange("");
12375
- setComboboxValue("");
12376
- },
12377
- onSuccess: () => {
12378
- comboboxData.onSearchValueChange("");
12379
- setComboboxValue("");
12380
- }
12381
- }
12382
- );
12383
- };
12384
- const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
12385
- const { mutateAsync: requestOrderEdit } = useOrderEditRequest(preview.id);
12386
- const onSubmit = async () => {
12387
- setIsSubmitting(true);
12388
- let requestSucceeded = false;
12389
- await requestOrderEdit(void 0, {
12390
- onError: (e) => {
12391
- ui.toast.error(e.message);
12392
- },
12393
- onSuccess: () => {
12394
- requestSucceeded = true;
12395
- }
12396
- });
12397
- if (!requestSucceeded) {
12398
- setIsSubmitting(false);
12399
- return;
12400
- }
12401
- await confirmOrderEdit(void 0, {
12402
- onError: (e) => {
12403
- ui.toast.error(e.message);
12404
- },
12405
- onSuccess: () => {
12406
- handleSuccess();
12407
- },
12408
- onSettled: () => {
12409
- setIsSubmitting(false);
12410
- }
12411
- });
12412
- };
12413
12372
  if (isError) {
12414
12373
  throw error;
12415
12374
  }
12416
- return /* @__PURE__ */ jsxRuntime.jsxs(KeyboundForm, { className: "flex flex-1 flex-col", onSubmit, children: [
12417
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-4", children: [
12418
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
12419
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
12420
- /* @__PURE__ */ jsxRuntime.jsx(ui.Label, { size: "small", weight: "plus", htmlFor: "promotion-combobox", children: "Apply promotions" }),
12421
- /* @__PURE__ */ jsxRuntime.jsx(ui.Hint, { id: "promotion-combobox-hint", children: "Manage promotions that should be applied to the order." })
12422
- ] }),
12423
- /* @__PURE__ */ jsxRuntime.jsx(
12424
- Combobox,
12425
- {
12426
- id: "promotion-combobox",
12427
- "aria-describedby": "promotion-combobox-hint",
12428
- isFetchingNextPage: comboboxData.isFetchingNextPage,
12429
- fetchNextPage: comboboxData.fetchNextPage,
12430
- options: comboboxData.options,
12431
- onSearchValueChange: comboboxData.onSearchValueChange,
12432
- searchValue: comboboxData.searchValue,
12433
- disabled: comboboxData.disabled || isAddingPromotions,
12434
- onChange: add,
12435
- value: comboboxValue
12436
- }
12437
- )
12438
- ] }),
12439
- /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
12440
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-2", children: promotions == null ? void 0 : promotions.map((promotion) => /* @__PURE__ */ jsxRuntime.jsx(
12441
- PromotionItem,
12442
- {
12443
- promotion,
12444
- orderId: preview.id,
12445
- isLoading: isPending
12446
- },
12447
- promotion.id
12448
- )) })
12449
- ] }) }),
12450
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
12451
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
12452
- /* @__PURE__ */ jsxRuntime.jsx(
12453
- ui.Button,
12454
- {
12455
- size: "small",
12456
- type: "submit",
12457
- isLoading: isSubmitting || isAddingPromotions,
12458
- children: "Save"
12459
- }
12460
- )
12461
- ] }) })
12375
+ const isReady = !isPending && !!order;
12376
+ return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
12377
+ /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Header, { children: [
12378
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Shipping Address" }) }),
12379
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Edit the shipping address for the draft order" }) })
12380
+ ] }),
12381
+ isReady && /* @__PURE__ */ jsxRuntime.jsx(ShippingAddressForm, { order })
12462
12382
  ] });
12463
12383
  };
12464
- const PromotionItem = ({
12465
- promotion,
12466
- orderId,
12467
- isLoading
12468
- }) => {
12469
- var _a;
12470
- const { mutateAsync: removePromotions, isPending } = useDraftOrderRemovePromotions(orderId);
12471
- const onRemove = async () => {
12472
- removePromotions(
12384
+ const ShippingAddressForm = ({ order }) => {
12385
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
12386
+ const form = reactHookForm.useForm({
12387
+ defaultValues: {
12388
+ first_name: ((_a = order.shipping_address) == null ? void 0 : _a.first_name) ?? "",
12389
+ last_name: ((_b = order.shipping_address) == null ? void 0 : _b.last_name) ?? "",
12390
+ company: ((_c = order.shipping_address) == null ? void 0 : _c.company) ?? "",
12391
+ address_1: ((_d = order.shipping_address) == null ? void 0 : _d.address_1) ?? "",
12392
+ address_2: ((_e = order.shipping_address) == null ? void 0 : _e.address_2) ?? "",
12393
+ city: ((_f = order.shipping_address) == null ? void 0 : _f.city) ?? "",
12394
+ province: ((_g = order.shipping_address) == null ? void 0 : _g.province) ?? "",
12395
+ country_code: ((_h = order.shipping_address) == null ? void 0 : _h.country_code) ?? "",
12396
+ postal_code: ((_i = order.shipping_address) == null ? void 0 : _i.postal_code) ?? "",
12397
+ phone: ((_j = order.shipping_address) == null ? void 0 : _j.phone) ?? ""
12398
+ },
12399
+ resolver: zod.zodResolver(schema$1)
12400
+ });
12401
+ const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
12402
+ const { handleSuccess } = useRouteModal();
12403
+ const onSubmit = form.handleSubmit(async (data) => {
12404
+ await mutateAsync(
12473
12405
  {
12474
- promo_codes: [promotion.code]
12406
+ shipping_address: {
12407
+ first_name: data.first_name,
12408
+ last_name: data.last_name,
12409
+ company: data.company,
12410
+ address_1: data.address_1,
12411
+ address_2: data.address_2,
12412
+ city: data.city,
12413
+ province: data.province,
12414
+ country_code: data.country_code,
12415
+ postal_code: data.postal_code,
12416
+ phone: data.phone
12417
+ }
12475
12418
  },
12476
12419
  {
12477
- onError: (e) => {
12478
- ui.toast.error(e.message);
12420
+ onSuccess: () => {
12421
+ handleSuccess();
12422
+ },
12423
+ onError: (error) => {
12424
+ ui.toast.error(error.message);
12479
12425
  }
12480
12426
  }
12481
12427
  );
12482
- };
12483
- const displayValue = getDisplayValue(promotion);
12484
- return /* @__PURE__ */ jsxRuntime.jsxs(
12485
- "div",
12428
+ });
12429
+ return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(
12430
+ KeyboundForm,
12486
12431
  {
12487
- className: ui.clx(
12488
- "bg-ui-bg-component shadow-elevation-card-rest flex items-center justify-between rounded-lg px-3 py-2",
12489
- {
12490
- "animate-pulse": isLoading
12491
- }
12492
- ),
12432
+ className: "flex flex-1 flex-col overflow-hidden",
12433
+ onSubmit,
12493
12434
  children: [
12494
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
12495
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: promotion.code }),
12496
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-ui-fg-subtle flex items-center gap-1.5", children: [
12497
- displayValue && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
12498
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", children: displayValue }),
12499
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", children: "·" })
12500
- ] }),
12501
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", className: "capitalize", children: (_a = promotion.application_method) == null ? void 0 : _a.allocation })
12502
- ] })
12503
- ] }),
12504
- /* @__PURE__ */ jsxRuntime.jsx(
12505
- ui.IconButton,
12506
- {
12507
- size: "small",
12508
- type: "button",
12509
- variant: "transparent",
12510
- onClick: onRemove,
12511
- isLoading: isPending || isLoading,
12512
- children: /* @__PURE__ */ jsxRuntime.jsx(icons.XMark, {})
12513
- }
12514
- )
12435
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-4", children: [
12436
+ /* @__PURE__ */ jsxRuntime.jsx(
12437
+ Form$2.Field,
12438
+ {
12439
+ control: form.control,
12440
+ name: "country_code",
12441
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
12442
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Country" }),
12443
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(CountrySelect, { ...field }) }),
12444
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12445
+ ] })
12446
+ }
12447
+ ),
12448
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
12449
+ /* @__PURE__ */ jsxRuntime.jsx(
12450
+ Form$2.Field,
12451
+ {
12452
+ control: form.control,
12453
+ name: "first_name",
12454
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
12455
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "First name" }),
12456
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
12457
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12458
+ ] })
12459
+ }
12460
+ ),
12461
+ /* @__PURE__ */ jsxRuntime.jsx(
12462
+ Form$2.Field,
12463
+ {
12464
+ control: form.control,
12465
+ name: "last_name",
12466
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
12467
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Last name" }),
12468
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
12469
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12470
+ ] })
12471
+ }
12472
+ )
12473
+ ] }),
12474
+ /* @__PURE__ */ jsxRuntime.jsx(
12475
+ Form$2.Field,
12476
+ {
12477
+ control: form.control,
12478
+ name: "company",
12479
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
12480
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { optional: true, children: "Company" }),
12481
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
12482
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12483
+ ] })
12484
+ }
12485
+ ),
12486
+ /* @__PURE__ */ jsxRuntime.jsx(
12487
+ Form$2.Field,
12488
+ {
12489
+ control: form.control,
12490
+ name: "address_1",
12491
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
12492
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Address" }),
12493
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
12494
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12495
+ ] })
12496
+ }
12497
+ ),
12498
+ /* @__PURE__ */ jsxRuntime.jsx(
12499
+ Form$2.Field,
12500
+ {
12501
+ control: form.control,
12502
+ name: "address_2",
12503
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
12504
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { optional: true, children: "Apartment, suite, etc." }),
12505
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
12506
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12507
+ ] })
12508
+ }
12509
+ ),
12510
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
12511
+ /* @__PURE__ */ jsxRuntime.jsx(
12512
+ Form$2.Field,
12513
+ {
12514
+ control: form.control,
12515
+ name: "postal_code",
12516
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
12517
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Postal code" }),
12518
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
12519
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12520
+ ] })
12521
+ }
12522
+ ),
12523
+ /* @__PURE__ */ jsxRuntime.jsx(
12524
+ Form$2.Field,
12525
+ {
12526
+ control: form.control,
12527
+ name: "city",
12528
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
12529
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "City" }),
12530
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
12531
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12532
+ ] })
12533
+ }
12534
+ )
12535
+ ] }),
12536
+ /* @__PURE__ */ jsxRuntime.jsx(
12537
+ Form$2.Field,
12538
+ {
12539
+ control: form.control,
12540
+ name: "province",
12541
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
12542
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { optional: true, children: "Province / State" }),
12543
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
12544
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12545
+ ] })
12546
+ }
12547
+ ),
12548
+ /* @__PURE__ */ jsxRuntime.jsx(
12549
+ Form$2.Field,
12550
+ {
12551
+ control: form.control,
12552
+ name: "phone",
12553
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
12554
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { optional: true, children: "Phone" }),
12555
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
12556
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12557
+ ] })
12558
+ }
12559
+ )
12560
+ ] }) }),
12561
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
12562
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
12563
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
12564
+ ] }) })
12515
12565
  ]
12516
- },
12517
- promotion.id
12518
- );
12519
- };
12520
- function getDisplayValue(promotion) {
12521
- var _a, _b, _c, _d;
12522
- const value = (_a = promotion.application_method) == null ? void 0 : _a.value;
12523
- if (!value) {
12524
- return null;
12525
- }
12526
- if (((_b = promotion.application_method) == null ? void 0 : _b.type) === "fixed") {
12527
- const currency = (_c = promotion.application_method) == null ? void 0 : _c.currency_code;
12528
- if (!currency) {
12529
- return null;
12530
12566
  }
12531
- return getLocaleAmount(value, currency);
12532
- } else if (((_d = promotion.application_method) == null ? void 0 : _d.type) === "percentage") {
12533
- return formatPercentage(value);
12534
- }
12535
- return null;
12536
- }
12537
- const formatter = new Intl.NumberFormat([], {
12538
- style: "percent",
12539
- minimumFractionDigits: 2
12540
- });
12541
- const formatPercentage = (value, isPercentageValue = false) => {
12542
- let val = value || 0;
12543
- if (!isPercentageValue) {
12544
- val = val / 100;
12545
- }
12546
- return formatter.format(val);
12567
+ ) });
12547
12568
  };
12548
- function getPromotionIds(items, shippingMethods) {
12549
- const promotionIds = /* @__PURE__ */ new Set();
12550
- for (const item of items) {
12551
- if (item.adjustments) {
12552
- for (const adjustment of item.adjustments) {
12553
- if (adjustment.promotion_id) {
12554
- promotionIds.add(adjustment.promotion_id);
12555
- }
12556
- }
12557
- }
12558
- }
12559
- for (const shippingMethod of shippingMethods) {
12560
- if (shippingMethod.adjustments) {
12561
- for (const adjustment of shippingMethod.adjustments) {
12562
- if (adjustment.promotion_id) {
12563
- promotionIds.add(adjustment.promotion_id);
12564
- }
12565
- }
12566
- }
12567
- }
12568
- return Array.from(promotionIds);
12569
- }
12569
+ const schema$1 = addressSchema;
12570
12570
  const TransferOwnership = () => {
12571
12571
  const { id } = reactRouterDom.useParams();
12572
12572
  const { draft_order, isPending, isError, error } = useDraftOrder(id, {
@@ -13064,40 +13064,40 @@ const routeModule = {
13064
13064
  loader,
13065
13065
  children: [
13066
13066
  {
13067
- Component: Email,
13068
- path: "/draft-orders/:id/email"
13067
+ Component: BillingAddress,
13068
+ path: "/draft-orders/:id/billing-address"
13069
13069
  },
13070
13070
  {
13071
13071
  Component: CustomItems,
13072
13072
  path: "/draft-orders/:id/custom-items"
13073
13073
  },
13074
13074
  {
13075
- Component: BillingAddress,
13076
- path: "/draft-orders/:id/billing-address"
13077
- },
13078
- {
13079
- Component: Metadata,
13080
- path: "/draft-orders/:id/metadata"
13075
+ Component: Email,
13076
+ path: "/draft-orders/:id/email"
13081
13077
  },
13082
13078
  {
13083
13079
  Component: Items,
13084
13080
  path: "/draft-orders/:id/items"
13085
13081
  },
13086
13082
  {
13087
- Component: ShippingAddress,
13088
- path: "/draft-orders/:id/shipping-address"
13083
+ Component: Metadata,
13084
+ path: "/draft-orders/:id/metadata"
13089
13085
  },
13090
13086
  {
13091
- Component: Shipping,
13092
- path: "/draft-orders/:id/shipping"
13087
+ Component: Promotions,
13088
+ path: "/draft-orders/:id/promotions"
13093
13089
  },
13094
13090
  {
13095
13091
  Component: SalesChannel,
13096
13092
  path: "/draft-orders/:id/sales-channel"
13097
13093
  },
13098
13094
  {
13099
- Component: Promotions,
13100
- path: "/draft-orders/:id/promotions"
13095
+ Component: Shipping,
13096
+ path: "/draft-orders/:id/shipping"
13097
+ },
13098
+ {
13099
+ Component: ShippingAddress,
13100
+ path: "/draft-orders/:id/shipping-address"
13101
13101
  },
13102
13102
  {
13103
13103
  Component: TransferOwnership,