@medusajs/draft-order 2.11.4-preview-20251110090143 → 2.11.4-preview-20251110120148

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.
@@ -10814,832 +10814,1141 @@ const customItemSchema = objectType({
10814
10814
  quantity: numberType(),
10815
10815
  unit_price: unionType([numberType(), stringType()])
10816
10816
  });
10817
- const InlineTip = forwardRef(
10818
- ({ variant = "tip", label, className, children, ...props }, ref) => {
10819
- const labelValue = label || (variant === "warning" ? "Warning" : "Tip");
10820
- return /* @__PURE__ */ jsxs(
10821
- "div",
10822
- {
10823
- ref,
10824
- className: clx(
10825
- "bg-ui-bg-component txt-small text-ui-fg-subtle grid grid-cols-[4px_1fr] items-start gap-3 rounded-lg border p-3",
10826
- className
10827
- ),
10828
- ...props,
10829
- children: [
10830
- /* @__PURE__ */ jsx(
10831
- "div",
10832
- {
10833
- role: "presentation",
10834
- className: clx("w-4px bg-ui-tag-neutral-icon h-full rounded-full", {
10835
- "bg-ui-tag-orange-icon": variant === "warning"
10836
- })
10837
- }
10838
- ),
10839
- /* @__PURE__ */ jsxs("div", { className: "text-pretty", children: [
10840
- /* @__PURE__ */ jsxs("strong", { className: "txt-small-plus text-ui-fg-base", children: [
10841
- labelValue,
10842
- ":"
10843
- ] }),
10844
- " ",
10845
- children
10846
- ] })
10847
- ]
10848
- }
10849
- );
10850
- }
10851
- );
10852
- InlineTip.displayName = "InlineTip";
10853
- const MetadataFieldSchema = objectType({
10854
- key: stringType(),
10855
- disabled: booleanType().optional(),
10856
- value: anyType()
10857
- });
10858
- const MetadataSchema = objectType({
10859
- metadata: arrayType(MetadataFieldSchema)
10860
- });
10861
- const Metadata = () => {
10862
- const { id } = useParams();
10863
- const { order, isPending, isError, error } = useOrder(id, {
10864
- fields: "metadata"
10817
+ const PROMOTION_QUERY_KEY = "promotions";
10818
+ const promotionsQueryKeys = {
10819
+ list: (query2) => [
10820
+ PROMOTION_QUERY_KEY,
10821
+ query2 ? query2 : void 0
10822
+ ],
10823
+ detail: (id, query2) => [
10824
+ PROMOTION_QUERY_KEY,
10825
+ id,
10826
+ query2 ? query2 : void 0
10827
+ ]
10828
+ };
10829
+ const usePromotions = (query2, options) => {
10830
+ const { data, ...rest } = useQuery({
10831
+ queryKey: promotionsQueryKeys.list(query2),
10832
+ queryFn: async () => sdk.admin.promotion.list(query2),
10833
+ ...options
10865
10834
  });
10866
- if (isError) {
10867
- throw error;
10835
+ return { ...data, ...rest };
10836
+ };
10837
+ const Promotions = () => {
10838
+ const { id } = useParams();
10839
+ const {
10840
+ order: preview,
10841
+ isError: isPreviewError,
10842
+ error: previewError
10843
+ } = useOrderPreview(id, void 0);
10844
+ useInitiateOrderEdit({ preview });
10845
+ const { onCancel } = useCancelOrderEdit({ preview });
10846
+ if (isPreviewError) {
10847
+ throw previewError;
10868
10848
  }
10869
- const isReady = !isPending && !!order;
10870
- return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
10871
- /* @__PURE__ */ jsxs(RouteDrawer.Header, { children: [
10872
- /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Metadata" }) }),
10873
- /* @__PURE__ */ jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Add metadata to the draft order." }) })
10874
- ] }),
10875
- !isReady ? /* @__PURE__ */ jsx(PlaceholderInner, {}) : /* @__PURE__ */ jsx(MetadataForm, { orderId: id, metadata: order == null ? void 0 : order.metadata })
10849
+ const isReady = !!preview;
10850
+ return /* @__PURE__ */ jsxs(RouteDrawer, { onClose: onCancel, children: [
10851
+ /* @__PURE__ */ jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Promotions" }) }) }),
10852
+ isReady && /* @__PURE__ */ jsx(PromotionForm, { preview })
10876
10853
  ] });
10877
10854
  };
10878
- const METADATA_KEY_LABEL_ID = "metadata-form-key-label";
10879
- const METADATA_VALUE_LABEL_ID = "metadata-form-value-label";
10880
- const MetadataForm = ({ orderId, metadata }) => {
10855
+ const PromotionForm = ({ preview }) => {
10856
+ const { items, shipping_methods } = preview;
10857
+ const [isSubmitting, setIsSubmitting] = useState(false);
10858
+ const [comboboxValue, setComboboxValue] = useState("");
10881
10859
  const { handleSuccess } = useRouteModal();
10882
- const hasUneditableRows = getHasUneditableRows(metadata);
10883
- const { mutateAsync, isPending } = useUpdateDraftOrder(orderId);
10884
- const form = useForm({
10885
- defaultValues: {
10886
- metadata: getDefaultValues(metadata)
10860
+ const { mutateAsync: addPromotions, isPending: isAddingPromotions } = useDraftOrderAddPromotions(preview.id);
10861
+ const promoIds = getPromotionIds(items, shipping_methods);
10862
+ const { promotions, isPending, isError, error } = usePromotions(
10863
+ {
10864
+ id: promoIds
10887
10865
  },
10888
- resolver: zodResolver(MetadataSchema)
10866
+ {
10867
+ enabled: !!promoIds.length
10868
+ }
10869
+ );
10870
+ const comboboxData = useComboboxData({
10871
+ queryKey: ["promotions", "combobox", promoIds],
10872
+ queryFn: async (params) => {
10873
+ return await sdk.admin.promotion.list({
10874
+ ...params,
10875
+ id: {
10876
+ $nin: promoIds
10877
+ }
10878
+ });
10879
+ },
10880
+ getOptions: (data) => {
10881
+ return data.promotions.map((promotion) => ({
10882
+ label: promotion.code,
10883
+ value: promotion.code
10884
+ }));
10885
+ }
10889
10886
  });
10890
- const handleSubmit = form.handleSubmit(async (data) => {
10891
- const parsedData = parseValues(data);
10892
- await mutateAsync(
10887
+ const add = async (value) => {
10888
+ if (!value) {
10889
+ return;
10890
+ }
10891
+ addPromotions(
10893
10892
  {
10894
- metadata: parsedData
10893
+ promo_codes: [value]
10895
10894
  },
10896
10895
  {
10897
- onSuccess: () => {
10898
- toast.success("Metadata updated");
10899
- handleSuccess();
10896
+ onError: (e) => {
10897
+ toast.error(e.message);
10898
+ comboboxData.onSearchValueChange("");
10899
+ setComboboxValue("");
10900
10900
  },
10901
- onError: (error) => {
10902
- toast.error(error.message);
10901
+ onSuccess: () => {
10902
+ comboboxData.onSearchValueChange("");
10903
+ setComboboxValue("");
10903
10904
  }
10904
10905
  }
10905
10906
  );
10906
- });
10907
- const { fields, insert, remove } = useFieldArray({
10908
- control: form.control,
10909
- name: "metadata"
10910
- });
10911
- function deleteRow(index) {
10912
- remove(index);
10913
- if (fields.length === 1) {
10914
- insert(0, {
10915
- key: "",
10916
- value: "",
10917
- disabled: false
10918
- });
10907
+ };
10908
+ const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
10909
+ const { mutateAsync: requestOrderEdit } = useOrderEditRequest(preview.id);
10910
+ const onSubmit = async () => {
10911
+ setIsSubmitting(true);
10912
+ let requestSucceeded = false;
10913
+ await requestOrderEdit(void 0, {
10914
+ onError: (e) => {
10915
+ toast.error(e.message);
10916
+ },
10917
+ onSuccess: () => {
10918
+ requestSucceeded = true;
10919
+ }
10920
+ });
10921
+ if (!requestSucceeded) {
10922
+ setIsSubmitting(false);
10923
+ return;
10919
10924
  }
10920
- }
10921
- function insertRow(index, position) {
10922
- insert(index + (position === "above" ? 0 : 1), {
10923
- key: "",
10924
- value: "",
10925
- disabled: false
10925
+ await confirmOrderEdit(void 0, {
10926
+ onError: (e) => {
10927
+ toast.error(e.message);
10928
+ },
10929
+ onSuccess: () => {
10930
+ handleSuccess();
10931
+ },
10932
+ onSettled: () => {
10933
+ setIsSubmitting(false);
10934
+ }
10926
10935
  });
10936
+ };
10937
+ if (isError) {
10938
+ throw error;
10927
10939
  }
10928
- return /* @__PURE__ */ jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxs(
10929
- KeyboundForm,
10930
- {
10931
- onSubmit: handleSubmit,
10932
- className: "flex flex-1 flex-col overflow-hidden",
10933
- children: [
10934
- /* @__PURE__ */ jsxs(RouteDrawer.Body, { className: "flex flex-1 flex-col gap-y-8 overflow-y-auto", children: [
10935
- /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest grid grid-cols-1 divide-y rounded-lg", children: [
10936
- /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-subtle grid grid-cols-2 divide-x rounded-t-lg", children: [
10937
- /* @__PURE__ */ jsx("div", { className: "txt-compact-small-plus text-ui-fg-subtle px-2 py-1.5", children: /* @__PURE__ */ jsx("label", { id: METADATA_KEY_LABEL_ID, children: "Key" }) }),
10938
- /* @__PURE__ */ jsx("div", { className: "txt-compact-small-plus text-ui-fg-subtle px-2 py-1.5", children: /* @__PURE__ */ jsx("label", { id: METADATA_VALUE_LABEL_ID, children: "Value" }) })
10939
- ] }),
10940
- fields.map((field, index) => {
10941
- const isDisabled = field.disabled || false;
10942
- let placeholder = "-";
10943
- if (typeof field.value === "object") {
10944
- placeholder = "{ ... }";
10945
- }
10946
- if (Array.isArray(field.value)) {
10947
- placeholder = "[ ... ]";
10948
- }
10949
- return /* @__PURE__ */ jsx(
10950
- ConditionalTooltip,
10951
- {
10952
- showTooltip: isDisabled,
10953
- content: "This row is disabled because it contains non-primitive data.",
10954
- children: /* @__PURE__ */ jsxs("div", { className: "group/table relative", children: [
10955
- /* @__PURE__ */ jsxs(
10956
- "div",
10957
- {
10958
- className: clx("grid grid-cols-2 divide-x", {
10959
- "overflow-hidden rounded-b-lg": index === fields.length - 1
10960
- }),
10961
- children: [
10962
- /* @__PURE__ */ jsx(
10963
- Form$2.Field,
10964
- {
10965
- control: form.control,
10966
- name: `metadata.${index}.key`,
10967
- render: ({ field: field2 }) => {
10968
- return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
10969
- GridInput,
10970
- {
10971
- "aria-labelledby": METADATA_KEY_LABEL_ID,
10972
- ...field2,
10973
- disabled: isDisabled,
10974
- placeholder: "Key"
10975
- }
10976
- ) }) });
10977
- }
10978
- }
10979
- ),
10980
- /* @__PURE__ */ jsx(
10981
- Form$2.Field,
10982
- {
10983
- control: form.control,
10984
- name: `metadata.${index}.value`,
10985
- render: ({ field: { value, ...field2 } }) => {
10986
- return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
10987
- GridInput,
10988
- {
10989
- "aria-labelledby": METADATA_VALUE_LABEL_ID,
10990
- ...field2,
10991
- value: isDisabled ? placeholder : value,
10992
- disabled: isDisabled,
10993
- placeholder: "Value"
10994
- }
10995
- ) }) });
10996
- }
10997
- }
10998
- )
10999
- ]
11000
- }
11001
- ),
11002
- /* @__PURE__ */ jsxs(DropdownMenu, { children: [
11003
- /* @__PURE__ */ jsx(
11004
- DropdownMenu.Trigger,
11005
- {
11006
- className: clx(
11007
- "invisible absolute inset-y-0 -right-2.5 my-auto group-hover/table:visible data-[state='open']:visible",
11008
- {
11009
- hidden: isDisabled
11010
- }
11011
- ),
11012
- disabled: isDisabled,
11013
- asChild: true,
11014
- children: /* @__PURE__ */ jsx(IconButton, { size: "2xsmall", children: /* @__PURE__ */ jsx(EllipsisVertical, {}) })
11015
- }
11016
- ),
11017
- /* @__PURE__ */ jsxs(DropdownMenu.Content, { children: [
11018
- /* @__PURE__ */ jsxs(
11019
- DropdownMenu.Item,
11020
- {
11021
- className: "gap-x-2",
11022
- onClick: () => insertRow(index, "above"),
11023
- children: [
11024
- /* @__PURE__ */ jsx(ArrowUpMini, { className: "text-ui-fg-subtle" }),
11025
- "Insert row above"
11026
- ]
11027
- }
11028
- ),
11029
- /* @__PURE__ */ jsxs(
11030
- DropdownMenu.Item,
11031
- {
11032
- className: "gap-x-2",
11033
- onClick: () => insertRow(index, "below"),
11034
- children: [
11035
- /* @__PURE__ */ jsx(ArrowDownMini, { className: "text-ui-fg-subtle" }),
11036
- "Insert row below"
11037
- ]
11038
- }
11039
- ),
11040
- /* @__PURE__ */ jsx(DropdownMenu.Separator, {}),
11041
- /* @__PURE__ */ jsxs(
11042
- DropdownMenu.Item,
11043
- {
11044
- className: "gap-x-2",
11045
- onClick: () => deleteRow(index),
11046
- children: [
11047
- /* @__PURE__ */ jsx(Trash, { className: "text-ui-fg-subtle" }),
11048
- "Delete row"
11049
- ]
11050
- }
11051
- )
11052
- ] })
11053
- ] })
11054
- ] })
11055
- },
11056
- field.id
11057
- );
11058
- })
11059
- ] }),
11060
- hasUneditableRows && /* @__PURE__ */ jsx(InlineTip, { variant: "warning", label: "Some rows are disabled", children: "This object contains non-primitive metadata, such as arrays or objects, that can't be edited here. To edit the disabled rows, use the API directly." })
10940
+ return /* @__PURE__ */ jsxs(KeyboundForm, { className: "flex flex-1 flex-col", onSubmit, children: [
10941
+ /* @__PURE__ */ jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-4", children: [
10942
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3", children: [
10943
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
10944
+ /* @__PURE__ */ jsx(Label$1, { size: "small", weight: "plus", htmlFor: "promotion-combobox", children: "Apply promotions" }),
10945
+ /* @__PURE__ */ jsx(Hint$1, { id: "promotion-combobox-hint", children: "Manage promotions that should be applied to the order." })
11061
10946
  ] }),
11062
- /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
11063
- /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
11064
- /* @__PURE__ */ jsx(Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
11065
- ] }) })
11066
- ]
11067
- }
11068
- ) });
11069
- };
11070
- const GridInput = forwardRef(({ className, ...props }, ref) => {
11071
- return /* @__PURE__ */ jsx(
11072
- "input",
11073
- {
11074
- ref,
11075
- ...props,
11076
- autoComplete: "off",
11077
- className: clx(
11078
- "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",
11079
- className
10947
+ /* @__PURE__ */ jsx(
10948
+ Combobox,
10949
+ {
10950
+ id: "promotion-combobox",
10951
+ "aria-describedby": "promotion-combobox-hint",
10952
+ isFetchingNextPage: comboboxData.isFetchingNextPage,
10953
+ fetchNextPage: comboboxData.fetchNextPage,
10954
+ options: comboboxData.options,
10955
+ onSearchValueChange: comboboxData.onSearchValueChange,
10956
+ searchValue: comboboxData.searchValue,
10957
+ disabled: comboboxData.disabled || isAddingPromotions,
10958
+ onChange: add,
10959
+ value: comboboxValue
10960
+ }
10961
+ )
10962
+ ] }),
10963
+ /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
10964
+ /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-2", children: promotions == null ? void 0 : promotions.map((promotion) => /* @__PURE__ */ jsx(
10965
+ PromotionItem,
10966
+ {
10967
+ promotion,
10968
+ orderId: preview.id,
10969
+ isLoading: isPending
10970
+ },
10971
+ promotion.id
10972
+ )) })
10973
+ ] }) }),
10974
+ /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
10975
+ /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
10976
+ /* @__PURE__ */ jsx(
10977
+ Button,
10978
+ {
10979
+ size: "small",
10980
+ type: "submit",
10981
+ isLoading: isSubmitting || isAddingPromotions,
10982
+ children: "Save"
10983
+ }
11080
10984
  )
11081
- }
11082
- );
11083
- });
11084
- GridInput.displayName = "MetadataForm.GridInput";
11085
- const PlaceholderInner = () => {
11086
- return /* @__PURE__ */ jsxs("div", { className: "flex flex-1 flex-col overflow-hidden", children: [
11087
- /* @__PURE__ */ jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsx(Skeleton, { className: "h-[148ox] w-full rounded-lg" }) }),
11088
- /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
11089
- /* @__PURE__ */ jsx(Skeleton, { className: "h-7 w-12 rounded-md" }),
11090
- /* @__PURE__ */ jsx(Skeleton, { className: "h-7 w-12 rounded-md" })
11091
10985
  ] }) })
11092
10986
  ] });
11093
10987
  };
11094
- const EDITABLE_TYPES = ["string", "number", "boolean"];
11095
- function getDefaultValues(metadata) {
11096
- if (!metadata || !Object.keys(metadata).length) {
11097
- return [
10988
+ const PromotionItem = ({
10989
+ promotion,
10990
+ orderId,
10991
+ isLoading
10992
+ }) => {
10993
+ var _a;
10994
+ const { mutateAsync: removePromotions, isPending } = useDraftOrderRemovePromotions(orderId);
10995
+ const onRemove = async () => {
10996
+ removePromotions(
11098
10997
  {
11099
- key: "",
11100
- value: "",
11101
- disabled: false
10998
+ promo_codes: [promotion.code]
10999
+ },
11000
+ {
11001
+ onError: (e) => {
11002
+ toast.error(e.message);
11003
+ }
11102
11004
  }
11103
- ];
11005
+ );
11006
+ };
11007
+ const displayValue = getDisplayValue(promotion);
11008
+ return /* @__PURE__ */ jsxs(
11009
+ "div",
11010
+ {
11011
+ className: clx(
11012
+ "bg-ui-bg-component shadow-elevation-card-rest flex items-center justify-between rounded-lg px-3 py-2",
11013
+ {
11014
+ "animate-pulse": isLoading
11015
+ }
11016
+ ),
11017
+ children: [
11018
+ /* @__PURE__ */ jsxs("div", { children: [
11019
+ /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: promotion.code }),
11020
+ /* @__PURE__ */ jsxs("div", { className: "text-ui-fg-subtle flex items-center gap-1.5", children: [
11021
+ displayValue && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
11022
+ /* @__PURE__ */ jsx(Text, { size: "small", leading: "compact", children: displayValue }),
11023
+ /* @__PURE__ */ jsx(Text, { size: "small", leading: "compact", children: "·" })
11024
+ ] }),
11025
+ /* @__PURE__ */ jsx(Text, { size: "small", leading: "compact", className: "capitalize", children: (_a = promotion.application_method) == null ? void 0 : _a.allocation })
11026
+ ] })
11027
+ ] }),
11028
+ /* @__PURE__ */ jsx(
11029
+ IconButton,
11030
+ {
11031
+ size: "small",
11032
+ type: "button",
11033
+ variant: "transparent",
11034
+ onClick: onRemove,
11035
+ isLoading: isPending || isLoading,
11036
+ children: /* @__PURE__ */ jsx(XMark, {})
11037
+ }
11038
+ )
11039
+ ]
11040
+ },
11041
+ promotion.id
11042
+ );
11043
+ };
11044
+ function getDisplayValue(promotion) {
11045
+ var _a, _b, _c, _d;
11046
+ const value = (_a = promotion.application_method) == null ? void 0 : _a.value;
11047
+ if (!value) {
11048
+ return null;
11104
11049
  }
11105
- return Object.entries(metadata).map(([key, value]) => {
11106
- if (!EDITABLE_TYPES.includes(typeof value)) {
11107
- return {
11108
- key,
11109
- value,
11110
- disabled: true
11111
- };
11112
- }
11113
- let stringValue = value;
11114
- if (typeof value !== "string") {
11115
- stringValue = JSON.stringify(value);
11050
+ if (((_b = promotion.application_method) == null ? void 0 : _b.type) === "fixed") {
11051
+ const currency = (_c = promotion.application_method) == null ? void 0 : _c.currency_code;
11052
+ if (!currency) {
11053
+ return null;
11116
11054
  }
11117
- return {
11118
- key,
11119
- value: stringValue,
11120
- original_key: key
11121
- };
11122
- });
11055
+ return getLocaleAmount(value, currency);
11056
+ } else if (((_d = promotion.application_method) == null ? void 0 : _d.type) === "percentage") {
11057
+ return formatPercentage(value);
11058
+ }
11059
+ return null;
11123
11060
  }
11124
- function parseValues(values) {
11125
- const metadata = values.metadata;
11126
- const isEmpty = !metadata.length || metadata.length === 1 && !metadata[0].key && !metadata[0].value;
11127
- if (isEmpty) {
11128
- return null;
11061
+ const formatter = new Intl.NumberFormat([], {
11062
+ style: "percent",
11063
+ minimumFractionDigits: 2
11064
+ });
11065
+ const formatPercentage = (value, isPercentageValue = false) => {
11066
+ let val = value || 0;
11067
+ if (!isPercentageValue) {
11068
+ val = val / 100;
11129
11069
  }
11130
- const update = {};
11131
- metadata.forEach((field) => {
11132
- let key = field.key;
11133
- let value = field.value;
11134
- const disabled = field.disabled;
11135
- if (!key || !value) {
11136
- return;
11137
- }
11138
- if (disabled) {
11139
- update[key] = value;
11140
- return;
11070
+ return formatter.format(val);
11071
+ };
11072
+ function getPromotionIds(items, shippingMethods) {
11073
+ const promotionIds = /* @__PURE__ */ new Set();
11074
+ for (const item of items) {
11075
+ if (item.adjustments) {
11076
+ for (const adjustment of item.adjustments) {
11077
+ if (adjustment.promotion_id) {
11078
+ promotionIds.add(adjustment.promotion_id);
11079
+ }
11080
+ }
11141
11081
  }
11142
- key = key.trim();
11143
- value = value.trim();
11144
- if (value === "true") {
11145
- update[key] = true;
11146
- } else if (value === "false") {
11147
- update[key] = false;
11148
- } else {
11149
- const parsedNumber = parseFloat(value);
11150
- if (!isNaN(parsedNumber)) {
11151
- update[key] = parsedNumber;
11152
- } else {
11153
- update[key] = value;
11082
+ }
11083
+ for (const shippingMethod of shippingMethods) {
11084
+ if (shippingMethod.adjustments) {
11085
+ for (const adjustment of shippingMethod.adjustments) {
11086
+ if (adjustment.promotion_id) {
11087
+ promotionIds.add(adjustment.promotion_id);
11088
+ }
11154
11089
  }
11155
11090
  }
11156
- });
11157
- return update;
11158
- }
11159
- function getHasUneditableRows(metadata) {
11160
- if (!metadata) {
11161
- return false;
11162
11091
  }
11163
- return Object.values(metadata).some(
11164
- (value) => !EDITABLE_TYPES.includes(typeof value)
11165
- );
11092
+ return Array.from(promotionIds);
11166
11093
  }
11167
- const PROMOTION_QUERY_KEY = "promotions";
11168
- const promotionsQueryKeys = {
11169
- list: (query2) => [
11170
- PROMOTION_QUERY_KEY,
11171
- query2 ? query2 : void 0
11172
- ],
11173
- detail: (id, query2) => [
11174
- PROMOTION_QUERY_KEY,
11175
- id,
11176
- query2 ? query2 : void 0
11177
- ]
11178
- };
11179
- const usePromotions = (query2, options) => {
11180
- const { data, ...rest } = useQuery({
11181
- queryKey: promotionsQueryKeys.list(query2),
11182
- queryFn: async () => sdk.admin.promotion.list(query2),
11183
- ...options
11184
- });
11185
- return { ...data, ...rest };
11186
- };
11187
- const Promotions = () => {
11094
+ const InlineTip = forwardRef(
11095
+ ({ variant = "tip", label, className, children, ...props }, ref) => {
11096
+ const labelValue = label || (variant === "warning" ? "Warning" : "Tip");
11097
+ return /* @__PURE__ */ jsxs(
11098
+ "div",
11099
+ {
11100
+ ref,
11101
+ className: clx(
11102
+ "bg-ui-bg-component txt-small text-ui-fg-subtle grid grid-cols-[4px_1fr] items-start gap-3 rounded-lg border p-3",
11103
+ className
11104
+ ),
11105
+ ...props,
11106
+ children: [
11107
+ /* @__PURE__ */ jsx(
11108
+ "div",
11109
+ {
11110
+ role: "presentation",
11111
+ className: clx("w-4px bg-ui-tag-neutral-icon h-full rounded-full", {
11112
+ "bg-ui-tag-orange-icon": variant === "warning"
11113
+ })
11114
+ }
11115
+ ),
11116
+ /* @__PURE__ */ jsxs("div", { className: "text-pretty", children: [
11117
+ /* @__PURE__ */ jsxs("strong", { className: "txt-small-plus text-ui-fg-base", children: [
11118
+ labelValue,
11119
+ ":"
11120
+ ] }),
11121
+ " ",
11122
+ children
11123
+ ] })
11124
+ ]
11125
+ }
11126
+ );
11127
+ }
11128
+ );
11129
+ InlineTip.displayName = "InlineTip";
11130
+ const MetadataFieldSchema = objectType({
11131
+ key: stringType(),
11132
+ disabled: booleanType().optional(),
11133
+ value: anyType()
11134
+ });
11135
+ const MetadataSchema = objectType({
11136
+ metadata: arrayType(MetadataFieldSchema)
11137
+ });
11138
+ const Metadata = () => {
11188
11139
  const { id } = useParams();
11189
- const {
11190
- order: preview,
11191
- isError: isPreviewError,
11192
- error: previewError
11193
- } = useOrderPreview(id, void 0);
11194
- useInitiateOrderEdit({ preview });
11195
- const { onCancel } = useCancelOrderEdit({ preview });
11196
- if (isPreviewError) {
11197
- throw previewError;
11140
+ const { order, isPending, isError, error } = useOrder(id, {
11141
+ fields: "metadata"
11142
+ });
11143
+ if (isError) {
11144
+ throw error;
11198
11145
  }
11199
- const isReady = !!preview;
11200
- return /* @__PURE__ */ jsxs(RouteDrawer, { onClose: onCancel, children: [
11201
- /* @__PURE__ */ jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Promotions" }) }) }),
11202
- isReady && /* @__PURE__ */ jsx(PromotionForm, { preview })
11146
+ const isReady = !isPending && !!order;
11147
+ return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
11148
+ /* @__PURE__ */ jsxs(RouteDrawer.Header, { children: [
11149
+ /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Metadata" }) }),
11150
+ /* @__PURE__ */ jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Add metadata to the draft order." }) })
11151
+ ] }),
11152
+ !isReady ? /* @__PURE__ */ jsx(PlaceholderInner, {}) : /* @__PURE__ */ jsx(MetadataForm, { orderId: id, metadata: order == null ? void 0 : order.metadata })
11203
11153
  ] });
11204
11154
  };
11205
- const PromotionForm = ({ preview }) => {
11206
- const { items, shipping_methods } = preview;
11207
- const [isSubmitting, setIsSubmitting] = useState(false);
11208
- const [comboboxValue, setComboboxValue] = useState("");
11155
+ const METADATA_KEY_LABEL_ID = "metadata-form-key-label";
11156
+ const METADATA_VALUE_LABEL_ID = "metadata-form-value-label";
11157
+ const MetadataForm = ({ orderId, metadata }) => {
11209
11158
  const { handleSuccess } = useRouteModal();
11210
- const { mutateAsync: addPromotions, isPending: isAddingPromotions } = useDraftOrderAddPromotions(preview.id);
11211
- const promoIds = getPromotionIds(items, shipping_methods);
11212
- const { promotions, isPending, isError, error } = usePromotions(
11213
- {
11214
- id: promoIds
11215
- },
11216
- {
11217
- enabled: !!promoIds.length
11218
- }
11219
- );
11220
- const comboboxData = useComboboxData({
11221
- queryKey: ["promotions", "combobox", promoIds],
11222
- queryFn: async (params) => {
11223
- return await sdk.admin.promotion.list({
11224
- ...params,
11225
- id: {
11226
- $nin: promoIds
11227
- }
11228
- });
11159
+ const hasUneditableRows = getHasUneditableRows(metadata);
11160
+ const { mutateAsync, isPending } = useUpdateDraftOrder(orderId);
11161
+ const form = useForm({
11162
+ defaultValues: {
11163
+ metadata: getDefaultValues(metadata)
11229
11164
  },
11230
- getOptions: (data) => {
11231
- return data.promotions.map((promotion) => ({
11232
- label: promotion.code,
11233
- value: promotion.code
11234
- }));
11235
- }
11165
+ resolver: zodResolver(MetadataSchema)
11236
11166
  });
11237
- const add = async (value) => {
11238
- if (!value) {
11239
- return;
11240
- }
11241
- addPromotions(
11167
+ const handleSubmit = form.handleSubmit(async (data) => {
11168
+ const parsedData = parseValues(data);
11169
+ await mutateAsync(
11242
11170
  {
11243
- promo_codes: [value]
11171
+ metadata: parsedData
11244
11172
  },
11245
11173
  {
11246
- onError: (e) => {
11247
- toast.error(e.message);
11248
- comboboxData.onSearchValueChange("");
11249
- setComboboxValue("");
11250
- },
11251
11174
  onSuccess: () => {
11252
- comboboxData.onSearchValueChange("");
11253
- setComboboxValue("");
11175
+ toast.success("Metadata updated");
11176
+ handleSuccess();
11177
+ },
11178
+ onError: (error) => {
11179
+ toast.error(error.message);
11254
11180
  }
11255
11181
  }
11256
11182
  );
11257
- };
11258
- const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
11259
- const { mutateAsync: requestOrderEdit } = useOrderEditRequest(preview.id);
11260
- const onSubmit = async () => {
11261
- setIsSubmitting(true);
11262
- let requestSucceeded = false;
11263
- await requestOrderEdit(void 0, {
11264
- onError: (e) => {
11265
- toast.error(e.message);
11266
- },
11267
- onSuccess: () => {
11268
- requestSucceeded = true;
11269
- }
11270
- });
11271
- if (!requestSucceeded) {
11272
- setIsSubmitting(false);
11273
- return;
11183
+ });
11184
+ const { fields, insert, remove } = useFieldArray({
11185
+ control: form.control,
11186
+ name: "metadata"
11187
+ });
11188
+ function deleteRow(index) {
11189
+ remove(index);
11190
+ if (fields.length === 1) {
11191
+ insert(0, {
11192
+ key: "",
11193
+ value: "",
11194
+ disabled: false
11195
+ });
11274
11196
  }
11275
- await confirmOrderEdit(void 0, {
11276
- onError: (e) => {
11277
- toast.error(e.message);
11278
- },
11279
- onSuccess: () => {
11280
- handleSuccess();
11281
- },
11282
- onSettled: () => {
11283
- setIsSubmitting(false);
11284
- }
11197
+ }
11198
+ function insertRow(index, position) {
11199
+ insert(index + (position === "above" ? 0 : 1), {
11200
+ key: "",
11201
+ value: "",
11202
+ disabled: false
11285
11203
  });
11286
- };
11287
- if (isError) {
11288
- throw error;
11289
11204
  }
11290
- return /* @__PURE__ */ jsxs(KeyboundForm, { className: "flex flex-1 flex-col", onSubmit, children: [
11291
- /* @__PURE__ */ jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-4", children: [
11292
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3", children: [
11293
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
11294
- /* @__PURE__ */ jsx(Label$1, { size: "small", weight: "plus", htmlFor: "promotion-combobox", children: "Apply promotions" }),
11295
- /* @__PURE__ */ jsx(Hint$1, { id: "promotion-combobox-hint", children: "Manage promotions that should be applied to the order." })
11296
- ] }),
11297
- /* @__PURE__ */ jsx(
11298
- Combobox,
11299
- {
11300
- id: "promotion-combobox",
11301
- "aria-describedby": "promotion-combobox-hint",
11302
- isFetchingNextPage: comboboxData.isFetchingNextPage,
11303
- fetchNextPage: comboboxData.fetchNextPage,
11304
- options: comboboxData.options,
11305
- onSearchValueChange: comboboxData.onSearchValueChange,
11306
- searchValue: comboboxData.searchValue,
11307
- disabled: comboboxData.disabled || isAddingPromotions,
11308
- onChange: add,
11309
- value: comboboxValue
11310
- }
11311
- )
11312
- ] }),
11313
- /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
11314
- /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-2", children: promotions == null ? void 0 : promotions.map((promotion) => /* @__PURE__ */ jsx(
11315
- PromotionItem,
11316
- {
11317
- promotion,
11318
- orderId: preview.id,
11319
- isLoading: isPending
11320
- },
11321
- promotion.id
11322
- )) })
11323
- ] }) }),
11324
- /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
11325
- /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
11326
- /* @__PURE__ */ jsx(
11327
- Button,
11328
- {
11329
- size: "small",
11330
- type: "submit",
11331
- isLoading: isSubmitting || isAddingPromotions,
11332
- children: "Save"
11333
- }
11334
- )
11335
- ] }) })
11336
- ] });
11337
- };
11338
- const PromotionItem = ({
11339
- promotion,
11340
- orderId,
11341
- isLoading
11342
- }) => {
11343
- var _a;
11344
- const { mutateAsync: removePromotions, isPending } = useDraftOrderRemovePromotions(orderId);
11345
- const onRemove = async () => {
11346
- removePromotions(
11347
- {
11348
- promo_codes: [promotion.code]
11349
- },
11350
- {
11351
- onError: (e) => {
11352
- toast.error(e.message);
11353
- }
11354
- }
11355
- );
11356
- };
11357
- const displayValue = getDisplayValue(promotion);
11358
- return /* @__PURE__ */ jsxs(
11359
- "div",
11205
+ return /* @__PURE__ */ jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxs(
11206
+ KeyboundForm,
11360
11207
  {
11361
- className: clx(
11362
- "bg-ui-bg-component shadow-elevation-card-rest flex items-center justify-between rounded-lg px-3 py-2",
11363
- {
11364
- "animate-pulse": isLoading
11365
- }
11366
- ),
11208
+ onSubmit: handleSubmit,
11209
+ className: "flex flex-1 flex-col overflow-hidden",
11367
11210
  children: [
11368
- /* @__PURE__ */ jsxs("div", { children: [
11369
- /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: promotion.code }),
11370
- /* @__PURE__ */ jsxs("div", { className: "text-ui-fg-subtle flex items-center gap-1.5", children: [
11371
- displayValue && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
11372
- /* @__PURE__ */ jsx(Text, { size: "small", leading: "compact", children: displayValue }),
11373
- /* @__PURE__ */ jsx(Text, { size: "small", leading: "compact", children: "·" })
11211
+ /* @__PURE__ */ jsxs(RouteDrawer.Body, { className: "flex flex-1 flex-col gap-y-8 overflow-y-auto", children: [
11212
+ /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest grid grid-cols-1 divide-y rounded-lg", children: [
11213
+ /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-subtle grid grid-cols-2 divide-x rounded-t-lg", children: [
11214
+ /* @__PURE__ */ jsx("div", { className: "txt-compact-small-plus text-ui-fg-subtle px-2 py-1.5", children: /* @__PURE__ */ jsx("label", { id: METADATA_KEY_LABEL_ID, children: "Key" }) }),
11215
+ /* @__PURE__ */ jsx("div", { className: "txt-compact-small-plus text-ui-fg-subtle px-2 py-1.5", children: /* @__PURE__ */ jsx("label", { id: METADATA_VALUE_LABEL_ID, children: "Value" }) })
11374
11216
  ] }),
11375
- /* @__PURE__ */ jsx(Text, { size: "small", leading: "compact", className: "capitalize", children: (_a = promotion.application_method) == null ? void 0 : _a.allocation })
11376
- ] })
11217
+ fields.map((field, index) => {
11218
+ const isDisabled = field.disabled || false;
11219
+ let placeholder = "-";
11220
+ if (typeof field.value === "object") {
11221
+ placeholder = "{ ... }";
11222
+ }
11223
+ if (Array.isArray(field.value)) {
11224
+ placeholder = "[ ... ]";
11225
+ }
11226
+ return /* @__PURE__ */ jsx(
11227
+ ConditionalTooltip,
11228
+ {
11229
+ showTooltip: isDisabled,
11230
+ content: "This row is disabled because it contains non-primitive data.",
11231
+ children: /* @__PURE__ */ jsxs("div", { className: "group/table relative", children: [
11232
+ /* @__PURE__ */ jsxs(
11233
+ "div",
11234
+ {
11235
+ className: clx("grid grid-cols-2 divide-x", {
11236
+ "overflow-hidden rounded-b-lg": index === fields.length - 1
11237
+ }),
11238
+ children: [
11239
+ /* @__PURE__ */ jsx(
11240
+ Form$2.Field,
11241
+ {
11242
+ control: form.control,
11243
+ name: `metadata.${index}.key`,
11244
+ render: ({ field: field2 }) => {
11245
+ return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
11246
+ GridInput,
11247
+ {
11248
+ "aria-labelledby": METADATA_KEY_LABEL_ID,
11249
+ ...field2,
11250
+ disabled: isDisabled,
11251
+ placeholder: "Key"
11252
+ }
11253
+ ) }) });
11254
+ }
11255
+ }
11256
+ ),
11257
+ /* @__PURE__ */ jsx(
11258
+ Form$2.Field,
11259
+ {
11260
+ control: form.control,
11261
+ name: `metadata.${index}.value`,
11262
+ render: ({ field: { value, ...field2 } }) => {
11263
+ return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
11264
+ GridInput,
11265
+ {
11266
+ "aria-labelledby": METADATA_VALUE_LABEL_ID,
11267
+ ...field2,
11268
+ value: isDisabled ? placeholder : value,
11269
+ disabled: isDisabled,
11270
+ placeholder: "Value"
11271
+ }
11272
+ ) }) });
11273
+ }
11274
+ }
11275
+ )
11276
+ ]
11277
+ }
11278
+ ),
11279
+ /* @__PURE__ */ jsxs(DropdownMenu, { children: [
11280
+ /* @__PURE__ */ jsx(
11281
+ DropdownMenu.Trigger,
11282
+ {
11283
+ className: clx(
11284
+ "invisible absolute inset-y-0 -right-2.5 my-auto group-hover/table:visible data-[state='open']:visible",
11285
+ {
11286
+ hidden: isDisabled
11287
+ }
11288
+ ),
11289
+ disabled: isDisabled,
11290
+ asChild: true,
11291
+ children: /* @__PURE__ */ jsx(IconButton, { size: "2xsmall", children: /* @__PURE__ */ jsx(EllipsisVertical, {}) })
11292
+ }
11293
+ ),
11294
+ /* @__PURE__ */ jsxs(DropdownMenu.Content, { children: [
11295
+ /* @__PURE__ */ jsxs(
11296
+ DropdownMenu.Item,
11297
+ {
11298
+ className: "gap-x-2",
11299
+ onClick: () => insertRow(index, "above"),
11300
+ children: [
11301
+ /* @__PURE__ */ jsx(ArrowUpMini, { className: "text-ui-fg-subtle" }),
11302
+ "Insert row above"
11303
+ ]
11304
+ }
11305
+ ),
11306
+ /* @__PURE__ */ jsxs(
11307
+ DropdownMenu.Item,
11308
+ {
11309
+ className: "gap-x-2",
11310
+ onClick: () => insertRow(index, "below"),
11311
+ children: [
11312
+ /* @__PURE__ */ jsx(ArrowDownMini, { className: "text-ui-fg-subtle" }),
11313
+ "Insert row below"
11314
+ ]
11315
+ }
11316
+ ),
11317
+ /* @__PURE__ */ jsx(DropdownMenu.Separator, {}),
11318
+ /* @__PURE__ */ jsxs(
11319
+ DropdownMenu.Item,
11320
+ {
11321
+ className: "gap-x-2",
11322
+ onClick: () => deleteRow(index),
11323
+ children: [
11324
+ /* @__PURE__ */ jsx(Trash, { className: "text-ui-fg-subtle" }),
11325
+ "Delete row"
11326
+ ]
11327
+ }
11328
+ )
11329
+ ] })
11330
+ ] })
11331
+ ] })
11332
+ },
11333
+ field.id
11334
+ );
11335
+ })
11336
+ ] }),
11337
+ hasUneditableRows && /* @__PURE__ */ jsx(InlineTip, { variant: "warning", label: "Some rows are disabled", children: "This object contains non-primitive metadata, such as arrays or objects, that can't be edited here. To edit the disabled rows, use the API directly." })
11377
11338
  ] }),
11378
- /* @__PURE__ */ jsx(
11379
- IconButton,
11380
- {
11381
- size: "small",
11382
- type: "button",
11383
- variant: "transparent",
11384
- onClick: onRemove,
11385
- isLoading: isPending || isLoading,
11386
- children: /* @__PURE__ */ jsx(XMark, {})
11387
- }
11388
- )
11339
+ /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
11340
+ /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
11341
+ /* @__PURE__ */ jsx(Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
11342
+ ] }) })
11389
11343
  ]
11390
- },
11391
- promotion.id
11392
- );
11393
- };
11394
- function getDisplayValue(promotion) {
11395
- var _a, _b, _c, _d;
11396
- const value = (_a = promotion.application_method) == null ? void 0 : _a.value;
11397
- if (!value) {
11398
- return null;
11399
- }
11400
- if (((_b = promotion.application_method) == null ? void 0 : _b.type) === "fixed") {
11401
- const currency = (_c = promotion.application_method) == null ? void 0 : _c.currency_code;
11402
- if (!currency) {
11403
- return null;
11404
11344
  }
11405
- return getLocaleAmount(value, currency);
11406
- } else if (((_d = promotion.application_method) == null ? void 0 : _d.type) === "percentage") {
11407
- return formatPercentage(value);
11408
- }
11409
- return null;
11410
- }
11411
- const formatter = new Intl.NumberFormat([], {
11412
- style: "percent",
11413
- minimumFractionDigits: 2
11414
- });
11415
- const formatPercentage = (value, isPercentageValue = false) => {
11416
- let val = value || 0;
11417
- if (!isPercentageValue) {
11418
- val = val / 100;
11419
- }
11420
- return formatter.format(val);
11345
+ ) });
11421
11346
  };
11422
- function getPromotionIds(items, shippingMethods) {
11423
- const promotionIds = /* @__PURE__ */ new Set();
11424
- for (const item of items) {
11425
- if (item.adjustments) {
11426
- for (const adjustment of item.adjustments) {
11427
- if (adjustment.promotion_id) {
11428
- promotionIds.add(adjustment.promotion_id);
11429
- }
11347
+ const GridInput = forwardRef(({ className, ...props }, ref) => {
11348
+ return /* @__PURE__ */ jsx(
11349
+ "input",
11350
+ {
11351
+ ref,
11352
+ ...props,
11353
+ autoComplete: "off",
11354
+ className: clx(
11355
+ "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",
11356
+ className
11357
+ )
11358
+ }
11359
+ );
11360
+ });
11361
+ GridInput.displayName = "MetadataForm.GridInput";
11362
+ const PlaceholderInner = () => {
11363
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-1 flex-col overflow-hidden", children: [
11364
+ /* @__PURE__ */ jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsx(Skeleton, { className: "h-[148ox] w-full rounded-lg" }) }),
11365
+ /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
11366
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-7 w-12 rounded-md" }),
11367
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-7 w-12 rounded-md" })
11368
+ ] }) })
11369
+ ] });
11370
+ };
11371
+ const EDITABLE_TYPES = ["string", "number", "boolean"];
11372
+ function getDefaultValues(metadata) {
11373
+ if (!metadata || !Object.keys(metadata).length) {
11374
+ return [
11375
+ {
11376
+ key: "",
11377
+ value: "",
11378
+ disabled: false
11430
11379
  }
11380
+ ];
11381
+ }
11382
+ return Object.entries(metadata).map(([key, value]) => {
11383
+ if (!EDITABLE_TYPES.includes(typeof value)) {
11384
+ return {
11385
+ key,
11386
+ value,
11387
+ disabled: true
11388
+ };
11389
+ }
11390
+ let stringValue = value;
11391
+ if (typeof value !== "string") {
11392
+ stringValue = JSON.stringify(value);
11431
11393
  }
11394
+ return {
11395
+ key,
11396
+ value: stringValue,
11397
+ original_key: key
11398
+ };
11399
+ });
11400
+ }
11401
+ function parseValues(values) {
11402
+ const metadata = values.metadata;
11403
+ const isEmpty = !metadata.length || metadata.length === 1 && !metadata[0].key && !metadata[0].value;
11404
+ if (isEmpty) {
11405
+ return null;
11432
11406
  }
11433
- for (const shippingMethod of shippingMethods) {
11434
- if (shippingMethod.adjustments) {
11435
- for (const adjustment of shippingMethod.adjustments) {
11436
- if (adjustment.promotion_id) {
11437
- promotionIds.add(adjustment.promotion_id);
11438
- }
11407
+ const update = {};
11408
+ metadata.forEach((field) => {
11409
+ let key = field.key;
11410
+ let value = field.value;
11411
+ const disabled = field.disabled;
11412
+ if (!key || !value) {
11413
+ return;
11414
+ }
11415
+ if (disabled) {
11416
+ update[key] = value;
11417
+ return;
11418
+ }
11419
+ key = key.trim();
11420
+ value = value.trim();
11421
+ if (value === "true") {
11422
+ update[key] = true;
11423
+ } else if (value === "false") {
11424
+ update[key] = false;
11425
+ } else {
11426
+ const parsedNumber = parseFloat(value);
11427
+ if (!isNaN(parsedNumber)) {
11428
+ update[key] = parsedNumber;
11429
+ } else {
11430
+ update[key] = value;
11439
11431
  }
11440
11432
  }
11433
+ });
11434
+ return update;
11435
+ }
11436
+ function getHasUneditableRows(metadata) {
11437
+ if (!metadata) {
11438
+ return false;
11441
11439
  }
11442
- return Array.from(promotionIds);
11440
+ return Object.values(metadata).some(
11441
+ (value) => !EDITABLE_TYPES.includes(typeof value)
11442
+ );
11443
11443
  }
11444
- const STACKED_FOCUS_MODAL_ID = "shipping-form";
11445
- const Shipping = () => {
11446
- var _a;
11444
+ const SalesChannel = () => {
11447
11445
  const { id } = useParams();
11448
- const { order, isPending, isError, error } = useOrder(id, {
11449
- fields: "+items.*,+items.variant.*,+items.variant.product.*,+items.variant.product.shipping_profile.*,+currency_code"
11450
- });
11451
- const {
11452
- order: preview,
11453
- isPending: isPreviewPending,
11454
- isError: isPreviewError,
11455
- error: previewError
11456
- } = useOrderPreview(id);
11457
- useInitiateOrderEdit({ preview });
11458
- const { onCancel } = useCancelOrderEdit({ preview });
11459
- if (isError) {
11460
- throw error;
11461
- }
11462
- if (isPreviewError) {
11463
- throw previewError;
11464
- }
11465
- const orderHasItems = (((_a = order == null ? void 0 : order.items) == null ? void 0 : _a.length) || 0) > 0;
11466
- const isReady = preview && !isPreviewPending && order && !isPending;
11467
- return /* @__PURE__ */ jsx(RouteFocusModal, { onClose: onCancel, children: !orderHasItems ? /* @__PURE__ */ jsxs("div", { className: "flex h-full flex-col overflow-hidden ", children: [
11468
- /* @__PURE__ */ jsx(RouteFocusModal.Header, {}),
11469
- /* @__PURE__ */ jsx(RouteFocusModal.Body, { className: "flex flex-1 flex-col overflow-hidden", children: /* @__PURE__ */ jsx("div", { className: "flex flex-1 flex-col items-center overflow-y-auto", children: /* @__PURE__ */ jsxs("div", { className: "flex w-full max-w-[720px] flex-col gap-y-6 px-6 py-16", children: [
11470
- /* @__PURE__ */ jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Shipping" }) }),
11471
- /* @__PURE__ */ jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "This draft order currently has no items. Add items to the order before adding shipping." }) })
11472
- ] }) }) }),
11473
- /* @__PURE__ */ jsx(RouteFocusModal.Footer, { children: /* @__PURE__ */ jsx(RouteFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }) })
11474
- ] }) : isReady ? /* @__PURE__ */ jsx(ShippingForm, { preview, order }) : /* @__PURE__ */ jsxs("div", { children: [
11475
- /* @__PURE__ */ jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Edit Shipping" }) }),
11476
- /* @__PURE__ */ jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Loading data for the draft order, please wait..." }) })
11477
- ] }) });
11478
- };
11479
- const ShippingForm = ({ preview, order }) => {
11480
- var _a;
11481
- const { setIsOpen } = useStackedModal();
11482
- const [isSubmitting, setIsSubmitting] = useState(false);
11483
- const [data, setData] = useState(null);
11484
- const appliedShippingOptionIds = (_a = preview.shipping_methods) == null ? void 0 : _a.map((method) => method.shipping_option_id).filter(Boolean);
11485
- const { shipping_options } = useShippingOptions(
11446
+ const { draft_order, isPending, isError, error } = useDraftOrder(
11447
+ id,
11486
11448
  {
11487
- id: appliedShippingOptionIds,
11488
- fields: "+service_zone.*,+service_zone.fulfillment_set.*,+service_zone.fulfillment_set.location.*"
11449
+ fields: "+sales_channel_id"
11489
11450
  },
11490
11451
  {
11491
- enabled: appliedShippingOptionIds.length > 0
11452
+ enabled: !!id
11492
11453
  }
11493
11454
  );
11494
- const uniqueShippingProfiles = useMemo(() => {
11495
- const profiles = /* @__PURE__ */ new Map();
11496
- getUniqueShippingProfiles(order.items).forEach((profile) => {
11497
- profiles.set(profile.id, profile);
11498
- });
11499
- shipping_options == null ? void 0 : shipping_options.forEach((option) => {
11500
- profiles.set(option.shipping_profile_id, option.shipping_profile);
11501
- });
11502
- return Array.from(profiles.values());
11503
- }, [order.items, shipping_options]);
11455
+ if (isError) {
11456
+ throw error;
11457
+ }
11458
+ const ISrEADY = !!draft_order && !isPending;
11459
+ return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
11460
+ /* @__PURE__ */ jsxs(RouteDrawer.Header, { children: [
11461
+ /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Sales Channel" }) }),
11462
+ /* @__PURE__ */ jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Update which sales channel the draft order is associated with" }) })
11463
+ ] }),
11464
+ ISrEADY && /* @__PURE__ */ jsx(SalesChannelForm, { order: draft_order })
11465
+ ] });
11466
+ };
11467
+ const SalesChannelForm = ({ order }) => {
11468
+ const form = useForm({
11469
+ defaultValues: {
11470
+ sales_channel_id: order.sales_channel_id || ""
11471
+ },
11472
+ resolver: zodResolver(schema$2)
11473
+ });
11474
+ const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
11504
11475
  const { handleSuccess } = useRouteModal();
11505
- const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
11506
- const { mutateAsync: requestOrderEdit } = useDraftOrderRequestEdit(preview.id);
11507
- const { mutateAsync: removeShippingMethod } = useDraftOrderRemoveShippingMethod(preview.id);
11508
- const { mutateAsync: removeActionShippingMethod } = useDraftOrderRemoveActionShippingMethod(preview.id);
11509
- const onSubmit = async () => {
11510
- setIsSubmitting(true);
11511
- let requestSucceeded = false;
11512
- await requestOrderEdit(void 0, {
11513
- onError: (e) => {
11514
- toast.error(`Failed to request order edit: ${e.message}`);
11515
- },
11516
- onSuccess: () => {
11517
- requestSucceeded = true;
11518
- }
11519
- });
11520
- if (!requestSucceeded) {
11521
- setIsSubmitting(false);
11522
- return;
11523
- }
11524
- await confirmOrderEdit(void 0, {
11525
- onError: (e) => {
11526
- toast.error(`Failed to confirm order edit: ${e.message}`);
11527
- },
11528
- onSuccess: () => {
11529
- handleSuccess();
11476
+ const onSubmit = form.handleSubmit(async (data) => {
11477
+ await mutateAsync(
11478
+ {
11479
+ sales_channel_id: data.sales_channel_id
11530
11480
  },
11531
- onSettled: () => {
11532
- setIsSubmitting(false);
11533
- }
11534
- });
11535
- };
11536
- const onKeydown = useCallback(
11537
- (e) => {
11538
- if (e.key === "Enter" && (e.ctrlKey || e.metaKey)) {
11539
- if (data || isSubmitting) {
11540
- return;
11481
+ {
11482
+ onSuccess: () => {
11483
+ toast.success("Sales channel updated");
11484
+ handleSuccess();
11485
+ },
11486
+ onError: (error) => {
11487
+ toast.error(error.message);
11541
11488
  }
11542
- onSubmit();
11543
11489
  }
11490
+ );
11491
+ });
11492
+ return /* @__PURE__ */ jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxs(
11493
+ KeyboundForm,
11494
+ {
11495
+ className: "flex flex-1 flex-col overflow-hidden",
11496
+ onSubmit,
11497
+ children: [
11498
+ /* @__PURE__ */ jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsx(SalesChannelField, { control: form.control, order }) }),
11499
+ /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
11500
+ /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
11501
+ /* @__PURE__ */ jsx(Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
11502
+ ] }) })
11503
+ ]
11504
+ }
11505
+ ) });
11506
+ };
11507
+ const SalesChannelField = ({ control, order }) => {
11508
+ const salesChannels = useComboboxData({
11509
+ queryFn: async (params) => {
11510
+ return await sdk.admin.salesChannel.list(params);
11544
11511
  },
11545
- [data, isSubmitting, onSubmit]
11546
- );
11547
- useEffect(() => {
11548
- document.addEventListener("keydown", onKeydown);
11549
- return () => {
11550
- document.removeEventListener("keydown", onKeydown);
11551
- };
11552
- }, [onKeydown]);
11553
- return /* @__PURE__ */ jsxs("div", { className: "flex h-full flex-col overflow-hidden", children: [
11554
- /* @__PURE__ */ jsx(RouteFocusModal.Header, {}),
11555
- /* @__PURE__ */ jsxs(RouteFocusModal.Body, { className: "flex flex-1 flex-col overflow-hidden", children: [
11556
- /* @__PURE__ */ jsx("div", { className: "flex flex-1 flex-col items-center overflow-y-auto", children: /* @__PURE__ */ jsxs("div", { className: "flex w-full max-w-[720px] flex-col gap-y-6 px-6 py-16", children: [
11557
- /* @__PURE__ */ jsxs("div", { children: [
11558
- /* @__PURE__ */ jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Shipping" }) }),
11559
- /* @__PURE__ */ jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Choose which shipping method(s) to use for the items in the order." }) })
11560
- ] }),
11561
- /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
11562
- /* @__PURE__ */ jsx(Accordion.Root, { type: "multiple", children: /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-subtle shadow-elevation-card-rest rounded-xl", children: [
11563
- /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between px-4 py-2", children: [
11512
+ queryKey: ["sales-channels"],
11513
+ getOptions: (data) => {
11514
+ return data.sales_channels.map((salesChannel) => ({
11515
+ label: salesChannel.name,
11516
+ value: salesChannel.id
11517
+ }));
11518
+ },
11519
+ defaultValue: order.sales_channel_id || void 0
11520
+ });
11521
+ return /* @__PURE__ */ jsx(
11522
+ Form$2.Field,
11523
+ {
11524
+ control,
11525
+ name: "sales_channel_id",
11526
+ render: ({ field }) => {
11527
+ return /* @__PURE__ */ jsxs(Form$2.Item, { children: [
11528
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Sales Channel" }),
11529
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
11530
+ Combobox,
11531
+ {
11532
+ options: salesChannels.options,
11533
+ fetchNextPage: salesChannels.fetchNextPage,
11534
+ isFetchingNextPage: salesChannels.isFetchingNextPage,
11535
+ searchValue: salesChannels.searchValue,
11536
+ onSearchValueChange: salesChannels.onSearchValueChange,
11537
+ placeholder: "Select sales channel",
11538
+ ...field
11539
+ }
11540
+ ) }),
11541
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11542
+ ] });
11543
+ }
11544
+ }
11545
+ );
11546
+ };
11547
+ const schema$2 = objectType({
11548
+ sales_channel_id: stringType().min(1)
11549
+ });
11550
+ const ShippingAddress = () => {
11551
+ const { id } = useParams();
11552
+ const { order, isPending, isError, error } = useOrder(id, {
11553
+ fields: "+shipping_address"
11554
+ });
11555
+ if (isError) {
11556
+ throw error;
11557
+ }
11558
+ const isReady = !isPending && !!order;
11559
+ return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
11560
+ /* @__PURE__ */ jsxs(RouteDrawer.Header, { children: [
11561
+ /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Shipping Address" }) }),
11562
+ /* @__PURE__ */ jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Edit the shipping address for the draft order" }) })
11563
+ ] }),
11564
+ isReady && /* @__PURE__ */ jsx(ShippingAddressForm, { order })
11565
+ ] });
11566
+ };
11567
+ const ShippingAddressForm = ({ order }) => {
11568
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
11569
+ const form = useForm({
11570
+ defaultValues: {
11571
+ first_name: ((_a = order.shipping_address) == null ? void 0 : _a.first_name) ?? "",
11572
+ last_name: ((_b = order.shipping_address) == null ? void 0 : _b.last_name) ?? "",
11573
+ company: ((_c = order.shipping_address) == null ? void 0 : _c.company) ?? "",
11574
+ address_1: ((_d = order.shipping_address) == null ? void 0 : _d.address_1) ?? "",
11575
+ address_2: ((_e = order.shipping_address) == null ? void 0 : _e.address_2) ?? "",
11576
+ city: ((_f = order.shipping_address) == null ? void 0 : _f.city) ?? "",
11577
+ province: ((_g = order.shipping_address) == null ? void 0 : _g.province) ?? "",
11578
+ country_code: ((_h = order.shipping_address) == null ? void 0 : _h.country_code) ?? "",
11579
+ postal_code: ((_i = order.shipping_address) == null ? void 0 : _i.postal_code) ?? "",
11580
+ phone: ((_j = order.shipping_address) == null ? void 0 : _j.phone) ?? ""
11581
+ },
11582
+ resolver: zodResolver(schema$1)
11583
+ });
11584
+ const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
11585
+ const { handleSuccess } = useRouteModal();
11586
+ const onSubmit = form.handleSubmit(async (data) => {
11587
+ await mutateAsync(
11588
+ {
11589
+ shipping_address: {
11590
+ first_name: data.first_name,
11591
+ last_name: data.last_name,
11592
+ company: data.company,
11593
+ address_1: data.address_1,
11594
+ address_2: data.address_2,
11595
+ city: data.city,
11596
+ province: data.province,
11597
+ country_code: data.country_code,
11598
+ postal_code: data.postal_code,
11599
+ phone: data.phone
11600
+ }
11601
+ },
11602
+ {
11603
+ onSuccess: () => {
11604
+ handleSuccess();
11605
+ },
11606
+ onError: (error) => {
11607
+ toast.error(error.message);
11608
+ }
11609
+ }
11610
+ );
11611
+ });
11612
+ return /* @__PURE__ */ jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxs(
11613
+ KeyboundForm,
11614
+ {
11615
+ className: "flex flex-1 flex-col overflow-hidden",
11616
+ onSubmit,
11617
+ children: [
11618
+ /* @__PURE__ */ jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-y-4", children: [
11619
+ /* @__PURE__ */ jsx(
11620
+ Form$2.Field,
11621
+ {
11622
+ control: form.control,
11623
+ name: "country_code",
11624
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
11625
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Country" }),
11626
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(CountrySelect, { ...field }) }),
11627
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11628
+ ] })
11629
+ }
11630
+ ),
11631
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
11564
11632
  /* @__PURE__ */ jsx(
11565
- Text,
11633
+ Form$2.Field,
11566
11634
  {
11567
- size: "xsmall",
11568
- weight: "plus",
11569
- className: "text-ui-fg-muted",
11570
- children: "Shipping profile"
11635
+ control: form.control,
11636
+ name: "first_name",
11637
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
11638
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "First name" }),
11639
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
11640
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11641
+ ] })
11571
11642
  }
11572
11643
  ),
11573
11644
  /* @__PURE__ */ jsx(
11574
- Text,
11645
+ Form$2.Field,
11575
11646
  {
11576
- size: "xsmall",
11577
- weight: "plus",
11578
- className: "text-ui-fg-muted",
11579
- children: "Action"
11647
+ control: form.control,
11648
+ name: "last_name",
11649
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
11650
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Last name" }),
11651
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
11652
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11653
+ ] })
11580
11654
  }
11581
11655
  )
11582
11656
  ] }),
11583
- /* @__PURE__ */ jsx("div", { className: "px-[5px] pb-[5px]", children: uniqueShippingProfiles.map((profile) => {
11584
- var _a2, _b, _c, _d, _e, _f, _g;
11585
- const items = getItemsWithShippingProfile(
11586
- profile.id,
11587
- order.items
11588
- );
11589
- const hasItems = items.length > 0;
11590
- const shippingOption = shipping_options == null ? void 0 : shipping_options.find(
11591
- (option) => option.shipping_profile_id === profile.id
11592
- );
11593
- const shippingMethod = preview.shipping_methods.find(
11594
- (method) => method.shipping_option_id === (shippingOption == null ? void 0 : shippingOption.id)
11595
- );
11596
- const addShippingMethodAction = (_a2 = shippingMethod == null ? void 0 : shippingMethod.actions) == null ? void 0 : _a2.find(
11597
- (action) => action.action === "SHIPPING_ADD"
11598
- );
11599
- return /* @__PURE__ */ jsxs(
11600
- Accordion.Item,
11657
+ /* @__PURE__ */ jsx(
11658
+ Form$2.Field,
11659
+ {
11660
+ control: form.control,
11661
+ name: "company",
11662
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
11663
+ /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Company" }),
11664
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
11665
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11666
+ ] })
11667
+ }
11668
+ ),
11669
+ /* @__PURE__ */ jsx(
11670
+ Form$2.Field,
11671
+ {
11672
+ control: form.control,
11673
+ name: "address_1",
11674
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
11675
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Address" }),
11676
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
11677
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11678
+ ] })
11679
+ }
11680
+ ),
11681
+ /* @__PURE__ */ jsx(
11682
+ Form$2.Field,
11683
+ {
11684
+ control: form.control,
11685
+ name: "address_2",
11686
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
11687
+ /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Apartment, suite, etc." }),
11688
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
11689
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11690
+ ] })
11691
+ }
11692
+ ),
11693
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
11694
+ /* @__PURE__ */ jsx(
11695
+ Form$2.Field,
11601
11696
  {
11602
- value: profile.id,
11603
- className: "bg-ui-bg-base shadow-elevation-card-rest rounded-lg",
11604
- children: [
11605
- /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-3 px-3 py-2", children: [
11606
- /* @__PURE__ */ jsxs("div", { className: "flex w-full items-center gap-x-3 overflow-hidden", children: [
11607
- /* @__PURE__ */ jsx(Accordion.Trigger, { asChild: true, children: /* @__PURE__ */ jsx(
11608
- IconButton,
11609
- {
11610
- size: "2xsmall",
11611
- variant: "transparent",
11612
- className: "group/trigger",
11613
- disabled: !hasItems,
11614
- children: /* @__PURE__ */ jsx(TriangleRightMini, { className: "transition-transform group-data-[state=open]/trigger:rotate-90" })
11615
- }
11616
- ) }),
11617
- !shippingOption ? /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-3", children: [
11618
- /* @__PURE__ */ jsx("div", { className: "shadow-borders-base flex size-7 items-center justify-center rounded-md", children: /* @__PURE__ */ jsx("div", { className: "bg-ui-bg-component-hover flex size-6 items-center justify-center rounded", children: /* @__PURE__ */ jsx(Shopping, { className: "text-ui-fg-subtle" }) }) }),
11619
- /* @__PURE__ */ jsxs("div", { className: "flex flex-1 flex-col", children: [
11620
- /* @__PURE__ */ jsx(
11621
- Text,
11622
- {
11623
- size: "small",
11624
- weight: "plus",
11625
- leading: "compact",
11626
- children: profile.name
11627
- }
11628
- ),
11629
- /* @__PURE__ */ jsxs(
11630
- Text,
11631
- {
11632
- size: "small",
11633
- leading: "compact",
11634
- className: "text-ui-fg-subtle",
11635
- children: [
11636
- items.length,
11637
- " ",
11638
- pluralize(items.length, "items", "item")
11639
- ]
11640
- }
11641
- )
11642
- ] })
11697
+ control: form.control,
11698
+ name: "postal_code",
11699
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
11700
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Postal code" }),
11701
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
11702
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11703
+ ] })
11704
+ }
11705
+ ),
11706
+ /* @__PURE__ */ jsx(
11707
+ Form$2.Field,
11708
+ {
11709
+ control: form.control,
11710
+ name: "city",
11711
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
11712
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "City" }),
11713
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
11714
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11715
+ ] })
11716
+ }
11717
+ )
11718
+ ] }),
11719
+ /* @__PURE__ */ jsx(
11720
+ Form$2.Field,
11721
+ {
11722
+ control: form.control,
11723
+ name: "province",
11724
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
11725
+ /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Province / State" }),
11726
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
11727
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11728
+ ] })
11729
+ }
11730
+ ),
11731
+ /* @__PURE__ */ jsx(
11732
+ Form$2.Field,
11733
+ {
11734
+ control: form.control,
11735
+ name: "phone",
11736
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
11737
+ /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Phone" }),
11738
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
11739
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11740
+ ] })
11741
+ }
11742
+ )
11743
+ ] }) }),
11744
+ /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
11745
+ /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
11746
+ /* @__PURE__ */ jsx(Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
11747
+ ] }) })
11748
+ ]
11749
+ }
11750
+ ) });
11751
+ };
11752
+ const schema$1 = addressSchema;
11753
+ const STACKED_FOCUS_MODAL_ID = "shipping-form";
11754
+ const Shipping = () => {
11755
+ var _a;
11756
+ const { id } = useParams();
11757
+ const { order, isPending, isError, error } = useOrder(id, {
11758
+ fields: "+items.*,+items.variant.*,+items.variant.product.*,+items.variant.product.shipping_profile.*,+currency_code"
11759
+ });
11760
+ const {
11761
+ order: preview,
11762
+ isPending: isPreviewPending,
11763
+ isError: isPreviewError,
11764
+ error: previewError
11765
+ } = useOrderPreview(id);
11766
+ useInitiateOrderEdit({ preview });
11767
+ const { onCancel } = useCancelOrderEdit({ preview });
11768
+ if (isError) {
11769
+ throw error;
11770
+ }
11771
+ if (isPreviewError) {
11772
+ throw previewError;
11773
+ }
11774
+ const orderHasItems = (((_a = order == null ? void 0 : order.items) == null ? void 0 : _a.length) || 0) > 0;
11775
+ const isReady = preview && !isPreviewPending && order && !isPending;
11776
+ return /* @__PURE__ */ jsx(RouteFocusModal, { onClose: onCancel, children: !orderHasItems ? /* @__PURE__ */ jsxs("div", { className: "flex h-full flex-col overflow-hidden ", children: [
11777
+ /* @__PURE__ */ jsx(RouteFocusModal.Header, {}),
11778
+ /* @__PURE__ */ jsx(RouteFocusModal.Body, { className: "flex flex-1 flex-col overflow-hidden", children: /* @__PURE__ */ jsx("div", { className: "flex flex-1 flex-col items-center overflow-y-auto", children: /* @__PURE__ */ jsxs("div", { className: "flex w-full max-w-[720px] flex-col gap-y-6 px-6 py-16", children: [
11779
+ /* @__PURE__ */ jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Shipping" }) }),
11780
+ /* @__PURE__ */ jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "This draft order currently has no items. Add items to the order before adding shipping." }) })
11781
+ ] }) }) }),
11782
+ /* @__PURE__ */ jsx(RouteFocusModal.Footer, { children: /* @__PURE__ */ jsx(RouteFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }) })
11783
+ ] }) : isReady ? /* @__PURE__ */ jsx(ShippingForm, { preview, order }) : /* @__PURE__ */ jsxs("div", { children: [
11784
+ /* @__PURE__ */ jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Edit Shipping" }) }),
11785
+ /* @__PURE__ */ jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Loading data for the draft order, please wait..." }) })
11786
+ ] }) });
11787
+ };
11788
+ const ShippingForm = ({ preview, order }) => {
11789
+ var _a;
11790
+ const { setIsOpen } = useStackedModal();
11791
+ const [isSubmitting, setIsSubmitting] = useState(false);
11792
+ const [data, setData] = useState(null);
11793
+ const appliedShippingOptionIds = (_a = preview.shipping_methods) == null ? void 0 : _a.map((method) => method.shipping_option_id).filter(Boolean);
11794
+ const { shipping_options } = useShippingOptions(
11795
+ {
11796
+ id: appliedShippingOptionIds,
11797
+ fields: "+service_zone.*,+service_zone.fulfillment_set.*,+service_zone.fulfillment_set.location.*"
11798
+ },
11799
+ {
11800
+ enabled: appliedShippingOptionIds.length > 0
11801
+ }
11802
+ );
11803
+ const uniqueShippingProfiles = useMemo(() => {
11804
+ const profiles = /* @__PURE__ */ new Map();
11805
+ getUniqueShippingProfiles(order.items).forEach((profile) => {
11806
+ profiles.set(profile.id, profile);
11807
+ });
11808
+ shipping_options == null ? void 0 : shipping_options.forEach((option) => {
11809
+ profiles.set(option.shipping_profile_id, option.shipping_profile);
11810
+ });
11811
+ return Array.from(profiles.values());
11812
+ }, [order.items, shipping_options]);
11813
+ const { handleSuccess } = useRouteModal();
11814
+ const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
11815
+ const { mutateAsync: requestOrderEdit } = useDraftOrderRequestEdit(preview.id);
11816
+ const { mutateAsync: removeShippingMethod } = useDraftOrderRemoveShippingMethod(preview.id);
11817
+ const { mutateAsync: removeActionShippingMethod } = useDraftOrderRemoveActionShippingMethod(preview.id);
11818
+ const onSubmit = async () => {
11819
+ setIsSubmitting(true);
11820
+ let requestSucceeded = false;
11821
+ await requestOrderEdit(void 0, {
11822
+ onError: (e) => {
11823
+ toast.error(`Failed to request order edit: ${e.message}`);
11824
+ },
11825
+ onSuccess: () => {
11826
+ requestSucceeded = true;
11827
+ }
11828
+ });
11829
+ if (!requestSucceeded) {
11830
+ setIsSubmitting(false);
11831
+ return;
11832
+ }
11833
+ await confirmOrderEdit(void 0, {
11834
+ onError: (e) => {
11835
+ toast.error(`Failed to confirm order edit: ${e.message}`);
11836
+ },
11837
+ onSuccess: () => {
11838
+ handleSuccess();
11839
+ },
11840
+ onSettled: () => {
11841
+ setIsSubmitting(false);
11842
+ }
11843
+ });
11844
+ };
11845
+ const onKeydown = useCallback(
11846
+ (e) => {
11847
+ if (e.key === "Enter" && (e.ctrlKey || e.metaKey)) {
11848
+ if (data || isSubmitting) {
11849
+ return;
11850
+ }
11851
+ onSubmit();
11852
+ }
11853
+ },
11854
+ [data, isSubmitting, onSubmit]
11855
+ );
11856
+ useEffect(() => {
11857
+ document.addEventListener("keydown", onKeydown);
11858
+ return () => {
11859
+ document.removeEventListener("keydown", onKeydown);
11860
+ };
11861
+ }, [onKeydown]);
11862
+ return /* @__PURE__ */ jsxs("div", { className: "flex h-full flex-col overflow-hidden", children: [
11863
+ /* @__PURE__ */ jsx(RouteFocusModal.Header, {}),
11864
+ /* @__PURE__ */ jsxs(RouteFocusModal.Body, { className: "flex flex-1 flex-col overflow-hidden", children: [
11865
+ /* @__PURE__ */ jsx("div", { className: "flex flex-1 flex-col items-center overflow-y-auto", children: /* @__PURE__ */ jsxs("div", { className: "flex w-full max-w-[720px] flex-col gap-y-6 px-6 py-16", children: [
11866
+ /* @__PURE__ */ jsxs("div", { children: [
11867
+ /* @__PURE__ */ jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Shipping" }) }),
11868
+ /* @__PURE__ */ jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Choose which shipping method(s) to use for the items in the order." }) })
11869
+ ] }),
11870
+ /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
11871
+ /* @__PURE__ */ jsx(Accordion.Root, { type: "multiple", children: /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-subtle shadow-elevation-card-rest rounded-xl", children: [
11872
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between px-4 py-2", children: [
11873
+ /* @__PURE__ */ jsx(
11874
+ Text,
11875
+ {
11876
+ size: "xsmall",
11877
+ weight: "plus",
11878
+ className: "text-ui-fg-muted",
11879
+ children: "Shipping profile"
11880
+ }
11881
+ ),
11882
+ /* @__PURE__ */ jsx(
11883
+ Text,
11884
+ {
11885
+ size: "xsmall",
11886
+ weight: "plus",
11887
+ className: "text-ui-fg-muted",
11888
+ children: "Action"
11889
+ }
11890
+ )
11891
+ ] }),
11892
+ /* @__PURE__ */ jsx("div", { className: "px-[5px] pb-[5px]", children: uniqueShippingProfiles.map((profile) => {
11893
+ var _a2, _b, _c, _d, _e, _f, _g;
11894
+ const items = getItemsWithShippingProfile(
11895
+ profile.id,
11896
+ order.items
11897
+ );
11898
+ const hasItems = items.length > 0;
11899
+ const shippingOption = shipping_options == null ? void 0 : shipping_options.find(
11900
+ (option) => option.shipping_profile_id === profile.id
11901
+ );
11902
+ const shippingMethod = preview.shipping_methods.find(
11903
+ (method) => method.shipping_option_id === (shippingOption == null ? void 0 : shippingOption.id)
11904
+ );
11905
+ const addShippingMethodAction = (_a2 = shippingMethod == null ? void 0 : shippingMethod.actions) == null ? void 0 : _a2.find(
11906
+ (action) => action.action === "SHIPPING_ADD"
11907
+ );
11908
+ return /* @__PURE__ */ jsxs(
11909
+ Accordion.Item,
11910
+ {
11911
+ value: profile.id,
11912
+ className: "bg-ui-bg-base shadow-elevation-card-rest rounded-lg",
11913
+ children: [
11914
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-3 px-3 py-2", children: [
11915
+ /* @__PURE__ */ jsxs("div", { className: "flex w-full items-center gap-x-3 overflow-hidden", children: [
11916
+ /* @__PURE__ */ jsx(Accordion.Trigger, { asChild: true, children: /* @__PURE__ */ jsx(
11917
+ IconButton,
11918
+ {
11919
+ size: "2xsmall",
11920
+ variant: "transparent",
11921
+ className: "group/trigger",
11922
+ disabled: !hasItems,
11923
+ children: /* @__PURE__ */ jsx(TriangleRightMini, { className: "transition-transform group-data-[state=open]/trigger:rotate-90" })
11924
+ }
11925
+ ) }),
11926
+ !shippingOption ? /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-3", children: [
11927
+ /* @__PURE__ */ jsx("div", { className: "shadow-borders-base flex size-7 items-center justify-center rounded-md", children: /* @__PURE__ */ jsx("div", { className: "bg-ui-bg-component-hover flex size-6 items-center justify-center rounded", children: /* @__PURE__ */ jsx(Shopping, { className: "text-ui-fg-subtle" }) }) }),
11928
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-1 flex-col", children: [
11929
+ /* @__PURE__ */ jsx(
11930
+ Text,
11931
+ {
11932
+ size: "small",
11933
+ weight: "plus",
11934
+ leading: "compact",
11935
+ children: profile.name
11936
+ }
11937
+ ),
11938
+ /* @__PURE__ */ jsxs(
11939
+ Text,
11940
+ {
11941
+ size: "small",
11942
+ leading: "compact",
11943
+ className: "text-ui-fg-subtle",
11944
+ children: [
11945
+ items.length,
11946
+ " ",
11947
+ pluralize(items.length, "items", "item")
11948
+ ]
11949
+ }
11950
+ )
11951
+ ] })
11643
11952
  ] }) : /* @__PURE__ */ jsxs("div", { className: "flex w-full flex-1 items-center gap-[5px] overflow-hidden max-sm:flex-col max-sm:items-start", children: [
11644
11953
  /* @__PURE__ */ jsx(
11645
11954
  Tooltip,
@@ -11797,766 +12106,457 @@ const ShippingForm = ({ preview, order }) => {
11797
12106
  leading: "compact",
11798
12107
  weight: "plus",
11799
12108
  children: [
11800
- (_b2 = (_a3 = item.variant) == null ? void 0 : _a3.product) == null ? void 0 : _b2.title,
11801
- " (",
11802
- (_c2 = item.variant) == null ? void 0 : _c2.title,
11803
- ")"
11804
- ]
11805
- }
11806
- ),
11807
- /* @__PURE__ */ jsx(
11808
- Text,
11809
- {
11810
- size: "small",
11811
- leading: "compact",
11812
- className: "text-ui-fg-subtle",
11813
- children: (_e2 = (_d2 = item.variant) == null ? void 0 : _d2.options) == null ? void 0 : _e2.map((option) => option.value).join(" · ")
11814
- }
11815
- )
11816
- ] })
11817
- ] })
11818
- ]
11819
- },
11820
- item.id
11821
- ),
11822
- idx !== items.length - 1 && /* @__PURE__ */ jsx(Divider, { variant: "dashed" })
11823
- ] }, item.id);
11824
- })
11825
- ] })
11826
- ]
11827
- },
11828
- profile.id
11829
- );
11830
- }) })
11831
- ] }) })
11832
- ] }) }),
11833
- /* @__PURE__ */ jsx(
11834
- StackedFocusModal,
11835
- {
11836
- id: STACKED_FOCUS_MODAL_ID,
11837
- onOpenChangeCallback: (open) => {
11838
- if (!open) {
11839
- setData(null);
11840
- }
11841
- return open;
11842
- },
11843
- children: data && /* @__PURE__ */ jsx(ShippingProfileForm, { data, order, preview })
11844
- }
11845
- )
11846
- ] }),
11847
- /* @__PURE__ */ jsx(RouteFocusModal.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-x-2", children: [
11848
- /* @__PURE__ */ jsx(RouteFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
11849
- /* @__PURE__ */ jsx(
11850
- Button,
11851
- {
11852
- size: "small",
11853
- type: "button",
11854
- isLoading: isSubmitting,
11855
- onClick: onSubmit,
11856
- children: "Save"
11857
- }
11858
- )
11859
- ] }) })
11860
- ] });
11861
- };
11862
- const StackedModalTrigger = ({
11863
- shippingProfileId,
11864
- shippingOption,
11865
- shippingMethod,
11866
- setData,
11867
- children
11868
- }) => {
11869
- const { setIsOpen, getIsOpen } = useStackedModal();
11870
- const isOpen = getIsOpen(STACKED_FOCUS_MODAL_ID);
11871
- const onToggle = () => {
11872
- if (isOpen) {
11873
- setIsOpen(STACKED_FOCUS_MODAL_ID, false);
11874
- setData(null);
11875
- } else {
11876
- setIsOpen(STACKED_FOCUS_MODAL_ID, true);
11877
- setData({
11878
- shippingProfileId,
11879
- shippingOption,
11880
- shippingMethod
11881
- });
11882
- }
11883
- };
11884
- return /* @__PURE__ */ jsx(
11885
- Button,
11886
- {
11887
- size: "small",
11888
- variant: "secondary",
11889
- onClick: onToggle,
11890
- className: "text-ui-fg-primary shrink-0",
11891
- children
11892
- }
11893
- );
11894
- };
11895
- const ShippingProfileForm = ({
11896
- data,
11897
- order,
11898
- preview
11899
- }) => {
11900
- var _a, _b, _c, _d, _e, _f;
11901
- const { setIsOpen } = useStackedModal();
11902
- const form = useForm({
11903
- resolver: zodResolver(shippingMethodSchema),
11904
- defaultValues: {
11905
- location_id: (_d = (_c = (_b = (_a = data.shippingOption) == null ? void 0 : _a.service_zone) == null ? void 0 : _b.fulfillment_set) == null ? void 0 : _c.location) == null ? void 0 : _d.id,
11906
- shipping_option_id: (_e = data.shippingOption) == null ? void 0 : _e.id,
11907
- custom_amount: (_f = data.shippingMethod) == null ? void 0 : _f.amount
11908
- }
11909
- });
11910
- const { mutateAsync: addShippingMethod, isPending } = useDraftOrderAddShippingMethod(order.id);
11911
- const {
11912
- mutateAsync: updateShippingMethod,
11913
- isPending: isUpdatingShippingMethod
11914
- } = useDraftOrderUpdateShippingMethod(order.id);
11915
- const onSubmit = form.handleSubmit(async (values) => {
11916
- if (isEqual(values, form.formState.defaultValues)) {
11917
- setIsOpen(STACKED_FOCUS_MODAL_ID, false);
11918
- return;
11919
- }
11920
- if (data.shippingMethod) {
11921
- await updateShippingMethod(
11922
- {
11923
- method_id: data.shippingMethod.id,
11924
- shipping_option_id: values.shipping_option_id,
11925
- custom_amount: values.custom_amount ? convertNumber(values.custom_amount) : void 0
11926
- },
11927
- {
11928
- onError: (e) => {
11929
- toast.error(e.message);
11930
- },
11931
- onSuccess: () => {
11932
- setIsOpen(STACKED_FOCUS_MODAL_ID, false);
11933
- }
11934
- }
11935
- );
11936
- return;
11937
- }
11938
- await addShippingMethod(
11939
- {
11940
- shipping_option_id: values.shipping_option_id,
11941
- custom_amount: values.custom_amount ? convertNumber(values.custom_amount) : void 0
11942
- },
11943
- {
11944
- onError: (e) => {
11945
- toast.error(e.message);
11946
- },
11947
- onSuccess: () => {
11948
- setIsOpen(STACKED_FOCUS_MODAL_ID, false);
11949
- }
11950
- }
11951
- );
11952
- });
11953
- return /* @__PURE__ */ jsx(StackedFocusModal.Content, { children: /* @__PURE__ */ jsx(Form$2, { ...form, children: /* @__PURE__ */ jsxs(
11954
- KeyboundForm,
11955
- {
11956
- className: "flex h-full flex-col overflow-hidden",
11957
- onSubmit,
11958
- children: [
11959
- /* @__PURE__ */ jsx(StackedFocusModal.Header, {}),
11960
- /* @__PURE__ */ jsx(StackedFocusModal.Body, { className: "flex flex-1 flex-col overflow-hidden", children: /* @__PURE__ */ jsx("div", { className: "flex flex-1 flex-col items-center overflow-y-auto", children: /* @__PURE__ */ jsxs("div", { className: "flex w-full max-w-[720px] flex-col gap-y-6 px-6 py-16", children: [
11961
- /* @__PURE__ */ jsxs("div", { children: [
11962
- /* @__PURE__ */ jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Shipping" }) }),
11963
- /* @__PURE__ */ jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Add a shipping method for the selected shipping profile. You can see the items that will be shipped using this method in the preview below." }) })
11964
- ] }),
11965
- /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
11966
- /* @__PURE__ */ jsx(
11967
- LocationField,
11968
- {
11969
- control: form.control,
11970
- setValue: form.setValue
11971
- }
11972
- ),
11973
- /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
11974
- /* @__PURE__ */ jsx(
11975
- ShippingOptionField,
11976
- {
11977
- shippingProfileId: data.shippingProfileId,
11978
- preview,
11979
- control: form.control
11980
- }
11981
- ),
11982
- /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
11983
- /* @__PURE__ */ jsx(
11984
- CustomAmountField,
11985
- {
11986
- control: form.control,
11987
- currencyCode: order.currency_code
11988
- }
11989
- ),
11990
- /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
11991
- /* @__PURE__ */ jsx(
11992
- ItemsPreview,
11993
- {
11994
- order,
11995
- shippingProfileId: data.shippingProfileId
11996
- }
11997
- )
11998
- ] }) }) }),
11999
- /* @__PURE__ */ jsx(StackedFocusModal.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-x-2", children: [
12000
- /* @__PURE__ */ jsx(StackedFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
12001
- /* @__PURE__ */ jsx(
12002
- Button,
12003
- {
12004
- size: "small",
12005
- type: "submit",
12006
- isLoading: isPending || isUpdatingShippingMethod,
12007
- children: data.shippingMethod ? "Update" : "Add"
12008
- }
12009
- )
12010
- ] }) })
12011
- ]
12012
- }
12013
- ) }) });
12014
- };
12015
- const shippingMethodSchema = objectType({
12016
- location_id: stringType(),
12017
- shipping_option_id: stringType(),
12018
- custom_amount: unionType([numberType(), stringType()]).optional()
12019
- });
12020
- const ItemsPreview = ({ order, shippingProfileId }) => {
12021
- const matches = order.items.filter(
12022
- (item) => {
12023
- var _a, _b, _c;
12024
- return ((_c = (_b = (_a = item.variant) == null ? void 0 : _a.product) == null ? void 0 : _b.shipping_profile) == null ? void 0 : _c.id) === shippingProfileId;
12025
- }
12026
- );
12027
- return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-y-6", children: [
12028
- /* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 items-center gap-3", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
12029
- /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: "Items to ship" }),
12030
- /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Items with the selected shipping profile." })
12031
- ] }) }),
12032
- /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-subtle shadow-elevation-card-rest rounded-xl", children: [
12033
- /* @__PURE__ */ jsxs("div", { className: "text-ui-fg-muted grid grid-cols-2 gap-3 px-4 py-2", children: [
12034
- /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: "Item" }) }),
12035
- /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: "Quantity" }) })
12036
- ] }),
12037
- /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-y-1.5 px-[5px] pb-[5px]", children: matches.length > 0 ? matches == null ? void 0 : matches.map((item) => /* @__PURE__ */ jsxs(
12038
- "div",
12039
- {
12040
- className: "bg-ui-bg-base shadow-elevation-card-rest grid grid-cols-2 items-center gap-3 rounded-lg px-4 py-2",
12041
- children: [
12042
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-3", children: [
12043
- /* @__PURE__ */ jsx(
12044
- Thumbnail,
12045
- {
12046
- thumbnail: item.thumbnail,
12047
- alt: item.product_title ?? void 0
12048
- }
12049
- ),
12050
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
12051
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-1", children: [
12052
- /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: item.product_title }),
12053
- /* @__PURE__ */ jsxs(
12054
- Text,
12055
- {
12056
- size: "small",
12057
- leading: "compact",
12058
- className: "text-ui-fg-subtle",
12059
- children: [
12060
- "(",
12061
- item.variant_title,
12062
- ")"
12063
- ]
12064
- }
12065
- )
12066
- ] }),
12067
- /* @__PURE__ */ jsx(
12068
- Text,
12069
- {
12070
- size: "small",
12071
- leading: "compact",
12072
- className: "text-ui-fg-subtle",
12073
- children: item.variant_sku
12074
- }
12075
- )
12076
- ] })
12077
- ] }),
12078
- /* @__PURE__ */ jsxs(
12079
- Text,
12080
- {
12081
- size: "small",
12082
- leading: "compact",
12083
- className: "text-ui-fg-subtle",
12084
- children: [
12085
- item.quantity,
12086
- "x"
12087
- ]
12088
- }
12089
- )
12090
- ]
12091
- },
12092
- item.id
12093
- )) : /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest flex flex-col items-center justify-center gap-1 gap-x-3 rounded-lg p-4", children: [
12094
- /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: "No items found" }),
12095
- /* @__PURE__ */ jsxs(Text, { size: "small", className: "text-ui-fg-subtle", children: [
12096
- 'No items found for "',
12097
- query,
12098
- '".'
12099
- ] })
12100
- ] }) })
12101
- ] })
12102
- ] });
12103
- };
12104
- const LocationField = ({ control, setValue }) => {
12105
- const locations = useComboboxData({
12106
- queryKey: ["locations"],
12107
- queryFn: async (params) => {
12108
- return await sdk.admin.stockLocation.list(params);
12109
- },
12110
- getOptions: (data) => {
12111
- return data.stock_locations.map((location) => ({
12112
- label: location.name,
12113
- value: location.id
12114
- }));
12115
- }
12116
- });
12117
- return /* @__PURE__ */ jsx(
12118
- Form$2.Field,
12119
- {
12120
- control,
12121
- name: "location_id",
12122
- render: ({ field: { onChange, ...field } }) => {
12123
- return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
12124
- /* @__PURE__ */ jsxs("div", { children: [
12125
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Location" }),
12126
- /* @__PURE__ */ jsx(Form$2.Hint, { children: "Choose where you want to ship the items from." })
12127
- ] }),
12128
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
12129
- Combobox,
12130
- {
12131
- options: locations.options,
12132
- fetchNextPage: locations.fetchNextPage,
12133
- isFetchingNextPage: locations.isFetchingNextPage,
12134
- searchValue: locations.searchValue,
12135
- onSearchValueChange: locations.onSearchValueChange,
12136
- placeholder: "Select location",
12137
- onChange: (value) => {
12138
- setValue("shipping_option_id", "", {
12139
- shouldDirty: true,
12140
- shouldTouch: true
12141
- });
12142
- onChange(value);
12109
+ (_b2 = (_a3 = item.variant) == null ? void 0 : _a3.product) == null ? void 0 : _b2.title,
12110
+ " (",
12111
+ (_c2 = item.variant) == null ? void 0 : _c2.title,
12112
+ ")"
12113
+ ]
12114
+ }
12115
+ ),
12116
+ /* @__PURE__ */ jsx(
12117
+ Text,
12118
+ {
12119
+ size: "small",
12120
+ leading: "compact",
12121
+ className: "text-ui-fg-subtle",
12122
+ children: (_e2 = (_d2 = item.variant) == null ? void 0 : _d2.options) == null ? void 0 : _e2.map((option) => option.value).join(" · ")
12123
+ }
12124
+ )
12125
+ ] })
12126
+ ] })
12127
+ ]
12128
+ },
12129
+ item.id
12130
+ ),
12131
+ idx !== items.length - 1 && /* @__PURE__ */ jsx(Divider, { variant: "dashed" })
12132
+ ] }, item.id);
12133
+ })
12134
+ ] })
12135
+ ]
12143
12136
  },
12144
- ...field
12137
+ profile.id
12138
+ );
12139
+ }) })
12140
+ ] }) })
12141
+ ] }) }),
12142
+ /* @__PURE__ */ jsx(
12143
+ StackedFocusModal,
12144
+ {
12145
+ id: STACKED_FOCUS_MODAL_ID,
12146
+ onOpenChangeCallback: (open) => {
12147
+ if (!open) {
12148
+ setData(null);
12145
12149
  }
12146
- ) })
12147
- ] }) });
12148
- }
12149
- }
12150
- );
12151
- };
12152
- const ShippingOptionField = ({
12153
- shippingProfileId,
12154
- preview,
12155
- control
12156
- }) => {
12157
- var _a;
12158
- const locationId = useWatch({ control, name: "location_id" });
12159
- const shippingOptions = useComboboxData({
12160
- queryKey: ["shipping_options", locationId, shippingProfileId],
12161
- queryFn: async (params) => {
12162
- return await sdk.admin.shippingOption.list({
12163
- ...params,
12164
- stock_location_id: locationId,
12165
- shipping_profile_id: shippingProfileId
12166
- });
12167
- },
12168
- getOptions: (data) => {
12169
- return data.shipping_options.map((option) => {
12170
- var _a2;
12171
- if ((_a2 = option.rules) == null ? void 0 : _a2.find(
12172
- (r) => r.attribute === "is_return" && r.value === "true"
12173
- )) {
12174
- return void 0;
12150
+ return open;
12151
+ },
12152
+ children: data && /* @__PURE__ */ jsx(ShippingProfileForm, { data, order, preview })
12175
12153
  }
12176
- return {
12177
- label: option.name,
12178
- value: option.id
12179
- };
12180
- }).filter(Boolean);
12181
- },
12182
- enabled: !!locationId && !!shippingProfileId,
12183
- defaultValue: ((_a = preview.shipping_methods[0]) == null ? void 0 : _a.shipping_option_id) || void 0
12184
- });
12185
- const tooltipContent = !locationId && !shippingProfileId ? "Choose a location and shipping profile first." : !locationId ? "Choose a location first." : "Choose a shipping profile first.";
12186
- return /* @__PURE__ */ jsx(
12187
- Form$2.Field,
12188
- {
12189
- control,
12190
- name: "shipping_option_id",
12191
- render: ({ field }) => {
12192
- return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
12193
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
12194
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Shipping option" }),
12195
- /* @__PURE__ */ jsx(Form$2.Hint, { children: "Choose the shipping option to use." })
12196
- ] }),
12197
- /* @__PURE__ */ jsx(
12198
- ConditionalTooltip,
12199
- {
12200
- content: tooltipContent,
12201
- showTooltip: !locationId || !shippingProfileId,
12202
- children: /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
12203
- Combobox,
12204
- {
12205
- options: shippingOptions.options,
12206
- fetchNextPage: shippingOptions.fetchNextPage,
12207
- isFetchingNextPage: shippingOptions.isFetchingNextPage,
12208
- searchValue: shippingOptions.searchValue,
12209
- onSearchValueChange: shippingOptions.onSearchValueChange,
12210
- placeholder: "Select shipping option",
12211
- ...field,
12212
- disabled: !locationId || !shippingProfileId
12213
- }
12214
- ) }) })
12215
- }
12216
- )
12217
- ] }) });
12218
- }
12219
- }
12220
- );
12221
- };
12222
- const CustomAmountField = ({
12223
- control,
12224
- currencyCode
12225
- }) => {
12226
- return /* @__PURE__ */ jsx(
12227
- Form$2.Field,
12228
- {
12229
- control,
12230
- name: "custom_amount",
12231
- render: ({ field: { onChange, ...field } }) => {
12232
- return /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
12233
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
12234
- /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Custom amount" }),
12235
- /* @__PURE__ */ jsx(Form$2.Hint, { children: "Set a custom amount for the shipping option." })
12236
- ] }),
12237
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
12238
- CurrencyInput,
12239
- {
12240
- ...field,
12241
- onValueChange: (value) => onChange(value),
12242
- symbol: getNativeSymbol(currencyCode),
12243
- code: currencyCode
12244
- }
12245
- ) })
12246
- ] });
12247
- }
12248
- }
12249
- );
12250
- };
12251
- const SalesChannel = () => {
12252
- const { id } = useParams();
12253
- const { draft_order, isPending, isError, error } = useDraftOrder(
12254
- id,
12255
- {
12256
- fields: "+sales_channel_id"
12257
- },
12258
- {
12259
- enabled: !!id
12260
- }
12261
- );
12262
- if (isError) {
12263
- throw error;
12264
- }
12265
- const ISrEADY = !!draft_order && !isPending;
12266
- return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
12267
- /* @__PURE__ */ jsxs(RouteDrawer.Header, { children: [
12268
- /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Sales Channel" }) }),
12269
- /* @__PURE__ */ jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Update which sales channel the draft order is associated with" }) })
12154
+ )
12270
12155
  ] }),
12271
- ISrEADY && /* @__PURE__ */ jsx(SalesChannelForm, { order: draft_order })
12156
+ /* @__PURE__ */ jsx(RouteFocusModal.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-x-2", children: [
12157
+ /* @__PURE__ */ jsx(RouteFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
12158
+ /* @__PURE__ */ jsx(
12159
+ Button,
12160
+ {
12161
+ size: "small",
12162
+ type: "button",
12163
+ isLoading: isSubmitting,
12164
+ onClick: onSubmit,
12165
+ children: "Save"
12166
+ }
12167
+ )
12168
+ ] }) })
12272
12169
  ] });
12273
12170
  };
12274
- const SalesChannelForm = ({ order }) => {
12275
- const form = useForm({
12276
- defaultValues: {
12277
- sales_channel_id: order.sales_channel_id || ""
12278
- },
12279
- resolver: zodResolver(schema$2)
12280
- });
12281
- const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
12282
- const { handleSuccess } = useRouteModal();
12283
- const onSubmit = form.handleSubmit(async (data) => {
12284
- await mutateAsync(
12285
- {
12286
- sales_channel_id: data.sales_channel_id
12287
- },
12288
- {
12289
- onSuccess: () => {
12290
- toast.success("Sales channel updated");
12291
- handleSuccess();
12292
- },
12293
- onError: (error) => {
12294
- toast.error(error.message);
12295
- }
12296
- }
12297
- );
12298
- });
12299
- return /* @__PURE__ */ jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxs(
12300
- KeyboundForm,
12301
- {
12302
- className: "flex flex-1 flex-col overflow-hidden",
12303
- onSubmit,
12304
- children: [
12305
- /* @__PURE__ */ jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsx(SalesChannelField, { control: form.control, order }) }),
12306
- /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
12307
- /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
12308
- /* @__PURE__ */ jsx(Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
12309
- ] }) })
12310
- ]
12171
+ const StackedModalTrigger = ({
12172
+ shippingProfileId,
12173
+ shippingOption,
12174
+ shippingMethod,
12175
+ setData,
12176
+ children
12177
+ }) => {
12178
+ const { setIsOpen, getIsOpen } = useStackedModal();
12179
+ const isOpen = getIsOpen(STACKED_FOCUS_MODAL_ID);
12180
+ const onToggle = () => {
12181
+ if (isOpen) {
12182
+ setIsOpen(STACKED_FOCUS_MODAL_ID, false);
12183
+ setData(null);
12184
+ } else {
12185
+ setIsOpen(STACKED_FOCUS_MODAL_ID, true);
12186
+ setData({
12187
+ shippingProfileId,
12188
+ shippingOption,
12189
+ shippingMethod
12190
+ });
12311
12191
  }
12312
- ) });
12313
- };
12314
- const SalesChannelField = ({ control, order }) => {
12315
- const salesChannels = useComboboxData({
12316
- queryFn: async (params) => {
12317
- return await sdk.admin.salesChannel.list(params);
12318
- },
12319
- queryKey: ["sales-channels"],
12320
- getOptions: (data) => {
12321
- return data.sales_channels.map((salesChannel) => ({
12322
- label: salesChannel.name,
12323
- value: salesChannel.id
12324
- }));
12325
- },
12326
- defaultValue: order.sales_channel_id || void 0
12327
- });
12192
+ };
12328
12193
  return /* @__PURE__ */ jsx(
12329
- Form$2.Field,
12194
+ Button,
12330
12195
  {
12331
- control,
12332
- name: "sales_channel_id",
12333
- render: ({ field }) => {
12334
- return /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12335
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Sales Channel" }),
12336
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
12337
- Combobox,
12338
- {
12339
- options: salesChannels.options,
12340
- fetchNextPage: salesChannels.fetchNextPage,
12341
- isFetchingNextPage: salesChannels.isFetchingNextPage,
12342
- searchValue: salesChannels.searchValue,
12343
- onSearchValueChange: salesChannels.onSearchValueChange,
12344
- placeholder: "Select sales channel",
12345
- ...field
12346
- }
12347
- ) }),
12348
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12349
- ] });
12350
- }
12196
+ size: "small",
12197
+ variant: "secondary",
12198
+ onClick: onToggle,
12199
+ className: "text-ui-fg-primary shrink-0",
12200
+ children
12351
12201
  }
12352
12202
  );
12353
12203
  };
12354
- const schema$2 = objectType({
12355
- sales_channel_id: stringType().min(1)
12356
- });
12357
- const ShippingAddress = () => {
12358
- const { id } = useParams();
12359
- const { order, isPending, isError, error } = useOrder(id, {
12360
- fields: "+shipping_address"
12361
- });
12362
- if (isError) {
12363
- throw error;
12364
- }
12365
- const isReady = !isPending && !!order;
12366
- return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
12367
- /* @__PURE__ */ jsxs(RouteDrawer.Header, { children: [
12368
- /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Shipping Address" }) }),
12369
- /* @__PURE__ */ jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Edit the shipping address for the draft order" }) })
12370
- ] }),
12371
- isReady && /* @__PURE__ */ jsx(ShippingAddressForm, { order })
12372
- ] });
12373
- };
12374
- const ShippingAddressForm = ({ order }) => {
12375
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
12204
+ const ShippingProfileForm = ({
12205
+ data,
12206
+ order,
12207
+ preview
12208
+ }) => {
12209
+ var _a, _b, _c, _d, _e, _f;
12210
+ const { setIsOpen } = useStackedModal();
12376
12211
  const form = useForm({
12212
+ resolver: zodResolver(shippingMethodSchema),
12377
12213
  defaultValues: {
12378
- first_name: ((_a = order.shipping_address) == null ? void 0 : _a.first_name) ?? "",
12379
- last_name: ((_b = order.shipping_address) == null ? void 0 : _b.last_name) ?? "",
12380
- company: ((_c = order.shipping_address) == null ? void 0 : _c.company) ?? "",
12381
- address_1: ((_d = order.shipping_address) == null ? void 0 : _d.address_1) ?? "",
12382
- address_2: ((_e = order.shipping_address) == null ? void 0 : _e.address_2) ?? "",
12383
- city: ((_f = order.shipping_address) == null ? void 0 : _f.city) ?? "",
12384
- province: ((_g = order.shipping_address) == null ? void 0 : _g.province) ?? "",
12385
- country_code: ((_h = order.shipping_address) == null ? void 0 : _h.country_code) ?? "",
12386
- postal_code: ((_i = order.shipping_address) == null ? void 0 : _i.postal_code) ?? "",
12387
- phone: ((_j = order.shipping_address) == null ? void 0 : _j.phone) ?? ""
12388
- },
12389
- resolver: zodResolver(schema$1)
12214
+ location_id: (_d = (_c = (_b = (_a = data.shippingOption) == null ? void 0 : _a.service_zone) == null ? void 0 : _b.fulfillment_set) == null ? void 0 : _c.location) == null ? void 0 : _d.id,
12215
+ shipping_option_id: (_e = data.shippingOption) == null ? void 0 : _e.id,
12216
+ custom_amount: (_f = data.shippingMethod) == null ? void 0 : _f.amount
12217
+ }
12390
12218
  });
12391
- const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
12392
- const { handleSuccess } = useRouteModal();
12393
- const onSubmit = form.handleSubmit(async (data) => {
12394
- await mutateAsync(
12395
- {
12396
- shipping_address: {
12397
- first_name: data.first_name,
12398
- last_name: data.last_name,
12399
- company: data.company,
12400
- address_1: data.address_1,
12401
- address_2: data.address_2,
12402
- city: data.city,
12403
- province: data.province,
12404
- country_code: data.country_code,
12405
- postal_code: data.postal_code,
12406
- phone: data.phone
12219
+ const { mutateAsync: addShippingMethod, isPending } = useDraftOrderAddShippingMethod(order.id);
12220
+ const {
12221
+ mutateAsync: updateShippingMethod,
12222
+ isPending: isUpdatingShippingMethod
12223
+ } = useDraftOrderUpdateShippingMethod(order.id);
12224
+ const onSubmit = form.handleSubmit(async (values) => {
12225
+ if (isEqual(values, form.formState.defaultValues)) {
12226
+ setIsOpen(STACKED_FOCUS_MODAL_ID, false);
12227
+ return;
12228
+ }
12229
+ if (data.shippingMethod) {
12230
+ await updateShippingMethod(
12231
+ {
12232
+ method_id: data.shippingMethod.id,
12233
+ shipping_option_id: values.shipping_option_id,
12234
+ custom_amount: values.custom_amount ? convertNumber(values.custom_amount) : void 0
12235
+ },
12236
+ {
12237
+ onError: (e) => {
12238
+ toast.error(e.message);
12239
+ },
12240
+ onSuccess: () => {
12241
+ setIsOpen(STACKED_FOCUS_MODAL_ID, false);
12242
+ }
12407
12243
  }
12244
+ );
12245
+ return;
12246
+ }
12247
+ await addShippingMethod(
12248
+ {
12249
+ shipping_option_id: values.shipping_option_id,
12250
+ custom_amount: values.custom_amount ? convertNumber(values.custom_amount) : void 0
12408
12251
  },
12409
12252
  {
12410
- onSuccess: () => {
12411
- handleSuccess();
12253
+ onError: (e) => {
12254
+ toast.error(e.message);
12412
12255
  },
12413
- onError: (error) => {
12414
- toast.error(error.message);
12256
+ onSuccess: () => {
12257
+ setIsOpen(STACKED_FOCUS_MODAL_ID, false);
12415
12258
  }
12416
12259
  }
12417
12260
  );
12418
12261
  });
12419
- return /* @__PURE__ */ jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxs(
12262
+ return /* @__PURE__ */ jsx(StackedFocusModal.Content, { children: /* @__PURE__ */ jsx(Form$2, { ...form, children: /* @__PURE__ */ jsxs(
12420
12263
  KeyboundForm,
12421
12264
  {
12422
- className: "flex flex-1 flex-col overflow-hidden",
12265
+ className: "flex h-full flex-col overflow-hidden",
12423
12266
  onSubmit,
12424
12267
  children: [
12425
- /* @__PURE__ */ jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-y-4", children: [
12268
+ /* @__PURE__ */ jsx(StackedFocusModal.Header, {}),
12269
+ /* @__PURE__ */ jsx(StackedFocusModal.Body, { className: "flex flex-1 flex-col overflow-hidden", children: /* @__PURE__ */ jsx("div", { className: "flex flex-1 flex-col items-center overflow-y-auto", children: /* @__PURE__ */ jsxs("div", { className: "flex w-full max-w-[720px] flex-col gap-y-6 px-6 py-16", children: [
12270
+ /* @__PURE__ */ jsxs("div", { children: [
12271
+ /* @__PURE__ */ jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Shipping" }) }),
12272
+ /* @__PURE__ */ jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Add a shipping method for the selected shipping profile. You can see the items that will be shipped using this method in the preview below." }) })
12273
+ ] }),
12274
+ /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
12426
12275
  /* @__PURE__ */ jsx(
12427
- Form$2.Field,
12276
+ LocationField,
12428
12277
  {
12429
12278
  control: form.control,
12430
- name: "country_code",
12431
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12432
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Country" }),
12433
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(CountrySelect, { ...field }) }),
12434
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12435
- ] })
12279
+ setValue: form.setValue
12436
12280
  }
12437
12281
  ),
12438
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
12439
- /* @__PURE__ */ jsx(
12440
- Form$2.Field,
12441
- {
12442
- control: form.control,
12443
- name: "first_name",
12444
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12445
- /* @__PURE__ */ jsx(Form$2.Label, { children: "First name" }),
12446
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12447
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12448
- ] })
12449
- }
12450
- ),
12451
- /* @__PURE__ */ jsx(
12452
- Form$2.Field,
12453
- {
12454
- control: form.control,
12455
- name: "last_name",
12456
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12457
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Last name" }),
12458
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12459
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12460
- ] })
12461
- }
12462
- )
12463
- ] }),
12282
+ /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
12464
12283
  /* @__PURE__ */ jsx(
12465
- Form$2.Field,
12284
+ ShippingOptionField,
12466
12285
  {
12467
- control: form.control,
12468
- name: "company",
12469
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12470
- /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Company" }),
12471
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12472
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12473
- ] })
12286
+ shippingProfileId: data.shippingProfileId,
12287
+ preview,
12288
+ control: form.control
12474
12289
  }
12475
12290
  ),
12291
+ /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
12476
12292
  /* @__PURE__ */ jsx(
12477
- Form$2.Field,
12293
+ CustomAmountField,
12478
12294
  {
12479
12295
  control: form.control,
12480
- name: "address_1",
12481
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12482
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Address" }),
12483
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12484
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12485
- ] })
12296
+ currencyCode: order.currency_code
12486
12297
  }
12487
12298
  ),
12299
+ /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
12488
12300
  /* @__PURE__ */ jsx(
12489
- Form$2.Field,
12301
+ ItemsPreview,
12490
12302
  {
12491
- control: form.control,
12492
- name: "address_2",
12493
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12494
- /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Apartment, suite, etc." }),
12495
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12496
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12303
+ order,
12304
+ shippingProfileId: data.shippingProfileId
12305
+ }
12306
+ )
12307
+ ] }) }) }),
12308
+ /* @__PURE__ */ jsx(StackedFocusModal.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-x-2", children: [
12309
+ /* @__PURE__ */ jsx(StackedFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
12310
+ /* @__PURE__ */ jsx(
12311
+ Button,
12312
+ {
12313
+ size: "small",
12314
+ type: "submit",
12315
+ isLoading: isPending || isUpdatingShippingMethod,
12316
+ children: data.shippingMethod ? "Update" : "Add"
12317
+ }
12318
+ )
12319
+ ] }) })
12320
+ ]
12321
+ }
12322
+ ) }) });
12323
+ };
12324
+ const shippingMethodSchema = objectType({
12325
+ location_id: stringType(),
12326
+ shipping_option_id: stringType(),
12327
+ custom_amount: unionType([numberType(), stringType()]).optional()
12328
+ });
12329
+ const ItemsPreview = ({ order, shippingProfileId }) => {
12330
+ const matches = order.items.filter(
12331
+ (item) => {
12332
+ var _a, _b, _c;
12333
+ return ((_c = (_b = (_a = item.variant) == null ? void 0 : _a.product) == null ? void 0 : _b.shipping_profile) == null ? void 0 : _c.id) === shippingProfileId;
12334
+ }
12335
+ );
12336
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-y-6", children: [
12337
+ /* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 items-center gap-3", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
12338
+ /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: "Items to ship" }),
12339
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Items with the selected shipping profile." })
12340
+ ] }) }),
12341
+ /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-subtle shadow-elevation-card-rest rounded-xl", children: [
12342
+ /* @__PURE__ */ jsxs("div", { className: "text-ui-fg-muted grid grid-cols-2 gap-3 px-4 py-2", children: [
12343
+ /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: "Item" }) }),
12344
+ /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: "Quantity" }) })
12345
+ ] }),
12346
+ /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-y-1.5 px-[5px] pb-[5px]", children: matches.length > 0 ? matches == null ? void 0 : matches.map((item) => /* @__PURE__ */ jsxs(
12347
+ "div",
12348
+ {
12349
+ className: "bg-ui-bg-base shadow-elevation-card-rest grid grid-cols-2 items-center gap-3 rounded-lg px-4 py-2",
12350
+ children: [
12351
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-3", children: [
12352
+ /* @__PURE__ */ jsx(
12353
+ Thumbnail,
12354
+ {
12355
+ thumbnail: item.thumbnail,
12356
+ alt: item.product_title ?? void 0
12357
+ }
12358
+ ),
12359
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
12360
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-1", children: [
12361
+ /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: item.product_title }),
12362
+ /* @__PURE__ */ jsxs(
12363
+ Text,
12364
+ {
12365
+ size: "small",
12366
+ leading: "compact",
12367
+ className: "text-ui-fg-subtle",
12368
+ children: [
12369
+ "(",
12370
+ item.variant_title,
12371
+ ")"
12372
+ ]
12373
+ }
12374
+ )
12375
+ ] }),
12376
+ /* @__PURE__ */ jsx(
12377
+ Text,
12378
+ {
12379
+ size: "small",
12380
+ leading: "compact",
12381
+ className: "text-ui-fg-subtle",
12382
+ children: item.variant_sku
12383
+ }
12384
+ )
12497
12385
  ] })
12498
- }
12499
- ),
12500
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
12501
- /* @__PURE__ */ jsx(
12502
- Form$2.Field,
12503
- {
12504
- control: form.control,
12505
- name: "postal_code",
12506
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12507
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Postal code" }),
12508
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12509
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12510
- ] })
12511
- }
12512
- ),
12513
- /* @__PURE__ */ jsx(
12514
- Form$2.Field,
12386
+ ] }),
12387
+ /* @__PURE__ */ jsxs(
12388
+ Text,
12515
12389
  {
12516
- control: form.control,
12517
- name: "city",
12518
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12519
- /* @__PURE__ */ jsx(Form$2.Label, { children: "City" }),
12520
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12521
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12522
- ] })
12390
+ size: "small",
12391
+ leading: "compact",
12392
+ className: "text-ui-fg-subtle",
12393
+ children: [
12394
+ item.quantity,
12395
+ "x"
12396
+ ]
12523
12397
  }
12524
12398
  )
12399
+ ]
12400
+ },
12401
+ item.id
12402
+ )) : /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest flex flex-col items-center justify-center gap-1 gap-x-3 rounded-lg p-4", children: [
12403
+ /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: "No items found" }),
12404
+ /* @__PURE__ */ jsxs(Text, { size: "small", className: "text-ui-fg-subtle", children: [
12405
+ 'No items found for "',
12406
+ query,
12407
+ '".'
12408
+ ] })
12409
+ ] }) })
12410
+ ] })
12411
+ ] });
12412
+ };
12413
+ const LocationField = ({ control, setValue }) => {
12414
+ const locations = useComboboxData({
12415
+ queryKey: ["locations"],
12416
+ queryFn: async (params) => {
12417
+ return await sdk.admin.stockLocation.list(params);
12418
+ },
12419
+ getOptions: (data) => {
12420
+ return data.stock_locations.map((location) => ({
12421
+ label: location.name,
12422
+ value: location.id
12423
+ }));
12424
+ }
12425
+ });
12426
+ return /* @__PURE__ */ jsx(
12427
+ Form$2.Field,
12428
+ {
12429
+ control,
12430
+ name: "location_id",
12431
+ render: ({ field: { onChange, ...field } }) => {
12432
+ return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
12433
+ /* @__PURE__ */ jsxs("div", { children: [
12434
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Location" }),
12435
+ /* @__PURE__ */ jsx(Form$2.Hint, { children: "Choose where you want to ship the items from." })
12525
12436
  ] }),
12526
- /* @__PURE__ */ jsx(
12527
- Form$2.Field,
12437
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
12438
+ Combobox,
12528
12439
  {
12529
- control: form.control,
12530
- name: "province",
12531
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12532
- /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Province / State" }),
12533
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12534
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12535
- ] })
12440
+ options: locations.options,
12441
+ fetchNextPage: locations.fetchNextPage,
12442
+ isFetchingNextPage: locations.isFetchingNextPage,
12443
+ searchValue: locations.searchValue,
12444
+ onSearchValueChange: locations.onSearchValueChange,
12445
+ placeholder: "Select location",
12446
+ onChange: (value) => {
12447
+ setValue("shipping_option_id", "", {
12448
+ shouldDirty: true,
12449
+ shouldTouch: true
12450
+ });
12451
+ onChange(value);
12452
+ },
12453
+ ...field
12536
12454
  }
12537
- ),
12455
+ ) })
12456
+ ] }) });
12457
+ }
12458
+ }
12459
+ );
12460
+ };
12461
+ const ShippingOptionField = ({
12462
+ shippingProfileId,
12463
+ preview,
12464
+ control
12465
+ }) => {
12466
+ var _a;
12467
+ const locationId = useWatch({ control, name: "location_id" });
12468
+ const shippingOptions = useComboboxData({
12469
+ queryKey: ["shipping_options", locationId, shippingProfileId],
12470
+ queryFn: async (params) => {
12471
+ return await sdk.admin.shippingOption.list({
12472
+ ...params,
12473
+ stock_location_id: locationId,
12474
+ shipping_profile_id: shippingProfileId
12475
+ });
12476
+ },
12477
+ getOptions: (data) => {
12478
+ return data.shipping_options.map((option) => {
12479
+ var _a2;
12480
+ if ((_a2 = option.rules) == null ? void 0 : _a2.find(
12481
+ (r) => r.attribute === "is_return" && r.value === "true"
12482
+ )) {
12483
+ return void 0;
12484
+ }
12485
+ return {
12486
+ label: option.name,
12487
+ value: option.id
12488
+ };
12489
+ }).filter(Boolean);
12490
+ },
12491
+ enabled: !!locationId && !!shippingProfileId,
12492
+ defaultValue: ((_a = preview.shipping_methods[0]) == null ? void 0 : _a.shipping_option_id) || void 0
12493
+ });
12494
+ const tooltipContent = !locationId && !shippingProfileId ? "Choose a location and shipping profile first." : !locationId ? "Choose a location first." : "Choose a shipping profile first.";
12495
+ return /* @__PURE__ */ jsx(
12496
+ Form$2.Field,
12497
+ {
12498
+ control,
12499
+ name: "shipping_option_id",
12500
+ render: ({ field }) => {
12501
+ return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
12502
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
12503
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Shipping option" }),
12504
+ /* @__PURE__ */ jsx(Form$2.Hint, { children: "Choose the shipping option to use." })
12505
+ ] }),
12538
12506
  /* @__PURE__ */ jsx(
12539
- Form$2.Field,
12507
+ ConditionalTooltip,
12540
12508
  {
12541
- control: form.control,
12542
- name: "phone",
12543
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12544
- /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Phone" }),
12545
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12546
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12547
- ] })
12509
+ content: tooltipContent,
12510
+ showTooltip: !locationId || !shippingProfileId,
12511
+ children: /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
12512
+ Combobox,
12513
+ {
12514
+ options: shippingOptions.options,
12515
+ fetchNextPage: shippingOptions.fetchNextPage,
12516
+ isFetchingNextPage: shippingOptions.isFetchingNextPage,
12517
+ searchValue: shippingOptions.searchValue,
12518
+ onSearchValueChange: shippingOptions.onSearchValueChange,
12519
+ placeholder: "Select shipping option",
12520
+ ...field,
12521
+ disabled: !locationId || !shippingProfileId
12522
+ }
12523
+ ) }) })
12548
12524
  }
12549
12525
  )
12550
- ] }) }),
12551
- /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
12552
- /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
12553
- /* @__PURE__ */ jsx(Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
12554
- ] }) })
12555
- ]
12526
+ ] }) });
12527
+ }
12556
12528
  }
12557
- ) });
12529
+ );
12530
+ };
12531
+ const CustomAmountField = ({
12532
+ control,
12533
+ currencyCode
12534
+ }) => {
12535
+ return /* @__PURE__ */ jsx(
12536
+ Form$2.Field,
12537
+ {
12538
+ control,
12539
+ name: "custom_amount",
12540
+ render: ({ field: { onChange, ...field } }) => {
12541
+ return /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
12542
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
12543
+ /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Custom amount" }),
12544
+ /* @__PURE__ */ jsx(Form$2.Hint, { children: "Set a custom amount for the shipping option." })
12545
+ ] }),
12546
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
12547
+ CurrencyInput,
12548
+ {
12549
+ ...field,
12550
+ onValueChange: (value) => onChange(value),
12551
+ symbol: getNativeSymbol(currencyCode),
12552
+ code: currencyCode
12553
+ }
12554
+ ) })
12555
+ ] });
12556
+ }
12557
+ }
12558
+ );
12558
12559
  };
12559
- const schema$1 = addressSchema;
12560
12560
  const TransferOwnership = () => {
12561
12561
  const { id } = useParams();
12562
12562
  const { draft_order, isPending, isError, error } = useDraftOrder(id, {
@@ -13069,17 +13069,13 @@ const routeModule = {
13069
13069
  Component: Items,
13070
13070
  path: "/draft-orders/:id/items"
13071
13071
  },
13072
- {
13073
- Component: Metadata,
13074
- path: "/draft-orders/:id/metadata"
13075
- },
13076
13072
  {
13077
13073
  Component: Promotions,
13078
13074
  path: "/draft-orders/:id/promotions"
13079
13075
  },
13080
13076
  {
13081
- Component: Shipping,
13082
- path: "/draft-orders/:id/shipping"
13077
+ Component: Metadata,
13078
+ path: "/draft-orders/:id/metadata"
13083
13079
  },
13084
13080
  {
13085
13081
  Component: SalesChannel,
@@ -13089,6 +13085,10 @@ const routeModule = {
13089
13085
  Component: ShippingAddress,
13090
13086
  path: "/draft-orders/:id/shipping-address"
13091
13087
  },
13088
+ {
13089
+ Component: Shipping,
13090
+ path: "/draft-orders/:id/shipping"
13091
+ },
13092
13092
  {
13093
13093
  Component: TransferOwnership,
13094
13094
  path: "/draft-orders/:id/transfer-ownership"