@medusajs/draft-order 2.11.1-snapshot-20251021090705 → 2.11.1-snapshot-20251021110351

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.
@@ -9850,1718 +9850,2027 @@ const EmailForm = ({ order }) => {
9850
9850
  const schema$3 = objectType({
9851
9851
  email: stringType().email()
9852
9852
  });
9853
- const InlineTip = React.forwardRef(
9854
- ({ variant = "tip", label, className, children, ...props }, ref) => {
9855
- const labelValue = label || (variant === "warning" ? "Warning" : "Tip");
9853
+ const NumberInput = React.forwardRef(
9854
+ ({
9855
+ value,
9856
+ onChange,
9857
+ size = "base",
9858
+ min = 0,
9859
+ max = 100,
9860
+ step = 1,
9861
+ className,
9862
+ disabled,
9863
+ ...props
9864
+ }, ref) => {
9865
+ const handleChange = (event) => {
9866
+ const newValue = event.target.value === "" ? min : Number(event.target.value);
9867
+ if (!isNaN(newValue) && (max === void 0 || newValue <= max) && (min === void 0 || newValue >= min)) {
9868
+ onChange(newValue);
9869
+ }
9870
+ };
9871
+ const handleIncrement = () => {
9872
+ const newValue = value + step;
9873
+ if (max === void 0 || newValue <= max) {
9874
+ onChange(newValue);
9875
+ }
9876
+ };
9877
+ const handleDecrement = () => {
9878
+ const newValue = value - step;
9879
+ if (min === void 0 || newValue >= min) {
9880
+ onChange(newValue);
9881
+ }
9882
+ };
9856
9883
  return /* @__PURE__ */ jsxRuntime.jsxs(
9857
9884
  "div",
9858
9885
  {
9859
- ref,
9860
9886
  className: ui.clx(
9861
- "bg-ui-bg-component txt-small text-ui-fg-subtle grid grid-cols-[4px_1fr] items-start gap-3 rounded-lg border p-3",
9887
+ "inline-flex rounded-md bg-ui-bg-field shadow-borders-base overflow-hidden divide-x transition-fg",
9888
+ "[&:has(input:focus)]:shadow-borders-interactive-with-active",
9889
+ {
9890
+ "h-7": size === "small",
9891
+ "h-8": size === "base"
9892
+ },
9862
9893
  className
9863
9894
  ),
9864
- ...props,
9865
9895
  children: [
9866
9896
  /* @__PURE__ */ jsxRuntime.jsx(
9867
- "div",
9897
+ "input",
9868
9898
  {
9869
- role: "presentation",
9870
- className: ui.clx("w-4px bg-ui-tag-neutral-icon h-full rounded-full", {
9871
- "bg-ui-tag-orange-icon": variant === "warning"
9872
- })
9899
+ ref,
9900
+ type: "number",
9901
+ value,
9902
+ onChange: handleChange,
9903
+ min,
9904
+ max,
9905
+ step,
9906
+ className: ui.clx(
9907
+ "flex-1 px-2 py-1 bg-transparent txt-compact-small text-ui-fg-base outline-none [appearance:textfield]",
9908
+ "[&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none",
9909
+ "placeholder:text-ui-fg-muted"
9910
+ ),
9911
+ ...props
9873
9912
  }
9874
9913
  ),
9875
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-pretty", children: [
9876
- /* @__PURE__ */ jsxRuntime.jsxs("strong", { className: "txt-small-plus text-ui-fg-base", children: [
9877
- labelValue,
9878
- ":"
9879
- ] }),
9880
- " ",
9881
- children
9882
- ] })
9914
+ /* @__PURE__ */ jsxRuntime.jsxs(
9915
+ "button",
9916
+ {
9917
+ className: ui.clx(
9918
+ "flex items-center justify-center outline-none transition-fg",
9919
+ "disabled:cursor-not-allowed disabled:text-ui-fg-muted",
9920
+ "focus:bg-ui-bg-field-component-hover",
9921
+ "hover:bg-ui-bg-field-component-hover",
9922
+ {
9923
+ "size-7": size === "small",
9924
+ "size-8": size === "base"
9925
+ }
9926
+ ),
9927
+ type: "button",
9928
+ onClick: handleDecrement,
9929
+ disabled: min !== void 0 && value <= min || disabled,
9930
+ children: [
9931
+ /* @__PURE__ */ jsxRuntime.jsx(icons.Minus, {}),
9932
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: `Decrease by ${step}` })
9933
+ ]
9934
+ }
9935
+ ),
9936
+ /* @__PURE__ */ jsxRuntime.jsxs(
9937
+ "button",
9938
+ {
9939
+ className: ui.clx(
9940
+ "flex items-center justify-center outline-none transition-fg",
9941
+ "disabled:cursor-not-allowed disabled:text-ui-fg-muted",
9942
+ "focus:bg-ui-bg-field-hover",
9943
+ "hover:bg-ui-bg-field-hover",
9944
+ {
9945
+ "size-7": size === "small",
9946
+ "size-8": size === "base"
9947
+ }
9948
+ ),
9949
+ type: "button",
9950
+ onClick: handleIncrement,
9951
+ disabled: max !== void 0 && value >= max || disabled,
9952
+ children: [
9953
+ /* @__PURE__ */ jsxRuntime.jsx(icons.Plus, {}),
9954
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: `Increase by ${step}` })
9955
+ ]
9956
+ }
9957
+ )
9883
9958
  ]
9884
9959
  }
9885
9960
  );
9886
9961
  }
9887
9962
  );
9888
- InlineTip.displayName = "InlineTip";
9889
- const MetadataFieldSchema = objectType({
9890
- key: stringType(),
9891
- disabled: booleanType().optional(),
9892
- value: anyType()
9893
- });
9894
- const MetadataSchema = objectType({
9895
- metadata: arrayType(MetadataFieldSchema)
9896
- });
9897
- const Metadata = () => {
9963
+ const PRODUCT_VARIANTS_QUERY_KEY = "product-variants";
9964
+ const productVariantsQueryKeys = {
9965
+ list: (query2) => [
9966
+ PRODUCT_VARIANTS_QUERY_KEY,
9967
+ query2 ? query2 : void 0
9968
+ ]
9969
+ };
9970
+ const useProductVariants = (query2, options) => {
9971
+ const { data, ...rest } = reactQuery.useQuery({
9972
+ queryKey: productVariantsQueryKeys.list(query2),
9973
+ queryFn: async () => await sdk.admin.productVariant.list(query2),
9974
+ ...options
9975
+ });
9976
+ return { ...data, ...rest };
9977
+ };
9978
+ const useCancelOrderEdit = ({ preview }) => {
9979
+ const { mutateAsync: cancelOrderEdit } = useDraftOrderCancelEdit(preview == null ? void 0 : preview.id);
9980
+ const onCancel = React.useCallback(async () => {
9981
+ if (!preview) {
9982
+ return true;
9983
+ }
9984
+ let res = false;
9985
+ await cancelOrderEdit(void 0, {
9986
+ onError: (e) => {
9987
+ ui.toast.error(e.message);
9988
+ },
9989
+ onSuccess: () => {
9990
+ res = true;
9991
+ }
9992
+ });
9993
+ return res;
9994
+ }, [preview, cancelOrderEdit]);
9995
+ return { onCancel };
9996
+ };
9997
+ let IS_REQUEST_RUNNING = false;
9998
+ const useInitiateOrderEdit = ({
9999
+ preview
10000
+ }) => {
10001
+ const navigate = reactRouterDom.useNavigate();
10002
+ const { mutateAsync } = useDraftOrderBeginEdit(preview == null ? void 0 : preview.id);
10003
+ React.useEffect(() => {
10004
+ async function run() {
10005
+ if (IS_REQUEST_RUNNING || !preview) {
10006
+ return;
10007
+ }
10008
+ if (preview.order_change) {
10009
+ return;
10010
+ }
10011
+ IS_REQUEST_RUNNING = true;
10012
+ await mutateAsync(void 0, {
10013
+ onError: (e) => {
10014
+ ui.toast.error(e.message);
10015
+ navigate(`/draft-orders/${preview.id}`, { replace: true });
10016
+ return;
10017
+ }
10018
+ });
10019
+ IS_REQUEST_RUNNING = false;
10020
+ }
10021
+ run();
10022
+ }, [preview, navigate, mutateAsync]);
10023
+ };
10024
+ function convertNumber(value) {
10025
+ return typeof value === "string" ? Number(value.replace(",", ".")) : value;
10026
+ }
10027
+ const STACKED_MODAL_ID = "items_stacked_modal";
10028
+ const Items = () => {
9898
10029
  const { id } = reactRouterDom.useParams();
9899
- const { order, isPending, isError, error } = useOrder(id, {
9900
- fields: "metadata"
10030
+ const {
10031
+ order: preview,
10032
+ isPending: isPreviewPending,
10033
+ isError: isPreviewError,
10034
+ error: previewError
10035
+ } = useOrderPreview(id, void 0, {
10036
+ placeholderData: reactQuery.keepPreviousData
9901
10037
  });
10038
+ useInitiateOrderEdit({ preview });
10039
+ const { draft_order, isPending, isError, error } = useDraftOrder(
10040
+ id,
10041
+ {
10042
+ fields: "currency_code"
10043
+ },
10044
+ {
10045
+ enabled: !!id
10046
+ }
10047
+ );
10048
+ const { onCancel } = useCancelOrderEdit({ preview });
9902
10049
  if (isError) {
9903
10050
  throw error;
9904
10051
  }
9905
- const isReady = !isPending && !!order;
9906
- return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
9907
- /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Header, { children: [
9908
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Metadata" }) }),
9909
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Add metadata to the draft order." }) })
9910
- ] }),
9911
- !isReady ? /* @__PURE__ */ jsxRuntime.jsx(PlaceholderInner, {}) : /* @__PURE__ */ jsxRuntime.jsx(MetadataForm, { orderId: id, metadata: order == null ? void 0 : order.metadata })
9912
- ] });
10052
+ if (isPreviewError) {
10053
+ throw previewError;
10054
+ }
10055
+ const ready = !!preview && !isPreviewPending && !!draft_order && !isPending;
10056
+ return /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal, { onClose: onCancel, children: ready ? /* @__PURE__ */ jsxRuntime.jsx(ItemsForm, { preview, currencyCode: draft_order.currency_code }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10057
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Edit Items" }) }),
10058
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Loading data for the draft order, please wait..." }) })
10059
+ ] }) });
9913
10060
  };
9914
- const METADATA_KEY_LABEL_ID = "metadata-form-key-label";
9915
- const METADATA_VALUE_LABEL_ID = "metadata-form-value-label";
9916
- const MetadataForm = ({ orderId, metadata }) => {
10061
+ const ItemsForm = ({ preview, currencyCode }) => {
10062
+ var _a;
10063
+ const [isSubmitting, setIsSubmitting] = React.useState(false);
10064
+ const [modalContent, setModalContent] = React.useState(
10065
+ null
10066
+ );
9917
10067
  const { handleSuccess } = useRouteModal();
9918
- const hasUneditableRows = getHasUneditableRows(metadata);
9919
- const { mutateAsync, isPending } = useUpdateDraftOrder(orderId);
9920
- const form = reactHookForm.useForm({
9921
- defaultValues: {
9922
- metadata: getDefaultValues(metadata)
9923
- },
9924
- resolver: zod.zodResolver(MetadataSchema)
9925
- });
9926
- const handleSubmit = form.handleSubmit(async (data) => {
9927
- const parsedData = parseValues(data);
9928
- await mutateAsync(
9929
- {
9930
- metadata: parsedData
9931
- },
9932
- {
9933
- onSuccess: () => {
9934
- ui.toast.success("Metadata updated");
9935
- handleSuccess();
9936
- },
9937
- onError: (error) => {
9938
- ui.toast.error(error.message);
9939
- }
10068
+ const { searchValue, onSearchValueChange, query: query2 } = useDebouncedSearch();
10069
+ const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
10070
+ const { mutateAsync: requestOrderEdit } = useDraftOrderRequestEdit(preview.id);
10071
+ const itemCount = ((_a = preview.items) == null ? void 0 : _a.reduce((acc, item) => acc + item.quantity, 0)) || 0;
10072
+ const matches = React.useMemo(() => {
10073
+ return matchSorter.matchSorter(preview.items, query2, {
10074
+ keys: ["product_title", "variant_title", "variant_sku", "title"]
10075
+ });
10076
+ }, [preview.items, query2]);
10077
+ const onSubmit = async () => {
10078
+ setIsSubmitting(true);
10079
+ let requestSucceeded = false;
10080
+ await requestOrderEdit(void 0, {
10081
+ onError: (e) => {
10082
+ ui.toast.error(`Failed to request order edit: ${e.message}`);
10083
+ },
10084
+ onSuccess: () => {
10085
+ requestSucceeded = true;
9940
10086
  }
9941
- );
9942
- });
9943
- const { fields, insert, remove } = reactHookForm.useFieldArray({
9944
- control: form.control,
9945
- name: "metadata"
9946
- });
9947
- function deleteRow(index) {
9948
- remove(index);
9949
- if (fields.length === 1) {
9950
- insert(0, {
9951
- key: "",
9952
- value: "",
9953
- disabled: false
9954
- });
10087
+ });
10088
+ if (!requestSucceeded) {
10089
+ setIsSubmitting(false);
10090
+ return;
9955
10091
  }
9956
- }
9957
- function insertRow(index, position) {
9958
- insert(index + (position === "above" ? 0 : 1), {
9959
- key: "",
9960
- value: "",
9961
- disabled: false
10092
+ await confirmOrderEdit(void 0, {
10093
+ onError: (e) => {
10094
+ ui.toast.error(`Failed to confirm order edit: ${e.message}`);
10095
+ },
10096
+ onSuccess: () => {
10097
+ handleSuccess();
10098
+ },
10099
+ onSettled: () => {
10100
+ setIsSubmitting(false);
10101
+ }
9962
10102
  });
9963
- }
9964
- return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(
9965
- KeyboundForm,
9966
- {
9967
- onSubmit: handleSubmit,
9968
- className: "flex flex-1 flex-col overflow-hidden",
9969
- children: [
9970
- /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Body, { className: "flex flex-1 flex-col gap-y-8 overflow-y-auto", children: [
9971
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest grid grid-cols-1 divide-y rounded-lg", children: [
9972
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-subtle grid grid-cols-2 divide-x rounded-t-lg", children: [
9973
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "txt-compact-small-plus text-ui-fg-subtle px-2 py-1.5", children: /* @__PURE__ */ jsxRuntime.jsx("label", { id: METADATA_KEY_LABEL_ID, children: "Key" }) }),
9974
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "txt-compact-small-plus text-ui-fg-subtle px-2 py-1.5", children: /* @__PURE__ */ jsxRuntime.jsx("label", { id: METADATA_VALUE_LABEL_ID, children: "Value" }) })
10103
+ };
10104
+ const onKeyDown = React.useCallback(
10105
+ (e) => {
10106
+ if (e.key === "Enter" && (e.ctrlKey || e.metaKey)) {
10107
+ if (modalContent || isSubmitting) {
10108
+ return;
10109
+ }
10110
+ onSubmit();
10111
+ }
10112
+ },
10113
+ [modalContent, isSubmitting, onSubmit]
10114
+ );
10115
+ React.useEffect(() => {
10116
+ document.addEventListener("keydown", onKeyDown);
10117
+ return () => {
10118
+ document.removeEventListener("keydown", onKeyDown);
10119
+ };
10120
+ }, [onKeyDown]);
10121
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-full flex-col overflow-hidden", children: [
10122
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Header, {}),
10123
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Body, { className: "flex flex-1 flex-col overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsxs(
10124
+ StackedFocusModal,
10125
+ {
10126
+ id: STACKED_MODAL_ID,
10127
+ onOpenChangeCallback: (open) => {
10128
+ if (!open) {
10129
+ setModalContent(null);
10130
+ }
10131
+ },
10132
+ children: [
10133
+ /* @__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: [
10134
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10135
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Items" }) }),
10136
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Edit the items in the draft order" }) })
9975
10137
  ] }),
9976
- fields.map((field, index) => {
9977
- const isDisabled = field.disabled || false;
9978
- let placeholder = "-";
9979
- if (typeof field.value === "object") {
9980
- placeholder = "{ ... }";
9981
- }
9982
- if (Array.isArray(field.value)) {
9983
- placeholder = "[ ... ]";
9984
- }
9985
- return /* @__PURE__ */ jsxRuntime.jsx(
9986
- ConditionalTooltip,
9987
- {
9988
- showTooltip: isDisabled,
9989
- content: "This row is disabled because it contains non-primitive data.",
9990
- children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "group/table relative", children: [
9991
- /* @__PURE__ */ jsxRuntime.jsxs(
9992
- "div",
9993
- {
9994
- className: ui.clx("grid grid-cols-2 divide-x", {
9995
- "overflow-hidden rounded-b-lg": index === fields.length - 1
9996
- }),
9997
- children: [
9998
- /* @__PURE__ */ jsxRuntime.jsx(
9999
- Form$2.Field,
10000
- {
10001
- control: form.control,
10002
- name: `metadata.${index}.key`,
10003
- render: ({ field: field2 }) => {
10004
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
10005
- GridInput,
10006
- {
10007
- "aria-labelledby": METADATA_KEY_LABEL_ID,
10008
- ...field2,
10009
- disabled: isDisabled,
10010
- placeholder: "Key"
10011
- }
10012
- ) }) });
10013
- }
10014
- }
10015
- ),
10016
- /* @__PURE__ */ jsxRuntime.jsx(
10017
- Form$2.Field,
10018
- {
10019
- control: form.control,
10020
- name: `metadata.${index}.value`,
10021
- render: ({ field: { value, ...field2 } }) => {
10022
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
10023
- GridInput,
10024
- {
10025
- "aria-labelledby": METADATA_VALUE_LABEL_ID,
10026
- ...field2,
10027
- value: isDisabled ? placeholder : value,
10028
- disabled: isDisabled,
10029
- placeholder: "Value"
10030
- }
10031
- ) }) });
10032
- }
10033
- }
10034
- )
10035
- ]
10036
- }
10037
- ),
10038
- /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu, { children: [
10138
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
10139
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-6", children: [
10140
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 items-center gap-3", children: [
10141
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
10142
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "Items" }),
10143
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Choose items from the product catalog." })
10144
+ ] }),
10145
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
10146
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(
10147
+ ui.Input,
10148
+ {
10149
+ type: "search",
10150
+ placeholder: "Search items",
10151
+ value: searchValue,
10152
+ onChange: (e) => onSearchValueChange(e.target.value)
10153
+ }
10154
+ ) }),
10155
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu, { children: [
10156
+ /* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenu.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { type: "button", children: /* @__PURE__ */ jsxRuntime.jsx(icons.Plus, {}) }) }),
10157
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu.Content, { children: [
10039
10158
  /* @__PURE__ */ jsxRuntime.jsx(
10040
- ui.DropdownMenu.Trigger,
10159
+ StackedModalTrigger$1,
10041
10160
  {
10042
- className: ui.clx(
10043
- "invisible absolute inset-y-0 -right-2.5 my-auto group-hover/table:visible data-[state='open']:visible",
10044
- {
10045
- hidden: isDisabled
10046
- }
10047
- ),
10048
- disabled: isDisabled,
10049
- asChild: true,
10050
- children: /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { size: "2xsmall", children: /* @__PURE__ */ jsxRuntime.jsx(icons.EllipsisVertical, {}) })
10161
+ type: "add-items",
10162
+ setModalContent
10051
10163
  }
10052
10164
  ),
10053
- /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu.Content, { children: [
10054
- /* @__PURE__ */ jsxRuntime.jsxs(
10055
- ui.DropdownMenu.Item,
10056
- {
10057
- className: "gap-x-2",
10058
- onClick: () => insertRow(index, "above"),
10059
- children: [
10060
- /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowUpMini, { className: "text-ui-fg-subtle" }),
10061
- "Insert row above"
10062
- ]
10063
- }
10064
- ),
10065
- /* @__PURE__ */ jsxRuntime.jsxs(
10066
- ui.DropdownMenu.Item,
10067
- {
10068
- className: "gap-x-2",
10069
- onClick: () => insertRow(index, "below"),
10070
- children: [
10071
- /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowDownMini, { className: "text-ui-fg-subtle" }),
10072
- "Insert row below"
10073
- ]
10074
- }
10075
- ),
10076
- /* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenu.Separator, {}),
10077
- /* @__PURE__ */ jsxRuntime.jsxs(
10078
- ui.DropdownMenu.Item,
10079
- {
10080
- className: "gap-x-2",
10081
- onClick: () => deleteRow(index),
10082
- children: [
10083
- /* @__PURE__ */ jsxRuntime.jsx(icons.Trash, { className: "text-ui-fg-subtle" }),
10084
- "Delete row"
10085
- ]
10086
- }
10087
- )
10088
- ] })
10165
+ /* @__PURE__ */ jsxRuntime.jsx(
10166
+ StackedModalTrigger$1,
10167
+ {
10168
+ type: "add-custom-item",
10169
+ setModalContent
10170
+ }
10171
+ )
10089
10172
  ] })
10090
10173
  ] })
10091
- },
10092
- field.id
10093
- );
10094
- })
10095
- ] }),
10096
- hasUneditableRows && /* @__PURE__ */ jsxRuntime.jsx(InlineTip, { variant: "warning", label: "Some rows are disabled", children: "This object contains non-primitive metadata, such as arrays or objects, that can't be edited here. To edit the disabled rows, use the API directly." })
10097
- ] }),
10098
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
10099
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
10100
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
10101
- ] }) })
10102
- ]
10103
- }
10104
- ) });
10105
- };
10106
- const GridInput = React.forwardRef(({ className, ...props }, ref) => {
10107
- return /* @__PURE__ */ jsxRuntime.jsx(
10108
- "input",
10109
- {
10110
- ref,
10111
- ...props,
10112
- autoComplete: "off",
10113
- className: ui.clx(
10114
- "txt-compact-small text-ui-fg-base placeholder:text-ui-fg-muted disabled:text-ui-fg-disabled disabled:bg-ui-bg-base bg-transparent px-2 py-1.5 outline-none",
10115
- className
10174
+ ] })
10175
+ ] }),
10176
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-subtle shadow-elevation-card-rest rounded-xl", children: [
10177
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-[5px]", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-ui-fg-muted grid grid-cols-[2fr_1fr_2fr_28px] gap-3 px-4 py-2", children: [
10178
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: "Item" }) }),
10179
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: "Quantity" }) }),
10180
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-right", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: "Price" }) }),
10181
+ /* @__PURE__ */ jsxRuntime.jsx("div", {})
10182
+ ] }) }),
10183
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-y-1.5 px-[5px] pb-[5px]", children: itemCount <= 0 ? /* @__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: [
10184
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "There are no items in this order" }),
10185
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Add items to the order to get started." })
10186
+ ] }) : matches.length > 0 ? matches == null ? void 0 : matches.map((item) => /* @__PURE__ */ jsxRuntime.jsx(
10187
+ Item,
10188
+ {
10189
+ item,
10190
+ preview,
10191
+ currencyCode
10192
+ },
10193
+ item.id
10194
+ )) : /* @__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: [
10195
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "No items found" }),
10196
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: [
10197
+ 'No items found for "',
10198
+ query2,
10199
+ '".'
10200
+ ] })
10201
+ ] }) })
10202
+ ] })
10203
+ ] }),
10204
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
10205
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-[1fr_0.5fr_0.5fr] gap-3", children: [
10206
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "Subtotal" }) }),
10207
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsxs(
10208
+ ui.Text,
10209
+ {
10210
+ size: "small",
10211
+ leading: "compact",
10212
+ className: "text-ui-fg-subtle",
10213
+ children: [
10214
+ itemCount,
10215
+ " ",
10216
+ itemCount === 1 ? "item" : "items"
10217
+ ]
10218
+ }
10219
+ ) }),
10220
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-right", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: getStylizedAmount(preview.item_subtotal, currencyCode) }) })
10221
+ ] })
10222
+ ] }) }),
10223
+ modalContent && (modalContent === "add-items" ? /* @__PURE__ */ jsxRuntime.jsx(ExistingItemsForm, { orderId: preview.id, items: preview.items }) : modalContent === "add-custom-item" ? /* @__PURE__ */ jsxRuntime.jsx(
10224
+ CustomItemForm,
10225
+ {
10226
+ orderId: preview.id,
10227
+ currencyCode
10228
+ }
10229
+ ) : null)
10230
+ ]
10231
+ }
10232
+ ) }),
10233
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
10234
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
10235
+ /* @__PURE__ */ jsxRuntime.jsx(
10236
+ ui.Button,
10237
+ {
10238
+ size: "small",
10239
+ type: "button",
10240
+ onClick: onSubmit,
10241
+ isLoading: isSubmitting,
10242
+ children: "Save"
10243
+ }
10116
10244
  )
10117
- }
10118
- );
10119
- });
10120
- GridInput.displayName = "MetadataForm.GridInput";
10121
- const PlaceholderInner = () => {
10122
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-1 flex-col overflow-hidden", children: [
10123
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-[148ox] w-full rounded-lg" }) }),
10124
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
10125
- /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-7 w-12 rounded-md" }),
10126
- /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-7 w-12 rounded-md" })
10127
10245
  ] }) })
10128
10246
  ] });
10129
10247
  };
10130
- const EDITABLE_TYPES = ["string", "number", "boolean"];
10131
- function getDefaultValues(metadata) {
10132
- if (!metadata || !Object.keys(metadata).length) {
10133
- return [
10134
- {
10135
- key: "",
10136
- value: "",
10137
- disabled: false
10138
- }
10139
- ];
10248
+ const Item = ({ item, preview, currencyCode }) => {
10249
+ if (item.variant_id) {
10250
+ return /* @__PURE__ */ jsxRuntime.jsx(VariantItem, { item, preview, currencyCode });
10140
10251
  }
10141
- return Object.entries(metadata).map(([key, value]) => {
10142
- if (!EDITABLE_TYPES.includes(typeof value)) {
10143
- return {
10144
- key,
10145
- value,
10146
- disabled: true
10147
- };
10148
- }
10149
- let stringValue = value;
10150
- if (typeof value !== "string") {
10151
- stringValue = JSON.stringify(value);
10152
- }
10153
- return {
10154
- key,
10155
- value: stringValue,
10156
- original_key: key
10157
- };
10252
+ return /* @__PURE__ */ jsxRuntime.jsx(CustomItem, { item, preview, currencyCode });
10253
+ };
10254
+ const VariantItem = ({ item, preview, currencyCode }) => {
10255
+ const [editing, setEditing] = React.useState(false);
10256
+ const form = reactHookForm.useForm({
10257
+ defaultValues: {
10258
+ quantity: item.quantity,
10259
+ unit_price: item.unit_price
10260
+ },
10261
+ resolver: zod.zodResolver(variantItemSchema)
10158
10262
  });
10159
- }
10160
- function parseValues(values) {
10161
- const metadata = values.metadata;
10162
- const isEmpty = !metadata.length || metadata.length === 1 && !metadata[0].key && !metadata[0].value;
10163
- if (isEmpty) {
10164
- return null;
10165
- }
10166
- const update = {};
10167
- metadata.forEach((field) => {
10168
- let key = field.key;
10169
- let value = field.value;
10170
- const disabled = field.disabled;
10171
- if (!key || !value) {
10263
+ const actionId = React.useMemo(() => {
10264
+ var _a, _b;
10265
+ return (_b = (_a = item.actions) == null ? void 0 : _a.find((a) => a.action === "ITEM_ADD")) == null ? void 0 : _b.id;
10266
+ }, [item]);
10267
+ const { mutateAsync: updateActionItem, isPending: isUpdatingActionItem } = useDraftOrderUpdateActionItem(preview.id);
10268
+ const { mutateAsync: updateOriginalItem, isPending: isUpdatingOriginalItem } = useDraftOrderUpdateItem(preview.id);
10269
+ const isPending = isUpdatingActionItem || isUpdatingOriginalItem;
10270
+ const onSubmit = form.handleSubmit(async (data) => {
10271
+ if (convertNumber(data.unit_price) === item.unit_price && data.quantity === item.quantity) {
10272
+ setEditing(false);
10172
10273
  return;
10173
10274
  }
10174
- if (disabled) {
10175
- update[key] = value;
10275
+ if (!actionId) {
10276
+ await updateOriginalItem(
10277
+ {
10278
+ item_id: item.id,
10279
+ quantity: data.quantity,
10280
+ unit_price: convertNumber(data.unit_price)
10281
+ },
10282
+ {
10283
+ onSuccess: () => {
10284
+ setEditing(false);
10285
+ },
10286
+ onError: (e) => {
10287
+ ui.toast.error(e.message);
10288
+ }
10289
+ }
10290
+ );
10176
10291
  return;
10177
10292
  }
10178
- key = key.trim();
10179
- value = value.trim();
10180
- if (value === "true") {
10181
- update[key] = true;
10182
- } else if (value === "false") {
10183
- update[key] = false;
10184
- } else {
10185
- const parsedNumber = parseFloat(value);
10186
- if (!isNaN(parsedNumber)) {
10187
- update[key] = parsedNumber;
10188
- } else {
10189
- update[key] = value;
10190
- }
10191
- }
10192
- });
10193
- return update;
10194
- }
10195
- function getHasUneditableRows(metadata) {
10196
- if (!metadata) {
10197
- return false;
10198
- }
10199
- return Object.values(metadata).some(
10200
- (value) => !EDITABLE_TYPES.includes(typeof value)
10201
- );
10202
- }
10203
- const PROMOTION_QUERY_KEY = "promotions";
10204
- const promotionsQueryKeys = {
10205
- list: (query2) => [
10206
- PROMOTION_QUERY_KEY,
10207
- query2 ? query2 : void 0
10208
- ],
10209
- detail: (id, query2) => [
10210
- PROMOTION_QUERY_KEY,
10211
- id,
10212
- query2 ? query2 : void 0
10213
- ]
10214
- };
10215
- const usePromotions = (query2, options) => {
10216
- const { data, ...rest } = reactQuery.useQuery({
10217
- queryKey: promotionsQueryKeys.list(query2),
10218
- queryFn: async () => sdk.admin.promotion.list(query2),
10219
- ...options
10220
- });
10221
- return { ...data, ...rest };
10222
- };
10223
- const useCancelOrderEdit = ({ preview }) => {
10224
- const { mutateAsync: cancelOrderEdit } = useDraftOrderCancelEdit(preview == null ? void 0 : preview.id);
10225
- const onCancel = React.useCallback(async () => {
10226
- if (!preview) {
10227
- return true;
10228
- }
10229
- let res = false;
10230
- await cancelOrderEdit(void 0, {
10231
- onError: (e) => {
10232
- ui.toast.error(e.message);
10293
+ await updateActionItem(
10294
+ {
10295
+ action_id: actionId,
10296
+ quantity: data.quantity,
10297
+ unit_price: convertNumber(data.unit_price)
10233
10298
  },
10234
- onSuccess: () => {
10235
- res = true;
10236
- }
10237
- });
10238
- return res;
10239
- }, [preview, cancelOrderEdit]);
10240
- return { onCancel };
10241
- };
10242
- let IS_REQUEST_RUNNING = false;
10243
- const useInitiateOrderEdit = ({
10244
- preview
10245
- }) => {
10246
- const navigate = reactRouterDom.useNavigate();
10247
- const { mutateAsync } = useDraftOrderBeginEdit(preview == null ? void 0 : preview.id);
10248
- React.useEffect(() => {
10249
- async function run() {
10250
- if (IS_REQUEST_RUNNING || !preview) {
10251
- return;
10252
- }
10253
- if (preview.order_change) {
10254
- return;
10255
- }
10256
- IS_REQUEST_RUNNING = true;
10257
- await mutateAsync(void 0, {
10299
+ {
10300
+ onSuccess: () => {
10301
+ setEditing(false);
10302
+ },
10258
10303
  onError: (e) => {
10259
10304
  ui.toast.error(e.message);
10260
- navigate(`/draft-orders/${preview.id}`, { replace: true });
10261
- return;
10262
10305
  }
10263
- });
10264
- IS_REQUEST_RUNNING = false;
10265
- }
10266
- run();
10267
- }, [preview, navigate, mutateAsync]);
10268
- };
10269
- const Promotions = () => {
10270
- const { id } = reactRouterDom.useParams();
10271
- const {
10272
- order: preview,
10273
- isError: isPreviewError,
10274
- error: previewError
10275
- } = useOrderPreview(id, void 0);
10276
- useInitiateOrderEdit({ preview });
10277
- const { onCancel } = useCancelOrderEdit({ preview });
10278
- if (isPreviewError) {
10279
- throw previewError;
10280
- }
10281
- const isReady = !!preview;
10282
- return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { onClose: onCancel, children: [
10283
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Promotions" }) }) }),
10284
- isReady && /* @__PURE__ */ jsxRuntime.jsx(PromotionForm, { preview })
10285
- ] });
10306
+ }
10307
+ );
10308
+ });
10309
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2, { ...form, children: /* @__PURE__ */ jsxRuntime.jsx("form", { onSubmit, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest grid grid-cols-[minmax(0,2fr)_minmax(0,1fr)_minmax(0,2fr)_28px] items-center gap-3 rounded-lg px-4 py-2", children: [
10310
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full items-center gap-x-3", children: [
10311
+ /* @__PURE__ */ jsxRuntime.jsx(
10312
+ Thumbnail,
10313
+ {
10314
+ thumbnail: item.thumbnail,
10315
+ alt: item.product_title ?? void 0
10316
+ }
10317
+ ),
10318
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
10319
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-1", children: [
10320
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: item.product_title }),
10321
+ /* @__PURE__ */ jsxRuntime.jsxs(
10322
+ ui.Text,
10323
+ {
10324
+ size: "small",
10325
+ leading: "compact",
10326
+ className: "text-ui-fg-subtle",
10327
+ children: [
10328
+ "(",
10329
+ item.variant_title,
10330
+ ")"
10331
+ ]
10332
+ }
10333
+ )
10334
+ ] }),
10335
+ /* @__PURE__ */ jsxRuntime.jsx(
10336
+ ui.Text,
10337
+ {
10338
+ size: "small",
10339
+ leading: "compact",
10340
+ className: "text-ui-fg-subtle",
10341
+ children: item.variant_sku
10342
+ }
10343
+ )
10344
+ ] })
10345
+ ] }),
10346
+ editing ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(
10347
+ Form$2.Field,
10348
+ {
10349
+ control: form.control,
10350
+ name: "quantity",
10351
+ render: ({ field }) => {
10352
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(NumberInput, { ...field }) }) });
10353
+ }
10354
+ }
10355
+ ) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: item.quantity }) }),
10356
+ editing ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(
10357
+ Form$2.Field,
10358
+ {
10359
+ control: form.control,
10360
+ name: "unit_price",
10361
+ render: ({ field: { onChange, ...field } }) => {
10362
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
10363
+ ui.CurrencyInput,
10364
+ {
10365
+ ...field,
10366
+ symbol: getNativeSymbol(currencyCode),
10367
+ code: currencyCode,
10368
+ onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value)
10369
+ }
10370
+ ) }) });
10371
+ }
10372
+ }
10373
+ ) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex w-full flex-1 items-center justify-end", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: getLocaleAmount(item.unit_price, currencyCode) }) }),
10374
+ /* @__PURE__ */ jsxRuntime.jsx(
10375
+ ui.IconButton,
10376
+ {
10377
+ type: "button",
10378
+ size: "small",
10379
+ onClick: editing ? onSubmit : () => {
10380
+ setEditing(true);
10381
+ },
10382
+ disabled: isPending,
10383
+ children: editing ? /* @__PURE__ */ jsxRuntime.jsx(icons.Check, {}) : /* @__PURE__ */ jsxRuntime.jsx(icons.PencilSquare, {})
10384
+ }
10385
+ )
10386
+ ] }) }) });
10286
10387
  };
10287
- const PromotionForm = ({ preview }) => {
10288
- const { items, shipping_methods } = preview;
10289
- const [isSubmitting, setIsSubmitting] = React.useState(false);
10290
- const [comboboxValue, setComboboxValue] = React.useState("");
10291
- const { handleSuccess } = useRouteModal();
10292
- const { mutateAsync: addPromotions, isPending: isAddingPromotions } = useDraftOrderAddPromotions(preview.id);
10293
- const promoIds = getPromotionIds(items, shipping_methods);
10294
- const { promotions, isPending, isError, error } = usePromotions(
10295
- {
10296
- id: promoIds
10388
+ const variantItemSchema = objectType({
10389
+ quantity: numberType(),
10390
+ unit_price: unionType([numberType(), stringType()])
10391
+ });
10392
+ const CustomItem = ({ item, preview, currencyCode }) => {
10393
+ const [editing, setEditing] = React.useState(false);
10394
+ const { quantity, unit_price, title } = item;
10395
+ const form = reactHookForm.useForm({
10396
+ defaultValues: {
10397
+ title,
10398
+ quantity,
10399
+ unit_price
10297
10400
  },
10298
- {
10299
- enabled: !!promoIds.length
10401
+ resolver: zod.zodResolver(customItemSchema)
10402
+ });
10403
+ React.useEffect(() => {
10404
+ form.reset({
10405
+ title,
10406
+ quantity,
10407
+ unit_price
10408
+ });
10409
+ }, [form, title, quantity, unit_price]);
10410
+ const actionId = React.useMemo(() => {
10411
+ var _a, _b;
10412
+ return (_b = (_a = item.actions) == null ? void 0 : _a.find((a) => a.action === "ITEM_ADD")) == null ? void 0 : _b.id;
10413
+ }, [item]);
10414
+ const { mutateAsync: updateActionItem, isPending: isUpdatingActionItem } = useDraftOrderUpdateActionItem(preview.id);
10415
+ const { mutateAsync: removeActionItem, isPending: isRemovingActionItem } = useDraftOrderRemoveActionItem(preview.id);
10416
+ const { mutateAsync: updateOriginalItem, isPending: isUpdatingOriginalItem } = useDraftOrderUpdateItem(preview.id);
10417
+ const isPending = isUpdatingActionItem || isUpdatingOriginalItem;
10418
+ const onSubmit = form.handleSubmit(async (data) => {
10419
+ if (convertNumber(data.unit_price) === item.unit_price && data.quantity === item.quantity && data.title === item.title) {
10420
+ setEditing(false);
10421
+ return;
10300
10422
  }
10301
- );
10302
- const comboboxData = useComboboxData({
10303
- queryKey: ["promotions", "combobox", promoIds],
10304
- queryFn: async (params) => {
10305
- return await sdk.admin.promotion.list({
10306
- ...params,
10307
- id: {
10308
- $nin: promoIds
10423
+ if (!actionId) {
10424
+ await updateOriginalItem(
10425
+ {
10426
+ item_id: item.id,
10427
+ quantity: data.quantity,
10428
+ unit_price: convertNumber(data.unit_price)
10429
+ },
10430
+ {
10431
+ onSuccess: () => {
10432
+ setEditing(false);
10433
+ },
10434
+ onError: (e) => {
10435
+ ui.toast.error(e.message);
10436
+ }
10309
10437
  }
10310
- });
10311
- },
10312
- getOptions: (data) => {
10313
- return data.promotions.map((promotion) => ({
10314
- label: promotion.code,
10315
- value: promotion.code
10316
- }));
10438
+ );
10439
+ return;
10317
10440
  }
10318
- });
10319
- const add = async (value) => {
10320
- if (!value) {
10441
+ if (data.quantity === 0) {
10442
+ await removeActionItem(actionId, {
10443
+ onSuccess: () => {
10444
+ setEditing(false);
10445
+ },
10446
+ onError: (e) => {
10447
+ ui.toast.error(e.message);
10448
+ }
10449
+ });
10321
10450
  return;
10322
10451
  }
10323
- addPromotions(
10452
+ await updateActionItem(
10324
10453
  {
10325
- promo_codes: [value]
10454
+ action_id: actionId,
10455
+ quantity: data.quantity,
10456
+ unit_price: convertNumber(data.unit_price)
10326
10457
  },
10327
10458
  {
10459
+ onSuccess: () => {
10460
+ setEditing(false);
10461
+ },
10328
10462
  onError: (e) => {
10329
10463
  ui.toast.error(e.message);
10330
- comboboxData.onSearchValueChange("");
10331
- setComboboxValue("");
10332
- },
10333
- onSuccess: () => {
10334
- comboboxData.onSearchValueChange("");
10335
- setComboboxValue("");
10336
10464
  }
10337
10465
  }
10338
10466
  );
10339
- };
10340
- const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
10341
- const { mutateAsync: requestOrderEdit } = useOrderEditRequest(preview.id);
10342
- const onSubmit = async () => {
10343
- setIsSubmitting(true);
10344
- let requestSucceeded = false;
10345
- await requestOrderEdit(void 0, {
10346
- onError: (e) => {
10347
- ui.toast.error(e.message);
10348
- },
10349
- onSuccess: () => {
10350
- requestSucceeded = true;
10467
+ });
10468
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2, { ...form, children: /* @__PURE__ */ jsxRuntime.jsx("form", { onSubmit, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest grid grid-cols-[minmax(0,2fr)_minmax(0,1fr)_minmax(0,2fr)_28px] items-center gap-3 rounded-lg px-4 py-2", children: [
10469
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-3", children: [
10470
+ /* @__PURE__ */ jsxRuntime.jsx(
10471
+ Thumbnail,
10472
+ {
10473
+ thumbnail: item.thumbnail,
10474
+ alt: item.title ?? void 0
10475
+ }
10476
+ ),
10477
+ editing ? /* @__PURE__ */ jsxRuntime.jsx(
10478
+ Form$2.Field,
10479
+ {
10480
+ control: form.control,
10481
+ name: "title",
10482
+ render: ({ field }) => {
10483
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }) });
10484
+ }
10485
+ }
10486
+ ) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: item.title })
10487
+ ] }),
10488
+ editing ? /* @__PURE__ */ jsxRuntime.jsx(
10489
+ Form$2.Field,
10490
+ {
10491
+ control: form.control,
10492
+ name: "quantity",
10493
+ render: ({ field }) => {
10494
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(NumberInput, { ...field }) }) });
10495
+ }
10351
10496
  }
10352
- });
10353
- if (!requestSucceeded) {
10354
- setIsSubmitting(false);
10355
- return;
10356
- }
10357
- await confirmOrderEdit(void 0, {
10358
- onError: (e) => {
10359
- ui.toast.error(e.message);
10360
- },
10361
- onSuccess: () => {
10362
- handleSuccess();
10363
- },
10364
- onSettled: () => {
10365
- setIsSubmitting(false);
10497
+ ) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: item.quantity }),
10498
+ editing ? /* @__PURE__ */ jsxRuntime.jsx(
10499
+ Form$2.Field,
10500
+ {
10501
+ control: form.control,
10502
+ name: "unit_price",
10503
+ render: ({ field: { onChange, ...field } }) => {
10504
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
10505
+ ui.CurrencyInput,
10506
+ {
10507
+ ...field,
10508
+ symbol: getNativeSymbol(currencyCode),
10509
+ code: currencyCode,
10510
+ onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value)
10511
+ }
10512
+ ) }) });
10513
+ }
10366
10514
  }
10367
- });
10368
- };
10369
- if (isError) {
10370
- throw error;
10371
- }
10372
- return /* @__PURE__ */ jsxRuntime.jsxs(KeyboundForm, { className: "flex flex-1 flex-col", onSubmit, children: [
10373
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-4", children: [
10374
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
10375
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
10376
- /* @__PURE__ */ jsxRuntime.jsx(ui.Label, { size: "small", weight: "plus", htmlFor: "promotion-combobox", children: "Apply promotions" }),
10377
- /* @__PURE__ */ jsxRuntime.jsx(ui.Hint, { id: "promotion-combobox-hint", children: "Manage promotions that should be applied to the order." })
10378
- ] }),
10379
- /* @__PURE__ */ jsxRuntime.jsx(
10380
- Combobox,
10381
- {
10382
- id: "promotion-combobox",
10383
- "aria-describedby": "promotion-combobox-hint",
10384
- isFetchingNextPage: comboboxData.isFetchingNextPage,
10385
- fetchNextPage: comboboxData.fetchNextPage,
10386
- options: comboboxData.options,
10387
- onSearchValueChange: comboboxData.onSearchValueChange,
10388
- searchValue: comboboxData.searchValue,
10389
- disabled: comboboxData.disabled || isAddingPromotions,
10390
- onChange: add,
10391
- value: comboboxValue
10392
- }
10393
- )
10394
- ] }),
10395
- /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
10396
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-2", children: promotions == null ? void 0 : promotions.map((promotion) => /* @__PURE__ */ jsxRuntime.jsx(
10397
- PromotionItem,
10398
- {
10399
- promotion,
10400
- orderId: preview.id,
10401
- isLoading: isPending
10515
+ ) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-1 items-center justify-end", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: getLocaleAmount(item.unit_price, currencyCode) }) }),
10516
+ /* @__PURE__ */ jsxRuntime.jsx(
10517
+ ui.IconButton,
10518
+ {
10519
+ type: "button",
10520
+ size: "small",
10521
+ onClick: editing ? onSubmit : () => {
10522
+ setEditing(true);
10402
10523
  },
10403
- promotion.id
10404
- )) })
10405
- ] }) }),
10406
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
10407
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
10408
- /* @__PURE__ */ jsxRuntime.jsx(
10409
- ui.Button,
10410
- {
10411
- size: "small",
10412
- type: "submit",
10413
- isLoading: isSubmitting || isAddingPromotions,
10414
- children: "Save"
10415
- }
10416
- )
10417
- ] }) })
10418
- ] });
10524
+ disabled: isPending,
10525
+ children: editing ? /* @__PURE__ */ jsxRuntime.jsx(icons.Check, {}) : /* @__PURE__ */ jsxRuntime.jsx(icons.PencilSquare, {})
10526
+ }
10527
+ )
10528
+ ] }) }) });
10419
10529
  };
10420
- const PromotionItem = ({
10421
- promotion,
10422
- orderId,
10423
- isLoading
10530
+ const StackedModalTrigger$1 = ({
10531
+ type,
10532
+ setModalContent
10424
10533
  }) => {
10425
- var _a;
10426
- const { mutateAsync: removePromotions, isPending } = useDraftOrderRemovePromotions(orderId);
10427
- const onRemove = async () => {
10428
- removePromotions(
10534
+ const { setIsOpen } = useStackedModal();
10535
+ const onClick = React.useCallback(() => {
10536
+ setModalContent(type);
10537
+ setIsOpen(STACKED_MODAL_ID, true);
10538
+ }, [setModalContent, setIsOpen, type]);
10539
+ return /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenu.Item, { onClick, children: type === "add-items" ? "Add items" : "Add custom item" }) });
10540
+ };
10541
+ const VARIANT_PREFIX = "items";
10542
+ const LIMIT = 50;
10543
+ const ExistingItemsForm = ({ orderId, items }) => {
10544
+ const { setIsOpen } = useStackedModal();
10545
+ const [rowSelection, setRowSelection] = React.useState(
10546
+ items.reduce((acc, item) => {
10547
+ acc[item.variant_id] = true;
10548
+ return acc;
10549
+ }, {})
10550
+ );
10551
+ React.useEffect(() => {
10552
+ setRowSelection(
10553
+ items.reduce((acc, item) => {
10554
+ if (item.variant_id) {
10555
+ acc[item.variant_id] = true;
10556
+ }
10557
+ return acc;
10558
+ }, {})
10559
+ );
10560
+ }, [items]);
10561
+ const { q, order, offset } = useQueryParams(
10562
+ ["q", "order", "offset"],
10563
+ VARIANT_PREFIX
10564
+ );
10565
+ const { variants, count, isPending, isError, error } = useProductVariants(
10566
+ {
10567
+ q,
10568
+ order,
10569
+ offset: offset ? parseInt(offset) : void 0,
10570
+ limit: LIMIT
10571
+ },
10572
+ {
10573
+ placeholderData: reactQuery.keepPreviousData
10574
+ }
10575
+ );
10576
+ const columns = useColumns();
10577
+ const { mutateAsync } = useDraftOrderAddItems(orderId);
10578
+ const onSubmit = async () => {
10579
+ const ids = Object.keys(rowSelection).filter(
10580
+ (id) => !items.find((i) => i.variant_id === id)
10581
+ );
10582
+ await mutateAsync(
10429
10583
  {
10430
- promo_codes: [promotion.code]
10584
+ items: ids.map((id) => ({
10585
+ variant_id: id,
10586
+ quantity: 1
10587
+ }))
10431
10588
  },
10432
10589
  {
10590
+ onSuccess: () => {
10591
+ setRowSelection({});
10592
+ setIsOpen(STACKED_MODAL_ID, false);
10593
+ },
10433
10594
  onError: (e) => {
10434
10595
  ui.toast.error(e.message);
10435
10596
  }
10436
10597
  }
10437
10598
  );
10438
10599
  };
10439
- const displayValue = getDisplayValue(promotion);
10600
+ if (isError) {
10601
+ throw error;
10602
+ }
10440
10603
  return /* @__PURE__ */ jsxRuntime.jsxs(
10441
- "div",
10604
+ StackedFocusModal.Content,
10442
10605
  {
10443
- className: ui.clx(
10444
- "bg-ui-bg-component shadow-elevation-card-rest flex items-center justify-between rounded-lg px-3 py-2",
10445
- {
10446
- "animate-pulse": isLoading
10606
+ onOpenAutoFocus: (e) => {
10607
+ e.preventDefault();
10608
+ const searchInput = document.querySelector(
10609
+ "[data-modal-id='modal-search-input']"
10610
+ );
10611
+ if (searchInput) {
10612
+ searchInput.focus();
10447
10613
  }
10448
- ),
10614
+ },
10449
10615
  children: [
10450
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10451
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: promotion.code }),
10452
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-ui-fg-subtle flex items-center gap-1.5", children: [
10453
- displayValue && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
10454
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", children: displayValue }),
10455
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", children: "·" })
10456
- ] }),
10457
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", className: "capitalize", children: (_a = promotion.application_method) == null ? void 0 : _a.allocation })
10458
- ] })
10616
+ /* @__PURE__ */ jsxRuntime.jsxs(StackedFocusModal.Header, { children: [
10617
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Product Variants" }) }),
10618
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Choose product variants to add to the order." }) })
10459
10619
  ] }),
10460
- /* @__PURE__ */ jsxRuntime.jsx(
10461
- ui.IconButton,
10620
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Body, { className: "flex-1 overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(
10621
+ DataTable,
10462
10622
  {
10463
- size: "small",
10464
- type: "button",
10465
- variant: "transparent",
10466
- onClick: onRemove,
10467
- isLoading: isPending || isLoading,
10468
- children: /* @__PURE__ */ jsxRuntime.jsx(icons.XMark, {})
10623
+ data: variants,
10624
+ columns,
10625
+ isLoading: isPending,
10626
+ getRowId: (row) => row.id,
10627
+ rowCount: count,
10628
+ prefix: VARIANT_PREFIX,
10629
+ layout: "fill",
10630
+ rowSelection: {
10631
+ state: rowSelection,
10632
+ onRowSelectionChange: setRowSelection,
10633
+ enableRowSelection: (row) => {
10634
+ return !items.find((i) => i.variant_id === row.original.id);
10635
+ }
10636
+ },
10637
+ autoFocusSearch: true
10469
10638
  }
10470
- )
10639
+ ) }),
10640
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
10641
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
10642
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "button", onClick: onSubmit, children: "Update items" })
10643
+ ] }) })
10471
10644
  ]
10472
- },
10473
- promotion.id
10474
- );
10475
- };
10476
- function getDisplayValue(promotion) {
10477
- var _a, _b, _c, _d;
10478
- const value = (_a = promotion.application_method) == null ? void 0 : _a.value;
10479
- if (!value) {
10480
- return null;
10481
- }
10482
- if (((_b = promotion.application_method) == null ? void 0 : _b.type) === "fixed") {
10483
- const currency = (_c = promotion.application_method) == null ? void 0 : _c.currency_code;
10484
- if (!currency) {
10485
- return null;
10486
10645
  }
10487
- return getLocaleAmount(value, currency);
10488
- } else if (((_d = promotion.application_method) == null ? void 0 : _d.type) === "percentage") {
10489
- return formatPercentage(value);
10490
- }
10491
- return null;
10492
- }
10493
- const formatter = new Intl.NumberFormat([], {
10494
- style: "percent",
10495
- minimumFractionDigits: 2
10496
- });
10497
- const formatPercentage = (value, isPercentageValue = false) => {
10498
- let val = value || 0;
10499
- if (!isPercentageValue) {
10500
- val = val / 100;
10501
- }
10502
- return formatter.format(val);
10646
+ );
10503
10647
  };
10504
- function getPromotionIds(items, shippingMethods) {
10505
- const promotionIds = /* @__PURE__ */ new Set();
10506
- for (const item of items) {
10507
- if (item.adjustments) {
10508
- for (const adjustment of item.adjustments) {
10509
- if (adjustment.promotion_id) {
10510
- promotionIds.add(adjustment.promotion_id);
10648
+ const columnHelper = ui.createDataTableColumnHelper();
10649
+ const useColumns = () => {
10650
+ return React.useMemo(() => {
10651
+ return [
10652
+ columnHelper.select(),
10653
+ columnHelper.accessor("product.title", {
10654
+ header: "Product",
10655
+ cell: ({ row }) => {
10656
+ var _a, _b, _c;
10657
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-2", children: [
10658
+ /* @__PURE__ */ jsxRuntime.jsx(
10659
+ Thumbnail,
10660
+ {
10661
+ thumbnail: (_a = row.original.product) == null ? void 0 : _a.thumbnail,
10662
+ alt: (_b = row.original.product) == null ? void 0 : _b.title
10663
+ }
10664
+ ),
10665
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: (_c = row.original.product) == null ? void 0 : _c.title })
10666
+ ] });
10667
+ },
10668
+ enableSorting: true
10669
+ }),
10670
+ columnHelper.accessor("title", {
10671
+ header: "Variant",
10672
+ enableSorting: true
10673
+ }),
10674
+ columnHelper.accessor("sku", {
10675
+ header: "SKU",
10676
+ cell: ({ getValue }) => {
10677
+ return getValue() ?? "-";
10678
+ },
10679
+ enableSorting: true
10680
+ }),
10681
+ columnHelper.accessor("updated_at", {
10682
+ header: "Updated",
10683
+ cell: ({ getValue }) => {
10684
+ return /* @__PURE__ */ jsxRuntime.jsx(
10685
+ ui.Tooltip,
10686
+ {
10687
+ content: getFullDate({ date: getValue(), includeTime: true }),
10688
+ children: /* @__PURE__ */ jsxRuntime.jsx("span", { children: getFullDate({ date: getValue() }) })
10689
+ }
10690
+ );
10691
+ },
10692
+ enableSorting: true,
10693
+ sortAscLabel: "Oldest first",
10694
+ sortDescLabel: "Newest first"
10695
+ }),
10696
+ columnHelper.accessor("created_at", {
10697
+ header: "Created",
10698
+ cell: ({ getValue }) => {
10699
+ return /* @__PURE__ */ jsxRuntime.jsx(
10700
+ ui.Tooltip,
10701
+ {
10702
+ content: getFullDate({ date: getValue(), includeTime: true }),
10703
+ children: /* @__PURE__ */ jsxRuntime.jsx("span", { children: getFullDate({ date: getValue() }) })
10704
+ }
10705
+ );
10706
+ },
10707
+ enableSorting: true,
10708
+ sortAscLabel: "Oldest first",
10709
+ sortDescLabel: "Newest first"
10710
+ })
10711
+ ];
10712
+ }, []);
10713
+ };
10714
+ const CustomItemForm = ({ orderId, currencyCode }) => {
10715
+ const { setIsOpen } = useStackedModal();
10716
+ const { mutateAsync: addItems } = useDraftOrderAddItems(orderId);
10717
+ const form = reactHookForm.useForm({
10718
+ defaultValues: {
10719
+ title: "",
10720
+ quantity: 1,
10721
+ unit_price: ""
10722
+ },
10723
+ resolver: zod.zodResolver(customItemSchema)
10724
+ });
10725
+ const onSubmit = form.handleSubmit(async (data) => {
10726
+ await addItems(
10727
+ {
10728
+ items: [
10729
+ {
10730
+ title: data.title,
10731
+ quantity: data.quantity,
10732
+ unit_price: convertNumber(data.unit_price)
10733
+ }
10734
+ ]
10735
+ },
10736
+ {
10737
+ onSuccess: () => {
10738
+ setIsOpen(STACKED_MODAL_ID, false);
10739
+ },
10740
+ onError: (e) => {
10741
+ ui.toast.error(e.message);
10511
10742
  }
10512
10743
  }
10513
- }
10514
- }
10515
- for (const shippingMethod of shippingMethods) {
10516
- if (shippingMethod.adjustments) {
10517
- for (const adjustment of shippingMethod.adjustments) {
10518
- if (adjustment.promotion_id) {
10519
- promotionIds.add(adjustment.promotion_id);
10744
+ );
10745
+ });
10746
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2, { ...form, children: /* @__PURE__ */ jsxRuntime.jsx(KeyboundForm, { onSubmit, children: /* @__PURE__ */ jsxRuntime.jsxs(StackedFocusModal.Content, { children: [
10747
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Header, {}),
10748
+ /* @__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-2 py-16", children: [
10749
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10750
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Add custom item" }) }),
10751
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Add a custom item to the order. This will add a new line item that is not associated with an existing product." }) })
10752
+ ] }),
10753
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
10754
+ /* @__PURE__ */ jsxRuntime.jsx(
10755
+ Form$2.Field,
10756
+ {
10757
+ control: form.control,
10758
+ name: "title",
10759
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
10760
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10761
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Title" }),
10762
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Enter the title of the item" })
10763
+ ] }),
10764
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10765
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
10766
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
10767
+ ] })
10768
+ ] }) })
10520
10769
  }
10521
- }
10522
- }
10523
- }
10524
- return Array.from(promotionIds);
10525
- }
10526
- const NumberInput = React.forwardRef(
10527
- ({
10528
- value,
10529
- onChange,
10530
- size = "base",
10531
- min = 0,
10532
- max = 100,
10533
- step = 1,
10534
- className,
10535
- disabled,
10536
- ...props
10537
- }, ref) => {
10538
- const handleChange = (event) => {
10539
- const newValue = event.target.value === "" ? min : Number(event.target.value);
10540
- if (!isNaN(newValue) && (max === void 0 || newValue <= max) && (min === void 0 || newValue >= min)) {
10541
- onChange(newValue);
10542
- }
10543
- };
10544
- const handleIncrement = () => {
10545
- const newValue = value + step;
10546
- if (max === void 0 || newValue <= max) {
10547
- onChange(newValue);
10548
- }
10549
- };
10550
- const handleDecrement = () => {
10551
- const newValue = value - step;
10552
- if (min === void 0 || newValue >= min) {
10553
- onChange(newValue);
10554
- }
10555
- };
10770
+ ),
10771
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
10772
+ /* @__PURE__ */ jsxRuntime.jsx(
10773
+ Form$2.Field,
10774
+ {
10775
+ control: form.control,
10776
+ name: "unit_price",
10777
+ render: ({ field: { onChange, ...field } }) => /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
10778
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10779
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Unit price" }),
10780
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Enter the unit price of the item" })
10781
+ ] }),
10782
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10783
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
10784
+ ui.CurrencyInput,
10785
+ {
10786
+ symbol: getNativeSymbol(currencyCode),
10787
+ code: currencyCode,
10788
+ onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value),
10789
+ ...field
10790
+ }
10791
+ ) }),
10792
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
10793
+ ] })
10794
+ ] }) })
10795
+ }
10796
+ ),
10797
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
10798
+ /* @__PURE__ */ jsxRuntime.jsx(
10799
+ Form$2.Field,
10800
+ {
10801
+ control: form.control,
10802
+ name: "quantity",
10803
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
10804
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10805
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Quantity" }),
10806
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Enter the quantity of the item" })
10807
+ ] }),
10808
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full flex-1", children: [
10809
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(NumberInput, { ...field, className: "w-full" }) }) }),
10810
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
10811
+ ] })
10812
+ ] }) })
10813
+ }
10814
+ )
10815
+ ] }) }) }),
10816
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
10817
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
10818
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "button", onClick: onSubmit, children: "Add item" })
10819
+ ] }) })
10820
+ ] }) }) });
10821
+ };
10822
+ const customItemSchema = objectType({
10823
+ title: stringType().min(1),
10824
+ quantity: numberType(),
10825
+ unit_price: unionType([numberType(), stringType()])
10826
+ });
10827
+ const InlineTip = React.forwardRef(
10828
+ ({ variant = "tip", label, className, children, ...props }, ref) => {
10829
+ const labelValue = label || (variant === "warning" ? "Warning" : "Tip");
10556
10830
  return /* @__PURE__ */ jsxRuntime.jsxs(
10557
10831
  "div",
10558
10832
  {
10833
+ ref,
10559
10834
  className: ui.clx(
10560
- "inline-flex rounded-md bg-ui-bg-field shadow-borders-base overflow-hidden divide-x transition-fg",
10561
- "[&:has(input:focus)]:shadow-borders-interactive-with-active",
10562
- {
10563
- "h-7": size === "small",
10564
- "h-8": size === "base"
10565
- },
10835
+ "bg-ui-bg-component txt-small text-ui-fg-subtle grid grid-cols-[4px_1fr] items-start gap-3 rounded-lg border p-3",
10566
10836
  className
10567
10837
  ),
10838
+ ...props,
10568
10839
  children: [
10569
10840
  /* @__PURE__ */ jsxRuntime.jsx(
10570
- "input",
10841
+ "div",
10571
10842
  {
10572
- ref,
10573
- type: "number",
10574
- value,
10575
- onChange: handleChange,
10576
- min,
10577
- max,
10578
- step,
10579
- className: ui.clx(
10580
- "flex-1 px-2 py-1 bg-transparent txt-compact-small text-ui-fg-base outline-none [appearance:textfield]",
10581
- "[&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none",
10582
- "placeholder:text-ui-fg-muted"
10583
- ),
10584
- ...props
10843
+ role: "presentation",
10844
+ className: ui.clx("w-4px bg-ui-tag-neutral-icon h-full rounded-full", {
10845
+ "bg-ui-tag-orange-icon": variant === "warning"
10846
+ })
10585
10847
  }
10586
10848
  ),
10587
- /* @__PURE__ */ jsxRuntime.jsxs(
10588
- "button",
10589
- {
10590
- className: ui.clx(
10591
- "flex items-center justify-center outline-none transition-fg",
10592
- "disabled:cursor-not-allowed disabled:text-ui-fg-muted",
10593
- "focus:bg-ui-bg-field-component-hover",
10594
- "hover:bg-ui-bg-field-component-hover",
10595
- {
10596
- "size-7": size === "small",
10597
- "size-8": size === "base"
10598
- }
10599
- ),
10600
- type: "button",
10601
- onClick: handleDecrement,
10602
- disabled: min !== void 0 && value <= min || disabled,
10603
- children: [
10604
- /* @__PURE__ */ jsxRuntime.jsx(icons.Minus, {}),
10605
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: `Decrease by ${step}` })
10606
- ]
10607
- }
10608
- ),
10609
- /* @__PURE__ */ jsxRuntime.jsxs(
10610
- "button",
10611
- {
10612
- className: ui.clx(
10613
- "flex items-center justify-center outline-none transition-fg",
10614
- "disabled:cursor-not-allowed disabled:text-ui-fg-muted",
10615
- "focus:bg-ui-bg-field-hover",
10616
- "hover:bg-ui-bg-field-hover",
10617
- {
10618
- "size-7": size === "small",
10619
- "size-8": size === "base"
10620
- }
10621
- ),
10622
- type: "button",
10623
- onClick: handleIncrement,
10624
- disabled: max !== void 0 && value >= max || disabled,
10625
- children: [
10626
- /* @__PURE__ */ jsxRuntime.jsx(icons.Plus, {}),
10627
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: `Increase by ${step}` })
10628
- ]
10629
- }
10630
- )
10849
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-pretty", children: [
10850
+ /* @__PURE__ */ jsxRuntime.jsxs("strong", { className: "txt-small-plus text-ui-fg-base", children: [
10851
+ labelValue,
10852
+ ":"
10853
+ ] }),
10854
+ " ",
10855
+ children
10856
+ ] })
10631
10857
  ]
10632
10858
  }
10633
10859
  );
10634
10860
  }
10635
10861
  );
10636
- const PRODUCT_VARIANTS_QUERY_KEY = "product-variants";
10637
- const productVariantsQueryKeys = {
10638
- list: (query2) => [
10639
- PRODUCT_VARIANTS_QUERY_KEY,
10640
- query2 ? query2 : void 0
10641
- ]
10642
- };
10643
- const useProductVariants = (query2, options) => {
10644
- const { data, ...rest } = reactQuery.useQuery({
10645
- queryKey: productVariantsQueryKeys.list(query2),
10646
- queryFn: async () => await sdk.admin.productVariant.list(query2),
10647
- ...options
10648
- });
10649
- return { ...data, ...rest };
10650
- };
10651
- function convertNumber(value) {
10652
- return typeof value === "string" ? Number(value.replace(",", ".")) : value;
10653
- }
10654
- const STACKED_MODAL_ID = "items_stacked_modal";
10655
- const Items = () => {
10862
+ InlineTip.displayName = "InlineTip";
10863
+ const MetadataFieldSchema = objectType({
10864
+ key: stringType(),
10865
+ disabled: booleanType().optional(),
10866
+ value: anyType()
10867
+ });
10868
+ const MetadataSchema = objectType({
10869
+ metadata: arrayType(MetadataFieldSchema)
10870
+ });
10871
+ const Metadata = () => {
10656
10872
  const { id } = reactRouterDom.useParams();
10657
- const {
10658
- order: preview,
10659
- isPending: isPreviewPending,
10660
- isError: isPreviewError,
10661
- error: previewError
10662
- } = useOrderPreview(id, void 0, {
10663
- placeholderData: reactQuery.keepPreviousData
10873
+ const { order, isPending, isError, error } = useOrder(id, {
10874
+ fields: "metadata"
10664
10875
  });
10665
- useInitiateOrderEdit({ preview });
10666
- const { draft_order, isPending, isError, error } = useDraftOrder(
10667
- id,
10668
- {
10669
- fields: "currency_code"
10670
- },
10671
- {
10672
- enabled: !!id
10673
- }
10674
- );
10675
- const { onCancel } = useCancelOrderEdit({ preview });
10676
10876
  if (isError) {
10677
10877
  throw error;
10678
10878
  }
10679
- if (isPreviewError) {
10680
- throw previewError;
10681
- }
10682
- const ready = !!preview && !isPreviewPending && !!draft_order && !isPending;
10683
- return /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal, { onClose: onCancel, children: ready ? /* @__PURE__ */ jsxRuntime.jsx(ItemsForm, { preview, currencyCode: draft_order.currency_code }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10684
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Edit Items" }) }),
10685
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Loading data for the draft order, please wait..." }) })
10686
- ] }) });
10879
+ const isReady = !isPending && !!order;
10880
+ return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
10881
+ /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Header, { children: [
10882
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Metadata" }) }),
10883
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Add metadata to the draft order." }) })
10884
+ ] }),
10885
+ !isReady ? /* @__PURE__ */ jsxRuntime.jsx(PlaceholderInner, {}) : /* @__PURE__ */ jsxRuntime.jsx(MetadataForm, { orderId: id, metadata: order == null ? void 0 : order.metadata })
10886
+ ] });
10687
10887
  };
10688
- const ItemsForm = ({ preview, currencyCode }) => {
10689
- var _a;
10690
- const [isSubmitting, setIsSubmitting] = React.useState(false);
10691
- const [modalContent, setModalContent] = React.useState(
10692
- null
10693
- );
10888
+ const METADATA_KEY_LABEL_ID = "metadata-form-key-label";
10889
+ const METADATA_VALUE_LABEL_ID = "metadata-form-value-label";
10890
+ const MetadataForm = ({ orderId, metadata }) => {
10694
10891
  const { handleSuccess } = useRouteModal();
10695
- const { searchValue, onSearchValueChange, query: query2 } = useDebouncedSearch();
10696
- const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
10697
- const { mutateAsync: requestOrderEdit } = useDraftOrderRequestEdit(preview.id);
10698
- const itemCount = ((_a = preview.items) == null ? void 0 : _a.reduce((acc, item) => acc + item.quantity, 0)) || 0;
10699
- const matches = React.useMemo(() => {
10700
- return matchSorter.matchSorter(preview.items, query2, {
10701
- keys: ["product_title", "variant_title", "variant_sku", "title"]
10702
- });
10703
- }, [preview.items, query2]);
10704
- const onSubmit = async () => {
10705
- setIsSubmitting(true);
10706
- let requestSucceeded = false;
10707
- await requestOrderEdit(void 0, {
10708
- onError: (e) => {
10709
- ui.toast.error(`Failed to request order edit: ${e.message}`);
10892
+ const hasUneditableRows = getHasUneditableRows(metadata);
10893
+ const { mutateAsync, isPending } = useUpdateDraftOrder(orderId);
10894
+ const form = reactHookForm.useForm({
10895
+ defaultValues: {
10896
+ metadata: getDefaultValues(metadata)
10897
+ },
10898
+ resolver: zod.zodResolver(MetadataSchema)
10899
+ });
10900
+ const handleSubmit = form.handleSubmit(async (data) => {
10901
+ const parsedData = parseValues(data);
10902
+ await mutateAsync(
10903
+ {
10904
+ metadata: parsedData
10710
10905
  },
10711
- onSuccess: () => {
10712
- requestSucceeded = true;
10906
+ {
10907
+ onSuccess: () => {
10908
+ ui.toast.success("Metadata updated");
10909
+ handleSuccess();
10910
+ },
10911
+ onError: (error) => {
10912
+ ui.toast.error(error.message);
10913
+ }
10713
10914
  }
10714
- });
10715
- if (!requestSucceeded) {
10716
- setIsSubmitting(false);
10717
- return;
10915
+ );
10916
+ });
10917
+ const { fields, insert, remove } = reactHookForm.useFieldArray({
10918
+ control: form.control,
10919
+ name: "metadata"
10920
+ });
10921
+ function deleteRow(index) {
10922
+ remove(index);
10923
+ if (fields.length === 1) {
10924
+ insert(0, {
10925
+ key: "",
10926
+ value: "",
10927
+ disabled: false
10928
+ });
10718
10929
  }
10719
- await confirmOrderEdit(void 0, {
10720
- onError: (e) => {
10721
- ui.toast.error(`Failed to confirm order edit: ${e.message}`);
10722
- },
10723
- onSuccess: () => {
10724
- handleSuccess();
10725
- },
10726
- onSettled: () => {
10727
- setIsSubmitting(false);
10728
- }
10930
+ }
10931
+ function insertRow(index, position) {
10932
+ insert(index + (position === "above" ? 0 : 1), {
10933
+ key: "",
10934
+ value: "",
10935
+ disabled: false
10729
10936
  });
10730
- };
10731
- const onKeyDown = React.useCallback(
10732
- (e) => {
10733
- if (e.key === "Enter" && (e.ctrlKey || e.metaKey)) {
10734
- if (modalContent || isSubmitting) {
10735
- return;
10736
- }
10737
- onSubmit();
10738
- }
10739
- },
10740
- [modalContent, isSubmitting, onSubmit]
10741
- );
10742
- React.useEffect(() => {
10743
- document.addEventListener("keydown", onKeyDown);
10744
- return () => {
10745
- document.removeEventListener("keydown", onKeyDown);
10746
- };
10747
- }, [onKeyDown]);
10748
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-full flex-col overflow-hidden", children: [
10749
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Header, {}),
10750
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Body, { className: "flex flex-1 flex-col overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsxs(
10751
- StackedFocusModal,
10752
- {
10753
- id: STACKED_MODAL_ID,
10754
- onOpenChangeCallback: (open) => {
10755
- if (!open) {
10756
- setModalContent(null);
10757
- }
10758
- },
10759
- children: [
10760
- /* @__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: [
10761
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10762
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Items" }) }),
10763
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Edit the items in the draft order" }) })
10937
+ }
10938
+ return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(
10939
+ KeyboundForm,
10940
+ {
10941
+ onSubmit: handleSubmit,
10942
+ className: "flex flex-1 flex-col overflow-hidden",
10943
+ children: [
10944
+ /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Body, { className: "flex flex-1 flex-col gap-y-8 overflow-y-auto", children: [
10945
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest grid grid-cols-1 divide-y rounded-lg", children: [
10946
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-subtle grid grid-cols-2 divide-x rounded-t-lg", children: [
10947
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "txt-compact-small-plus text-ui-fg-subtle px-2 py-1.5", children: /* @__PURE__ */ jsxRuntime.jsx("label", { id: METADATA_KEY_LABEL_ID, children: "Key" }) }),
10948
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "txt-compact-small-plus text-ui-fg-subtle px-2 py-1.5", children: /* @__PURE__ */ jsxRuntime.jsx("label", { id: METADATA_VALUE_LABEL_ID, children: "Value" }) })
10764
10949
  ] }),
10765
- /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
10766
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-6", children: [
10767
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 items-center gap-3", children: [
10768
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
10769
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "Items" }),
10770
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Choose items from the product catalog." })
10771
- ] }),
10772
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
10773
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(
10774
- ui.Input,
10775
- {
10776
- type: "search",
10777
- placeholder: "Search items",
10778
- value: searchValue,
10779
- onChange: (e) => onSearchValueChange(e.target.value)
10780
- }
10781
- ) }),
10782
- /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu, { children: [
10783
- /* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenu.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { type: "button", children: /* @__PURE__ */ jsxRuntime.jsx(icons.Plus, {}) }) }),
10784
- /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu.Content, { children: [
10950
+ fields.map((field, index) => {
10951
+ const isDisabled = field.disabled || false;
10952
+ let placeholder = "-";
10953
+ if (typeof field.value === "object") {
10954
+ placeholder = "{ ... }";
10955
+ }
10956
+ if (Array.isArray(field.value)) {
10957
+ placeholder = "[ ... ]";
10958
+ }
10959
+ return /* @__PURE__ */ jsxRuntime.jsx(
10960
+ ConditionalTooltip,
10961
+ {
10962
+ showTooltip: isDisabled,
10963
+ content: "This row is disabled because it contains non-primitive data.",
10964
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "group/table relative", children: [
10965
+ /* @__PURE__ */ jsxRuntime.jsxs(
10966
+ "div",
10967
+ {
10968
+ className: ui.clx("grid grid-cols-2 divide-x", {
10969
+ "overflow-hidden rounded-b-lg": index === fields.length - 1
10970
+ }),
10971
+ children: [
10972
+ /* @__PURE__ */ jsxRuntime.jsx(
10973
+ Form$2.Field,
10974
+ {
10975
+ control: form.control,
10976
+ name: `metadata.${index}.key`,
10977
+ render: ({ field: field2 }) => {
10978
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
10979
+ GridInput,
10980
+ {
10981
+ "aria-labelledby": METADATA_KEY_LABEL_ID,
10982
+ ...field2,
10983
+ disabled: isDisabled,
10984
+ placeholder: "Key"
10985
+ }
10986
+ ) }) });
10987
+ }
10988
+ }
10989
+ ),
10990
+ /* @__PURE__ */ jsxRuntime.jsx(
10991
+ Form$2.Field,
10992
+ {
10993
+ control: form.control,
10994
+ name: `metadata.${index}.value`,
10995
+ render: ({ field: { value, ...field2 } }) => {
10996
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
10997
+ GridInput,
10998
+ {
10999
+ "aria-labelledby": METADATA_VALUE_LABEL_ID,
11000
+ ...field2,
11001
+ value: isDisabled ? placeholder : value,
11002
+ disabled: isDisabled,
11003
+ placeholder: "Value"
11004
+ }
11005
+ ) }) });
11006
+ }
11007
+ }
11008
+ )
11009
+ ]
11010
+ }
11011
+ ),
11012
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu, { children: [
10785
11013
  /* @__PURE__ */ jsxRuntime.jsx(
10786
- StackedModalTrigger$1,
11014
+ ui.DropdownMenu.Trigger,
10787
11015
  {
10788
- type: "add-items",
10789
- setModalContent
11016
+ className: ui.clx(
11017
+ "invisible absolute inset-y-0 -right-2.5 my-auto group-hover/table:visible data-[state='open']:visible",
11018
+ {
11019
+ hidden: isDisabled
11020
+ }
11021
+ ),
11022
+ disabled: isDisabled,
11023
+ asChild: true,
11024
+ children: /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { size: "2xsmall", children: /* @__PURE__ */ jsxRuntime.jsx(icons.EllipsisVertical, {}) })
10790
11025
  }
10791
11026
  ),
10792
- /* @__PURE__ */ jsxRuntime.jsx(
10793
- StackedModalTrigger$1,
10794
- {
10795
- type: "add-custom-item",
10796
- setModalContent
10797
- }
10798
- )
11027
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu.Content, { children: [
11028
+ /* @__PURE__ */ jsxRuntime.jsxs(
11029
+ ui.DropdownMenu.Item,
11030
+ {
11031
+ className: "gap-x-2",
11032
+ onClick: () => insertRow(index, "above"),
11033
+ children: [
11034
+ /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowUpMini, { className: "text-ui-fg-subtle" }),
11035
+ "Insert row above"
11036
+ ]
11037
+ }
11038
+ ),
11039
+ /* @__PURE__ */ jsxRuntime.jsxs(
11040
+ ui.DropdownMenu.Item,
11041
+ {
11042
+ className: "gap-x-2",
11043
+ onClick: () => insertRow(index, "below"),
11044
+ children: [
11045
+ /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowDownMini, { className: "text-ui-fg-subtle" }),
11046
+ "Insert row below"
11047
+ ]
11048
+ }
11049
+ ),
11050
+ /* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenu.Separator, {}),
11051
+ /* @__PURE__ */ jsxRuntime.jsxs(
11052
+ ui.DropdownMenu.Item,
11053
+ {
11054
+ className: "gap-x-2",
11055
+ onClick: () => deleteRow(index),
11056
+ children: [
11057
+ /* @__PURE__ */ jsxRuntime.jsx(icons.Trash, { className: "text-ui-fg-subtle" }),
11058
+ "Delete row"
11059
+ ]
11060
+ }
11061
+ )
11062
+ ] })
10799
11063
  ] })
10800
11064
  ] })
10801
- ] })
10802
- ] }),
10803
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-subtle shadow-elevation-card-rest rounded-xl", children: [
10804
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-[5px]", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-ui-fg-muted grid grid-cols-[2fr_1fr_2fr_28px] gap-3 px-4 py-2", children: [
10805
- /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: "Item" }) }),
10806
- /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: "Quantity" }) }),
10807
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-right", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: "Price" }) }),
10808
- /* @__PURE__ */ jsxRuntime.jsx("div", {})
10809
- ] }) }),
10810
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-y-1.5 px-[5px] pb-[5px]", children: itemCount <= 0 ? /* @__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: [
10811
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "There are no items in this order" }),
10812
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Add items to the order to get started." })
10813
- ] }) : matches.length > 0 ? matches == null ? void 0 : matches.map((item) => /* @__PURE__ */ jsxRuntime.jsx(
10814
- Item,
10815
- {
10816
- item,
10817
- preview,
10818
- currencyCode
10819
- },
10820
- item.id
10821
- )) : /* @__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: [
10822
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "No items found" }),
10823
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: [
10824
- 'No items found for "',
10825
- query2,
10826
- '".'
10827
- ] })
10828
- ] }) })
10829
- ] })
10830
- ] }),
10831
- /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
10832
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-[1fr_0.5fr_0.5fr] gap-3", children: [
10833
- /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "Subtotal" }) }),
10834
- /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsxs(
10835
- ui.Text,
10836
- {
10837
- size: "small",
10838
- leading: "compact",
10839
- className: "text-ui-fg-subtle",
10840
- children: [
10841
- itemCount,
10842
- " ",
10843
- itemCount === 1 ? "item" : "items"
10844
- ]
10845
- }
10846
- ) }),
10847
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-right", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: getStylizedAmount(preview.item_subtotal, currencyCode) }) })
10848
- ] })
10849
- ] }) }),
10850
- modalContent && (modalContent === "add-items" ? /* @__PURE__ */ jsxRuntime.jsx(ExistingItemsForm, { orderId: preview.id, items: preview.items }) : modalContent === "add-custom-item" ? /* @__PURE__ */ jsxRuntime.jsx(
10851
- CustomItemForm,
10852
- {
10853
- orderId: preview.id,
10854
- currencyCode
10855
- }
10856
- ) : null)
10857
- ]
10858
- }
10859
- ) }),
10860
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
10861
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
10862
- /* @__PURE__ */ jsxRuntime.jsx(
10863
- ui.Button,
10864
- {
10865
- size: "small",
10866
- type: "button",
10867
- onClick: onSubmit,
10868
- isLoading: isSubmitting,
10869
- children: "Save"
10870
- }
11065
+ },
11066
+ field.id
11067
+ );
11068
+ })
11069
+ ] }),
11070
+ hasUneditableRows && /* @__PURE__ */ jsxRuntime.jsx(InlineTip, { variant: "warning", label: "Some rows are disabled", children: "This object contains non-primitive metadata, such as arrays or objects, that can't be edited here. To edit the disabled rows, use the API directly." })
11071
+ ] }),
11072
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
11073
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
11074
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
11075
+ ] }) })
11076
+ ]
11077
+ }
11078
+ ) });
11079
+ };
11080
+ const GridInput = React.forwardRef(({ className, ...props }, ref) => {
11081
+ return /* @__PURE__ */ jsxRuntime.jsx(
11082
+ "input",
11083
+ {
11084
+ ref,
11085
+ ...props,
11086
+ autoComplete: "off",
11087
+ className: ui.clx(
11088
+ "txt-compact-small text-ui-fg-base placeholder:text-ui-fg-muted disabled:text-ui-fg-disabled disabled:bg-ui-bg-base bg-transparent px-2 py-1.5 outline-none",
11089
+ className
10871
11090
  )
11091
+ }
11092
+ );
11093
+ });
11094
+ GridInput.displayName = "MetadataForm.GridInput";
11095
+ const PlaceholderInner = () => {
11096
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-1 flex-col overflow-hidden", children: [
11097
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-[148ox] w-full rounded-lg" }) }),
11098
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
11099
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-7 w-12 rounded-md" }),
11100
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-7 w-12 rounded-md" })
10872
11101
  ] }) })
10873
11102
  ] });
10874
11103
  };
10875
- const Item = ({ item, preview, currencyCode }) => {
10876
- if (item.variant_id) {
10877
- return /* @__PURE__ */ jsxRuntime.jsx(VariantItem, { item, preview, currencyCode });
11104
+ const EDITABLE_TYPES = ["string", "number", "boolean"];
11105
+ function getDefaultValues(metadata) {
11106
+ if (!metadata || !Object.keys(metadata).length) {
11107
+ return [
11108
+ {
11109
+ key: "",
11110
+ value: "",
11111
+ disabled: false
11112
+ }
11113
+ ];
10878
11114
  }
10879
- return /* @__PURE__ */ jsxRuntime.jsx(CustomItem, { item, preview, currencyCode });
10880
- };
10881
- const VariantItem = ({ item, preview, currencyCode }) => {
10882
- const [editing, setEditing] = React.useState(false);
10883
- const form = reactHookForm.useForm({
10884
- defaultValues: {
10885
- quantity: item.quantity,
10886
- unit_price: item.unit_price
10887
- },
10888
- resolver: zod.zodResolver(variantItemSchema)
10889
- });
10890
- const actionId = React.useMemo(() => {
10891
- var _a, _b;
10892
- return (_b = (_a = item.actions) == null ? void 0 : _a.find((a) => a.action === "ITEM_ADD")) == null ? void 0 : _b.id;
10893
- }, [item]);
10894
- const { mutateAsync: updateActionItem, isPending: isUpdatingActionItem } = useDraftOrderUpdateActionItem(preview.id);
10895
- const { mutateAsync: updateOriginalItem, isPending: isUpdatingOriginalItem } = useDraftOrderUpdateItem(preview.id);
10896
- const isPending = isUpdatingActionItem || isUpdatingOriginalItem;
10897
- const onSubmit = form.handleSubmit(async (data) => {
10898
- if (convertNumber(data.unit_price) === item.unit_price && data.quantity === item.quantity) {
10899
- setEditing(false);
11115
+ return Object.entries(metadata).map(([key, value]) => {
11116
+ if (!EDITABLE_TYPES.includes(typeof value)) {
11117
+ return {
11118
+ key,
11119
+ value,
11120
+ disabled: true
11121
+ };
11122
+ }
11123
+ let stringValue = value;
11124
+ if (typeof value !== "string") {
11125
+ stringValue = JSON.stringify(value);
11126
+ }
11127
+ return {
11128
+ key,
11129
+ value: stringValue,
11130
+ original_key: key
11131
+ };
11132
+ });
11133
+ }
11134
+ function parseValues(values) {
11135
+ const metadata = values.metadata;
11136
+ const isEmpty = !metadata.length || metadata.length === 1 && !metadata[0].key && !metadata[0].value;
11137
+ if (isEmpty) {
11138
+ return null;
11139
+ }
11140
+ const update = {};
11141
+ metadata.forEach((field) => {
11142
+ let key = field.key;
11143
+ let value = field.value;
11144
+ const disabled = field.disabled;
11145
+ if (!key || !value) {
10900
11146
  return;
10901
11147
  }
10902
- if (!actionId) {
10903
- await updateOriginalItem(
10904
- {
10905
- item_id: item.id,
10906
- quantity: data.quantity,
10907
- unit_price: convertNumber(data.unit_price)
10908
- },
10909
- {
10910
- onSuccess: () => {
10911
- setEditing(false);
10912
- },
10913
- onError: (e) => {
10914
- ui.toast.error(e.message);
10915
- }
11148
+ if (disabled) {
11149
+ update[key] = value;
11150
+ return;
11151
+ }
11152
+ key = key.trim();
11153
+ value = value.trim();
11154
+ if (value === "true") {
11155
+ update[key] = true;
11156
+ } else if (value === "false") {
11157
+ update[key] = false;
11158
+ } else {
11159
+ const parsedNumber = parseFloat(value);
11160
+ if (!isNaN(parsedNumber)) {
11161
+ update[key] = parsedNumber;
11162
+ } else {
11163
+ update[key] = value;
11164
+ }
11165
+ }
11166
+ });
11167
+ return update;
11168
+ }
11169
+ function getHasUneditableRows(metadata) {
11170
+ if (!metadata) {
11171
+ return false;
11172
+ }
11173
+ return Object.values(metadata).some(
11174
+ (value) => !EDITABLE_TYPES.includes(typeof value)
11175
+ );
11176
+ }
11177
+ const PROMOTION_QUERY_KEY = "promotions";
11178
+ const promotionsQueryKeys = {
11179
+ list: (query2) => [
11180
+ PROMOTION_QUERY_KEY,
11181
+ query2 ? query2 : void 0
11182
+ ],
11183
+ detail: (id, query2) => [
11184
+ PROMOTION_QUERY_KEY,
11185
+ id,
11186
+ query2 ? query2 : void 0
11187
+ ]
11188
+ };
11189
+ const usePromotions = (query2, options) => {
11190
+ const { data, ...rest } = reactQuery.useQuery({
11191
+ queryKey: promotionsQueryKeys.list(query2),
11192
+ queryFn: async () => sdk.admin.promotion.list(query2),
11193
+ ...options
11194
+ });
11195
+ return { ...data, ...rest };
11196
+ };
11197
+ const Promotions = () => {
11198
+ const { id } = reactRouterDom.useParams();
11199
+ const {
11200
+ order: preview,
11201
+ isError: isPreviewError,
11202
+ error: previewError
11203
+ } = useOrderPreview(id, void 0);
11204
+ useInitiateOrderEdit({ preview });
11205
+ const { onCancel } = useCancelOrderEdit({ preview });
11206
+ if (isPreviewError) {
11207
+ throw previewError;
11208
+ }
11209
+ const isReady = !!preview;
11210
+ return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { onClose: onCancel, children: [
11211
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Promotions" }) }) }),
11212
+ isReady && /* @__PURE__ */ jsxRuntime.jsx(PromotionForm, { preview })
11213
+ ] });
11214
+ };
11215
+ const PromotionForm = ({ preview }) => {
11216
+ const { items, shipping_methods } = preview;
11217
+ const [isSubmitting, setIsSubmitting] = React.useState(false);
11218
+ const [comboboxValue, setComboboxValue] = React.useState("");
11219
+ const { handleSuccess } = useRouteModal();
11220
+ const { mutateAsync: addPromotions, isPending: isAddingPromotions } = useDraftOrderAddPromotions(preview.id);
11221
+ const promoIds = getPromotionIds(items, shipping_methods);
11222
+ const { promotions, isPending, isError, error } = usePromotions(
11223
+ {
11224
+ id: promoIds
11225
+ },
11226
+ {
11227
+ enabled: !!promoIds.length
11228
+ }
11229
+ );
11230
+ const comboboxData = useComboboxData({
11231
+ queryKey: ["promotions", "combobox", promoIds],
11232
+ queryFn: async (params) => {
11233
+ return await sdk.admin.promotion.list({
11234
+ ...params,
11235
+ id: {
11236
+ $nin: promoIds
10916
11237
  }
10917
- );
11238
+ });
11239
+ },
11240
+ getOptions: (data) => {
11241
+ return data.promotions.map((promotion) => ({
11242
+ label: promotion.code,
11243
+ value: promotion.code
11244
+ }));
11245
+ }
11246
+ });
11247
+ const add = async (value) => {
11248
+ if (!value) {
10918
11249
  return;
10919
11250
  }
10920
- await updateActionItem(
11251
+ addPromotions(
10921
11252
  {
10922
- action_id: actionId,
10923
- quantity: data.quantity,
10924
- unit_price: convertNumber(data.unit_price)
11253
+ promo_codes: [value]
10925
11254
  },
10926
11255
  {
10927
- onSuccess: () => {
10928
- setEditing(false);
10929
- },
10930
11256
  onError: (e) => {
10931
11257
  ui.toast.error(e.message);
11258
+ comboboxData.onSearchValueChange("");
11259
+ setComboboxValue("");
11260
+ },
11261
+ onSuccess: () => {
11262
+ comboboxData.onSearchValueChange("");
11263
+ setComboboxValue("");
10932
11264
  }
10933
11265
  }
10934
11266
  );
10935
- });
10936
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2, { ...form, children: /* @__PURE__ */ jsxRuntime.jsx("form", { onSubmit, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest grid grid-cols-[minmax(0,2fr)_minmax(0,1fr)_minmax(0,2fr)_28px] items-center gap-3 rounded-lg px-4 py-2", children: [
10937
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full items-center gap-x-3", children: [
10938
- /* @__PURE__ */ jsxRuntime.jsx(
10939
- Thumbnail,
10940
- {
10941
- thumbnail: item.thumbnail,
10942
- alt: item.product_title ?? void 0
10943
- }
10944
- ),
10945
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
10946
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-1", children: [
10947
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: item.product_title }),
10948
- /* @__PURE__ */ jsxRuntime.jsxs(
10949
- ui.Text,
10950
- {
10951
- size: "small",
10952
- leading: "compact",
10953
- className: "text-ui-fg-subtle",
10954
- children: [
10955
- "(",
10956
- item.variant_title,
10957
- ")"
10958
- ]
10959
- }
10960
- )
11267
+ };
11268
+ const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
11269
+ const { mutateAsync: requestOrderEdit } = useOrderEditRequest(preview.id);
11270
+ const onSubmit = async () => {
11271
+ setIsSubmitting(true);
11272
+ let requestSucceeded = false;
11273
+ await requestOrderEdit(void 0, {
11274
+ onError: (e) => {
11275
+ ui.toast.error(e.message);
11276
+ },
11277
+ onSuccess: () => {
11278
+ requestSucceeded = true;
11279
+ }
11280
+ });
11281
+ if (!requestSucceeded) {
11282
+ setIsSubmitting(false);
11283
+ return;
11284
+ }
11285
+ await confirmOrderEdit(void 0, {
11286
+ onError: (e) => {
11287
+ ui.toast.error(e.message);
11288
+ },
11289
+ onSuccess: () => {
11290
+ handleSuccess();
11291
+ },
11292
+ onSettled: () => {
11293
+ setIsSubmitting(false);
11294
+ }
11295
+ });
11296
+ };
11297
+ if (isError) {
11298
+ throw error;
11299
+ }
11300
+ return /* @__PURE__ */ jsxRuntime.jsxs(KeyboundForm, { className: "flex flex-1 flex-col", onSubmit, children: [
11301
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-4", children: [
11302
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
11303
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
11304
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Label, { size: "small", weight: "plus", htmlFor: "promotion-combobox", children: "Apply promotions" }),
11305
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Hint, { id: "promotion-combobox-hint", children: "Manage promotions that should be applied to the order." })
10961
11306
  ] }),
10962
11307
  /* @__PURE__ */ jsxRuntime.jsx(
10963
- ui.Text,
11308
+ Combobox,
10964
11309
  {
10965
- size: "small",
10966
- leading: "compact",
10967
- className: "text-ui-fg-subtle",
10968
- children: item.variant_sku
11310
+ id: "promotion-combobox",
11311
+ "aria-describedby": "promotion-combobox-hint",
11312
+ isFetchingNextPage: comboboxData.isFetchingNextPage,
11313
+ fetchNextPage: comboboxData.fetchNextPage,
11314
+ options: comboboxData.options,
11315
+ onSearchValueChange: comboboxData.onSearchValueChange,
11316
+ searchValue: comboboxData.searchValue,
11317
+ disabled: comboboxData.disabled || isAddingPromotions,
11318
+ onChange: add,
11319
+ value: comboboxValue
10969
11320
  }
10970
11321
  )
10971
- ] })
10972
- ] }),
10973
- editing ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(
10974
- Form$2.Field,
10975
- {
10976
- control: form.control,
10977
- name: "quantity",
10978
- render: ({ field }) => {
10979
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(NumberInput, { ...field }) }) });
10980
- }
10981
- }
10982
- ) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: item.quantity }) }),
10983
- editing ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(
10984
- Form$2.Field,
10985
- {
10986
- control: form.control,
10987
- name: "unit_price",
10988
- render: ({ field: { onChange, ...field } }) => {
10989
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
10990
- ui.CurrencyInput,
10991
- {
10992
- ...field,
10993
- symbol: getNativeSymbol(currencyCode),
10994
- code: currencyCode,
10995
- onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value)
10996
- }
10997
- ) }) });
10998
- }
10999
- }
11000
- ) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex w-full flex-1 items-center justify-end", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: getLocaleAmount(item.unit_price, currencyCode) }) }),
11001
- /* @__PURE__ */ jsxRuntime.jsx(
11002
- ui.IconButton,
11003
- {
11004
- type: "button",
11005
- size: "small",
11006
- onClick: editing ? onSubmit : () => {
11007
- setEditing(true);
11008
- },
11009
- disabled: isPending,
11010
- children: editing ? /* @__PURE__ */ jsxRuntime.jsx(icons.Check, {}) : /* @__PURE__ */ jsxRuntime.jsx(icons.PencilSquare, {})
11011
- }
11012
- )
11013
- ] }) }) });
11014
- };
11015
- const variantItemSchema = objectType({
11016
- quantity: numberType(),
11017
- unit_price: unionType([numberType(), stringType()])
11018
- });
11019
- const CustomItem = ({ item, preview, currencyCode }) => {
11020
- const [editing, setEditing] = React.useState(false);
11021
- const { quantity, unit_price, title } = item;
11022
- const form = reactHookForm.useForm({
11023
- defaultValues: {
11024
- title,
11025
- quantity,
11026
- unit_price
11027
- },
11028
- resolver: zod.zodResolver(customItemSchema)
11029
- });
11030
- React.useEffect(() => {
11031
- form.reset({
11032
- title,
11033
- quantity,
11034
- unit_price
11035
- });
11036
- }, [form, title, quantity, unit_price]);
11037
- const actionId = React.useMemo(() => {
11038
- var _a, _b;
11039
- return (_b = (_a = item.actions) == null ? void 0 : _a.find((a) => a.action === "ITEM_ADD")) == null ? void 0 : _b.id;
11040
- }, [item]);
11041
- const { mutateAsync: updateActionItem, isPending: isUpdatingActionItem } = useDraftOrderUpdateActionItem(preview.id);
11042
- const { mutateAsync: removeActionItem, isPending: isRemovingActionItem } = useDraftOrderRemoveActionItem(preview.id);
11043
- const { mutateAsync: updateOriginalItem, isPending: isUpdatingOriginalItem } = useDraftOrderUpdateItem(preview.id);
11044
- const isPending = isUpdatingActionItem || isUpdatingOriginalItem;
11045
- const onSubmit = form.handleSubmit(async (data) => {
11046
- if (convertNumber(data.unit_price) === item.unit_price && data.quantity === item.quantity && data.title === item.title) {
11047
- setEditing(false);
11048
- return;
11049
- }
11050
- if (!actionId) {
11051
- await updateOriginalItem(
11322
+ ] }),
11323
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
11324
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-2", children: promotions == null ? void 0 : promotions.map((promotion) => /* @__PURE__ */ jsxRuntime.jsx(
11325
+ PromotionItem,
11052
11326
  {
11053
- item_id: item.id,
11054
- quantity: data.quantity,
11055
- unit_price: convertNumber(data.unit_price)
11327
+ promotion,
11328
+ orderId: preview.id,
11329
+ isLoading: isPending
11056
11330
  },
11331
+ promotion.id
11332
+ )) })
11333
+ ] }) }),
11334
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
11335
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
11336
+ /* @__PURE__ */ jsxRuntime.jsx(
11337
+ ui.Button,
11057
11338
  {
11058
- onSuccess: () => {
11059
- setEditing(false);
11060
- },
11061
- onError: (e) => {
11062
- ui.toast.error(e.message);
11063
- }
11064
- }
11065
- );
11066
- return;
11067
- }
11068
- if (data.quantity === 0) {
11069
- await removeActionItem(actionId, {
11070
- onSuccess: () => {
11071
- setEditing(false);
11072
- },
11073
- onError: (e) => {
11074
- ui.toast.error(e.message);
11339
+ size: "small",
11340
+ type: "submit",
11341
+ isLoading: isSubmitting || isAddingPromotions,
11342
+ children: "Save"
11075
11343
  }
11076
- });
11077
- return;
11078
- }
11079
- await updateActionItem(
11344
+ )
11345
+ ] }) })
11346
+ ] });
11347
+ };
11348
+ const PromotionItem = ({
11349
+ promotion,
11350
+ orderId,
11351
+ isLoading
11352
+ }) => {
11353
+ var _a;
11354
+ const { mutateAsync: removePromotions, isPending } = useDraftOrderRemovePromotions(orderId);
11355
+ const onRemove = async () => {
11356
+ removePromotions(
11080
11357
  {
11081
- action_id: actionId,
11082
- quantity: data.quantity,
11083
- unit_price: convertNumber(data.unit_price)
11358
+ promo_codes: [promotion.code]
11084
11359
  },
11085
11360
  {
11086
- onSuccess: () => {
11087
- setEditing(false);
11088
- },
11089
11361
  onError: (e) => {
11090
11362
  ui.toast.error(e.message);
11091
11363
  }
11092
11364
  }
11093
11365
  );
11094
- });
11095
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2, { ...form, children: /* @__PURE__ */ jsxRuntime.jsx("form", { onSubmit, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest grid grid-cols-[minmax(0,2fr)_minmax(0,1fr)_minmax(0,2fr)_28px] items-center gap-3 rounded-lg px-4 py-2", children: [
11096
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-3", children: [
11097
- /* @__PURE__ */ jsxRuntime.jsx(
11098
- Thumbnail,
11366
+ };
11367
+ const displayValue = getDisplayValue(promotion);
11368
+ return /* @__PURE__ */ jsxRuntime.jsxs(
11369
+ "div",
11370
+ {
11371
+ className: ui.clx(
11372
+ "bg-ui-bg-component shadow-elevation-card-rest flex items-center justify-between rounded-lg px-3 py-2",
11099
11373
  {
11100
- thumbnail: item.thumbnail,
11101
- alt: item.title ?? void 0
11374
+ "animate-pulse": isLoading
11102
11375
  }
11103
11376
  ),
11104
- editing ? /* @__PURE__ */ jsxRuntime.jsx(
11105
- Form$2.Field,
11106
- {
11107
- control: form.control,
11108
- name: "title",
11109
- render: ({ field }) => {
11110
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }) });
11377
+ children: [
11378
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
11379
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: promotion.code }),
11380
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-ui-fg-subtle flex items-center gap-1.5", children: [
11381
+ displayValue && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
11382
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", children: displayValue }),
11383
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", children: "·" })
11384
+ ] }),
11385
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", className: "capitalize", children: (_a = promotion.application_method) == null ? void 0 : _a.allocation })
11386
+ ] })
11387
+ ] }),
11388
+ /* @__PURE__ */ jsxRuntime.jsx(
11389
+ ui.IconButton,
11390
+ {
11391
+ size: "small",
11392
+ type: "button",
11393
+ variant: "transparent",
11394
+ onClick: onRemove,
11395
+ isLoading: isPending || isLoading,
11396
+ children: /* @__PURE__ */ jsxRuntime.jsx(icons.XMark, {})
11111
11397
  }
11112
- }
11113
- ) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: item.title })
11114
- ] }),
11115
- editing ? /* @__PURE__ */ jsxRuntime.jsx(
11116
- Form$2.Field,
11117
- {
11118
- control: form.control,
11119
- name: "quantity",
11120
- render: ({ field }) => {
11121
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(NumberInput, { ...field }) }) });
11398
+ )
11399
+ ]
11400
+ },
11401
+ promotion.id
11402
+ );
11403
+ };
11404
+ function getDisplayValue(promotion) {
11405
+ var _a, _b, _c, _d;
11406
+ const value = (_a = promotion.application_method) == null ? void 0 : _a.value;
11407
+ if (!value) {
11408
+ return null;
11409
+ }
11410
+ if (((_b = promotion.application_method) == null ? void 0 : _b.type) === "fixed") {
11411
+ const currency = (_c = promotion.application_method) == null ? void 0 : _c.currency_code;
11412
+ if (!currency) {
11413
+ return null;
11414
+ }
11415
+ return getLocaleAmount(value, currency);
11416
+ } else if (((_d = promotion.application_method) == null ? void 0 : _d.type) === "percentage") {
11417
+ return formatPercentage(value);
11418
+ }
11419
+ return null;
11420
+ }
11421
+ const formatter = new Intl.NumberFormat([], {
11422
+ style: "percent",
11423
+ minimumFractionDigits: 2
11424
+ });
11425
+ const formatPercentage = (value, isPercentageValue = false) => {
11426
+ let val = value || 0;
11427
+ if (!isPercentageValue) {
11428
+ val = val / 100;
11429
+ }
11430
+ return formatter.format(val);
11431
+ };
11432
+ function getPromotionIds(items, shippingMethods) {
11433
+ const promotionIds = /* @__PURE__ */ new Set();
11434
+ for (const item of items) {
11435
+ if (item.adjustments) {
11436
+ for (const adjustment of item.adjustments) {
11437
+ if (adjustment.promotion_id) {
11438
+ promotionIds.add(adjustment.promotion_id);
11122
11439
  }
11123
11440
  }
11124
- ) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: item.quantity }),
11125
- editing ? /* @__PURE__ */ jsxRuntime.jsx(
11126
- Form$2.Field,
11127
- {
11128
- control: form.control,
11129
- name: "unit_price",
11130
- render: ({ field: { onChange, ...field } }) => {
11131
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
11132
- ui.CurrencyInput,
11133
- {
11134
- ...field,
11135
- symbol: getNativeSymbol(currencyCode),
11136
- code: currencyCode,
11137
- onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value)
11138
- }
11139
- ) }) });
11441
+ }
11442
+ }
11443
+ for (const shippingMethod of shippingMethods) {
11444
+ if (shippingMethod.adjustments) {
11445
+ for (const adjustment of shippingMethod.adjustments) {
11446
+ if (adjustment.promotion_id) {
11447
+ promotionIds.add(adjustment.promotion_id);
11140
11448
  }
11141
11449
  }
11142
- ) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-1 items-center justify-end", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: getLocaleAmount(item.unit_price, currencyCode) }) }),
11143
- /* @__PURE__ */ jsxRuntime.jsx(
11144
- ui.IconButton,
11145
- {
11146
- type: "button",
11147
- size: "small",
11148
- onClick: editing ? onSubmit : () => {
11149
- setEditing(true);
11150
- },
11151
- disabled: isPending,
11152
- children: editing ? /* @__PURE__ */ jsxRuntime.jsx(icons.Check, {}) : /* @__PURE__ */ jsxRuntime.jsx(icons.PencilSquare, {})
11153
- }
11154
- )
11155
- ] }) }) });
11156
- };
11157
- const StackedModalTrigger$1 = ({
11158
- type,
11159
- setModalContent
11160
- }) => {
11161
- const { setIsOpen } = useStackedModal();
11162
- const onClick = React.useCallback(() => {
11163
- setModalContent(type);
11164
- setIsOpen(STACKED_MODAL_ID, true);
11165
- }, [setModalContent, setIsOpen, type]);
11166
- return /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenu.Item, { onClick, children: type === "add-items" ? "Add items" : "Add custom item" }) });
11167
- };
11168
- const VARIANT_PREFIX = "items";
11169
- const LIMIT = 50;
11170
- const ExistingItemsForm = ({ orderId, items }) => {
11171
- const { setIsOpen } = useStackedModal();
11172
- const [rowSelection, setRowSelection] = React.useState(
11173
- items.reduce((acc, item) => {
11174
- acc[item.variant_id] = true;
11175
- return acc;
11176
- }, {})
11177
- );
11178
- React.useEffect(() => {
11179
- setRowSelection(
11180
- items.reduce((acc, item) => {
11181
- if (item.variant_id) {
11182
- acc[item.variant_id] = true;
11183
- }
11184
- return acc;
11185
- }, {})
11186
- );
11187
- }, [items]);
11188
- const { q, order, offset } = useQueryParams(
11189
- ["q", "order", "offset"],
11190
- VARIANT_PREFIX
11191
- );
11192
- const { variants, count, isPending, isError, error } = useProductVariants(
11450
+ }
11451
+ }
11452
+ return Array.from(promotionIds);
11453
+ }
11454
+ const SalesChannel = () => {
11455
+ const { id } = reactRouterDom.useParams();
11456
+ const { draft_order, isPending, isError, error } = useDraftOrder(
11457
+ id,
11193
11458
  {
11194
- q,
11195
- order,
11196
- offset: offset ? parseInt(offset) : void 0,
11197
- limit: LIMIT
11459
+ fields: "+sales_channel_id"
11198
11460
  },
11199
11461
  {
11200
- placeholderData: reactQuery.keepPreviousData
11462
+ enabled: !!id
11201
11463
  }
11202
11464
  );
11203
- const columns = useColumns();
11204
- const { mutateAsync } = useDraftOrderAddItems(orderId);
11205
- const onSubmit = async () => {
11206
- const ids = Object.keys(rowSelection).filter(
11207
- (id) => !items.find((i) => i.variant_id === id)
11208
- );
11209
- await mutateAsync(
11210
- {
11211
- items: ids.map((id) => ({
11212
- variant_id: id,
11213
- quantity: 1
11214
- }))
11215
- },
11216
- {
11217
- onSuccess: () => {
11218
- setRowSelection({});
11219
- setIsOpen(STACKED_MODAL_ID, false);
11220
- },
11221
- onError: (e) => {
11222
- ui.toast.error(e.message);
11223
- }
11224
- }
11225
- );
11226
- };
11227
11465
  if (isError) {
11228
11466
  throw error;
11229
11467
  }
11230
- return /* @__PURE__ */ jsxRuntime.jsxs(
11231
- StackedFocusModal.Content,
11232
- {
11233
- onOpenAutoFocus: (e) => {
11234
- e.preventDefault();
11235
- const searchInput = document.querySelector(
11236
- "[data-modal-id='modal-search-input']"
11237
- );
11238
- if (searchInput) {
11239
- searchInput.focus();
11240
- }
11241
- },
11242
- children: [
11243
- /* @__PURE__ */ jsxRuntime.jsxs(StackedFocusModal.Header, { children: [
11244
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Product Variants" }) }),
11245
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Choose product variants to add to the order." }) })
11246
- ] }),
11247
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Body, { className: "flex-1 overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(
11248
- DataTable,
11249
- {
11250
- data: variants,
11251
- columns,
11252
- isLoading: isPending,
11253
- getRowId: (row) => row.id,
11254
- rowCount: count,
11255
- prefix: VARIANT_PREFIX,
11256
- layout: "fill",
11257
- rowSelection: {
11258
- state: rowSelection,
11259
- onRowSelectionChange: setRowSelection,
11260
- enableRowSelection: (row) => {
11261
- return !items.find((i) => i.variant_id === row.original.id);
11262
- }
11263
- },
11264
- autoFocusSearch: true
11265
- }
11266
- ) }),
11267
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
11268
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
11269
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "button", onClick: onSubmit, children: "Update items" })
11270
- ] }) })
11271
- ]
11272
- }
11273
- );
11274
- };
11275
- const columnHelper = ui.createDataTableColumnHelper();
11276
- const useColumns = () => {
11277
- return React.useMemo(() => {
11278
- return [
11279
- columnHelper.select(),
11280
- columnHelper.accessor("product.title", {
11281
- header: "Product",
11282
- cell: ({ row }) => {
11283
- var _a, _b, _c;
11284
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-2", children: [
11285
- /* @__PURE__ */ jsxRuntime.jsx(
11286
- Thumbnail,
11287
- {
11288
- thumbnail: (_a = row.original.product) == null ? void 0 : _a.thumbnail,
11289
- alt: (_b = row.original.product) == null ? void 0 : _b.title
11290
- }
11291
- ),
11292
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: (_c = row.original.product) == null ? void 0 : _c.title })
11293
- ] });
11294
- },
11295
- enableSorting: true
11296
- }),
11297
- columnHelper.accessor("title", {
11298
- header: "Variant",
11299
- enableSorting: true
11300
- }),
11301
- columnHelper.accessor("sku", {
11302
- header: "SKU",
11303
- cell: ({ getValue }) => {
11304
- return getValue() ?? "-";
11305
- },
11306
- enableSorting: true
11307
- }),
11308
- columnHelper.accessor("updated_at", {
11309
- header: "Updated",
11310
- cell: ({ getValue }) => {
11311
- return /* @__PURE__ */ jsxRuntime.jsx(
11312
- ui.Tooltip,
11313
- {
11314
- content: getFullDate({ date: getValue(), includeTime: true }),
11315
- children: /* @__PURE__ */ jsxRuntime.jsx("span", { children: getFullDate({ date: getValue() }) })
11316
- }
11317
- );
11318
- },
11319
- enableSorting: true,
11320
- sortAscLabel: "Oldest first",
11321
- sortDescLabel: "Newest first"
11322
- }),
11323
- columnHelper.accessor("created_at", {
11324
- header: "Created",
11325
- cell: ({ getValue }) => {
11326
- return /* @__PURE__ */ jsxRuntime.jsx(
11327
- ui.Tooltip,
11328
- {
11329
- content: getFullDate({ date: getValue(), includeTime: true }),
11330
- children: /* @__PURE__ */ jsxRuntime.jsx("span", { children: getFullDate({ date: getValue() }) })
11331
- }
11332
- );
11333
- },
11334
- enableSorting: true,
11335
- sortAscLabel: "Oldest first",
11336
- sortDescLabel: "Newest first"
11337
- })
11338
- ];
11339
- }, []);
11468
+ const ISrEADY = !!draft_order && !isPending;
11469
+ return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
11470
+ /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Header, { children: [
11471
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Sales Channel" }) }),
11472
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Update which sales channel the draft order is associated with" }) })
11473
+ ] }),
11474
+ ISrEADY && /* @__PURE__ */ jsxRuntime.jsx(SalesChannelForm, { order: draft_order })
11475
+ ] });
11340
11476
  };
11341
- const CustomItemForm = ({ orderId, currencyCode }) => {
11342
- const { setIsOpen } = useStackedModal();
11343
- const { mutateAsync: addItems } = useDraftOrderAddItems(orderId);
11477
+ const SalesChannelForm = ({ order }) => {
11344
11478
  const form = reactHookForm.useForm({
11345
11479
  defaultValues: {
11346
- title: "",
11347
- quantity: 1,
11348
- unit_price: ""
11480
+ sales_channel_id: order.sales_channel_id || ""
11349
11481
  },
11350
- resolver: zod.zodResolver(customItemSchema)
11482
+ resolver: zod.zodResolver(schema$2)
11351
11483
  });
11484
+ const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
11485
+ const { handleSuccess } = useRouteModal();
11352
11486
  const onSubmit = form.handleSubmit(async (data) => {
11353
- await addItems(
11487
+ await mutateAsync(
11354
11488
  {
11355
- items: [
11356
- {
11357
- title: data.title,
11358
- quantity: data.quantity,
11359
- unit_price: convertNumber(data.unit_price)
11360
- }
11361
- ]
11489
+ sales_channel_id: data.sales_channel_id
11362
11490
  },
11363
11491
  {
11364
11492
  onSuccess: () => {
11365
- setIsOpen(STACKED_MODAL_ID, false);
11493
+ ui.toast.success("Sales channel updated");
11494
+ handleSuccess();
11366
11495
  },
11367
- onError: (e) => {
11368
- ui.toast.error(e.message);
11496
+ onError: (error) => {
11497
+ ui.toast.error(error.message);
11369
11498
  }
11370
11499
  }
11371
11500
  );
11372
11501
  });
11373
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2, { ...form, children: /* @__PURE__ */ jsxRuntime.jsx(KeyboundForm, { onSubmit, children: /* @__PURE__ */ jsxRuntime.jsxs(StackedFocusModal.Content, { children: [
11374
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Header, {}),
11375
- /* @__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-2 py-16", children: [
11376
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
11377
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Add custom item" }) }),
11378
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Add a custom item to the order. This will add a new line item that is not associated with an existing product." }) })
11379
- ] }),
11380
- /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
11381
- /* @__PURE__ */ jsxRuntime.jsx(
11382
- Form$2.Field,
11383
- {
11384
- control: form.control,
11385
- name: "title",
11386
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
11387
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
11388
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Title" }),
11389
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Enter the title of the item" })
11390
- ] }),
11391
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
11392
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
11393
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
11394
- ] })
11395
- ] }) })
11396
- }
11397
- ),
11398
- /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
11399
- /* @__PURE__ */ jsxRuntime.jsx(
11400
- Form$2.Field,
11401
- {
11402
- control: form.control,
11403
- name: "unit_price",
11404
- render: ({ field: { onChange, ...field } }) => /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
11405
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
11406
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Unit price" }),
11407
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Enter the unit price of the item" })
11408
- ] }),
11409
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
11410
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
11411
- ui.CurrencyInput,
11412
- {
11413
- symbol: getNativeSymbol(currencyCode),
11414
- code: currencyCode,
11415
- onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value),
11416
- ...field
11417
- }
11418
- ) }),
11419
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
11420
- ] })
11421
- ] }) })
11422
- }
11423
- ),
11424
- /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
11425
- /* @__PURE__ */ jsxRuntime.jsx(
11426
- Form$2.Field,
11427
- {
11428
- control: form.control,
11429
- name: "quantity",
11430
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
11431
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
11432
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Quantity" }),
11433
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Enter the quantity of the item" })
11434
- ] }),
11435
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full flex-1", children: [
11436
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(NumberInput, { ...field, className: "w-full" }) }) }),
11437
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
11438
- ] })
11439
- ] }) })
11440
- }
11441
- )
11442
- ] }) }) }),
11443
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
11444
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
11445
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "button", onClick: onSubmit, children: "Add item" })
11446
- ] }) })
11447
- ] }) }) });
11502
+ return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(
11503
+ KeyboundForm,
11504
+ {
11505
+ className: "flex flex-1 flex-col overflow-hidden",
11506
+ onSubmit,
11507
+ children: [
11508
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsx(SalesChannelField, { control: form.control, order }) }),
11509
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
11510
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
11511
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
11512
+ ] }) })
11513
+ ]
11514
+ }
11515
+ ) });
11448
11516
  };
11449
- const customItemSchema = objectType({
11450
- title: stringType().min(1),
11451
- quantity: numberType(),
11452
- unit_price: unionType([numberType(), stringType()])
11517
+ const SalesChannelField = ({ control, order }) => {
11518
+ const salesChannels = useComboboxData({
11519
+ queryFn: async (params) => {
11520
+ return await sdk.admin.salesChannel.list(params);
11521
+ },
11522
+ queryKey: ["sales-channels"],
11523
+ getOptions: (data) => {
11524
+ return data.sales_channels.map((salesChannel) => ({
11525
+ label: salesChannel.name,
11526
+ value: salesChannel.id
11527
+ }));
11528
+ },
11529
+ defaultValue: order.sales_channel_id || void 0
11530
+ });
11531
+ return /* @__PURE__ */ jsxRuntime.jsx(
11532
+ Form$2.Field,
11533
+ {
11534
+ control,
11535
+ name: "sales_channel_id",
11536
+ render: ({ field }) => {
11537
+ return /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
11538
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Sales Channel" }),
11539
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
11540
+ Combobox,
11541
+ {
11542
+ options: salesChannels.options,
11543
+ fetchNextPage: salesChannels.fetchNextPage,
11544
+ isFetchingNextPage: salesChannels.isFetchingNextPage,
11545
+ searchValue: salesChannels.searchValue,
11546
+ onSearchValueChange: salesChannels.onSearchValueChange,
11547
+ placeholder: "Select sales channel",
11548
+ ...field
11549
+ }
11550
+ ) }),
11551
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
11552
+ ] });
11553
+ }
11554
+ }
11555
+ );
11556
+ };
11557
+ const schema$2 = objectType({
11558
+ sales_channel_id: stringType().min(1)
11453
11559
  });
11454
- const STACKED_FOCUS_MODAL_ID = "shipping-form";
11455
- const Shipping = () => {
11456
- var _a;
11560
+ const ShippingAddress = () => {
11457
11561
  const { id } = reactRouterDom.useParams();
11458
11562
  const { order, isPending, isError, error } = useOrder(id, {
11459
- fields: "+items.*,+items.variant.*,+items.variant.product.*,+items.variant.product.shipping_profile.*,+currency_code"
11563
+ fields: "+shipping_address"
11460
11564
  });
11461
- const {
11462
- order: preview,
11463
- isPending: isPreviewPending,
11464
- isError: isPreviewError,
11465
- error: previewError
11466
- } = useOrderPreview(id);
11467
- useInitiateOrderEdit({ preview });
11468
- const { onCancel } = useCancelOrderEdit({ preview });
11469
11565
  if (isError) {
11470
11566
  throw error;
11471
11567
  }
11472
- if (isPreviewError) {
11473
- throw previewError;
11474
- }
11475
- const orderHasItems = (((_a = order == null ? void 0 : order.items) == null ? void 0 : _a.length) || 0) > 0;
11476
- const isReady = preview && !isPreviewPending && order && !isPending;
11477
- return /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal, { onClose: onCancel, children: !orderHasItems ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-full flex-col overflow-hidden ", children: [
11478
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Header, {}),
11479
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Body, { className: "flex flex-1 flex-col overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-1 flex-col items-center overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full max-w-[720px] flex-col gap-y-6 py-16 px-6", children: [
11480
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Shipping" }) }),
11481
- /* @__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." }) })
11482
- ] }) }) }),
11483
- /* @__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" }) }) })
11484
- ] }) : isReady ? /* @__PURE__ */ jsxRuntime.jsx(ShippingForm, { preview, order }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
11485
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Edit Shipping" }) }),
11486
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Loading data for the draft order, please wait..." }) })
11487
- ] }) });
11568
+ const isReady = !isPending && !!order;
11569
+ return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
11570
+ /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Header, { children: [
11571
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Shipping Address" }) }),
11572
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Edit the shipping address for the draft order" }) })
11573
+ ] }),
11574
+ isReady && /* @__PURE__ */ jsxRuntime.jsx(ShippingAddressForm, { order })
11575
+ ] });
11488
11576
  };
11489
- const ShippingForm = ({ preview, order }) => {
11490
- var _a;
11491
- const { setIsOpen } = useStackedModal();
11492
- const [isSubmitting, setIsSubmitting] = React.useState(false);
11493
- const [data, setData] = React.useState(null);
11494
- const appliedShippingOptionIds = (_a = preview.shipping_methods) == null ? void 0 : _a.map((method) => method.shipping_option_id).filter(Boolean);
11495
- const { shipping_options } = useShippingOptions(
11496
- {
11497
- id: appliedShippingOptionIds,
11498
- fields: "+service_zone.*,+service_zone.fulfillment_set.*,+service_zone.fulfillment_set.location.*"
11577
+ const ShippingAddressForm = ({ order }) => {
11578
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
11579
+ const form = reactHookForm.useForm({
11580
+ defaultValues: {
11581
+ first_name: ((_a = order.shipping_address) == null ? void 0 : _a.first_name) ?? "",
11582
+ last_name: ((_b = order.shipping_address) == null ? void 0 : _b.last_name) ?? "",
11583
+ company: ((_c = order.shipping_address) == null ? void 0 : _c.company) ?? "",
11584
+ address_1: ((_d = order.shipping_address) == null ? void 0 : _d.address_1) ?? "",
11585
+ address_2: ((_e = order.shipping_address) == null ? void 0 : _e.address_2) ?? "",
11586
+ city: ((_f = order.shipping_address) == null ? void 0 : _f.city) ?? "",
11587
+ province: ((_g = order.shipping_address) == null ? void 0 : _g.province) ?? "",
11588
+ country_code: ((_h = order.shipping_address) == null ? void 0 : _h.country_code) ?? "",
11589
+ postal_code: ((_i = order.shipping_address) == null ? void 0 : _i.postal_code) ?? "",
11590
+ phone: ((_j = order.shipping_address) == null ? void 0 : _j.phone) ?? ""
11499
11591
  },
11500
- {
11501
- enabled: appliedShippingOptionIds.length > 0
11502
- }
11503
- );
11504
- const uniqueShippingProfiles = React.useMemo(() => {
11505
- const profiles = /* @__PURE__ */ new Map();
11506
- getUniqueShippingProfiles(order.items).forEach((profile) => {
11507
- profiles.set(profile.id, profile);
11508
- });
11509
- shipping_options == null ? void 0 : shipping_options.forEach((option) => {
11510
- profiles.set(option.shipping_profile_id, option.shipping_profile);
11511
- });
11512
- return Array.from(profiles.values());
11513
- }, [order.items, shipping_options]);
11592
+ resolver: zod.zodResolver(schema$1)
11593
+ });
11594
+ const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
11514
11595
  const { handleSuccess } = useRouteModal();
11515
- const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
11516
- const { mutateAsync: requestOrderEdit } = useDraftOrderRequestEdit(preview.id);
11517
- const { mutateAsync: removeShippingMethod } = useDraftOrderRemoveShippingMethod(preview.id);
11518
- const { mutateAsync: removeActionShippingMethod } = useDraftOrderRemoveActionShippingMethod(preview.id);
11519
- const onSubmit = async () => {
11520
- setIsSubmitting(true);
11521
- let requestSucceeded = false;
11522
- await requestOrderEdit(void 0, {
11523
- onError: (e) => {
11524
- ui.toast.error(`Failed to request order edit: ${e.message}`);
11525
- },
11526
- onSuccess: () => {
11527
- requestSucceeded = true;
11528
- }
11529
- });
11530
- if (!requestSucceeded) {
11531
- setIsSubmitting(false);
11532
- return;
11533
- }
11534
- await confirmOrderEdit(void 0, {
11535
- onError: (e) => {
11536
- ui.toast.error(`Failed to confirm order edit: ${e.message}`);
11537
- },
11538
- onSuccess: () => {
11539
- handleSuccess();
11596
+ const onSubmit = form.handleSubmit(async (data) => {
11597
+ await mutateAsync(
11598
+ {
11599
+ shipping_address: {
11600
+ first_name: data.first_name,
11601
+ last_name: data.last_name,
11602
+ company: data.company,
11603
+ address_1: data.address_1,
11604
+ address_2: data.address_2,
11605
+ city: data.city,
11606
+ province: data.province,
11607
+ country_code: data.country_code,
11608
+ postal_code: data.postal_code,
11609
+ phone: data.phone
11610
+ }
11540
11611
  },
11541
- onSettled: () => {
11542
- setIsSubmitting(false);
11543
- }
11544
- });
11545
- };
11546
- const onKeydown = React.useCallback(
11547
- (e) => {
11548
- if (e.key === "Enter" && (e.ctrlKey || e.metaKey)) {
11549
- if (data || isSubmitting) {
11550
- return;
11612
+ {
11613
+ onSuccess: () => {
11614
+ handleSuccess();
11615
+ },
11616
+ onError: (error) => {
11617
+ ui.toast.error(error.message);
11551
11618
  }
11552
- onSubmit();
11553
11619
  }
11554
- },
11555
- [data, isSubmitting, onSubmit]
11556
- );
11557
- React.useEffect(() => {
11558
- document.addEventListener("keydown", onKeydown);
11559
- return () => {
11560
- document.removeEventListener("keydown", onKeydown);
11561
- };
11562
- }, [onKeydown]);
11563
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-full flex-col overflow-hidden", children: [
11564
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Header, {}),
11620
+ );
11621
+ });
11622
+ return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(
11623
+ KeyboundForm,
11624
+ {
11625
+ className: "flex flex-1 flex-col overflow-hidden",
11626
+ onSubmit,
11627
+ children: [
11628
+ /* @__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: [
11629
+ /* @__PURE__ */ jsxRuntime.jsx(
11630
+ Form$2.Field,
11631
+ {
11632
+ control: form.control,
11633
+ name: "country_code",
11634
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
11635
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Country" }),
11636
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(CountrySelect, { ...field }) }),
11637
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
11638
+ ] })
11639
+ }
11640
+ ),
11641
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
11642
+ /* @__PURE__ */ jsxRuntime.jsx(
11643
+ Form$2.Field,
11644
+ {
11645
+ control: form.control,
11646
+ name: "first_name",
11647
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
11648
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "First name" }),
11649
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
11650
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
11651
+ ] })
11652
+ }
11653
+ ),
11654
+ /* @__PURE__ */ jsxRuntime.jsx(
11655
+ Form$2.Field,
11656
+ {
11657
+ control: form.control,
11658
+ name: "last_name",
11659
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
11660
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Last name" }),
11661
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
11662
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
11663
+ ] })
11664
+ }
11665
+ )
11666
+ ] }),
11667
+ /* @__PURE__ */ jsxRuntime.jsx(
11668
+ Form$2.Field,
11669
+ {
11670
+ control: form.control,
11671
+ name: "company",
11672
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
11673
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { optional: true, children: "Company" }),
11674
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
11675
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
11676
+ ] })
11677
+ }
11678
+ ),
11679
+ /* @__PURE__ */ jsxRuntime.jsx(
11680
+ Form$2.Field,
11681
+ {
11682
+ control: form.control,
11683
+ name: "address_1",
11684
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
11685
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Address" }),
11686
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
11687
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
11688
+ ] })
11689
+ }
11690
+ ),
11691
+ /* @__PURE__ */ jsxRuntime.jsx(
11692
+ Form$2.Field,
11693
+ {
11694
+ control: form.control,
11695
+ name: "address_2",
11696
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
11697
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { optional: true, children: "Apartment, suite, etc." }),
11698
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
11699
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
11700
+ ] })
11701
+ }
11702
+ ),
11703
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
11704
+ /* @__PURE__ */ jsxRuntime.jsx(
11705
+ Form$2.Field,
11706
+ {
11707
+ control: form.control,
11708
+ name: "postal_code",
11709
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
11710
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Postal code" }),
11711
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
11712
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
11713
+ ] })
11714
+ }
11715
+ ),
11716
+ /* @__PURE__ */ jsxRuntime.jsx(
11717
+ Form$2.Field,
11718
+ {
11719
+ control: form.control,
11720
+ name: "city",
11721
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
11722
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "City" }),
11723
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
11724
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
11725
+ ] })
11726
+ }
11727
+ )
11728
+ ] }),
11729
+ /* @__PURE__ */ jsxRuntime.jsx(
11730
+ Form$2.Field,
11731
+ {
11732
+ control: form.control,
11733
+ name: "province",
11734
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
11735
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { optional: true, children: "Province / State" }),
11736
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
11737
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
11738
+ ] })
11739
+ }
11740
+ ),
11741
+ /* @__PURE__ */ jsxRuntime.jsx(
11742
+ Form$2.Field,
11743
+ {
11744
+ control: form.control,
11745
+ name: "phone",
11746
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
11747
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { optional: true, children: "Phone" }),
11748
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
11749
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
11750
+ ] })
11751
+ }
11752
+ )
11753
+ ] }) }),
11754
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
11755
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
11756
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
11757
+ ] }) })
11758
+ ]
11759
+ }
11760
+ ) });
11761
+ };
11762
+ const schema$1 = addressSchema;
11763
+ const STACKED_FOCUS_MODAL_ID = "shipping-form";
11764
+ const Shipping = () => {
11765
+ var _a;
11766
+ const { id } = reactRouterDom.useParams();
11767
+ const { order, isPending, isError, error } = useOrder(id, {
11768
+ fields: "+items.*,+items.variant.*,+items.variant.product.*,+items.variant.product.shipping_profile.*,+currency_code"
11769
+ });
11770
+ const {
11771
+ order: preview,
11772
+ isPending: isPreviewPending,
11773
+ isError: isPreviewError,
11774
+ error: previewError
11775
+ } = useOrderPreview(id);
11776
+ useInitiateOrderEdit({ preview });
11777
+ const { onCancel } = useCancelOrderEdit({ preview });
11778
+ if (isError) {
11779
+ throw error;
11780
+ }
11781
+ if (isPreviewError) {
11782
+ throw previewError;
11783
+ }
11784
+ const orderHasItems = (((_a = order == null ? void 0 : order.items) == null ? void 0 : _a.length) || 0) > 0;
11785
+ const isReady = preview && !isPreviewPending && order && !isPending;
11786
+ return /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal, { onClose: onCancel, children: !orderHasItems ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-full flex-col overflow-hidden ", children: [
11787
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Header, {}),
11788
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Body, { className: "flex flex-1 flex-col overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-1 flex-col items-center overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full max-w-[720px] flex-col gap-y-6 py-16 px-6", children: [
11789
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Shipping" }) }),
11790
+ /* @__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." }) })
11791
+ ] }) }) }),
11792
+ /* @__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" }) }) })
11793
+ ] }) : isReady ? /* @__PURE__ */ jsxRuntime.jsx(ShippingForm, { preview, order }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
11794
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Edit Shipping" }) }),
11795
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Loading data for the draft order, please wait..." }) })
11796
+ ] }) });
11797
+ };
11798
+ const ShippingForm = ({ preview, order }) => {
11799
+ var _a;
11800
+ const { setIsOpen } = useStackedModal();
11801
+ const [isSubmitting, setIsSubmitting] = React.useState(false);
11802
+ const [data, setData] = React.useState(null);
11803
+ const appliedShippingOptionIds = (_a = preview.shipping_methods) == null ? void 0 : _a.map((method) => method.shipping_option_id).filter(Boolean);
11804
+ const { shipping_options } = useShippingOptions(
11805
+ {
11806
+ id: appliedShippingOptionIds,
11807
+ fields: "+service_zone.*,+service_zone.fulfillment_set.*,+service_zone.fulfillment_set.location.*"
11808
+ },
11809
+ {
11810
+ enabled: appliedShippingOptionIds.length > 0
11811
+ }
11812
+ );
11813
+ const uniqueShippingProfiles = React.useMemo(() => {
11814
+ const profiles = /* @__PURE__ */ new Map();
11815
+ getUniqueShippingProfiles(order.items).forEach((profile) => {
11816
+ profiles.set(profile.id, profile);
11817
+ });
11818
+ shipping_options == null ? void 0 : shipping_options.forEach((option) => {
11819
+ profiles.set(option.shipping_profile_id, option.shipping_profile);
11820
+ });
11821
+ return Array.from(profiles.values());
11822
+ }, [order.items, shipping_options]);
11823
+ const { handleSuccess } = useRouteModal();
11824
+ const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
11825
+ const { mutateAsync: requestOrderEdit } = useDraftOrderRequestEdit(preview.id);
11826
+ const { mutateAsync: removeShippingMethod } = useDraftOrderRemoveShippingMethod(preview.id);
11827
+ const { mutateAsync: removeActionShippingMethod } = useDraftOrderRemoveActionShippingMethod(preview.id);
11828
+ const onSubmit = async () => {
11829
+ setIsSubmitting(true);
11830
+ let requestSucceeded = false;
11831
+ await requestOrderEdit(void 0, {
11832
+ onError: (e) => {
11833
+ ui.toast.error(`Failed to request order edit: ${e.message}`);
11834
+ },
11835
+ onSuccess: () => {
11836
+ requestSucceeded = true;
11837
+ }
11838
+ });
11839
+ if (!requestSucceeded) {
11840
+ setIsSubmitting(false);
11841
+ return;
11842
+ }
11843
+ await confirmOrderEdit(void 0, {
11844
+ onError: (e) => {
11845
+ ui.toast.error(`Failed to confirm order edit: ${e.message}`);
11846
+ },
11847
+ onSuccess: () => {
11848
+ handleSuccess();
11849
+ },
11850
+ onSettled: () => {
11851
+ setIsSubmitting(false);
11852
+ }
11853
+ });
11854
+ };
11855
+ const onKeydown = React.useCallback(
11856
+ (e) => {
11857
+ if (e.key === "Enter" && (e.ctrlKey || e.metaKey)) {
11858
+ if (data || isSubmitting) {
11859
+ return;
11860
+ }
11861
+ onSubmit();
11862
+ }
11863
+ },
11864
+ [data, isSubmitting, onSubmit]
11865
+ );
11866
+ React.useEffect(() => {
11867
+ document.addEventListener("keydown", onKeydown);
11868
+ return () => {
11869
+ document.removeEventListener("keydown", onKeydown);
11870
+ };
11871
+ }, [onKeydown]);
11872
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-full flex-col overflow-hidden", children: [
11873
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Header, {}),
11565
11874
  /* @__PURE__ */ jsxRuntime.jsxs(RouteFocusModal.Body, { className: "flex flex-1 flex-col overflow-hidden", children: [
11566
11875
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-1 flex-col items-center overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full max-w-[720px] flex-col gap-y-6 py-16 px-6", children: [
11567
11876
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
@@ -11819,648 +12128,445 @@ const ShippingForm = ({ preview, order }) => {
11819
12128
  {
11820
12129
  size: "small",
11821
12130
  leading: "compact",
11822
- className: "text-ui-fg-subtle",
11823
- children: (_e2 = (_d2 = item.variant) == null ? void 0 : _d2.options) == null ? void 0 : _e2.map((option) => option.value).join(" · ")
11824
- }
11825
- )
11826
- ] })
11827
- ] })
11828
- ]
11829
- },
11830
- item.id
11831
- ),
11832
- idx !== items.length - 1 && /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" })
11833
- ] }, item.id);
11834
- })
11835
- ] })
11836
- ]
11837
- },
11838
- profile.id
11839
- );
11840
- }) })
11841
- ] }) })
11842
- ] }) }),
11843
- /* @__PURE__ */ jsxRuntime.jsx(
11844
- StackedFocusModal,
11845
- {
11846
- id: STACKED_FOCUS_MODAL_ID,
11847
- onOpenChangeCallback: (open) => {
11848
- if (!open) {
11849
- setData(null);
11850
- }
11851
- return open;
11852
- },
11853
- children: data && /* @__PURE__ */ jsxRuntime.jsx(ShippingProfileForm, { data, order, preview })
11854
- }
11855
- )
11856
- ] }),
11857
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-x-2", children: [
11858
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
11859
- /* @__PURE__ */ jsxRuntime.jsx(
11860
- ui.Button,
11861
- {
11862
- size: "small",
11863
- type: "button",
11864
- isLoading: isSubmitting,
11865
- onClick: onSubmit,
11866
- children: "Save"
11867
- }
11868
- )
11869
- ] }) })
11870
- ] });
11871
- };
11872
- const StackedModalTrigger = ({
11873
- shippingProfileId,
11874
- shippingOption,
11875
- shippingMethod,
11876
- setData,
11877
- children
11878
- }) => {
11879
- const { setIsOpen, getIsOpen } = useStackedModal();
11880
- const isOpen = getIsOpen(STACKED_FOCUS_MODAL_ID);
11881
- const onToggle = () => {
11882
- if (isOpen) {
11883
- setIsOpen(STACKED_FOCUS_MODAL_ID, false);
11884
- setData(null);
11885
- } else {
11886
- setIsOpen(STACKED_FOCUS_MODAL_ID, true);
11887
- setData({
11888
- shippingProfileId,
11889
- shippingOption,
11890
- shippingMethod
11891
- });
11892
- }
11893
- };
11894
- return /* @__PURE__ */ jsxRuntime.jsx(
11895
- ui.Button,
11896
- {
11897
- size: "small",
11898
- variant: "secondary",
11899
- onClick: onToggle,
11900
- className: "text-ui-fg-primary shrink-0",
11901
- children
11902
- }
11903
- );
11904
- };
11905
- const ShippingProfileForm = ({
11906
- data,
11907
- order,
11908
- preview
11909
- }) => {
11910
- var _a, _b, _c, _d, _e, _f;
11911
- const { setIsOpen } = useStackedModal();
11912
- const form = reactHookForm.useForm({
11913
- resolver: zod.zodResolver(shippingMethodSchema),
11914
- defaultValues: {
11915
- 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,
11916
- shipping_option_id: (_e = data.shippingOption) == null ? void 0 : _e.id,
11917
- custom_amount: (_f = data.shippingMethod) == null ? void 0 : _f.amount
11918
- }
11919
- });
11920
- const { mutateAsync: addShippingMethod, isPending } = useDraftOrderAddShippingMethod(order.id);
11921
- const {
11922
- mutateAsync: updateShippingMethod,
11923
- isPending: isUpdatingShippingMethod
11924
- } = useDraftOrderUpdateShippingMethod(order.id);
11925
- const onSubmit = form.handleSubmit(async (values) => {
11926
- if (lodash.isEqual(values, form.formState.defaultValues)) {
11927
- setIsOpen(STACKED_FOCUS_MODAL_ID, false);
11928
- return;
11929
- }
11930
- if (data.shippingMethod) {
11931
- await updateShippingMethod(
11932
- {
11933
- method_id: data.shippingMethod.id,
11934
- shipping_option_id: values.shipping_option_id,
11935
- custom_amount: values.custom_amount ? convertNumber(values.custom_amount) : void 0
11936
- },
11937
- {
11938
- onError: (e) => {
11939
- ui.toast.error(e.message);
11940
- },
11941
- onSuccess: () => {
11942
- setIsOpen(STACKED_FOCUS_MODAL_ID, false);
11943
- }
11944
- }
11945
- );
11946
- return;
11947
- }
11948
- await addShippingMethod(
11949
- {
11950
- shipping_option_id: values.shipping_option_id,
11951
- custom_amount: values.custom_amount ? convertNumber(values.custom_amount) : void 0
11952
- },
11953
- {
11954
- onError: (e) => {
11955
- ui.toast.error(e.message);
11956
- },
11957
- onSuccess: () => {
11958
- setIsOpen(STACKED_FOCUS_MODAL_ID, false);
11959
- }
11960
- }
11961
- );
11962
- });
11963
- return /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Content, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2, { ...form, children: /* @__PURE__ */ jsxRuntime.jsxs(
11964
- KeyboundForm,
11965
- {
11966
- className: "flex h-full flex-col overflow-hidden",
11967
- onSubmit,
11968
- children: [
11969
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Header, {}),
11970
- /* @__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 py-16 px-6", children: [
11971
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
11972
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Shipping" }) }),
11973
- /* @__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." }) })
11974
- ] }),
11975
- /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
11976
- /* @__PURE__ */ jsxRuntime.jsx(
11977
- LocationField,
11978
- {
11979
- control: form.control,
11980
- setValue: form.setValue
11981
- }
11982
- ),
11983
- /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
11984
- /* @__PURE__ */ jsxRuntime.jsx(
11985
- ShippingOptionField,
11986
- {
11987
- shippingProfileId: data.shippingProfileId,
11988
- preview,
11989
- control: form.control
11990
- }
11991
- ),
11992
- /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
11993
- /* @__PURE__ */ jsxRuntime.jsx(
11994
- CustomAmountField,
11995
- {
11996
- control: form.control,
11997
- currencyCode: order.currency_code
11998
- }
11999
- ),
12000
- /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
12001
- /* @__PURE__ */ jsxRuntime.jsx(
12002
- ItemsPreview,
12003
- {
12004
- order,
12005
- shippingProfileId: data.shippingProfileId
12006
- }
12007
- )
12008
- ] }) }) }),
12009
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-x-2", children: [
12010
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
12011
- /* @__PURE__ */ jsxRuntime.jsx(
12012
- ui.Button,
12013
- {
12014
- size: "small",
12015
- type: "submit",
12016
- isLoading: isPending || isUpdatingShippingMethod,
12017
- children: data.shippingMethod ? "Update" : "Add"
12018
- }
12019
- )
12020
- ] }) })
12021
- ]
12022
- }
12023
- ) }) });
12024
- };
12025
- const shippingMethodSchema = objectType({
12026
- location_id: stringType(),
12027
- shipping_option_id: stringType(),
12028
- custom_amount: unionType([numberType(), stringType()]).optional()
12029
- });
12030
- const ItemsPreview = ({ order, shippingProfileId }) => {
12031
- const matches = order.items.filter(
12032
- (item) => {
12033
- var _a, _b, _c;
12034
- return ((_c = (_b = (_a = item.variant) == null ? void 0 : _a.product) == null ? void 0 : _b.shipping_profile) == null ? void 0 : _c.id) === shippingProfileId;
12035
- }
12036
- );
12037
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-6", children: [
12038
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-2 items-center gap-3", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
12039
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "Items to ship" }),
12040
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Items with the selected shipping profile." })
12041
- ] }) }),
12042
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-subtle shadow-elevation-card-rest rounded-xl", children: [
12043
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-3 px-4 py-2 text-ui-fg-muted", children: [
12044
- /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: "Item" }) }),
12045
- /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: "Quantity" }) })
12046
- ] }),
12047
- /* @__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(
12048
- "div",
12049
- {
12050
- className: "grid grid-cols-2 gap-3 px-4 py-2 bg-ui-bg-base shadow-elevation-card-rest rounded-lg items-center",
12051
- children: [
12052
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-3", children: [
12053
- /* @__PURE__ */ jsxRuntime.jsx(
12054
- Thumbnail,
12055
- {
12056
- thumbnail: item.thumbnail,
12057
- alt: item.product_title ?? void 0
12058
- }
12059
- ),
12060
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
12061
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-1", children: [
12062
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: item.product_title }),
12063
- /* @__PURE__ */ jsxRuntime.jsxs(
12064
- ui.Text,
12065
- {
12066
- size: "small",
12067
- leading: "compact",
12068
- className: "text-ui-fg-subtle",
12069
- children: [
12070
- "(",
12071
- item.variant_title,
12072
- ")"
12073
- ]
12074
- }
12075
- )
12076
- ] }),
12077
- /* @__PURE__ */ jsxRuntime.jsx(
12078
- ui.Text,
12079
- {
12080
- size: "small",
12081
- leading: "compact",
12082
- className: "text-ui-fg-subtle",
12083
- children: item.variant_sku
12084
- }
12085
- )
12086
- ] })
12087
- ] }),
12088
- /* @__PURE__ */ jsxRuntime.jsxs(
12089
- ui.Text,
12090
- {
12091
- size: "small",
12092
- leading: "compact",
12093
- className: "text-ui-fg-subtle",
12094
- children: [
12095
- item.quantity,
12096
- "x"
12097
- ]
12098
- }
12099
- )
12100
- ]
12101
- },
12102
- item.id
12103
- )) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-center gap-x-3 bg-ui-bg-base rounded-lg p-4 shadow-elevation-card-rest flex-col gap-1", children: [
12104
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "No items found" }),
12105
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: [
12106
- 'No items found for "',
12107
- query,
12108
- '".'
12109
- ] })
12110
- ] }) })
12111
- ] })
12112
- ] });
12113
- };
12114
- const LocationField = ({ control, setValue }) => {
12115
- const locations = useComboboxData({
12116
- queryKey: ["locations"],
12117
- queryFn: async (params) => {
12118
- return await sdk.admin.stockLocation.list(params);
12119
- },
12120
- getOptions: (data) => {
12121
- return data.stock_locations.map((location) => ({
12122
- label: location.name,
12123
- value: location.id
12124
- }));
12125
- }
12126
- });
12127
- return /* @__PURE__ */ jsxRuntime.jsx(
12128
- Form$2.Field,
12129
- {
12130
- control,
12131
- name: "location_id",
12132
- render: ({ field: { onChange, ...field } }) => {
12133
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
12134
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
12135
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Location" }),
12136
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Choose where you want to ship the items from." })
12137
- ] }),
12138
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
12139
- Combobox,
12140
- {
12141
- options: locations.options,
12142
- fetchNextPage: locations.fetchNextPage,
12143
- isFetchingNextPage: locations.isFetchingNextPage,
12144
- searchValue: locations.searchValue,
12145
- onSearchValueChange: locations.onSearchValueChange,
12146
- placeholder: "Select location",
12147
- onChange: (value) => {
12148
- setValue("shipping_option_id", "", {
12149
- shouldDirty: true,
12150
- shouldTouch: true
12151
- });
12152
- onChange(value);
12131
+ className: "text-ui-fg-subtle",
12132
+ children: (_e2 = (_d2 = item.variant) == null ? void 0 : _d2.options) == null ? void 0 : _e2.map((option) => option.value).join(" · ")
12133
+ }
12134
+ )
12135
+ ] })
12136
+ ] })
12137
+ ]
12138
+ },
12139
+ item.id
12140
+ ),
12141
+ idx !== items.length - 1 && /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" })
12142
+ ] }, item.id);
12143
+ })
12144
+ ] })
12145
+ ]
12153
12146
  },
12154
- ...field
12147
+ profile.id
12148
+ );
12149
+ }) })
12150
+ ] }) })
12151
+ ] }) }),
12152
+ /* @__PURE__ */ jsxRuntime.jsx(
12153
+ StackedFocusModal,
12154
+ {
12155
+ id: STACKED_FOCUS_MODAL_ID,
12156
+ onOpenChangeCallback: (open) => {
12157
+ if (!open) {
12158
+ setData(null);
12155
12159
  }
12156
- ) })
12157
- ] }) });
12158
- }
12159
- }
12160
- );
12160
+ return open;
12161
+ },
12162
+ children: data && /* @__PURE__ */ jsxRuntime.jsx(ShippingProfileForm, { data, order, preview })
12163
+ }
12164
+ )
12165
+ ] }),
12166
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-x-2", children: [
12167
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
12168
+ /* @__PURE__ */ jsxRuntime.jsx(
12169
+ ui.Button,
12170
+ {
12171
+ size: "small",
12172
+ type: "button",
12173
+ isLoading: isSubmitting,
12174
+ onClick: onSubmit,
12175
+ children: "Save"
12176
+ }
12177
+ )
12178
+ ] }) })
12179
+ ] });
12161
12180
  };
12162
- const ShippingOptionField = ({
12181
+ const StackedModalTrigger = ({
12163
12182
  shippingProfileId,
12164
- preview,
12165
- control
12183
+ shippingOption,
12184
+ shippingMethod,
12185
+ setData,
12186
+ children
12166
12187
  }) => {
12167
- var _a;
12168
- const locationId = reactHookForm.useWatch({ control, name: "location_id" });
12169
- const shippingOptions = useComboboxData({
12170
- queryKey: ["shipping_options", locationId, shippingProfileId],
12171
- queryFn: async (params) => {
12172
- return await sdk.admin.shippingOption.list({
12173
- ...params,
12174
- stock_location_id: locationId,
12175
- shipping_profile_id: shippingProfileId
12188
+ const { setIsOpen, getIsOpen } = useStackedModal();
12189
+ const isOpen = getIsOpen(STACKED_FOCUS_MODAL_ID);
12190
+ const onToggle = () => {
12191
+ if (isOpen) {
12192
+ setIsOpen(STACKED_FOCUS_MODAL_ID, false);
12193
+ setData(null);
12194
+ } else {
12195
+ setIsOpen(STACKED_FOCUS_MODAL_ID, true);
12196
+ setData({
12197
+ shippingProfileId,
12198
+ shippingOption,
12199
+ shippingMethod
12176
12200
  });
12177
- },
12178
- getOptions: (data) => {
12179
- return data.shipping_options.map((option) => {
12180
- var _a2;
12181
- if ((_a2 = option.rules) == null ? void 0 : _a2.find(
12182
- (r) => r.attribute === "is_return" && r.value === "true"
12183
- )) {
12184
- return void 0;
12185
- }
12186
- return {
12187
- label: option.name,
12188
- value: option.id
12189
- };
12190
- }).filter(Boolean);
12191
- },
12192
- enabled: !!locationId && !!shippingProfileId,
12193
- defaultValue: ((_a = preview.shipping_methods[0]) == null ? void 0 : _a.shipping_option_id) || void 0
12194
- });
12195
- const tooltipContent = !locationId && !shippingProfileId ? "Choose a location and shipping profile first." : !locationId ? "Choose a location first." : "Choose a shipping profile first.";
12196
- return /* @__PURE__ */ jsxRuntime.jsx(
12197
- Form$2.Field,
12198
- {
12199
- control,
12200
- name: "shipping_option_id",
12201
- render: ({ field }) => {
12202
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
12203
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
12204
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Shipping option" }),
12205
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Choose the shipping option to use." })
12206
- ] }),
12207
- /* @__PURE__ */ jsxRuntime.jsx(
12208
- ConditionalTooltip,
12209
- {
12210
- content: tooltipContent,
12211
- showTooltip: !locationId || !shippingProfileId,
12212
- children: /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
12213
- Combobox,
12214
- {
12215
- options: shippingOptions.options,
12216
- fetchNextPage: shippingOptions.fetchNextPage,
12217
- isFetchingNextPage: shippingOptions.isFetchingNextPage,
12218
- searchValue: shippingOptions.searchValue,
12219
- onSearchValueChange: shippingOptions.onSearchValueChange,
12220
- placeholder: "Select shipping option",
12221
- ...field,
12222
- disabled: !locationId || !shippingProfileId
12223
- }
12224
- ) }) })
12225
- }
12226
- )
12227
- ] }) });
12228
- }
12229
12201
  }
12230
- );
12231
- };
12232
- const CustomAmountField = ({
12233
- control,
12234
- currencyCode
12235
- }) => {
12202
+ };
12236
12203
  return /* @__PURE__ */ jsxRuntime.jsx(
12237
- Form$2.Field,
12204
+ ui.Button,
12238
12205
  {
12239
- control,
12240
- name: "custom_amount",
12241
- render: ({ field: { onChange, ...field } }) => {
12242
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
12243
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
12244
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { optional: true, children: "Custom amount" }),
12245
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Set a custom amount for the shipping option." })
12246
- ] }),
12247
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
12248
- ui.CurrencyInput,
12249
- {
12250
- ...field,
12251
- onValueChange: (value) => onChange(value),
12252
- symbol: getNativeSymbol(currencyCode),
12253
- code: currencyCode
12254
- }
12255
- ) })
12256
- ] });
12257
- }
12206
+ size: "small",
12207
+ variant: "secondary",
12208
+ onClick: onToggle,
12209
+ className: "text-ui-fg-primary shrink-0",
12210
+ children
12258
12211
  }
12259
12212
  );
12260
12213
  };
12261
- const ShippingAddress = () => {
12262
- const { id } = reactRouterDom.useParams();
12263
- const { order, isPending, isError, error } = useOrder(id, {
12264
- fields: "+shipping_address"
12265
- });
12266
- if (isError) {
12267
- throw error;
12268
- }
12269
- const isReady = !isPending && !!order;
12270
- return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
12271
- /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Header, { children: [
12272
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Shipping Address" }) }),
12273
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Edit the shipping address for the draft order" }) })
12274
- ] }),
12275
- isReady && /* @__PURE__ */ jsxRuntime.jsx(ShippingAddressForm, { order })
12276
- ] });
12277
- };
12278
- const ShippingAddressForm = ({ order }) => {
12279
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
12214
+ const ShippingProfileForm = ({
12215
+ data,
12216
+ order,
12217
+ preview
12218
+ }) => {
12219
+ var _a, _b, _c, _d, _e, _f;
12220
+ const { setIsOpen } = useStackedModal();
12280
12221
  const form = reactHookForm.useForm({
12222
+ resolver: zod.zodResolver(shippingMethodSchema),
12281
12223
  defaultValues: {
12282
- first_name: ((_a = order.shipping_address) == null ? void 0 : _a.first_name) ?? "",
12283
- last_name: ((_b = order.shipping_address) == null ? void 0 : _b.last_name) ?? "",
12284
- company: ((_c = order.shipping_address) == null ? void 0 : _c.company) ?? "",
12285
- address_1: ((_d = order.shipping_address) == null ? void 0 : _d.address_1) ?? "",
12286
- address_2: ((_e = order.shipping_address) == null ? void 0 : _e.address_2) ?? "",
12287
- city: ((_f = order.shipping_address) == null ? void 0 : _f.city) ?? "",
12288
- province: ((_g = order.shipping_address) == null ? void 0 : _g.province) ?? "",
12289
- country_code: ((_h = order.shipping_address) == null ? void 0 : _h.country_code) ?? "",
12290
- postal_code: ((_i = order.shipping_address) == null ? void 0 : _i.postal_code) ?? "",
12291
- phone: ((_j = order.shipping_address) == null ? void 0 : _j.phone) ?? ""
12292
- },
12293
- resolver: zod.zodResolver(schema$2)
12224
+ 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,
12225
+ shipping_option_id: (_e = data.shippingOption) == null ? void 0 : _e.id,
12226
+ custom_amount: (_f = data.shippingMethod) == null ? void 0 : _f.amount
12227
+ }
12294
12228
  });
12295
- const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
12296
- const { handleSuccess } = useRouteModal();
12297
- const onSubmit = form.handleSubmit(async (data) => {
12298
- await mutateAsync(
12299
- {
12300
- shipping_address: {
12301
- first_name: data.first_name,
12302
- last_name: data.last_name,
12303
- company: data.company,
12304
- address_1: data.address_1,
12305
- address_2: data.address_2,
12306
- city: data.city,
12307
- province: data.province,
12308
- country_code: data.country_code,
12309
- postal_code: data.postal_code,
12310
- phone: data.phone
12229
+ const { mutateAsync: addShippingMethod, isPending } = useDraftOrderAddShippingMethod(order.id);
12230
+ const {
12231
+ mutateAsync: updateShippingMethod,
12232
+ isPending: isUpdatingShippingMethod
12233
+ } = useDraftOrderUpdateShippingMethod(order.id);
12234
+ const onSubmit = form.handleSubmit(async (values) => {
12235
+ if (lodash.isEqual(values, form.formState.defaultValues)) {
12236
+ setIsOpen(STACKED_FOCUS_MODAL_ID, false);
12237
+ return;
12238
+ }
12239
+ if (data.shippingMethod) {
12240
+ await updateShippingMethod(
12241
+ {
12242
+ method_id: data.shippingMethod.id,
12243
+ shipping_option_id: values.shipping_option_id,
12244
+ custom_amount: values.custom_amount ? convertNumber(values.custom_amount) : void 0
12245
+ },
12246
+ {
12247
+ onError: (e) => {
12248
+ ui.toast.error(e.message);
12249
+ },
12250
+ onSuccess: () => {
12251
+ setIsOpen(STACKED_FOCUS_MODAL_ID, false);
12252
+ }
12311
12253
  }
12254
+ );
12255
+ return;
12256
+ }
12257
+ await addShippingMethod(
12258
+ {
12259
+ shipping_option_id: values.shipping_option_id,
12260
+ custom_amount: values.custom_amount ? convertNumber(values.custom_amount) : void 0
12312
12261
  },
12313
12262
  {
12314
- onSuccess: () => {
12315
- handleSuccess();
12263
+ onError: (e) => {
12264
+ ui.toast.error(e.message);
12316
12265
  },
12317
- onError: (error) => {
12318
- ui.toast.error(error.message);
12266
+ onSuccess: () => {
12267
+ setIsOpen(STACKED_FOCUS_MODAL_ID, false);
12319
12268
  }
12320
12269
  }
12321
12270
  );
12322
12271
  });
12323
- return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(
12272
+ return /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Content, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2, { ...form, children: /* @__PURE__ */ jsxRuntime.jsxs(
12324
12273
  KeyboundForm,
12325
12274
  {
12326
- className: "flex flex-1 flex-col overflow-hidden",
12275
+ className: "flex h-full flex-col overflow-hidden",
12327
12276
  onSubmit,
12328
12277
  children: [
12329
- /* @__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: [
12278
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Header, {}),
12279
+ /* @__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 py-16 px-6", children: [
12280
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
12281
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Shipping" }) }),
12282
+ /* @__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." }) })
12283
+ ] }),
12284
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
12330
12285
  /* @__PURE__ */ jsxRuntime.jsx(
12331
- Form$2.Field,
12286
+ LocationField,
12332
12287
  {
12333
12288
  control: form.control,
12334
- name: "country_code",
12335
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
12336
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Country" }),
12337
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(CountrySelect, { ...field }) }),
12338
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12339
- ] })
12289
+ setValue: form.setValue
12340
12290
  }
12341
12291
  ),
12342
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
12343
- /* @__PURE__ */ jsxRuntime.jsx(
12344
- Form$2.Field,
12345
- {
12346
- control: form.control,
12347
- name: "first_name",
12348
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
12349
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "First name" }),
12350
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
12351
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12352
- ] })
12353
- }
12354
- ),
12355
- /* @__PURE__ */ jsxRuntime.jsx(
12356
- Form$2.Field,
12357
- {
12358
- control: form.control,
12359
- name: "last_name",
12360
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
12361
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Last name" }),
12362
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
12363
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12364
- ] })
12365
- }
12366
- )
12367
- ] }),
12292
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
12368
12293
  /* @__PURE__ */ jsxRuntime.jsx(
12369
- Form$2.Field,
12294
+ ShippingOptionField,
12370
12295
  {
12371
- control: form.control,
12372
- name: "company",
12373
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
12374
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { optional: true, children: "Company" }),
12375
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
12376
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12377
- ] })
12296
+ shippingProfileId: data.shippingProfileId,
12297
+ preview,
12298
+ control: form.control
12378
12299
  }
12379
12300
  ),
12301
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
12380
12302
  /* @__PURE__ */ jsxRuntime.jsx(
12381
- Form$2.Field,
12303
+ CustomAmountField,
12382
12304
  {
12383
12305
  control: form.control,
12384
- name: "address_1",
12385
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
12386
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Address" }),
12387
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
12388
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12389
- ] })
12306
+ currencyCode: order.currency_code
12390
12307
  }
12391
12308
  ),
12309
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
12392
12310
  /* @__PURE__ */ jsxRuntime.jsx(
12393
- Form$2.Field,
12311
+ ItemsPreview,
12394
12312
  {
12395
- control: form.control,
12396
- name: "address_2",
12397
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
12398
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { optional: true, children: "Apartment, suite, etc." }),
12399
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
12400
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12401
- ] })
12313
+ order,
12314
+ shippingProfileId: data.shippingProfileId
12402
12315
  }
12403
- ),
12404
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
12405
- /* @__PURE__ */ jsxRuntime.jsx(
12406
- Form$2.Field,
12407
- {
12408
- control: form.control,
12409
- name: "postal_code",
12410
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
12411
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Postal code" }),
12412
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
12413
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12414
- ] })
12415
- }
12416
- ),
12417
- /* @__PURE__ */ jsxRuntime.jsx(
12418
- Form$2.Field,
12316
+ )
12317
+ ] }) }) }),
12318
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-x-2", children: [
12319
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
12320
+ /* @__PURE__ */ jsxRuntime.jsx(
12321
+ ui.Button,
12322
+ {
12323
+ size: "small",
12324
+ type: "submit",
12325
+ isLoading: isPending || isUpdatingShippingMethod,
12326
+ children: data.shippingMethod ? "Update" : "Add"
12327
+ }
12328
+ )
12329
+ ] }) })
12330
+ ]
12331
+ }
12332
+ ) }) });
12333
+ };
12334
+ const shippingMethodSchema = objectType({
12335
+ location_id: stringType(),
12336
+ shipping_option_id: stringType(),
12337
+ custom_amount: unionType([numberType(), stringType()]).optional()
12338
+ });
12339
+ const ItemsPreview = ({ order, shippingProfileId }) => {
12340
+ const matches = order.items.filter(
12341
+ (item) => {
12342
+ var _a, _b, _c;
12343
+ return ((_c = (_b = (_a = item.variant) == null ? void 0 : _a.product) == null ? void 0 : _b.shipping_profile) == null ? void 0 : _c.id) === shippingProfileId;
12344
+ }
12345
+ );
12346
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-6", children: [
12347
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-2 items-center gap-3", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
12348
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "Items to ship" }),
12349
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Items with the selected shipping profile." })
12350
+ ] }) }),
12351
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-subtle shadow-elevation-card-rest rounded-xl", children: [
12352
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-3 px-4 py-2 text-ui-fg-muted", children: [
12353
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: "Item" }) }),
12354
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: "Quantity" }) })
12355
+ ] }),
12356
+ /* @__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(
12357
+ "div",
12358
+ {
12359
+ className: "grid grid-cols-2 gap-3 px-4 py-2 bg-ui-bg-base shadow-elevation-card-rest rounded-lg items-center",
12360
+ children: [
12361
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-3", children: [
12362
+ /* @__PURE__ */ jsxRuntime.jsx(
12363
+ Thumbnail,
12364
+ {
12365
+ thumbnail: item.thumbnail,
12366
+ alt: item.product_title ?? void 0
12367
+ }
12368
+ ),
12369
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
12370
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-1", children: [
12371
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: item.product_title }),
12372
+ /* @__PURE__ */ jsxRuntime.jsxs(
12373
+ ui.Text,
12374
+ {
12375
+ size: "small",
12376
+ leading: "compact",
12377
+ className: "text-ui-fg-subtle",
12378
+ children: [
12379
+ "(",
12380
+ item.variant_title,
12381
+ ")"
12382
+ ]
12383
+ }
12384
+ )
12385
+ ] }),
12386
+ /* @__PURE__ */ jsxRuntime.jsx(
12387
+ ui.Text,
12388
+ {
12389
+ size: "small",
12390
+ leading: "compact",
12391
+ className: "text-ui-fg-subtle",
12392
+ children: item.variant_sku
12393
+ }
12394
+ )
12395
+ ] })
12396
+ ] }),
12397
+ /* @__PURE__ */ jsxRuntime.jsxs(
12398
+ ui.Text,
12419
12399
  {
12420
- control: form.control,
12421
- name: "city",
12422
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
12423
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "City" }),
12424
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
12425
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12426
- ] })
12400
+ size: "small",
12401
+ leading: "compact",
12402
+ className: "text-ui-fg-subtle",
12403
+ children: [
12404
+ item.quantity,
12405
+ "x"
12406
+ ]
12427
12407
  }
12428
12408
  )
12409
+ ]
12410
+ },
12411
+ item.id
12412
+ )) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-center gap-x-3 bg-ui-bg-base rounded-lg p-4 shadow-elevation-card-rest flex-col gap-1", children: [
12413
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "No items found" }),
12414
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: [
12415
+ 'No items found for "',
12416
+ query,
12417
+ '".'
12418
+ ] })
12419
+ ] }) })
12420
+ ] })
12421
+ ] });
12422
+ };
12423
+ const LocationField = ({ control, setValue }) => {
12424
+ const locations = useComboboxData({
12425
+ queryKey: ["locations"],
12426
+ queryFn: async (params) => {
12427
+ return await sdk.admin.stockLocation.list(params);
12428
+ },
12429
+ getOptions: (data) => {
12430
+ return data.stock_locations.map((location) => ({
12431
+ label: location.name,
12432
+ value: location.id
12433
+ }));
12434
+ }
12435
+ });
12436
+ return /* @__PURE__ */ jsxRuntime.jsx(
12437
+ Form$2.Field,
12438
+ {
12439
+ control,
12440
+ name: "location_id",
12441
+ render: ({ field: { onChange, ...field } }) => {
12442
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
12443
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
12444
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Location" }),
12445
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Choose where you want to ship the items from." })
12446
+ ] }),
12447
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
12448
+ Combobox,
12449
+ {
12450
+ options: locations.options,
12451
+ fetchNextPage: locations.fetchNextPage,
12452
+ isFetchingNextPage: locations.isFetchingNextPage,
12453
+ searchValue: locations.searchValue,
12454
+ onSearchValueChange: locations.onSearchValueChange,
12455
+ placeholder: "Select location",
12456
+ onChange: (value) => {
12457
+ setValue("shipping_option_id", "", {
12458
+ shouldDirty: true,
12459
+ shouldTouch: true
12460
+ });
12461
+ onChange(value);
12462
+ },
12463
+ ...field
12464
+ }
12465
+ ) })
12466
+ ] }) });
12467
+ }
12468
+ }
12469
+ );
12470
+ };
12471
+ const ShippingOptionField = ({
12472
+ shippingProfileId,
12473
+ preview,
12474
+ control
12475
+ }) => {
12476
+ var _a;
12477
+ const locationId = reactHookForm.useWatch({ control, name: "location_id" });
12478
+ const shippingOptions = useComboboxData({
12479
+ queryKey: ["shipping_options", locationId, shippingProfileId],
12480
+ queryFn: async (params) => {
12481
+ return await sdk.admin.shippingOption.list({
12482
+ ...params,
12483
+ stock_location_id: locationId,
12484
+ shipping_profile_id: shippingProfileId
12485
+ });
12486
+ },
12487
+ getOptions: (data) => {
12488
+ return data.shipping_options.map((option) => {
12489
+ var _a2;
12490
+ if ((_a2 = option.rules) == null ? void 0 : _a2.find(
12491
+ (r) => r.attribute === "is_return" && r.value === "true"
12492
+ )) {
12493
+ return void 0;
12494
+ }
12495
+ return {
12496
+ label: option.name,
12497
+ value: option.id
12498
+ };
12499
+ }).filter(Boolean);
12500
+ },
12501
+ enabled: !!locationId && !!shippingProfileId,
12502
+ defaultValue: ((_a = preview.shipping_methods[0]) == null ? void 0 : _a.shipping_option_id) || void 0
12503
+ });
12504
+ const tooltipContent = !locationId && !shippingProfileId ? "Choose a location and shipping profile first." : !locationId ? "Choose a location first." : "Choose a shipping profile first.";
12505
+ return /* @__PURE__ */ jsxRuntime.jsx(
12506
+ Form$2.Field,
12507
+ {
12508
+ control,
12509
+ name: "shipping_option_id",
12510
+ render: ({ field }) => {
12511
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
12512
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
12513
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Shipping option" }),
12514
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Choose the shipping option to use." })
12429
12515
  ] }),
12430
12516
  /* @__PURE__ */ jsxRuntime.jsx(
12431
- Form$2.Field,
12517
+ ConditionalTooltip,
12432
12518
  {
12433
- control: form.control,
12434
- name: "province",
12435
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
12436
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { optional: true, children: "Province / State" }),
12437
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
12438
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12439
- ] })
12519
+ content: tooltipContent,
12520
+ showTooltip: !locationId || !shippingProfileId,
12521
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
12522
+ Combobox,
12523
+ {
12524
+ options: shippingOptions.options,
12525
+ fetchNextPage: shippingOptions.fetchNextPage,
12526
+ isFetchingNextPage: shippingOptions.isFetchingNextPage,
12527
+ searchValue: shippingOptions.searchValue,
12528
+ onSearchValueChange: shippingOptions.onSearchValueChange,
12529
+ placeholder: "Select shipping option",
12530
+ ...field,
12531
+ disabled: !locationId || !shippingProfileId
12532
+ }
12533
+ ) }) })
12440
12534
  }
12441
- ),
12442
- /* @__PURE__ */ jsxRuntime.jsx(
12443
- Form$2.Field,
12535
+ )
12536
+ ] }) });
12537
+ }
12538
+ }
12539
+ );
12540
+ };
12541
+ const CustomAmountField = ({
12542
+ control,
12543
+ currencyCode
12544
+ }) => {
12545
+ return /* @__PURE__ */ jsxRuntime.jsx(
12546
+ Form$2.Field,
12547
+ {
12548
+ control,
12549
+ name: "custom_amount",
12550
+ render: ({ field: { onChange, ...field } }) => {
12551
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
12552
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
12553
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { optional: true, children: "Custom amount" }),
12554
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Set a custom amount for the shipping option." })
12555
+ ] }),
12556
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
12557
+ ui.CurrencyInput,
12444
12558
  {
12445
- control: form.control,
12446
- name: "phone",
12447
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
12448
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { optional: true, children: "Phone" }),
12449
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
12450
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12451
- ] })
12559
+ ...field,
12560
+ onValueChange: (value) => onChange(value),
12561
+ symbol: getNativeSymbol(currencyCode),
12562
+ code: currencyCode
12452
12563
  }
12453
- )
12454
- ] }) }),
12455
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
12456
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
12457
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
12458
- ] }) })
12459
- ]
12564
+ ) })
12565
+ ] });
12566
+ }
12460
12567
  }
12461
- ) });
12568
+ );
12462
12569
  };
12463
- const schema$2 = addressSchema;
12464
12570
  const TransferOwnership = () => {
12465
12571
  const { id } = reactRouterDom.useParams();
12466
12572
  const { draft_order, isPending, isError, error } = useDraftOrder(id, {
@@ -12484,7 +12590,7 @@ const TransferOwnershipForm = ({ order }) => {
12484
12590
  defaultValues: {
12485
12591
  customer_id: order.customer_id || ""
12486
12592
  },
12487
- resolver: zod.zodResolver(schema$1)
12593
+ resolver: zod.zodResolver(schema)
12488
12594
  });
12489
12595
  const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
12490
12596
  const { handleSuccess } = useRouteModal();
@@ -12934,114 +13040,8 @@ const Illustration = () => {
12934
13040
  }
12935
13041
  );
12936
13042
  };
12937
- const schema$1 = objectType({
12938
- customer_id: stringType().min(1)
12939
- });
12940
- const SalesChannel = () => {
12941
- const { id } = reactRouterDom.useParams();
12942
- const { draft_order, isPending, isError, error } = useDraftOrder(
12943
- id,
12944
- {
12945
- fields: "+sales_channel_id"
12946
- },
12947
- {
12948
- enabled: !!id
12949
- }
12950
- );
12951
- if (isError) {
12952
- throw error;
12953
- }
12954
- const ISrEADY = !!draft_order && !isPending;
12955
- return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
12956
- /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Header, { children: [
12957
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Sales Channel" }) }),
12958
- /* @__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" }) })
12959
- ] }),
12960
- ISrEADY && /* @__PURE__ */ jsxRuntime.jsx(SalesChannelForm, { order: draft_order })
12961
- ] });
12962
- };
12963
- const SalesChannelForm = ({ order }) => {
12964
- const form = reactHookForm.useForm({
12965
- defaultValues: {
12966
- sales_channel_id: order.sales_channel_id || ""
12967
- },
12968
- resolver: zod.zodResolver(schema)
12969
- });
12970
- const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
12971
- const { handleSuccess } = useRouteModal();
12972
- const onSubmit = form.handleSubmit(async (data) => {
12973
- await mutateAsync(
12974
- {
12975
- sales_channel_id: data.sales_channel_id
12976
- },
12977
- {
12978
- onSuccess: () => {
12979
- ui.toast.success("Sales channel updated");
12980
- handleSuccess();
12981
- },
12982
- onError: (error) => {
12983
- ui.toast.error(error.message);
12984
- }
12985
- }
12986
- );
12987
- });
12988
- return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(
12989
- KeyboundForm,
12990
- {
12991
- className: "flex flex-1 flex-col overflow-hidden",
12992
- onSubmit,
12993
- children: [
12994
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsx(SalesChannelField, { control: form.control, order }) }),
12995
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
12996
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
12997
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
12998
- ] }) })
12999
- ]
13000
- }
13001
- ) });
13002
- };
13003
- const SalesChannelField = ({ control, order }) => {
13004
- const salesChannels = useComboboxData({
13005
- queryFn: async (params) => {
13006
- return await sdk.admin.salesChannel.list(params);
13007
- },
13008
- queryKey: ["sales-channels"],
13009
- getOptions: (data) => {
13010
- return data.sales_channels.map((salesChannel) => ({
13011
- label: salesChannel.name,
13012
- value: salesChannel.id
13013
- }));
13014
- },
13015
- defaultValue: order.sales_channel_id || void 0
13016
- });
13017
- return /* @__PURE__ */ jsxRuntime.jsx(
13018
- Form$2.Field,
13019
- {
13020
- control,
13021
- name: "sales_channel_id",
13022
- render: ({ field }) => {
13023
- return /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
13024
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Sales Channel" }),
13025
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
13026
- Combobox,
13027
- {
13028
- options: salesChannels.options,
13029
- fetchNextPage: salesChannels.fetchNextPage,
13030
- isFetchingNextPage: salesChannels.isFetchingNextPage,
13031
- searchValue: salesChannels.searchValue,
13032
- onSearchValueChange: salesChannels.onSearchValueChange,
13033
- placeholder: "Select sales channel",
13034
- ...field
13035
- }
13036
- ) }),
13037
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
13038
- ] });
13039
- }
13040
- }
13041
- );
13042
- };
13043
13043
  const schema = objectType({
13044
- sales_channel_id: stringType().min(1)
13044
+ customer_id: stringType().min(1)
13045
13045
  });
13046
13046
  const widgetModule = { widgets: [] };
13047
13047
  const routeModule = {
@@ -13075,6 +13075,10 @@ const routeModule = {
13075
13075
  Component: Email,
13076
13076
  path: "/draft-orders/:id/email"
13077
13077
  },
13078
+ {
13079
+ Component: Items,
13080
+ path: "/draft-orders/:id/items"
13081
+ },
13078
13082
  {
13079
13083
  Component: Metadata,
13080
13084
  path: "/draft-orders/:id/metadata"
@@ -13084,24 +13088,20 @@ const routeModule = {
13084
13088
  path: "/draft-orders/:id/promotions"
13085
13089
  },
13086
13090
  {
13087
- Component: Items,
13088
- path: "/draft-orders/:id/items"
13089
- },
13090
- {
13091
- Component: Shipping,
13092
- path: "/draft-orders/:id/shipping"
13091
+ Component: SalesChannel,
13092
+ path: "/draft-orders/:id/sales-channel"
13093
13093
  },
13094
13094
  {
13095
13095
  Component: ShippingAddress,
13096
13096
  path: "/draft-orders/:id/shipping-address"
13097
13097
  },
13098
13098
  {
13099
- Component: TransferOwnership,
13100
- path: "/draft-orders/:id/transfer-ownership"
13099
+ Component: Shipping,
13100
+ path: "/draft-orders/:id/shipping"
13101
13101
  },
13102
13102
  {
13103
- Component: SalesChannel,
13104
- path: "/draft-orders/:id/sales-channel"
13103
+ Component: TransferOwnership,
13104
+ path: "/draft-orders/:id/transfer-ownership"
13105
13105
  }
13106
13106
  ]
13107
13107
  }