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