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