@medusajs/draft-order 2.10.0-snapshot-20250827144020 → 2.10.0-snapshot-20250827155018

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, Minus, PencilSquare, EllipsisVertical, ArrowUpMini, ArrowDownMini } 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, EllipsisVertical, ArrowUpMini, ArrowDownMini, Minus, PencilSquare } 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";
@@ -9833,127 +9833,22 @@ const EmailForm = ({ order }) => {
9833
9833
  const schema$3 = objectType({
9834
9834
  email: stringType().email()
9835
9835
  });
9836
- const NumberInput = forwardRef(
9837
- ({
9838
- value,
9839
- onChange,
9840
- size = "base",
9841
- min = 0,
9842
- max = 100,
9843
- step = 1,
9844
- className,
9845
- disabled,
9846
- ...props
9847
- }, ref) => {
9848
- const handleChange = (event) => {
9849
- const newValue = event.target.value === "" ? min : Number(event.target.value);
9850
- if (!isNaN(newValue) && (max === void 0 || newValue <= max) && (min === void 0 || newValue >= min)) {
9851
- onChange(newValue);
9852
- }
9853
- };
9854
- const handleIncrement = () => {
9855
- const newValue = value + step;
9856
- if (max === void 0 || newValue <= max) {
9857
- onChange(newValue);
9858
- }
9859
- };
9860
- const handleDecrement = () => {
9861
- const newValue = value - step;
9862
- if (min === void 0 || newValue >= min) {
9863
- onChange(newValue);
9864
- }
9865
- };
9866
- return /* @__PURE__ */ jsxs(
9867
- "div",
9868
- {
9869
- className: clx(
9870
- "inline-flex rounded-md bg-ui-bg-field shadow-borders-base overflow-hidden divide-x transition-fg",
9871
- "[&:has(input:focus)]:shadow-borders-interactive-with-active",
9872
- {
9873
- "h-7": size === "small",
9874
- "h-8": size === "base"
9875
- },
9876
- className
9877
- ),
9878
- children: [
9879
- /* @__PURE__ */ jsx(
9880
- "input",
9881
- {
9882
- ref,
9883
- type: "number",
9884
- value,
9885
- onChange: handleChange,
9886
- min,
9887
- max,
9888
- step,
9889
- className: clx(
9890
- "flex-1 px-2 py-1 bg-transparent txt-compact-small text-ui-fg-base outline-none [appearance:textfield]",
9891
- "[&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none",
9892
- "placeholder:text-ui-fg-muted"
9893
- ),
9894
- ...props
9895
- }
9896
- ),
9897
- /* @__PURE__ */ jsxs(
9898
- "button",
9899
- {
9900
- className: clx(
9901
- "flex items-center justify-center outline-none transition-fg",
9902
- "disabled:cursor-not-allowed disabled:text-ui-fg-muted",
9903
- "focus:bg-ui-bg-field-component-hover",
9904
- "hover:bg-ui-bg-field-component-hover",
9905
- {
9906
- "size-7": size === "small",
9907
- "size-8": size === "base"
9908
- }
9909
- ),
9910
- type: "button",
9911
- onClick: handleDecrement,
9912
- disabled: min !== void 0 && value <= min || disabled,
9913
- children: [
9914
- /* @__PURE__ */ jsx(Minus, {}),
9915
- /* @__PURE__ */ jsx("span", { className: "sr-only", children: `Decrease by ${step}` })
9916
- ]
9917
- }
9918
- ),
9919
- /* @__PURE__ */ jsxs(
9920
- "button",
9921
- {
9922
- className: clx(
9923
- "flex items-center justify-center outline-none transition-fg",
9924
- "disabled:cursor-not-allowed disabled:text-ui-fg-muted",
9925
- "focus:bg-ui-bg-field-hover",
9926
- "hover:bg-ui-bg-field-hover",
9927
- {
9928
- "size-7": size === "small",
9929
- "size-8": size === "base"
9930
- }
9931
- ),
9932
- type: "button",
9933
- onClick: handleIncrement,
9934
- disabled: max !== void 0 && value >= max || disabled,
9935
- children: [
9936
- /* @__PURE__ */ jsx(Plus, {}),
9937
- /* @__PURE__ */ jsx("span", { className: "sr-only", children: `Increase by ${step}` })
9938
- ]
9939
- }
9940
- )
9941
- ]
9942
- }
9943
- );
9944
- }
9945
- );
9946
- const PRODUCT_VARIANTS_QUERY_KEY = "product-variants";
9947
- const productVariantsQueryKeys = {
9836
+ const PROMOTION_QUERY_KEY = "promotions";
9837
+ const promotionsQueryKeys = {
9948
9838
  list: (query2) => [
9949
- PRODUCT_VARIANTS_QUERY_KEY,
9839
+ PROMOTION_QUERY_KEY,
9840
+ query2 ? query2 : void 0
9841
+ ],
9842
+ detail: (id, query2) => [
9843
+ PROMOTION_QUERY_KEY,
9844
+ id,
9950
9845
  query2 ? query2 : void 0
9951
9846
  ]
9952
9847
  };
9953
- const useProductVariants = (query2, options) => {
9848
+ const usePromotions = (query2, options) => {
9954
9849
  const { data, ...rest } = useQuery({
9955
- queryKey: productVariantsQueryKeys.list(query2),
9956
- queryFn: async () => await sdk.admin.productVariant.list(query2),
9850
+ queryKey: promotionsQueryKeys.list(query2),
9851
+ queryFn: async () => sdk.admin.promotion.list(query2),
9957
9852
  ...options
9958
9853
  });
9959
9854
  return { ...data, ...rest };
@@ -10004,65 +9899,85 @@ const useInitiateOrderEdit = ({
10004
9899
  run();
10005
9900
  }, [preview, navigate, mutateAsync]);
10006
9901
  };
10007
- function convertNumber(value) {
10008
- return typeof value === "string" ? Number(value.replace(",", ".")) : value;
10009
- }
10010
- const STACKED_MODAL_ID = "items_stacked_modal";
10011
- const Items = () => {
9902
+ const Promotions = () => {
10012
9903
  const { id } = useParams();
10013
9904
  const {
10014
9905
  order: preview,
10015
- isPending: isPreviewPending,
10016
9906
  isError: isPreviewError,
10017
9907
  error: previewError
10018
- } = useOrderPreview(id, void 0, {
10019
- placeholderData: keepPreviousData
10020
- });
9908
+ } = useOrderPreview(id, void 0);
10021
9909
  useInitiateOrderEdit({ preview });
10022
- const { draft_order, isPending, isError, error } = useDraftOrder(
10023
- id,
10024
- {
10025
- fields: "currency_code"
10026
- },
10027
- {
10028
- enabled: !!id
10029
- }
10030
- );
10031
9910
  const { onCancel } = useCancelOrderEdit({ preview });
10032
- if (isError) {
10033
- throw error;
10034
- }
10035
9911
  if (isPreviewError) {
10036
9912
  throw previewError;
10037
9913
  }
10038
- const ready = !!preview && !isPreviewPending && !!draft_order && !isPending;
10039
- return /* @__PURE__ */ jsx(RouteFocusModal, { onClose: onCancel, children: ready ? /* @__PURE__ */ jsx(ItemsForm, { preview, currencyCode: draft_order.currency_code }) : /* @__PURE__ */ jsxs("div", { children: [
10040
- /* @__PURE__ */ jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Edit Items" }) }),
10041
- /* @__PURE__ */ jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Loading data for the draft order, please wait..." }) })
10042
- ] }) });
9914
+ const isReady = !!preview;
9915
+ return /* @__PURE__ */ jsxs(RouteDrawer, { onClose: onCancel, children: [
9916
+ /* @__PURE__ */ jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Promotions" }) }) }),
9917
+ isReady && /* @__PURE__ */ jsx(PromotionForm, { preview })
9918
+ ] });
10043
9919
  };
10044
- const ItemsForm = ({ preview, currencyCode }) => {
10045
- var _a;
9920
+ const PromotionForm = ({ preview }) => {
9921
+ const { items, shipping_methods } = preview;
10046
9922
  const [isSubmitting, setIsSubmitting] = useState(false);
10047
- const [modalContent, setModalContent] = useState(
10048
- null
10049
- );
9923
+ const [comboboxValue, setComboboxValue] = useState("");
10050
9924
  const { handleSuccess } = useRouteModal();
10051
- const { searchValue, onSearchValueChange, query: query2 } = useDebouncedSearch();
9925
+ const { mutateAsync: addPromotions, isPending: isAddingPromotions } = useDraftOrderAddPromotions(preview.id);
9926
+ const promoCodes = getPromotionCodes(items, shipping_methods);
9927
+ const { promotions, isPending, isError, error } = usePromotions(
9928
+ {
9929
+ code: promoCodes
9930
+ },
9931
+ {
9932
+ enabled: !!promoCodes.length
9933
+ }
9934
+ );
9935
+ const comboboxData = useComboboxData({
9936
+ queryKey: ["promotions", "combobox", promoCodes],
9937
+ queryFn: async (params) => {
9938
+ return await sdk.admin.promotion.list({
9939
+ ...params,
9940
+ code: {
9941
+ $nin: promoCodes
9942
+ }
9943
+ });
9944
+ },
9945
+ getOptions: (data) => {
9946
+ return data.promotions.map((promotion) => ({
9947
+ label: promotion.code,
9948
+ value: promotion.code
9949
+ }));
9950
+ }
9951
+ });
9952
+ const add = async (value) => {
9953
+ if (!value) {
9954
+ return;
9955
+ }
9956
+ addPromotions(
9957
+ {
9958
+ promo_codes: [value]
9959
+ },
9960
+ {
9961
+ onError: (e) => {
9962
+ toast.error(e.message);
9963
+ comboboxData.onSearchValueChange("");
9964
+ setComboboxValue("");
9965
+ },
9966
+ onSuccess: () => {
9967
+ comboboxData.onSearchValueChange("");
9968
+ setComboboxValue("");
9969
+ }
9970
+ }
9971
+ );
9972
+ };
10052
9973
  const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
10053
- const { mutateAsync: requestOrderEdit } = useDraftOrderRequestEdit(preview.id);
10054
- const itemCount = ((_a = preview.items) == null ? void 0 : _a.reduce((acc, item) => acc + item.quantity, 0)) || 0;
10055
- const matches = useMemo(() => {
10056
- return matchSorter(preview.items, query2, {
10057
- keys: ["product_title", "variant_title", "variant_sku", "title"]
10058
- });
10059
- }, [preview.items, query2]);
9974
+ const { mutateAsync: requestOrderEdit } = useOrderEditRequest(preview.id);
10060
9975
  const onSubmit = async () => {
10061
9976
  setIsSubmitting(true);
10062
9977
  let requestSucceeded = false;
10063
9978
  await requestOrderEdit(void 0, {
10064
9979
  onError: (e) => {
10065
- toast.error(`Failed to request order edit: ${e.message}`);
9980
+ toast.error(e.message);
10066
9981
  },
10067
9982
  onSuccess: () => {
10068
9983
  requestSucceeded = true;
@@ -10074,7 +9989,7 @@ const ItemsForm = ({ preview, currencyCode }) => {
10074
9989
  }
10075
9990
  await confirmOrderEdit(void 0, {
10076
9991
  onError: (e) => {
10077
- toast.error(`Failed to confirm order edit: ${e.message}`);
9992
+ toast.error(e.message);
10078
9993
  },
10079
9994
  onSuccess: () => {
10080
9995
  handleSuccess();
@@ -10084,860 +9999,294 @@ const ItemsForm = ({ preview, currencyCode }) => {
10084
9999
  }
10085
10000
  });
10086
10001
  };
10087
- const onKeyDown = useCallback(
10088
- (e) => {
10089
- if (e.key === "Enter" && (e.ctrlKey || e.metaKey)) {
10090
- if (modalContent || isSubmitting) {
10091
- return;
10092
- }
10093
- onSubmit();
10094
- }
10095
- },
10096
- [modalContent, isSubmitting, onSubmit]
10097
- );
10098
- useEffect(() => {
10099
- document.addEventListener("keydown", onKeyDown);
10100
- return () => {
10101
- document.removeEventListener("keydown", onKeyDown);
10102
- };
10103
- }, [onKeyDown]);
10104
- return /* @__PURE__ */ jsxs("div", { className: "flex h-full flex-col overflow-hidden", children: [
10105
- /* @__PURE__ */ jsx(RouteFocusModal.Header, {}),
10106
- /* @__PURE__ */ jsx(RouteFocusModal.Body, { className: "flex flex-1 flex-col overflow-hidden", children: /* @__PURE__ */ jsxs(
10107
- StackedFocusModal,
10108
- {
10109
- id: STACKED_MODAL_ID,
10110
- onOpenChangeCallback: (open) => {
10111
- if (!open) {
10112
- setModalContent(null);
10113
- }
10002
+ if (isError) {
10003
+ throw error;
10004
+ }
10005
+ return /* @__PURE__ */ jsxs(KeyboundForm, { className: "flex flex-1 flex-col", onSubmit, children: [
10006
+ /* @__PURE__ */ jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-4", children: [
10007
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3", children: [
10008
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
10009
+ /* @__PURE__ */ jsx(Label$1, { size: "small", weight: "plus", htmlFor: "promotion-combobox", children: "Apply promotions" }),
10010
+ /* @__PURE__ */ jsx(Hint$1, { id: "promotion-combobox-hint", children: "Manage promotions that should be applied to the order." })
10011
+ ] }),
10012
+ /* @__PURE__ */ jsx(
10013
+ Combobox,
10014
+ {
10015
+ id: "promotion-combobox",
10016
+ "aria-describedby": "promotion-combobox-hint",
10017
+ isFetchingNextPage: comboboxData.isFetchingNextPage,
10018
+ fetchNextPage: comboboxData.fetchNextPage,
10019
+ options: comboboxData.options,
10020
+ onSearchValueChange: comboboxData.onSearchValueChange,
10021
+ searchValue: comboboxData.searchValue,
10022
+ disabled: comboboxData.disabled || isAddingPromotions,
10023
+ onChange: add,
10024
+ value: comboboxValue
10025
+ }
10026
+ )
10027
+ ] }),
10028
+ /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
10029
+ /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-2", children: promotions == null ? void 0 : promotions.map((promotion) => /* @__PURE__ */ jsx(
10030
+ PromotionItem,
10031
+ {
10032
+ promotion,
10033
+ orderId: preview.id,
10034
+ isLoading: isPending
10114
10035
  },
10115
- children: [
10116
- /* @__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: [
10117
- /* @__PURE__ */ jsxs("div", { children: [
10118
- /* @__PURE__ */ jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Items" }) }),
10119
- /* @__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." }) })
10120
- ] }),
10121
- /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
10122
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-y-6", children: [
10123
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 items-center gap-3", children: [
10124
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
10125
- /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: "Items" }),
10126
- /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Choose items from the product catalog." })
10127
- ] }),
10128
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
10129
- /* @__PURE__ */ jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsx(
10130
- Input,
10131
- {
10132
- type: "search",
10133
- placeholder: "Search items",
10134
- value: searchValue,
10135
- onChange: (e) => onSearchValueChange(e.target.value)
10136
- }
10137
- ) }),
10138
- /* @__PURE__ */ jsxs(DropdownMenu, { children: [
10139
- /* @__PURE__ */ jsx(DropdownMenu.Trigger, { asChild: true, children: /* @__PURE__ */ jsx(IconButton, { type: "button", children: /* @__PURE__ */ jsx(Plus, {}) }) }),
10140
- /* @__PURE__ */ jsxs(DropdownMenu.Content, { children: [
10141
- /* @__PURE__ */ jsx(
10142
- StackedModalTrigger$1,
10143
- {
10144
- type: "add-items",
10145
- setModalContent
10146
- }
10147
- ),
10148
- /* @__PURE__ */ jsx(
10149
- StackedModalTrigger$1,
10150
- {
10151
- type: "add-custom-item",
10152
- setModalContent
10153
- }
10154
- )
10155
- ] })
10156
- ] })
10157
- ] })
10158
- ] }),
10159
- /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-subtle shadow-elevation-card-rest rounded-xl", children: [
10160
- /* @__PURE__ */ jsx("div", { className: "px-[5px]", children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-[1fr_1fr_1fr_28px] gap-3 px-4 py-2 text-ui-fg-muted", children: [
10161
- /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: "Item" }) }),
10162
- /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: "Quantity" }) }),
10163
- /* @__PURE__ */ jsx("div", { className: "text-right", children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: "Price" }) }),
10164
- /* @__PURE__ */ jsx("div", {})
10165
- ] }) }),
10166
- /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-y-1.5 px-[5px] pb-[5px]", children: itemCount <= 0 ? /* @__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: [
10167
- /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: "There are no items in this order" }),
10168
- /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Add items to the order to get started." })
10169
- ] }) : matches.length > 0 ? matches == null ? void 0 : matches.map((item) => /* @__PURE__ */ jsx(
10170
- Item,
10171
- {
10172
- item,
10173
- preview,
10174
- currencyCode
10175
- },
10176
- item.id
10177
- )) : /* @__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: [
10178
- /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: "No items found" }),
10179
- /* @__PURE__ */ jsxs(Text, { size: "small", className: "text-ui-fg-subtle", children: [
10180
- 'No items found for "',
10181
- query2,
10182
- '".'
10183
- ] })
10184
- ] }) })
10185
- ] })
10186
- ] }),
10187
- /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
10188
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-[1fr_0.5fr_0.5fr] gap-3", children: [
10189
- /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: "Subtotal" }) }),
10190
- /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsxs(
10191
- Text,
10192
- {
10193
- size: "small",
10194
- leading: "compact",
10195
- className: "text-ui-fg-subtle",
10196
- children: [
10197
- itemCount,
10198
- " ",
10199
- itemCount === 1 ? "item" : "items"
10200
- ]
10201
- }
10202
- ) }),
10203
- /* @__PURE__ */ jsx("div", { className: "text-right", children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: getStylizedAmount(preview.item_subtotal, currencyCode) }) })
10204
- ] })
10205
- ] }) }),
10206
- modalContent && (modalContent === "add-items" ? /* @__PURE__ */ jsx(ExistingItemsForm, { orderId: preview.id, items: preview.items }) : modalContent === "add-custom-item" ? /* @__PURE__ */ jsx(
10207
- CustomItemForm,
10208
- {
10209
- orderId: preview.id,
10210
- currencyCode
10211
- }
10212
- ) : null)
10213
- ]
10214
- }
10215
- ) }),
10216
- /* @__PURE__ */ jsx(RouteFocusModal.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-2 justify-end", children: [
10217
- /* @__PURE__ */ jsx(RouteFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
10036
+ promotion.id
10037
+ )) })
10038
+ ] }) }),
10039
+ /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
10040
+ /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
10218
10041
  /* @__PURE__ */ jsx(
10219
10042
  Button,
10220
10043
  {
10221
10044
  size: "small",
10222
- type: "button",
10223
- onClick: onSubmit,
10224
- isLoading: isSubmitting,
10045
+ type: "submit",
10046
+ isLoading: isSubmitting || isAddingPromotions,
10225
10047
  children: "Save"
10226
10048
  }
10227
10049
  )
10228
10050
  ] }) })
10229
10051
  ] });
10230
10052
  };
10231
- const Item = ({ item, preview, currencyCode }) => {
10232
- if (item.variant_id) {
10233
- return /* @__PURE__ */ jsx(VariantItem, { item, preview, currencyCode });
10234
- }
10235
- return /* @__PURE__ */ jsx(CustomItem, { item, preview, currencyCode });
10236
- };
10237
- const VariantItem = ({ item, preview, currencyCode }) => {
10238
- const [editing, setEditing] = useState(false);
10239
- const form = useForm({
10240
- defaultValues: {
10241
- quantity: item.quantity,
10242
- unit_price: item.unit_price
10243
- },
10244
- resolver: zodResolver(variantItemSchema)
10245
- });
10246
- const actionId = useMemo(() => {
10247
- var _a, _b;
10248
- return (_b = (_a = item.actions) == null ? void 0 : _a.find((a) => a.action === "ITEM_ADD")) == null ? void 0 : _b.id;
10249
- }, [item]);
10250
- const { mutateAsync: updateActionItem, isPending: isUpdatingActionItem } = useDraftOrderUpdateActionItem(preview.id);
10251
- const { mutateAsync: updateOriginalItem, isPending: isUpdatingOriginalItem } = useDraftOrderUpdateItem(preview.id);
10252
- const isPending = isUpdatingActionItem || isUpdatingOriginalItem;
10253
- const onSubmit = form.handleSubmit(async (data) => {
10254
- if (convertNumber(data.unit_price) === item.unit_price && data.quantity === item.quantity) {
10255
- setEditing(false);
10256
- return;
10257
- }
10258
- if (!actionId) {
10259
- await updateOriginalItem(
10260
- {
10261
- item_id: item.id,
10262
- quantity: data.quantity,
10263
- unit_price: convertNumber(data.unit_price)
10264
- },
10265
- {
10266
- onSuccess: () => {
10267
- setEditing(false);
10268
- },
10269
- onError: (e) => {
10270
- toast.error(e.message);
10271
- }
10272
- }
10273
- );
10274
- return;
10275
- }
10276
- await updateActionItem(
10053
+ const PromotionItem = ({
10054
+ promotion,
10055
+ orderId,
10056
+ isLoading
10057
+ }) => {
10058
+ var _a;
10059
+ const { mutateAsync: removePromotions, isPending } = useDraftOrderRemovePromotions(orderId);
10060
+ const onRemove = async () => {
10061
+ removePromotions(
10277
10062
  {
10278
- action_id: actionId,
10279
- quantity: data.quantity,
10280
- unit_price: convertNumber(data.unit_price)
10063
+ promo_codes: [promotion.code]
10281
10064
  },
10282
10065
  {
10283
- onSuccess: () => {
10284
- setEditing(false);
10285
- },
10286
10066
  onError: (e) => {
10287
10067
  toast.error(e.message);
10288
10068
  }
10289
10069
  }
10290
10070
  );
10291
- });
10292
- return /* @__PURE__ */ jsx(Form$2, { ...form, children: /* @__PURE__ */ jsx("form", { onSubmit, children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-[minmax(0,1fr)_minmax(0,1fr)_minmax(0,1fr)_28px] gap-3 px-4 py-2 bg-ui-bg-base shadow-elevation-card-rest rounded-lg items-center", children: [
10293
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-3 w-full", children: [
10294
- /* @__PURE__ */ jsx(
10295
- Thumbnail,
10071
+ };
10072
+ const displayValue = getDisplayValue(promotion);
10073
+ return /* @__PURE__ */ jsxs(
10074
+ "div",
10075
+ {
10076
+ className: clx(
10077
+ "px-3 py-2 rounded-lg bg-ui-bg-component shadow-elevation-card-rest flex items-center justify-between",
10296
10078
  {
10297
- thumbnail: item.thumbnail,
10298
- alt: item.product_title ?? void 0
10079
+ "animate-pulse": isLoading
10299
10080
  }
10300
10081
  ),
10301
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
10302
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-1", children: [
10303
- /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: item.product_title }),
10304
- /* @__PURE__ */ jsxs(
10305
- Text,
10306
- {
10307
- size: "small",
10308
- leading: "compact",
10309
- className: "text-ui-fg-subtle",
10310
- children: [
10311
- "(",
10312
- item.variant_title,
10313
- ")"
10314
- ]
10315
- }
10316
- )
10082
+ children: [
10083
+ /* @__PURE__ */ jsxs("div", { children: [
10084
+ /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: promotion.code }),
10085
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 text-ui-fg-subtle", children: [
10086
+ displayValue && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
10087
+ /* @__PURE__ */ jsx(Text, { size: "small", leading: "compact", children: displayValue }),
10088
+ /* @__PURE__ */ jsx(Text, { size: "small", leading: "compact", children: "·" })
10089
+ ] }),
10090
+ /* @__PURE__ */ jsx(Text, { size: "small", leading: "compact", className: "capitalize", children: (_a = promotion.application_method) == null ? void 0 : _a.allocation })
10091
+ ] })
10317
10092
  ] }),
10318
10093
  /* @__PURE__ */ jsx(
10319
- Text,
10094
+ IconButton,
10320
10095
  {
10321
10096
  size: "small",
10322
- leading: "compact",
10323
- className: "text-ui-fg-subtle",
10324
- children: item.variant_sku
10325
- }
10326
- )
10327
- ] })
10328
- ] }),
10329
- editing ? /* @__PURE__ */ jsx("div", { className: "flex-1 w-full", children: /* @__PURE__ */ jsx(
10330
- Form$2.Field,
10331
- {
10332
- control: form.control,
10333
- name: "quantity",
10334
- render: ({ field }) => {
10335
- return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(NumberInput, { ...field }) }) });
10097
+ type: "button",
10098
+ variant: "transparent",
10099
+ onClick: onRemove,
10100
+ isLoading: isPending || isLoading,
10101
+ children: /* @__PURE__ */ jsx(XMark, {})
10102
+ }
10103
+ )
10104
+ ]
10105
+ },
10106
+ promotion.id
10107
+ );
10108
+ };
10109
+ function getDisplayValue(promotion) {
10110
+ var _a, _b, _c, _d;
10111
+ const value = (_a = promotion.application_method) == null ? void 0 : _a.value;
10112
+ if (!value) {
10113
+ return null;
10114
+ }
10115
+ if (((_b = promotion.application_method) == null ? void 0 : _b.type) === "fixed") {
10116
+ const currency = (_c = promotion.application_method) == null ? void 0 : _c.currency_code;
10117
+ if (!currency) {
10118
+ return null;
10119
+ }
10120
+ return getLocaleAmount(value, currency);
10121
+ } else if (((_d = promotion.application_method) == null ? void 0 : _d.type) === "percentage") {
10122
+ return formatPercentage(value);
10123
+ }
10124
+ return null;
10125
+ }
10126
+ const formatter = new Intl.NumberFormat([], {
10127
+ style: "percent",
10128
+ minimumFractionDigits: 2
10129
+ });
10130
+ const formatPercentage = (value, isPercentageValue = false) => {
10131
+ let val = value || 0;
10132
+ if (!isPercentageValue) {
10133
+ val = val / 100;
10134
+ }
10135
+ return formatter.format(val);
10136
+ };
10137
+ function getPromotionCodes(items, shippingMethods) {
10138
+ const codes = /* @__PURE__ */ new Set();
10139
+ for (const item of items) {
10140
+ if (item.adjustments) {
10141
+ for (const adjustment of item.adjustments) {
10142
+ if (adjustment.code) {
10143
+ codes.add(adjustment.code);
10336
10144
  }
10337
10145
  }
10338
- ) }) : /* @__PURE__ */ jsx("div", { className: "flex-1 w-full", children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: item.quantity }) }),
10339
- editing ? /* @__PURE__ */ jsx("div", { className: "flex-1 w-full", children: /* @__PURE__ */ jsx(
10340
- Form$2.Field,
10341
- {
10342
- control: form.control,
10343
- name: "unit_price",
10344
- render: ({ field: { onChange, ...field } }) => {
10345
- return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
10346
- CurrencyInput,
10347
- {
10348
- ...field,
10349
- symbol: getNativeSymbol(currencyCode),
10350
- code: currencyCode,
10351
- onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value)
10352
- }
10353
- ) }) });
10146
+ }
10147
+ }
10148
+ for (const shippingMethod of shippingMethods) {
10149
+ if (shippingMethod.adjustments) {
10150
+ for (const adjustment of shippingMethod.adjustments) {
10151
+ if (adjustment.code) {
10152
+ codes.add(adjustment.code);
10354
10153
  }
10355
10154
  }
10356
- ) }) : /* @__PURE__ */ jsx("div", { className: "flex-1 flex items-center justify-end w-full", children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: getLocaleAmount(item.unit_price, currencyCode) }) }),
10357
- /* @__PURE__ */ jsx(
10358
- IconButton,
10155
+ }
10156
+ }
10157
+ return Array.from(codes);
10158
+ }
10159
+ const InlineTip = forwardRef(
10160
+ ({ variant = "tip", label, className, children, ...props }, ref) => {
10161
+ const labelValue = label || (variant === "warning" ? "Warning" : "Tip");
10162
+ return /* @__PURE__ */ jsxs(
10163
+ "div",
10359
10164
  {
10360
- type: "button",
10361
- size: "small",
10362
- onClick: editing ? onSubmit : () => {
10363
- setEditing(true);
10364
- },
10365
- disabled: isPending,
10366
- children: editing ? /* @__PURE__ */ jsx(Check, {}) : /* @__PURE__ */ jsx(PencilSquare, {})
10165
+ ref,
10166
+ className: clx(
10167
+ "bg-ui-bg-component txt-small text-ui-fg-subtle grid grid-cols-[4px_1fr] items-start gap-3 rounded-lg border p-3",
10168
+ className
10169
+ ),
10170
+ ...props,
10171
+ children: [
10172
+ /* @__PURE__ */ jsx(
10173
+ "div",
10174
+ {
10175
+ role: "presentation",
10176
+ className: clx("w-4px bg-ui-tag-neutral-icon h-full rounded-full", {
10177
+ "bg-ui-tag-orange-icon": variant === "warning"
10178
+ })
10179
+ }
10180
+ ),
10181
+ /* @__PURE__ */ jsxs("div", { className: "text-pretty", children: [
10182
+ /* @__PURE__ */ jsxs("strong", { className: "txt-small-plus text-ui-fg-base", children: [
10183
+ labelValue,
10184
+ ":"
10185
+ ] }),
10186
+ " ",
10187
+ children
10188
+ ] })
10189
+ ]
10367
10190
  }
10368
- )
10369
- ] }) }) });
10370
- };
10371
- const variantItemSchema = objectType({
10372
- quantity: numberType(),
10373
- unit_price: unionType([numberType(), stringType()])
10191
+ );
10192
+ }
10193
+ );
10194
+ InlineTip.displayName = "InlineTip";
10195
+ const MetadataFieldSchema = objectType({
10196
+ key: stringType(),
10197
+ disabled: booleanType().optional(),
10198
+ value: anyType()
10374
10199
  });
10375
- const CustomItem = ({ item, preview, currencyCode }) => {
10376
- const [editing, setEditing] = useState(false);
10377
- const { quantity, unit_price, title } = item;
10200
+ const MetadataSchema = objectType({
10201
+ metadata: arrayType(MetadataFieldSchema)
10202
+ });
10203
+ const Metadata = () => {
10204
+ const { id } = useParams();
10205
+ const { order, isPending, isError, error } = useOrder(id, {
10206
+ fields: "metadata"
10207
+ });
10208
+ if (isError) {
10209
+ throw error;
10210
+ }
10211
+ const isReady = !isPending && !!order;
10212
+ return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
10213
+ /* @__PURE__ */ jsxs(RouteDrawer.Header, { children: [
10214
+ /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Metadata" }) }),
10215
+ /* @__PURE__ */ jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Add metadata to the draft order." }) })
10216
+ ] }),
10217
+ !isReady ? /* @__PURE__ */ jsx(PlaceholderInner, {}) : /* @__PURE__ */ jsx(MetadataForm, { orderId: id, metadata: order == null ? void 0 : order.metadata })
10218
+ ] });
10219
+ };
10220
+ const METADATA_KEY_LABEL_ID = "metadata-form-key-label";
10221
+ const METADATA_VALUE_LABEL_ID = "metadata-form-value-label";
10222
+ const MetadataForm = ({ orderId, metadata }) => {
10223
+ const { handleSuccess } = useRouteModal();
10224
+ const hasUneditableRows = getHasUneditableRows(metadata);
10225
+ const { mutateAsync, isPending } = useUpdateDraftOrder(orderId);
10378
10226
  const form = useForm({
10379
10227
  defaultValues: {
10380
- title,
10381
- quantity,
10382
- unit_price
10228
+ metadata: getDefaultValues(metadata)
10383
10229
  },
10384
- resolver: zodResolver(customItemSchema)
10230
+ resolver: zodResolver(MetadataSchema)
10385
10231
  });
10386
- useEffect(() => {
10387
- form.reset({
10388
- title,
10389
- quantity,
10390
- unit_price
10391
- });
10392
- }, [form, title, quantity, unit_price]);
10393
- const actionId = useMemo(() => {
10394
- var _a, _b;
10395
- return (_b = (_a = item.actions) == null ? void 0 : _a.find((a) => a.action === "ITEM_ADD")) == null ? void 0 : _b.id;
10396
- }, [item]);
10397
- const { mutateAsync: updateActionItem, isPending: isUpdatingActionItem } = useDraftOrderUpdateActionItem(preview.id);
10398
- const { mutateAsync: removeActionItem, isPending: isRemovingActionItem } = useDraftOrderRemoveActionItem(preview.id);
10399
- const { mutateAsync: updateOriginalItem, isPending: isUpdatingOriginalItem } = useDraftOrderUpdateItem(preview.id);
10400
- const isPending = isUpdatingActionItem || isUpdatingOriginalItem;
10401
- const onSubmit = form.handleSubmit(async (data) => {
10402
- if (convertNumber(data.unit_price) === item.unit_price && data.quantity === item.quantity && data.title === item.title) {
10403
- setEditing(false);
10404
- return;
10405
- }
10406
- if (!actionId) {
10407
- await updateOriginalItem(
10408
- {
10409
- item_id: item.id,
10410
- quantity: data.quantity,
10411
- unit_price: convertNumber(data.unit_price)
10412
- },
10413
- {
10414
- onSuccess: () => {
10415
- setEditing(false);
10416
- },
10417
- onError: (e) => {
10418
- toast.error(e.message);
10419
- }
10420
- }
10421
- );
10422
- return;
10423
- }
10424
- if (data.quantity === 0) {
10425
- await removeActionItem(actionId, {
10426
- onSuccess: () => {
10427
- setEditing(false);
10428
- },
10429
- onError: (e) => {
10430
- toast.error(e.message);
10431
- }
10432
- });
10433
- return;
10434
- }
10435
- await updateActionItem(
10232
+ const handleSubmit = form.handleSubmit(async (data) => {
10233
+ const parsedData = parseValues(data);
10234
+ await mutateAsync(
10436
10235
  {
10437
- action_id: actionId,
10438
- quantity: data.quantity,
10439
- unit_price: convertNumber(data.unit_price)
10236
+ metadata: parsedData
10440
10237
  },
10441
10238
  {
10442
10239
  onSuccess: () => {
10443
- setEditing(false);
10240
+ toast.success("Metadata updated");
10241
+ handleSuccess();
10444
10242
  },
10445
- onError: (e) => {
10446
- toast.error(e.message);
10243
+ onError: (error) => {
10244
+ toast.error(error.message);
10447
10245
  }
10448
10246
  }
10449
10247
  );
10450
10248
  });
10451
- return /* @__PURE__ */ jsx(Form$2, { ...form, children: /* @__PURE__ */ jsx("form", { onSubmit, children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-[minmax(0,1fr)_minmax(0,1fr)_minmax(0,1fr)_28px] gap-3 px-4 py-2 bg-ui-bg-base shadow-elevation-card-rest rounded-lg items-center", children: [
10452
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-3", children: [
10453
- /* @__PURE__ */ jsx(
10454
- Thumbnail,
10455
- {
10456
- thumbnail: item.thumbnail,
10457
- alt: item.title ?? void 0
10458
- }
10459
- ),
10460
- editing ? /* @__PURE__ */ jsx(
10461
- Form$2.Field,
10462
- {
10463
- control: form.control,
10464
- name: "title",
10465
- render: ({ field }) => {
10466
- return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }) });
10467
- }
10468
- }
10469
- ) : /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: item.title })
10470
- ] }),
10471
- editing ? /* @__PURE__ */ jsx(
10472
- Form$2.Field,
10473
- {
10474
- control: form.control,
10475
- name: "quantity",
10476
- render: ({ field }) => {
10477
- return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(NumberInput, { ...field }) }) });
10478
- }
10479
- }
10480
- ) : /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: item.quantity }),
10481
- editing ? /* @__PURE__ */ jsx(
10482
- Form$2.Field,
10483
- {
10484
- control: form.control,
10485
- name: "unit_price",
10486
- render: ({ field: { onChange, ...field } }) => {
10487
- return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
10488
- CurrencyInput,
10489
- {
10490
- ...field,
10491
- symbol: getNativeSymbol(currencyCode),
10492
- code: currencyCode,
10493
- onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value)
10494
- }
10495
- ) }) });
10496
- }
10497
- }
10498
- ) : /* @__PURE__ */ jsx("div", { className: "flex-1 flex items-center justify-end", children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: getLocaleAmount(item.unit_price, currencyCode) }) }),
10499
- /* @__PURE__ */ jsx(
10500
- IconButton,
10501
- {
10502
- type: "button",
10503
- size: "small",
10504
- onClick: editing ? onSubmit : () => {
10505
- setEditing(true);
10506
- },
10507
- disabled: isPending,
10508
- children: editing ? /* @__PURE__ */ jsx(Check, {}) : /* @__PURE__ */ jsx(PencilSquare, {})
10509
- }
10510
- )
10511
- ] }) }) });
10512
- };
10513
- const StackedModalTrigger$1 = ({
10514
- type,
10515
- setModalContent
10516
- }) => {
10517
- const { setIsOpen } = useStackedModal();
10518
- const onClick = useCallback(() => {
10519
- setModalContent(type);
10520
- setIsOpen(STACKED_MODAL_ID, true);
10521
- }, [setModalContent, setIsOpen, type]);
10522
- return /* @__PURE__ */ jsx(StackedFocusModal.Trigger, { asChild: true, children: /* @__PURE__ */ jsx(DropdownMenu.Item, { onClick, children: type === "add-items" ? "Add items" : "Add custom item" }) });
10523
- };
10524
- const VARIANT_PREFIX = "items";
10525
- const LIMIT = 50;
10526
- const ExistingItemsForm = ({ orderId, items }) => {
10527
- const { setIsOpen } = useStackedModal();
10528
- const [rowSelection, setRowSelection] = useState(
10529
- items.reduce((acc, item) => {
10530
- acc[item.variant_id] = true;
10531
- return acc;
10532
- }, {})
10533
- );
10534
- useEffect(() => {
10535
- setRowSelection(
10536
- items.reduce((acc, item) => {
10537
- if (item.variant_id) {
10538
- acc[item.variant_id] = true;
10539
- }
10540
- return acc;
10541
- }, {})
10542
- );
10543
- }, [items]);
10544
- const { q, order, offset } = useQueryParams(
10545
- ["q", "order", "offset"],
10546
- VARIANT_PREFIX
10547
- );
10548
- const { variants, count, isPending, isError, error } = useProductVariants(
10549
- {
10550
- q,
10551
- order,
10552
- offset: offset ? parseInt(offset) : void 0,
10553
- limit: LIMIT
10554
- },
10555
- {
10556
- placeholderData: keepPreviousData
10249
+ const { fields, insert, remove } = useFieldArray({
10250
+ control: form.control,
10251
+ name: "metadata"
10252
+ });
10253
+ function deleteRow(index) {
10254
+ remove(index);
10255
+ if (fields.length === 1) {
10256
+ insert(0, {
10257
+ key: "",
10258
+ value: "",
10259
+ disabled: false
10260
+ });
10557
10261
  }
10558
- );
10559
- const columns = useColumns();
10560
- const { mutateAsync } = useDraftOrderAddItems(orderId);
10561
- const onSubmit = async () => {
10562
- const ids = Object.keys(rowSelection).filter(
10563
- (id) => !items.find((i) => i.variant_id === id)
10564
- );
10565
- await mutateAsync(
10566
- {
10567
- items: ids.map((id) => ({
10568
- variant_id: id,
10569
- quantity: 1
10570
- }))
10571
- },
10572
- {
10573
- onSuccess: () => {
10574
- setRowSelection({});
10575
- setIsOpen(STACKED_MODAL_ID, false);
10576
- },
10577
- onError: (e) => {
10578
- toast.error(e.message);
10579
- }
10580
- }
10581
- );
10582
- };
10583
- if (isError) {
10584
- throw error;
10585
10262
  }
10586
- return /* @__PURE__ */ jsxs(
10587
- StackedFocusModal.Content,
10263
+ function insertRow(index, position) {
10264
+ insert(index + (position === "above" ? 0 : 1), {
10265
+ key: "",
10266
+ value: "",
10267
+ disabled: false
10268
+ });
10269
+ }
10270
+ return /* @__PURE__ */ jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxs(
10271
+ KeyboundForm,
10588
10272
  {
10589
- onOpenAutoFocus: (e) => {
10590
- e.preventDefault();
10591
- const searchInput = document.querySelector(
10592
- "[data-modal-id='modal-search-input']"
10593
- );
10594
- if (searchInput) {
10595
- searchInput.focus();
10596
- }
10597
- },
10273
+ onSubmit: handleSubmit,
10274
+ className: "flex flex-1 flex-col overflow-hidden",
10598
10275
  children: [
10599
- /* @__PURE__ */ jsxs(StackedFocusModal.Header, { children: [
10600
- /* @__PURE__ */ jsx(StackedFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Product Variants" }) }),
10601
- /* @__PURE__ */ jsx(StackedFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Choose product variants to add to the order." }) })
10602
- ] }),
10603
- /* @__PURE__ */ jsx(StackedFocusModal.Body, { className: "flex-1 overflow-hidden", children: /* @__PURE__ */ jsx(
10604
- DataTable,
10605
- {
10606
- data: variants,
10607
- columns,
10608
- isLoading: isPending,
10609
- getRowId: (row) => row.id,
10610
- rowCount: count,
10611
- prefix: VARIANT_PREFIX,
10612
- layout: "fill",
10613
- rowSelection: {
10614
- state: rowSelection,
10615
- onRowSelectionChange: setRowSelection,
10616
- enableRowSelection: (row) => {
10617
- return !items.find((i) => i.variant_id === row.original.id);
10276
+ /* @__PURE__ */ jsxs(RouteDrawer.Body, { className: "flex flex-1 flex-col gap-y-8 overflow-y-auto", children: [
10277
+ /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest grid grid-cols-1 divide-y rounded-lg", children: [
10278
+ /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-subtle grid grid-cols-2 divide-x rounded-t-lg", children: [
10279
+ /* @__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" }) }),
10280
+ /* @__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" }) })
10281
+ ] }),
10282
+ fields.map((field, index) => {
10283
+ const isDisabled = field.disabled || false;
10284
+ let placeholder = "-";
10285
+ if (typeof field.value === "object") {
10286
+ placeholder = "{ ... }";
10618
10287
  }
10619
- },
10620
- autoFocusSearch: true
10621
- }
10622
- ) }),
10623
- /* @__PURE__ */ jsx(StackedFocusModal.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-2 justify-end", children: [
10624
- /* @__PURE__ */ jsx(StackedFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
10625
- /* @__PURE__ */ jsx(Button, { size: "small", type: "button", onClick: onSubmit, children: "Update items" })
10626
- ] }) })
10627
- ]
10628
- }
10629
- );
10630
- };
10631
- const columnHelper = createDataTableColumnHelper();
10632
- const useColumns = () => {
10633
- return useMemo(() => {
10634
- return [
10635
- columnHelper.select(),
10636
- columnHelper.accessor("product.title", {
10637
- header: "Product",
10638
- cell: ({ row }) => {
10639
- var _a, _b, _c;
10640
- return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-2", children: [
10641
- /* @__PURE__ */ jsx(
10642
- Thumbnail,
10643
- {
10644
- thumbnail: (_a = row.original.product) == null ? void 0 : _a.thumbnail,
10645
- alt: (_b = row.original.product) == null ? void 0 : _b.title
10646
- }
10647
- ),
10648
- /* @__PURE__ */ jsx("span", { children: (_c = row.original.product) == null ? void 0 : _c.title })
10649
- ] });
10650
- },
10651
- enableSorting: true
10652
- }),
10653
- columnHelper.accessor("title", {
10654
- header: "Variant",
10655
- enableSorting: true
10656
- }),
10657
- columnHelper.accessor("sku", {
10658
- header: "SKU",
10659
- cell: ({ getValue }) => {
10660
- return getValue() ?? "-";
10661
- },
10662
- enableSorting: true
10663
- }),
10664
- columnHelper.accessor("updated_at", {
10665
- header: "Updated",
10666
- cell: ({ getValue }) => {
10667
- return /* @__PURE__ */ jsx(
10668
- Tooltip,
10669
- {
10670
- content: getFullDate({ date: getValue(), includeTime: true }),
10671
- children: /* @__PURE__ */ jsx("span", { children: getFullDate({ date: getValue() }) })
10672
- }
10673
- );
10674
- },
10675
- enableSorting: true,
10676
- sortAscLabel: "Oldest first",
10677
- sortDescLabel: "Newest first"
10678
- }),
10679
- columnHelper.accessor("created_at", {
10680
- header: "Created",
10681
- cell: ({ getValue }) => {
10682
- return /* @__PURE__ */ jsx(
10683
- Tooltip,
10684
- {
10685
- content: getFullDate({ date: getValue(), includeTime: true }),
10686
- children: /* @__PURE__ */ jsx("span", { children: getFullDate({ date: getValue() }) })
10687
- }
10688
- );
10689
- },
10690
- enableSorting: true,
10691
- sortAscLabel: "Oldest first",
10692
- sortDescLabel: "Newest first"
10693
- })
10694
- ];
10695
- }, []);
10696
- };
10697
- const CustomItemForm = ({ orderId, currencyCode }) => {
10698
- const { setIsOpen } = useStackedModal();
10699
- const { mutateAsync: addItems } = useDraftOrderAddItems(orderId);
10700
- const form = useForm({
10701
- defaultValues: {
10702
- title: "",
10703
- quantity: 1,
10704
- unit_price: ""
10705
- },
10706
- resolver: zodResolver(customItemSchema)
10707
- });
10708
- const onSubmit = form.handleSubmit(async (data) => {
10709
- await addItems(
10710
- {
10711
- items: [
10712
- {
10713
- title: data.title,
10714
- quantity: data.quantity,
10715
- unit_price: convertNumber(data.unit_price)
10716
- }
10717
- ]
10718
- },
10719
- {
10720
- onSuccess: () => {
10721
- setIsOpen(STACKED_MODAL_ID, false);
10722
- },
10723
- onError: (e) => {
10724
- toast.error(e.message);
10725
- }
10726
- }
10727
- );
10728
- });
10729
- return /* @__PURE__ */ jsx(Form$2, { ...form, children: /* @__PURE__ */ jsx(KeyboundForm, { onSubmit, children: /* @__PURE__ */ jsxs(StackedFocusModal.Content, { children: [
10730
- /* @__PURE__ */ jsx(StackedFocusModal.Header, {}),
10731
- /* @__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: [
10732
- /* @__PURE__ */ jsxs("div", { children: [
10733
- /* @__PURE__ */ jsx(StackedFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Add custom item" }) }),
10734
- /* @__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." }) })
10735
- ] }),
10736
- /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
10737
- /* @__PURE__ */ jsx(
10738
- Form$2.Field,
10739
- {
10740
- control: form.control,
10741
- name: "title",
10742
- render: ({ field }) => /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
10743
- /* @__PURE__ */ jsxs("div", { children: [
10744
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Title" }),
10745
- /* @__PURE__ */ jsx(Form$2.Hint, { children: "Enter the title of the item" })
10746
- ] }),
10747
- /* @__PURE__ */ jsxs("div", { children: [
10748
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
10749
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
10750
- ] })
10751
- ] }) })
10752
- }
10753
- ),
10754
- /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
10755
- /* @__PURE__ */ jsx(
10756
- Form$2.Field,
10757
- {
10758
- control: form.control,
10759
- name: "unit_price",
10760
- render: ({ field: { onChange, ...field } }) => /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
10761
- /* @__PURE__ */ jsxs("div", { children: [
10762
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Unit price" }),
10763
- /* @__PURE__ */ jsx(Form$2.Hint, { children: "Enter the unit price of the item" })
10764
- ] }),
10765
- /* @__PURE__ */ jsxs("div", { children: [
10766
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
10767
- CurrencyInput,
10768
- {
10769
- symbol: getNativeSymbol(currencyCode),
10770
- code: currencyCode,
10771
- onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value),
10772
- ...field
10773
- }
10774
- ) }),
10775
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
10776
- ] })
10777
- ] }) })
10778
- }
10779
- ),
10780
- /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
10781
- /* @__PURE__ */ jsx(
10782
- Form$2.Field,
10783
- {
10784
- control: form.control,
10785
- name: "quantity",
10786
- render: ({ field }) => /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
10787
- /* @__PURE__ */ jsxs("div", { children: [
10788
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Quantity" }),
10789
- /* @__PURE__ */ jsx(Form$2.Hint, { children: "Enter the quantity of the item" })
10790
- ] }),
10791
- /* @__PURE__ */ jsxs("div", { className: "flex-1 w-full", children: [
10792
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx("div", { className: "flex-1 w-full", children: /* @__PURE__ */ jsx(NumberInput, { ...field, className: "w-full" }) }) }),
10793
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
10794
- ] })
10795
- ] }) })
10796
- }
10797
- )
10798
- ] }) }) }),
10799
- /* @__PURE__ */ jsx(StackedFocusModal.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-2 justify-end", children: [
10800
- /* @__PURE__ */ jsx(StackedFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
10801
- /* @__PURE__ */ jsx(Button, { size: "small", type: "button", onClick: onSubmit, children: "Add item" })
10802
- ] }) })
10803
- ] }) }) });
10804
- };
10805
- const customItemSchema = objectType({
10806
- title: stringType().min(1),
10807
- quantity: numberType(),
10808
- unit_price: unionType([numberType(), stringType()])
10809
- });
10810
- const InlineTip = forwardRef(
10811
- ({ variant = "tip", label, className, children, ...props }, ref) => {
10812
- const labelValue = label || (variant === "warning" ? "Warning" : "Tip");
10813
- return /* @__PURE__ */ jsxs(
10814
- "div",
10815
- {
10816
- ref,
10817
- className: clx(
10818
- "bg-ui-bg-component txt-small text-ui-fg-subtle grid grid-cols-[4px_1fr] items-start gap-3 rounded-lg border p-3",
10819
- className
10820
- ),
10821
- ...props,
10822
- children: [
10823
- /* @__PURE__ */ jsx(
10824
- "div",
10825
- {
10826
- role: "presentation",
10827
- className: clx("w-4px bg-ui-tag-neutral-icon h-full rounded-full", {
10828
- "bg-ui-tag-orange-icon": variant === "warning"
10829
- })
10830
- }
10831
- ),
10832
- /* @__PURE__ */ jsxs("div", { className: "text-pretty", children: [
10833
- /* @__PURE__ */ jsxs("strong", { className: "txt-small-plus text-ui-fg-base", children: [
10834
- labelValue,
10835
- ":"
10836
- ] }),
10837
- " ",
10838
- children
10839
- ] })
10840
- ]
10841
- }
10842
- );
10843
- }
10844
- );
10845
- InlineTip.displayName = "InlineTip";
10846
- const MetadataFieldSchema = objectType({
10847
- key: stringType(),
10848
- disabled: booleanType().optional(),
10849
- value: anyType()
10850
- });
10851
- const MetadataSchema = objectType({
10852
- metadata: arrayType(MetadataFieldSchema)
10853
- });
10854
- const Metadata = () => {
10855
- const { id } = useParams();
10856
- const { order, isPending, isError, error } = useOrder(id, {
10857
- fields: "metadata"
10858
- });
10859
- if (isError) {
10860
- throw error;
10861
- }
10862
- const isReady = !isPending && !!order;
10863
- return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
10864
- /* @__PURE__ */ jsxs(RouteDrawer.Header, { children: [
10865
- /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Metadata" }) }),
10866
- /* @__PURE__ */ jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Add metadata to the draft order." }) })
10867
- ] }),
10868
- !isReady ? /* @__PURE__ */ jsx(PlaceholderInner, {}) : /* @__PURE__ */ jsx(MetadataForm, { orderId: id, metadata: order == null ? void 0 : order.metadata })
10869
- ] });
10870
- };
10871
- const METADATA_KEY_LABEL_ID = "metadata-form-key-label";
10872
- const METADATA_VALUE_LABEL_ID = "metadata-form-value-label";
10873
- const MetadataForm = ({ orderId, metadata }) => {
10874
- const { handleSuccess } = useRouteModal();
10875
- const hasUneditableRows = getHasUneditableRows(metadata);
10876
- const { mutateAsync, isPending } = useUpdateDraftOrder(orderId);
10877
- const form = useForm({
10878
- defaultValues: {
10879
- metadata: getDefaultValues(metadata)
10880
- },
10881
- resolver: zodResolver(MetadataSchema)
10882
- });
10883
- const handleSubmit = form.handleSubmit(async (data) => {
10884
- const parsedData = parseValues(data);
10885
- await mutateAsync(
10886
- {
10887
- metadata: parsedData
10888
- },
10889
- {
10890
- onSuccess: () => {
10891
- toast.success("Metadata updated");
10892
- handleSuccess();
10893
- },
10894
- onError: (error) => {
10895
- toast.error(error.message);
10896
- }
10897
- }
10898
- );
10899
- });
10900
- const { fields, insert, remove } = useFieldArray({
10901
- control: form.control,
10902
- name: "metadata"
10903
- });
10904
- function deleteRow(index) {
10905
- remove(index);
10906
- if (fields.length === 1) {
10907
- insert(0, {
10908
- key: "",
10909
- value: "",
10910
- disabled: false
10911
- });
10912
- }
10913
- }
10914
- function insertRow(index, position) {
10915
- insert(index + (position === "above" ? 0 : 1), {
10916
- key: "",
10917
- value: "",
10918
- disabled: false
10919
- });
10920
- }
10921
- return /* @__PURE__ */ jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxs(
10922
- KeyboundForm,
10923
- {
10924
- onSubmit: handleSubmit,
10925
- className: "flex flex-1 flex-col overflow-hidden",
10926
- children: [
10927
- /* @__PURE__ */ jsxs(RouteDrawer.Body, { className: "flex flex-1 flex-col gap-y-8 overflow-y-auto", children: [
10928
- /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest grid grid-cols-1 divide-y rounded-lg", children: [
10929
- /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-subtle grid grid-cols-2 divide-x rounded-t-lg", children: [
10930
- /* @__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" }) }),
10931
- /* @__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" }) })
10932
- ] }),
10933
- fields.map((field, index) => {
10934
- const isDisabled = field.disabled || false;
10935
- let placeholder = "-";
10936
- if (typeof field.value === "object") {
10937
- placeholder = "{ ... }";
10938
- }
10939
- if (Array.isArray(field.value)) {
10940
- placeholder = "[ ... ]";
10288
+ if (Array.isArray(field.value)) {
10289
+ placeholder = "[ ... ]";
10941
10290
  }
10942
10291
  return /* @__PURE__ */ jsx(
10943
10292
  ConditionalTooltip,
@@ -11157,105 +10506,80 @@ function getHasUneditableRows(metadata) {
11157
10506
  (value) => !EDITABLE_TYPES.includes(typeof value)
11158
10507
  );
11159
10508
  }
11160
- const PROMOTION_QUERY_KEY = "promotions";
11161
- const promotionsQueryKeys = {
11162
- list: (query2) => [
11163
- PROMOTION_QUERY_KEY,
11164
- query2 ? query2 : void 0
11165
- ],
11166
- detail: (id, query2) => [
11167
- PROMOTION_QUERY_KEY,
11168
- id,
11169
- query2 ? query2 : void 0
11170
- ]
11171
- };
11172
- const usePromotions = (query2, options) => {
11173
- const { data, ...rest } = useQuery({
11174
- queryKey: promotionsQueryKeys.list(query2),
11175
- queryFn: async () => sdk.admin.promotion.list(query2),
11176
- ...options
11177
- });
11178
- return { ...data, ...rest };
11179
- };
11180
- const Promotions = () => {
10509
+ function convertNumber(value) {
10510
+ return typeof value === "string" ? Number(value.replace(",", ".")) : value;
10511
+ }
10512
+ const STACKED_FOCUS_MODAL_ID = "shipping-form";
10513
+ const Shipping = () => {
10514
+ var _a;
11181
10515
  const { id } = useParams();
10516
+ const { order, isPending, isError, error } = useOrder(id, {
10517
+ fields: "+items.*,+items.variant.*,+items.variant.product.*,+items.variant.product.shipping_profile.*,+currency_code"
10518
+ });
11182
10519
  const {
11183
10520
  order: preview,
10521
+ isPending: isPreviewPending,
11184
10522
  isError: isPreviewError,
11185
10523
  error: previewError
11186
- } = useOrderPreview(id, void 0);
10524
+ } = useOrderPreview(id);
11187
10525
  useInitiateOrderEdit({ preview });
11188
10526
  const { onCancel } = useCancelOrderEdit({ preview });
10527
+ if (isError) {
10528
+ throw error;
10529
+ }
11189
10530
  if (isPreviewError) {
11190
10531
  throw previewError;
11191
10532
  }
11192
- const isReady = !!preview;
11193
- return /* @__PURE__ */ jsxs(RouteDrawer, { onClose: onCancel, children: [
11194
- /* @__PURE__ */ jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Promotions" }) }) }),
11195
- isReady && /* @__PURE__ */ jsx(PromotionForm, { preview })
11196
- ] });
10533
+ const orderHasItems = (((_a = order == null ? void 0 : order.items) == null ? void 0 : _a.length) || 0) > 0;
10534
+ const isReady = preview && !isPreviewPending && order && !isPending;
10535
+ return /* @__PURE__ */ jsx(RouteFocusModal, { onClose: onCancel, children: !orderHasItems ? /* @__PURE__ */ jsxs("div", { className: "flex h-full flex-col overflow-hidden ", children: [
10536
+ /* @__PURE__ */ jsx(RouteFocusModal.Header, {}),
10537
+ /* @__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: [
10538
+ /* @__PURE__ */ jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Shipping" }) }),
10539
+ /* @__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." }) })
10540
+ ] }) }) }),
10541
+ /* @__PURE__ */ jsx(RouteFocusModal.Footer, { children: /* @__PURE__ */ jsx(RouteFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }) })
10542
+ ] }) : isReady ? /* @__PURE__ */ jsx(ShippingForm, { preview, order }) : /* @__PURE__ */ jsxs("div", { children: [
10543
+ /* @__PURE__ */ jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Edit Shipping" }) }),
10544
+ /* @__PURE__ */ jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Loading data for the draft order, please wait..." }) })
10545
+ ] }) });
11197
10546
  };
11198
- const PromotionForm = ({ preview }) => {
11199
- const { items, shipping_methods } = preview;
10547
+ const ShippingForm = ({ preview, order }) => {
10548
+ var _a;
10549
+ const { setIsOpen } = useStackedModal();
11200
10550
  const [isSubmitting, setIsSubmitting] = useState(false);
11201
- const [comboboxValue, setComboboxValue] = useState("");
11202
- const { handleSuccess } = useRouteModal();
11203
- const { mutateAsync: addPromotions, isPending: isAddingPromotions } = useDraftOrderAddPromotions(preview.id);
11204
- const promoCodes = getPromotionCodes(items, shipping_methods);
11205
- const { promotions, isPending, isError, error } = usePromotions(
10551
+ const [data, setData] = useState(null);
10552
+ const appliedShippingOptionIds = (_a = preview.shipping_methods) == null ? void 0 : _a.map((method) => method.shipping_option_id).filter(Boolean);
10553
+ const { shipping_options } = useShippingOptions(
11206
10554
  {
11207
- code: promoCodes
10555
+ id: appliedShippingOptionIds,
10556
+ fields: "+service_zone.*,+service_zone.fulfillment_set.*,+service_zone.fulfillment_set.location.*"
11208
10557
  },
11209
10558
  {
11210
- enabled: !!promoCodes.length
10559
+ enabled: appliedShippingOptionIds.length > 0
11211
10560
  }
11212
10561
  );
11213
- const comboboxData = useComboboxData({
11214
- queryKey: ["promotions", "combobox", promoCodes],
11215
- queryFn: async (params) => {
11216
- return await sdk.admin.promotion.list({
11217
- ...params,
11218
- code: {
11219
- $nin: promoCodes
11220
- }
11221
- });
11222
- },
11223
- getOptions: (data) => {
11224
- return data.promotions.map((promotion) => ({
11225
- label: promotion.code,
11226
- value: promotion.code
11227
- }));
11228
- }
11229
- });
11230
- const add = async (value) => {
11231
- if (!value) {
11232
- return;
11233
- }
11234
- addPromotions(
11235
- {
11236
- promo_codes: [value]
11237
- },
11238
- {
11239
- onError: (e) => {
11240
- toast.error(e.message);
11241
- comboboxData.onSearchValueChange("");
11242
- setComboboxValue("");
11243
- },
11244
- onSuccess: () => {
11245
- comboboxData.onSearchValueChange("");
11246
- setComboboxValue("");
11247
- }
11248
- }
11249
- );
11250
- };
10562
+ const uniqueShippingProfiles = useMemo(() => {
10563
+ const profiles = /* @__PURE__ */ new Map();
10564
+ getUniqueShippingProfiles(order.items).forEach((profile) => {
10565
+ profiles.set(profile.id, profile);
10566
+ });
10567
+ shipping_options == null ? void 0 : shipping_options.forEach((option) => {
10568
+ profiles.set(option.shipping_profile_id, option.shipping_profile);
10569
+ });
10570
+ return Array.from(profiles.values());
10571
+ }, [order.items, shipping_options]);
10572
+ const { handleSuccess } = useRouteModal();
11251
10573
  const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
11252
- const { mutateAsync: requestOrderEdit } = useOrderEditRequest(preview.id);
10574
+ const { mutateAsync: requestOrderEdit } = useDraftOrderRequestEdit(preview.id);
10575
+ const { mutateAsync: removeShippingMethod } = useDraftOrderRemoveShippingMethod(preview.id);
10576
+ const { mutateAsync: removeActionShippingMethod } = useDraftOrderRemoveActionShippingMethod(preview.id);
11253
10577
  const onSubmit = async () => {
11254
10578
  setIsSubmitting(true);
11255
10579
  let requestSucceeded = false;
11256
10580
  await requestOrderEdit(void 0, {
11257
10581
  onError: (e) => {
11258
- toast.error(e.message);
10582
+ toast.error(`Failed to request order edit: ${e.message}`);
11259
10583
  },
11260
10584
  onSuccess: () => {
11261
10585
  requestSucceeded = true;
@@ -11267,7 +10591,7 @@ const PromotionForm = ({ preview }) => {
11267
10591
  }
11268
10592
  await confirmOrderEdit(void 0, {
11269
10593
  onError: (e) => {
11270
- toast.error(e.message);
10594
+ toast.error(`Failed to confirm order edit: ${e.message}`);
11271
10595
  },
11272
10596
  onSuccess: () => {
11273
10597
  handleSuccess();
@@ -11277,371 +10601,16 @@ const PromotionForm = ({ preview }) => {
11277
10601
  }
11278
10602
  });
11279
10603
  };
11280
- if (isError) {
11281
- throw error;
11282
- }
11283
- return /* @__PURE__ */ jsxs(KeyboundForm, { className: "flex flex-1 flex-col", onSubmit, children: [
11284
- /* @__PURE__ */ jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-4", children: [
11285
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3", children: [
11286
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
11287
- /* @__PURE__ */ jsx(Label$1, { size: "small", weight: "plus", htmlFor: "promotion-combobox", children: "Apply promotions" }),
11288
- /* @__PURE__ */ jsx(Hint$1, { id: "promotion-combobox-hint", children: "Manage promotions that should be applied to the order." })
11289
- ] }),
11290
- /* @__PURE__ */ jsx(
11291
- Combobox,
11292
- {
11293
- id: "promotion-combobox",
11294
- "aria-describedby": "promotion-combobox-hint",
11295
- isFetchingNextPage: comboboxData.isFetchingNextPage,
11296
- fetchNextPage: comboboxData.fetchNextPage,
11297
- options: comboboxData.options,
11298
- onSearchValueChange: comboboxData.onSearchValueChange,
11299
- searchValue: comboboxData.searchValue,
11300
- disabled: comboboxData.disabled || isAddingPromotions,
11301
- onChange: add,
11302
- value: comboboxValue
11303
- }
11304
- )
11305
- ] }),
11306
- /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
11307
- /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-2", children: promotions == null ? void 0 : promotions.map((promotion) => /* @__PURE__ */ jsx(
11308
- PromotionItem,
11309
- {
11310
- promotion,
11311
- orderId: preview.id,
11312
- isLoading: isPending
11313
- },
11314
- promotion.id
11315
- )) })
11316
- ] }) }),
11317
- /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
11318
- /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
11319
- /* @__PURE__ */ jsx(
11320
- Button,
11321
- {
11322
- size: "small",
11323
- type: "submit",
11324
- isLoading: isSubmitting || isAddingPromotions,
11325
- children: "Save"
11326
- }
11327
- )
11328
- ] }) })
11329
- ] });
11330
- };
11331
- const PromotionItem = ({
11332
- promotion,
11333
- orderId,
11334
- isLoading
11335
- }) => {
11336
- var _a;
11337
- const { mutateAsync: removePromotions, isPending } = useDraftOrderRemovePromotions(orderId);
11338
- const onRemove = async () => {
11339
- removePromotions(
11340
- {
11341
- promo_codes: [promotion.code]
11342
- },
11343
- {
11344
- onError: (e) => {
11345
- toast.error(e.message);
10604
+ const onKeydown = useCallback(
10605
+ (e) => {
10606
+ if (e.key === "Enter" && (e.ctrlKey || e.metaKey)) {
10607
+ if (data || isSubmitting) {
10608
+ return;
11346
10609
  }
10610
+ onSubmit();
11347
10611
  }
11348
- );
11349
- };
11350
- const displayValue = getDisplayValue(promotion);
11351
- return /* @__PURE__ */ jsxs(
11352
- "div",
11353
- {
11354
- className: clx(
11355
- "px-3 py-2 rounded-lg bg-ui-bg-component shadow-elevation-card-rest flex items-center justify-between",
11356
- {
11357
- "animate-pulse": isLoading
11358
- }
11359
- ),
11360
- children: [
11361
- /* @__PURE__ */ jsxs("div", { children: [
11362
- /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: promotion.code }),
11363
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 text-ui-fg-subtle", children: [
11364
- displayValue && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
11365
- /* @__PURE__ */ jsx(Text, { size: "small", leading: "compact", children: displayValue }),
11366
- /* @__PURE__ */ jsx(Text, { size: "small", leading: "compact", children: "·" })
11367
- ] }),
11368
- /* @__PURE__ */ jsx(Text, { size: "small", leading: "compact", className: "capitalize", children: (_a = promotion.application_method) == null ? void 0 : _a.allocation })
11369
- ] })
11370
- ] }),
11371
- /* @__PURE__ */ jsx(
11372
- IconButton,
11373
- {
11374
- size: "small",
11375
- type: "button",
11376
- variant: "transparent",
11377
- onClick: onRemove,
11378
- isLoading: isPending || isLoading,
11379
- children: /* @__PURE__ */ jsx(XMark, {})
11380
- }
11381
- )
11382
- ]
11383
10612
  },
11384
- promotion.id
11385
- );
11386
- };
11387
- function getDisplayValue(promotion) {
11388
- var _a, _b, _c, _d;
11389
- const value = (_a = promotion.application_method) == null ? void 0 : _a.value;
11390
- if (!value) {
11391
- return null;
11392
- }
11393
- if (((_b = promotion.application_method) == null ? void 0 : _b.type) === "fixed") {
11394
- const currency = (_c = promotion.application_method) == null ? void 0 : _c.currency_code;
11395
- if (!currency) {
11396
- return null;
11397
- }
11398
- return getLocaleAmount(value, currency);
11399
- } else if (((_d = promotion.application_method) == null ? void 0 : _d.type) === "percentage") {
11400
- return formatPercentage(value);
11401
- }
11402
- return null;
11403
- }
11404
- const formatter = new Intl.NumberFormat([], {
11405
- style: "percent",
11406
- minimumFractionDigits: 2
11407
- });
11408
- const formatPercentage = (value, isPercentageValue = false) => {
11409
- let val = value || 0;
11410
- if (!isPercentageValue) {
11411
- val = val / 100;
11412
- }
11413
- return formatter.format(val);
11414
- };
11415
- function getPromotionCodes(items, shippingMethods) {
11416
- const codes = /* @__PURE__ */ new Set();
11417
- for (const item of items) {
11418
- if (item.adjustments) {
11419
- for (const adjustment of item.adjustments) {
11420
- if (adjustment.code) {
11421
- codes.add(adjustment.code);
11422
- }
11423
- }
11424
- }
11425
- }
11426
- for (const shippingMethod of shippingMethods) {
11427
- if (shippingMethod.adjustments) {
11428
- for (const adjustment of shippingMethod.adjustments) {
11429
- if (adjustment.code) {
11430
- codes.add(adjustment.code);
11431
- }
11432
- }
11433
- }
11434
- }
11435
- return Array.from(codes);
11436
- }
11437
- const SalesChannel = () => {
11438
- const { id } = useParams();
11439
- const { draft_order, isPending, isError, error } = useDraftOrder(
11440
- id,
11441
- {
11442
- fields: "+sales_channel_id"
11443
- },
11444
- {
11445
- enabled: !!id
11446
- }
11447
- );
11448
- if (isError) {
11449
- throw error;
11450
- }
11451
- const ISrEADY = !!draft_order && !isPending;
11452
- return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
11453
- /* @__PURE__ */ jsxs(RouteDrawer.Header, { children: [
11454
- /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Sales Channel" }) }),
11455
- /* @__PURE__ */ jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Update which sales channel the draft order is associated with" }) })
11456
- ] }),
11457
- ISrEADY && /* @__PURE__ */ jsx(SalesChannelForm, { order: draft_order })
11458
- ] });
11459
- };
11460
- const SalesChannelForm = ({ order }) => {
11461
- const form = useForm({
11462
- defaultValues: {
11463
- sales_channel_id: order.sales_channel_id || ""
11464
- },
11465
- resolver: zodResolver(schema$2)
11466
- });
11467
- const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
11468
- const { handleSuccess } = useRouteModal();
11469
- const onSubmit = form.handleSubmit(async (data) => {
11470
- await mutateAsync(
11471
- {
11472
- sales_channel_id: data.sales_channel_id
11473
- },
11474
- {
11475
- onSuccess: () => {
11476
- toast.success("Sales channel updated");
11477
- handleSuccess();
11478
- },
11479
- onError: (error) => {
11480
- toast.error(error.message);
11481
- }
11482
- }
11483
- );
11484
- });
11485
- return /* @__PURE__ */ jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxs(
11486
- KeyboundForm,
11487
- {
11488
- className: "flex flex-1 flex-col overflow-hidden",
11489
- onSubmit,
11490
- children: [
11491
- /* @__PURE__ */ jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsx(SalesChannelField, { control: form.control, order }) }),
11492
- /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
11493
- /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
11494
- /* @__PURE__ */ jsx(Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
11495
- ] }) })
11496
- ]
11497
- }
11498
- ) });
11499
- };
11500
- const SalesChannelField = ({ control, order }) => {
11501
- const salesChannels = useComboboxData({
11502
- queryFn: async (params) => {
11503
- return await sdk.admin.salesChannel.list(params);
11504
- },
11505
- queryKey: ["sales-channels"],
11506
- getOptions: (data) => {
11507
- return data.sales_channels.map((salesChannel) => ({
11508
- label: salesChannel.name,
11509
- value: salesChannel.id
11510
- }));
11511
- },
11512
- defaultValue: order.sales_channel_id || void 0
11513
- });
11514
- return /* @__PURE__ */ jsx(
11515
- Form$2.Field,
11516
- {
11517
- control,
11518
- name: "sales_channel_id",
11519
- render: ({ field }) => {
11520
- return /* @__PURE__ */ jsxs(Form$2.Item, { children: [
11521
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Sales Channel" }),
11522
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
11523
- Combobox,
11524
- {
11525
- options: salesChannels.options,
11526
- fetchNextPage: salesChannels.fetchNextPage,
11527
- isFetchingNextPage: salesChannels.isFetchingNextPage,
11528
- searchValue: salesChannels.searchValue,
11529
- onSearchValueChange: salesChannels.onSearchValueChange,
11530
- placeholder: "Select sales channel",
11531
- ...field
11532
- }
11533
- ) }),
11534
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11535
- ] });
11536
- }
11537
- }
11538
- );
11539
- };
11540
- const schema$2 = objectType({
11541
- sales_channel_id: stringType().min(1)
11542
- });
11543
- const STACKED_FOCUS_MODAL_ID = "shipping-form";
11544
- const Shipping = () => {
11545
- var _a;
11546
- const { id } = useParams();
11547
- const { order, isPending, isError, error } = useOrder(id, {
11548
- fields: "+items.*,+items.variant.*,+items.variant.product.*,+items.variant.product.shipping_profile.*,+currency_code"
11549
- });
11550
- const {
11551
- order: preview,
11552
- isPending: isPreviewPending,
11553
- isError: isPreviewError,
11554
- error: previewError
11555
- } = useOrderPreview(id);
11556
- useInitiateOrderEdit({ preview });
11557
- const { onCancel } = useCancelOrderEdit({ preview });
11558
- if (isError) {
11559
- throw error;
11560
- }
11561
- if (isPreviewError) {
11562
- throw previewError;
11563
- }
11564
- const orderHasItems = (((_a = order == null ? void 0 : order.items) == null ? void 0 : _a.length) || 0) > 0;
11565
- const isReady = preview && !isPreviewPending && order && !isPending;
11566
- return /* @__PURE__ */ jsx(RouteFocusModal, { onClose: onCancel, children: !orderHasItems ? /* @__PURE__ */ jsxs("div", { className: "flex h-full flex-col overflow-hidden ", children: [
11567
- /* @__PURE__ */ jsx(RouteFocusModal.Header, {}),
11568
- /* @__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: [
11569
- /* @__PURE__ */ jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Shipping" }) }),
11570
- /* @__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." }) })
11571
- ] }) }) }),
11572
- /* @__PURE__ */ jsx(RouteFocusModal.Footer, { children: /* @__PURE__ */ jsx(RouteFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }) })
11573
- ] }) : isReady ? /* @__PURE__ */ jsx(ShippingForm, { preview, order }) : /* @__PURE__ */ jsxs("div", { children: [
11574
- /* @__PURE__ */ jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Edit Shipping" }) }),
11575
- /* @__PURE__ */ jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Loading data for the draft order, please wait..." }) })
11576
- ] }) });
11577
- };
11578
- const ShippingForm = ({ preview, order }) => {
11579
- var _a;
11580
- const { setIsOpen } = useStackedModal();
11581
- const [isSubmitting, setIsSubmitting] = useState(false);
11582
- const [data, setData] = useState(null);
11583
- const appliedShippingOptionIds = (_a = preview.shipping_methods) == null ? void 0 : _a.map((method) => method.shipping_option_id).filter(Boolean);
11584
- const { shipping_options } = useShippingOptions(
11585
- {
11586
- id: appliedShippingOptionIds,
11587
- fields: "+service_zone.*,+service_zone.fulfillment_set.*,+service_zone.fulfillment_set.location.*"
11588
- },
11589
- {
11590
- enabled: appliedShippingOptionIds.length > 0
11591
- }
11592
- );
11593
- const uniqueShippingProfiles = useMemo(() => {
11594
- const profiles = /* @__PURE__ */ new Map();
11595
- getUniqueShippingProfiles(order.items).forEach((profile) => {
11596
- profiles.set(profile.id, profile);
11597
- });
11598
- shipping_options == null ? void 0 : shipping_options.forEach((option) => {
11599
- profiles.set(option.shipping_profile_id, option.shipping_profile);
11600
- });
11601
- return Array.from(profiles.values());
11602
- }, [order.items, shipping_options]);
11603
- const { handleSuccess } = useRouteModal();
11604
- const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
11605
- const { mutateAsync: requestOrderEdit } = useDraftOrderRequestEdit(preview.id);
11606
- const { mutateAsync: removeShippingMethod } = useDraftOrderRemoveShippingMethod(preview.id);
11607
- const { mutateAsync: removeActionShippingMethod } = useDraftOrderRemoveActionShippingMethod(preview.id);
11608
- const onSubmit = async () => {
11609
- setIsSubmitting(true);
11610
- let requestSucceeded = false;
11611
- await requestOrderEdit(void 0, {
11612
- onError: (e) => {
11613
- toast.error(`Failed to request order edit: ${e.message}`);
11614
- },
11615
- onSuccess: () => {
11616
- requestSucceeded = true;
11617
- }
11618
- });
11619
- if (!requestSucceeded) {
11620
- setIsSubmitting(false);
11621
- return;
11622
- }
11623
- await confirmOrderEdit(void 0, {
11624
- onError: (e) => {
11625
- toast.error(`Failed to confirm order edit: ${e.message}`);
11626
- },
11627
- onSuccess: () => {
11628
- handleSuccess();
11629
- },
11630
- onSettled: () => {
11631
- setIsSubmitting(false);
11632
- }
11633
- });
11634
- };
11635
- const onKeydown = useCallback(
11636
- (e) => {
11637
- if (e.key === "Enter" && (e.ctrlKey || e.metaKey)) {
11638
- if (data || isSubmitting) {
11639
- return;
11640
- }
11641
- onSubmit();
11642
- }
11643
- },
11644
- [data, isSubmitting, onSubmit]
10613
+ [data, isSubmitting, onSubmit]
11645
10614
  );
11646
10615
  useEffect(() => {
11647
10616
  document.addEventListener("keydown", onKeydown);
@@ -11847,7 +10816,7 @@ const ShippingForm = ({ preview, order }) => {
11847
10816
  ]
11848
10817
  }
11849
10818
  ) : /* @__PURE__ */ jsx(
11850
- StackedModalTrigger,
10819
+ StackedModalTrigger$1,
11851
10820
  {
11852
10821
  shippingProfileId: profile.id,
11853
10822
  shippingOption,
@@ -11958,7 +10927,7 @@ const ShippingForm = ({ preview, order }) => {
11958
10927
  ] }) })
11959
10928
  ] });
11960
10929
  };
11961
- const StackedModalTrigger = ({
10930
+ const StackedModalTrigger$1 = ({
11962
10931
  shippingProfileId,
11963
10932
  shippingOption,
11964
10933
  shippingMethod,
@@ -12379,7 +11348,7 @@ const ShippingAddressForm = ({ order }) => {
12379
11348
  postal_code: ((_i = order.shipping_address) == null ? void 0 : _i.postal_code) ?? "",
12380
11349
  phone: ((_j = order.shipping_address) == null ? void 0 : _j.phone) ?? ""
12381
11350
  },
12382
- resolver: zodResolver(schema$1)
11351
+ resolver: zodResolver(schema$2)
12383
11352
  });
12384
11353
  const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
12385
11354
  const { handleSuccess } = useRouteModal();
@@ -12549,7 +11518,7 @@ const ShippingAddressForm = ({ order }) => {
12549
11518
  }
12550
11519
  ) });
12551
11520
  };
12552
- const schema$1 = addressSchema;
11521
+ const schema$2 = addressSchema;
12553
11522
  const TransferOwnership = () => {
12554
11523
  const { id } = useParams();
12555
11524
  const { draft_order, isPending, isError, error } = useDraftOrder(id, {
@@ -12573,7 +11542,7 @@ const TransferOwnershipForm = ({ order }) => {
12573
11542
  defaultValues: {
12574
11543
  customer_id: order.customer_id || ""
12575
11544
  },
12576
- resolver: zodResolver(schema)
11545
+ resolver: zodResolver(schema$1)
12577
11546
  });
12578
11547
  const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
12579
11548
  const { handleSuccess } = useRouteModal();
@@ -13003,28 +11972,1059 @@ const Illustration = () => {
13003
11972
  /* @__PURE__ */ jsx("clipPath", { id: "clip4_20915_38670", children: /* @__PURE__ */ jsx(
13004
11973
  "rect",
13005
11974
  {
13006
- width: "12",
13007
- height: "12",
13008
- fill: "white",
13009
- transform: "matrix(0.865865 0.500278 -0.871576 0.490261 131.318 90.4594)"
11975
+ width: "12",
11976
+ height: "12",
11977
+ fill: "white",
11978
+ transform: "matrix(0.865865 0.500278 -0.871576 0.490261 131.318 90.4594)"
11979
+ }
11980
+ ) }),
11981
+ /* @__PURE__ */ jsx("clipPath", { id: "clip5_20915_38670", children: /* @__PURE__ */ jsx(
11982
+ "rect",
11983
+ {
11984
+ width: "12",
11985
+ height: "12",
11986
+ fill: "white",
11987
+ transform: "matrix(0.865865 0.500278 -0.871576 0.490261 141.709 96.4627)"
11988
+ }
11989
+ ) })
11990
+ ] })
11991
+ ]
11992
+ }
11993
+ );
11994
+ };
11995
+ const schema$1 = objectType({
11996
+ customer_id: stringType().min(1)
11997
+ });
11998
+ const SalesChannel = () => {
11999
+ const { id } = useParams();
12000
+ const { draft_order, isPending, isError, error } = useDraftOrder(
12001
+ id,
12002
+ {
12003
+ fields: "+sales_channel_id"
12004
+ },
12005
+ {
12006
+ enabled: !!id
12007
+ }
12008
+ );
12009
+ if (isError) {
12010
+ throw error;
12011
+ }
12012
+ const ISrEADY = !!draft_order && !isPending;
12013
+ return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
12014
+ /* @__PURE__ */ jsxs(RouteDrawer.Header, { children: [
12015
+ /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Sales Channel" }) }),
12016
+ /* @__PURE__ */ jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Update which sales channel the draft order is associated with" }) })
12017
+ ] }),
12018
+ ISrEADY && /* @__PURE__ */ jsx(SalesChannelForm, { order: draft_order })
12019
+ ] });
12020
+ };
12021
+ const SalesChannelForm = ({ order }) => {
12022
+ const form = useForm({
12023
+ defaultValues: {
12024
+ sales_channel_id: order.sales_channel_id || ""
12025
+ },
12026
+ resolver: zodResolver(schema)
12027
+ });
12028
+ const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
12029
+ const { handleSuccess } = useRouteModal();
12030
+ const onSubmit = form.handleSubmit(async (data) => {
12031
+ await mutateAsync(
12032
+ {
12033
+ sales_channel_id: data.sales_channel_id
12034
+ },
12035
+ {
12036
+ onSuccess: () => {
12037
+ toast.success("Sales channel updated");
12038
+ handleSuccess();
12039
+ },
12040
+ onError: (error) => {
12041
+ toast.error(error.message);
12042
+ }
12043
+ }
12044
+ );
12045
+ });
12046
+ return /* @__PURE__ */ jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxs(
12047
+ KeyboundForm,
12048
+ {
12049
+ className: "flex flex-1 flex-col overflow-hidden",
12050
+ onSubmit,
12051
+ children: [
12052
+ /* @__PURE__ */ jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsx(SalesChannelField, { control: form.control, order }) }),
12053
+ /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
12054
+ /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
12055
+ /* @__PURE__ */ jsx(Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
12056
+ ] }) })
12057
+ ]
12058
+ }
12059
+ ) });
12060
+ };
12061
+ const SalesChannelField = ({ control, order }) => {
12062
+ const salesChannels = useComboboxData({
12063
+ queryFn: async (params) => {
12064
+ return await sdk.admin.salesChannel.list(params);
12065
+ },
12066
+ queryKey: ["sales-channels"],
12067
+ getOptions: (data) => {
12068
+ return data.sales_channels.map((salesChannel) => ({
12069
+ label: salesChannel.name,
12070
+ value: salesChannel.id
12071
+ }));
12072
+ },
12073
+ defaultValue: order.sales_channel_id || void 0
12074
+ });
12075
+ return /* @__PURE__ */ jsx(
12076
+ Form$2.Field,
12077
+ {
12078
+ control,
12079
+ name: "sales_channel_id",
12080
+ render: ({ field }) => {
12081
+ return /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12082
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Sales Channel" }),
12083
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
12084
+ Combobox,
12085
+ {
12086
+ options: salesChannels.options,
12087
+ fetchNextPage: salesChannels.fetchNextPage,
12088
+ isFetchingNextPage: salesChannels.isFetchingNextPage,
12089
+ searchValue: salesChannels.searchValue,
12090
+ onSearchValueChange: salesChannels.onSearchValueChange,
12091
+ placeholder: "Select sales channel",
12092
+ ...field
12093
+ }
12094
+ ) }),
12095
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12096
+ ] });
12097
+ }
12098
+ }
12099
+ );
12100
+ };
12101
+ const schema = objectType({
12102
+ sales_channel_id: stringType().min(1)
12103
+ });
12104
+ const NumberInput = forwardRef(
12105
+ ({
12106
+ value,
12107
+ onChange,
12108
+ size = "base",
12109
+ min = 0,
12110
+ max = 100,
12111
+ step = 1,
12112
+ className,
12113
+ disabled,
12114
+ ...props
12115
+ }, ref) => {
12116
+ const handleChange = (event) => {
12117
+ const newValue = event.target.value === "" ? min : Number(event.target.value);
12118
+ if (!isNaN(newValue) && (max === void 0 || newValue <= max) && (min === void 0 || newValue >= min)) {
12119
+ onChange(newValue);
12120
+ }
12121
+ };
12122
+ const handleIncrement = () => {
12123
+ const newValue = value + step;
12124
+ if (max === void 0 || newValue <= max) {
12125
+ onChange(newValue);
12126
+ }
12127
+ };
12128
+ const handleDecrement = () => {
12129
+ const newValue = value - step;
12130
+ if (min === void 0 || newValue >= min) {
12131
+ onChange(newValue);
12132
+ }
12133
+ };
12134
+ return /* @__PURE__ */ jsxs(
12135
+ "div",
12136
+ {
12137
+ className: clx(
12138
+ "inline-flex rounded-md bg-ui-bg-field shadow-borders-base overflow-hidden divide-x transition-fg",
12139
+ "[&:has(input:focus)]:shadow-borders-interactive-with-active",
12140
+ {
12141
+ "h-7": size === "small",
12142
+ "h-8": size === "base"
12143
+ },
12144
+ className
12145
+ ),
12146
+ children: [
12147
+ /* @__PURE__ */ jsx(
12148
+ "input",
12149
+ {
12150
+ ref,
12151
+ type: "number",
12152
+ value,
12153
+ onChange: handleChange,
12154
+ min,
12155
+ max,
12156
+ step,
12157
+ className: clx(
12158
+ "flex-1 px-2 py-1 bg-transparent txt-compact-small text-ui-fg-base outline-none [appearance:textfield]",
12159
+ "[&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none",
12160
+ "placeholder:text-ui-fg-muted"
12161
+ ),
12162
+ ...props
12163
+ }
12164
+ ),
12165
+ /* @__PURE__ */ jsxs(
12166
+ "button",
12167
+ {
12168
+ className: clx(
12169
+ "flex items-center justify-center outline-none transition-fg",
12170
+ "disabled:cursor-not-allowed disabled:text-ui-fg-muted",
12171
+ "focus:bg-ui-bg-field-component-hover",
12172
+ "hover:bg-ui-bg-field-component-hover",
12173
+ {
12174
+ "size-7": size === "small",
12175
+ "size-8": size === "base"
12176
+ }
12177
+ ),
12178
+ type: "button",
12179
+ onClick: handleDecrement,
12180
+ disabled: min !== void 0 && value <= min || disabled,
12181
+ children: [
12182
+ /* @__PURE__ */ jsx(Minus, {}),
12183
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: `Decrease by ${step}` })
12184
+ ]
12185
+ }
12186
+ ),
12187
+ /* @__PURE__ */ jsxs(
12188
+ "button",
12189
+ {
12190
+ className: clx(
12191
+ "flex items-center justify-center outline-none transition-fg",
12192
+ "disabled:cursor-not-allowed disabled:text-ui-fg-muted",
12193
+ "focus:bg-ui-bg-field-hover",
12194
+ "hover:bg-ui-bg-field-hover",
12195
+ {
12196
+ "size-7": size === "small",
12197
+ "size-8": size === "base"
12198
+ }
12199
+ ),
12200
+ type: "button",
12201
+ onClick: handleIncrement,
12202
+ disabled: max !== void 0 && value >= max || disabled,
12203
+ children: [
12204
+ /* @__PURE__ */ jsx(Plus, {}),
12205
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: `Increase by ${step}` })
12206
+ ]
12207
+ }
12208
+ )
12209
+ ]
12210
+ }
12211
+ );
12212
+ }
12213
+ );
12214
+ const PRODUCT_VARIANTS_QUERY_KEY = "product-variants";
12215
+ const productVariantsQueryKeys = {
12216
+ list: (query2) => [
12217
+ PRODUCT_VARIANTS_QUERY_KEY,
12218
+ query2 ? query2 : void 0
12219
+ ]
12220
+ };
12221
+ const useProductVariants = (query2, options) => {
12222
+ const { data, ...rest } = useQuery({
12223
+ queryKey: productVariantsQueryKeys.list(query2),
12224
+ queryFn: async () => await sdk.admin.productVariant.list(query2),
12225
+ ...options
12226
+ });
12227
+ return { ...data, ...rest };
12228
+ };
12229
+ const STACKED_MODAL_ID = "items_stacked_modal";
12230
+ const Items = () => {
12231
+ const { id } = useParams();
12232
+ const {
12233
+ order: preview,
12234
+ isPending: isPreviewPending,
12235
+ isError: isPreviewError,
12236
+ error: previewError
12237
+ } = useOrderPreview(id, void 0, {
12238
+ placeholderData: keepPreviousData
12239
+ });
12240
+ useInitiateOrderEdit({ preview });
12241
+ const { draft_order, isPending, isError, error } = useDraftOrder(
12242
+ id,
12243
+ {
12244
+ fields: "currency_code"
12245
+ },
12246
+ {
12247
+ enabled: !!id
12248
+ }
12249
+ );
12250
+ const { onCancel } = useCancelOrderEdit({ preview });
12251
+ if (isError) {
12252
+ throw error;
12253
+ }
12254
+ if (isPreviewError) {
12255
+ throw previewError;
12256
+ }
12257
+ const ready = !!preview && !isPreviewPending && !!draft_order && !isPending;
12258
+ return /* @__PURE__ */ jsx(RouteFocusModal, { onClose: onCancel, children: ready ? /* @__PURE__ */ jsx(ItemsForm, { preview, currencyCode: draft_order.currency_code }) : /* @__PURE__ */ jsxs("div", { children: [
12259
+ /* @__PURE__ */ jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Edit Items" }) }),
12260
+ /* @__PURE__ */ jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Loading data for the draft order, please wait..." }) })
12261
+ ] }) });
12262
+ };
12263
+ const ItemsForm = ({ preview, currencyCode }) => {
12264
+ var _a;
12265
+ const [isSubmitting, setIsSubmitting] = useState(false);
12266
+ const [modalContent, setModalContent] = useState(
12267
+ null
12268
+ );
12269
+ const { handleSuccess } = useRouteModal();
12270
+ const { searchValue, onSearchValueChange, query: query2 } = useDebouncedSearch();
12271
+ const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
12272
+ const { mutateAsync: requestOrderEdit } = useDraftOrderRequestEdit(preview.id);
12273
+ const itemCount = ((_a = preview.items) == null ? void 0 : _a.reduce((acc, item) => acc + item.quantity, 0)) || 0;
12274
+ const matches = useMemo(() => {
12275
+ return matchSorter(preview.items, query2, {
12276
+ keys: ["product_title", "variant_title", "variant_sku", "title"]
12277
+ });
12278
+ }, [preview.items, query2]);
12279
+ const onSubmit = async () => {
12280
+ setIsSubmitting(true);
12281
+ let requestSucceeded = false;
12282
+ await requestOrderEdit(void 0, {
12283
+ onError: (e) => {
12284
+ toast.error(`Failed to request order edit: ${e.message}`);
12285
+ },
12286
+ onSuccess: () => {
12287
+ requestSucceeded = true;
12288
+ }
12289
+ });
12290
+ if (!requestSucceeded) {
12291
+ setIsSubmitting(false);
12292
+ return;
12293
+ }
12294
+ await confirmOrderEdit(void 0, {
12295
+ onError: (e) => {
12296
+ toast.error(`Failed to confirm order edit: ${e.message}`);
12297
+ },
12298
+ onSuccess: () => {
12299
+ handleSuccess();
12300
+ },
12301
+ onSettled: () => {
12302
+ setIsSubmitting(false);
12303
+ }
12304
+ });
12305
+ };
12306
+ const onKeyDown = useCallback(
12307
+ (e) => {
12308
+ if (e.key === "Enter" && (e.ctrlKey || e.metaKey)) {
12309
+ if (modalContent || isSubmitting) {
12310
+ return;
12311
+ }
12312
+ onSubmit();
12313
+ }
12314
+ },
12315
+ [modalContent, isSubmitting, onSubmit]
12316
+ );
12317
+ useEffect(() => {
12318
+ document.addEventListener("keydown", onKeyDown);
12319
+ return () => {
12320
+ document.removeEventListener("keydown", onKeyDown);
12321
+ };
12322
+ }, [onKeyDown]);
12323
+ return /* @__PURE__ */ jsxs("div", { className: "flex h-full flex-col overflow-hidden", children: [
12324
+ /* @__PURE__ */ jsx(RouteFocusModal.Header, {}),
12325
+ /* @__PURE__ */ jsx(RouteFocusModal.Body, { className: "flex flex-1 flex-col overflow-hidden", children: /* @__PURE__ */ jsxs(
12326
+ StackedFocusModal,
12327
+ {
12328
+ id: STACKED_MODAL_ID,
12329
+ onOpenChangeCallback: (open) => {
12330
+ if (!open) {
12331
+ setModalContent(null);
12332
+ }
12333
+ },
12334
+ children: [
12335
+ /* @__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: [
12336
+ /* @__PURE__ */ jsxs("div", { children: [
12337
+ /* @__PURE__ */ jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Items" }) }),
12338
+ /* @__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." }) })
12339
+ ] }),
12340
+ /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
12341
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-y-6", children: [
12342
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 items-center gap-3", children: [
12343
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
12344
+ /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: "Items" }),
12345
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Choose items from the product catalog." })
12346
+ ] }),
12347
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
12348
+ /* @__PURE__ */ jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsx(
12349
+ Input,
12350
+ {
12351
+ type: "search",
12352
+ placeholder: "Search items",
12353
+ value: searchValue,
12354
+ onChange: (e) => onSearchValueChange(e.target.value)
12355
+ }
12356
+ ) }),
12357
+ /* @__PURE__ */ jsxs(DropdownMenu, { children: [
12358
+ /* @__PURE__ */ jsx(DropdownMenu.Trigger, { asChild: true, children: /* @__PURE__ */ jsx(IconButton, { type: "button", children: /* @__PURE__ */ jsx(Plus, {}) }) }),
12359
+ /* @__PURE__ */ jsxs(DropdownMenu.Content, { children: [
12360
+ /* @__PURE__ */ jsx(
12361
+ StackedModalTrigger,
12362
+ {
12363
+ type: "add-items",
12364
+ setModalContent
12365
+ }
12366
+ ),
12367
+ /* @__PURE__ */ jsx(
12368
+ StackedModalTrigger,
12369
+ {
12370
+ type: "add-custom-item",
12371
+ setModalContent
12372
+ }
12373
+ )
12374
+ ] })
12375
+ ] })
12376
+ ] })
12377
+ ] }),
12378
+ /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-subtle shadow-elevation-card-rest rounded-xl", children: [
12379
+ /* @__PURE__ */ jsx("div", { className: "px-[5px]", children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-[1fr_1fr_1fr_28px] gap-3 px-4 py-2 text-ui-fg-muted", children: [
12380
+ /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: "Item" }) }),
12381
+ /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: "Quantity" }) }),
12382
+ /* @__PURE__ */ jsx("div", { className: "text-right", children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: "Price" }) }),
12383
+ /* @__PURE__ */ jsx("div", {})
12384
+ ] }) }),
12385
+ /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-y-1.5 px-[5px] pb-[5px]", children: itemCount <= 0 ? /* @__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: [
12386
+ /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: "There are no items in this order" }),
12387
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Add items to the order to get started." })
12388
+ ] }) : matches.length > 0 ? matches == null ? void 0 : matches.map((item) => /* @__PURE__ */ jsx(
12389
+ Item,
12390
+ {
12391
+ item,
12392
+ preview,
12393
+ currencyCode
12394
+ },
12395
+ item.id
12396
+ )) : /* @__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: [
12397
+ /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: "No items found" }),
12398
+ /* @__PURE__ */ jsxs(Text, { size: "small", className: "text-ui-fg-subtle", children: [
12399
+ 'No items found for "',
12400
+ query2,
12401
+ '".'
12402
+ ] })
12403
+ ] }) })
12404
+ ] })
12405
+ ] }),
12406
+ /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
12407
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-[1fr_0.5fr_0.5fr] gap-3", children: [
12408
+ /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: "Subtotal" }) }),
12409
+ /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsxs(
12410
+ Text,
12411
+ {
12412
+ size: "small",
12413
+ leading: "compact",
12414
+ className: "text-ui-fg-subtle",
12415
+ children: [
12416
+ itemCount,
12417
+ " ",
12418
+ itemCount === 1 ? "item" : "items"
12419
+ ]
12420
+ }
12421
+ ) }),
12422
+ /* @__PURE__ */ jsx("div", { className: "text-right", children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: getStylizedAmount(preview.item_subtotal, currencyCode) }) })
12423
+ ] })
12424
+ ] }) }),
12425
+ modalContent && (modalContent === "add-items" ? /* @__PURE__ */ jsx(ExistingItemsForm, { orderId: preview.id, items: preview.items }) : modalContent === "add-custom-item" ? /* @__PURE__ */ jsx(
12426
+ CustomItemForm,
12427
+ {
12428
+ orderId: preview.id,
12429
+ currencyCode
12430
+ }
12431
+ ) : null)
12432
+ ]
12433
+ }
12434
+ ) }),
12435
+ /* @__PURE__ */ jsx(RouteFocusModal.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-2 justify-end", children: [
12436
+ /* @__PURE__ */ jsx(RouteFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
12437
+ /* @__PURE__ */ jsx(
12438
+ Button,
12439
+ {
12440
+ size: "small",
12441
+ type: "button",
12442
+ onClick: onSubmit,
12443
+ isLoading: isSubmitting,
12444
+ children: "Save"
12445
+ }
12446
+ )
12447
+ ] }) })
12448
+ ] });
12449
+ };
12450
+ const Item = ({ item, preview, currencyCode }) => {
12451
+ if (item.variant_id) {
12452
+ return /* @__PURE__ */ jsx(VariantItem, { item, preview, currencyCode });
12453
+ }
12454
+ return /* @__PURE__ */ jsx(CustomItem, { item, preview, currencyCode });
12455
+ };
12456
+ const VariantItem = ({ item, preview, currencyCode }) => {
12457
+ const [editing, setEditing] = useState(false);
12458
+ const form = useForm({
12459
+ defaultValues: {
12460
+ quantity: item.quantity,
12461
+ unit_price: item.unit_price
12462
+ },
12463
+ resolver: zodResolver(variantItemSchema)
12464
+ });
12465
+ const actionId = useMemo(() => {
12466
+ var _a, _b;
12467
+ return (_b = (_a = item.actions) == null ? void 0 : _a.find((a) => a.action === "ITEM_ADD")) == null ? void 0 : _b.id;
12468
+ }, [item]);
12469
+ const { mutateAsync: updateActionItem, isPending: isUpdatingActionItem } = useDraftOrderUpdateActionItem(preview.id);
12470
+ const { mutateAsync: updateOriginalItem, isPending: isUpdatingOriginalItem } = useDraftOrderUpdateItem(preview.id);
12471
+ const isPending = isUpdatingActionItem || isUpdatingOriginalItem;
12472
+ const onSubmit = form.handleSubmit(async (data) => {
12473
+ if (convertNumber(data.unit_price) === item.unit_price && data.quantity === item.quantity) {
12474
+ setEditing(false);
12475
+ return;
12476
+ }
12477
+ if (!actionId) {
12478
+ await updateOriginalItem(
12479
+ {
12480
+ item_id: item.id,
12481
+ quantity: data.quantity,
12482
+ unit_price: convertNumber(data.unit_price)
12483
+ },
12484
+ {
12485
+ onSuccess: () => {
12486
+ setEditing(false);
12487
+ },
12488
+ onError: (e) => {
12489
+ toast.error(e.message);
12490
+ }
12491
+ }
12492
+ );
12493
+ return;
12494
+ }
12495
+ await updateActionItem(
12496
+ {
12497
+ action_id: actionId,
12498
+ quantity: data.quantity,
12499
+ unit_price: convertNumber(data.unit_price)
12500
+ },
12501
+ {
12502
+ onSuccess: () => {
12503
+ setEditing(false);
12504
+ },
12505
+ onError: (e) => {
12506
+ toast.error(e.message);
12507
+ }
12508
+ }
12509
+ );
12510
+ });
12511
+ return /* @__PURE__ */ jsx(Form$2, { ...form, children: /* @__PURE__ */ jsx("form", { onSubmit, children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-[minmax(0,1fr)_minmax(0,1fr)_minmax(0,1fr)_28px] gap-3 px-4 py-2 bg-ui-bg-base shadow-elevation-card-rest rounded-lg items-center", children: [
12512
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-3 w-full", children: [
12513
+ /* @__PURE__ */ jsx(
12514
+ Thumbnail,
12515
+ {
12516
+ thumbnail: item.thumbnail,
12517
+ alt: item.product_title ?? void 0
12518
+ }
12519
+ ),
12520
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
12521
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-1", children: [
12522
+ /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: item.product_title }),
12523
+ /* @__PURE__ */ jsxs(
12524
+ Text,
12525
+ {
12526
+ size: "small",
12527
+ leading: "compact",
12528
+ className: "text-ui-fg-subtle",
12529
+ children: [
12530
+ "(",
12531
+ item.variant_title,
12532
+ ")"
12533
+ ]
12534
+ }
12535
+ )
12536
+ ] }),
12537
+ /* @__PURE__ */ jsx(
12538
+ Text,
12539
+ {
12540
+ size: "small",
12541
+ leading: "compact",
12542
+ className: "text-ui-fg-subtle",
12543
+ children: item.variant_sku
12544
+ }
12545
+ )
12546
+ ] })
12547
+ ] }),
12548
+ editing ? /* @__PURE__ */ jsx("div", { className: "flex-1 w-full", children: /* @__PURE__ */ jsx(
12549
+ Form$2.Field,
12550
+ {
12551
+ control: form.control,
12552
+ name: "quantity",
12553
+ render: ({ field }) => {
12554
+ return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(NumberInput, { ...field }) }) });
12555
+ }
12556
+ }
12557
+ ) }) : /* @__PURE__ */ jsx("div", { className: "flex-1 w-full", children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: item.quantity }) }),
12558
+ editing ? /* @__PURE__ */ jsx("div", { className: "flex-1 w-full", children: /* @__PURE__ */ jsx(
12559
+ Form$2.Field,
12560
+ {
12561
+ control: form.control,
12562
+ name: "unit_price",
12563
+ render: ({ field: { onChange, ...field } }) => {
12564
+ return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
12565
+ CurrencyInput,
12566
+ {
12567
+ ...field,
12568
+ symbol: getNativeSymbol(currencyCode),
12569
+ code: currencyCode,
12570
+ onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value)
12571
+ }
12572
+ ) }) });
12573
+ }
12574
+ }
12575
+ ) }) : /* @__PURE__ */ jsx("div", { className: "flex-1 flex items-center justify-end w-full", children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: getLocaleAmount(item.unit_price, currencyCode) }) }),
12576
+ /* @__PURE__ */ jsx(
12577
+ IconButton,
12578
+ {
12579
+ type: "button",
12580
+ size: "small",
12581
+ onClick: editing ? onSubmit : () => {
12582
+ setEditing(true);
12583
+ },
12584
+ disabled: isPending,
12585
+ children: editing ? /* @__PURE__ */ jsx(Check, {}) : /* @__PURE__ */ jsx(PencilSquare, {})
12586
+ }
12587
+ )
12588
+ ] }) }) });
12589
+ };
12590
+ const variantItemSchema = objectType({
12591
+ quantity: numberType(),
12592
+ unit_price: unionType([numberType(), stringType()])
12593
+ });
12594
+ const CustomItem = ({ item, preview, currencyCode }) => {
12595
+ const [editing, setEditing] = useState(false);
12596
+ const { quantity, unit_price, title } = item;
12597
+ const form = useForm({
12598
+ defaultValues: {
12599
+ title,
12600
+ quantity,
12601
+ unit_price
12602
+ },
12603
+ resolver: zodResolver(customItemSchema)
12604
+ });
12605
+ useEffect(() => {
12606
+ form.reset({
12607
+ title,
12608
+ quantity,
12609
+ unit_price
12610
+ });
12611
+ }, [form, title, quantity, unit_price]);
12612
+ const actionId = useMemo(() => {
12613
+ var _a, _b;
12614
+ return (_b = (_a = item.actions) == null ? void 0 : _a.find((a) => a.action === "ITEM_ADD")) == null ? void 0 : _b.id;
12615
+ }, [item]);
12616
+ const { mutateAsync: updateActionItem, isPending: isUpdatingActionItem } = useDraftOrderUpdateActionItem(preview.id);
12617
+ const { mutateAsync: removeActionItem, isPending: isRemovingActionItem } = useDraftOrderRemoveActionItem(preview.id);
12618
+ const { mutateAsync: updateOriginalItem, isPending: isUpdatingOriginalItem } = useDraftOrderUpdateItem(preview.id);
12619
+ const isPending = isUpdatingActionItem || isUpdatingOriginalItem;
12620
+ const onSubmit = form.handleSubmit(async (data) => {
12621
+ if (convertNumber(data.unit_price) === item.unit_price && data.quantity === item.quantity && data.title === item.title) {
12622
+ setEditing(false);
12623
+ return;
12624
+ }
12625
+ if (!actionId) {
12626
+ await updateOriginalItem(
12627
+ {
12628
+ item_id: item.id,
12629
+ quantity: data.quantity,
12630
+ unit_price: convertNumber(data.unit_price)
12631
+ },
12632
+ {
12633
+ onSuccess: () => {
12634
+ setEditing(false);
12635
+ },
12636
+ onError: (e) => {
12637
+ toast.error(e.message);
12638
+ }
12639
+ }
12640
+ );
12641
+ return;
12642
+ }
12643
+ if (data.quantity === 0) {
12644
+ await removeActionItem(actionId, {
12645
+ onSuccess: () => {
12646
+ setEditing(false);
12647
+ },
12648
+ onError: (e) => {
12649
+ toast.error(e.message);
12650
+ }
12651
+ });
12652
+ return;
12653
+ }
12654
+ await updateActionItem(
12655
+ {
12656
+ action_id: actionId,
12657
+ quantity: data.quantity,
12658
+ unit_price: convertNumber(data.unit_price)
12659
+ },
12660
+ {
12661
+ onSuccess: () => {
12662
+ setEditing(false);
12663
+ },
12664
+ onError: (e) => {
12665
+ toast.error(e.message);
12666
+ }
12667
+ }
12668
+ );
12669
+ });
12670
+ return /* @__PURE__ */ jsx(Form$2, { ...form, children: /* @__PURE__ */ jsx("form", { onSubmit, children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-[minmax(0,1fr)_minmax(0,1fr)_minmax(0,1fr)_28px] gap-3 px-4 py-2 bg-ui-bg-base shadow-elevation-card-rest rounded-lg items-center", children: [
12671
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-3", children: [
12672
+ /* @__PURE__ */ jsx(
12673
+ Thumbnail,
12674
+ {
12675
+ thumbnail: item.thumbnail,
12676
+ alt: item.title ?? void 0
12677
+ }
12678
+ ),
12679
+ editing ? /* @__PURE__ */ jsx(
12680
+ Form$2.Field,
12681
+ {
12682
+ control: form.control,
12683
+ name: "title",
12684
+ render: ({ field }) => {
12685
+ return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }) });
12686
+ }
12687
+ }
12688
+ ) : /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: item.title })
12689
+ ] }),
12690
+ editing ? /* @__PURE__ */ jsx(
12691
+ Form$2.Field,
12692
+ {
12693
+ control: form.control,
12694
+ name: "quantity",
12695
+ render: ({ field }) => {
12696
+ return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(NumberInput, { ...field }) }) });
12697
+ }
12698
+ }
12699
+ ) : /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: item.quantity }),
12700
+ editing ? /* @__PURE__ */ jsx(
12701
+ Form$2.Field,
12702
+ {
12703
+ control: form.control,
12704
+ name: "unit_price",
12705
+ render: ({ field: { onChange, ...field } }) => {
12706
+ return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
12707
+ CurrencyInput,
12708
+ {
12709
+ ...field,
12710
+ symbol: getNativeSymbol(currencyCode),
12711
+ code: currencyCode,
12712
+ onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value)
12713
+ }
12714
+ ) }) });
12715
+ }
12716
+ }
12717
+ ) : /* @__PURE__ */ jsx("div", { className: "flex-1 flex items-center justify-end", children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: getLocaleAmount(item.unit_price, currencyCode) }) }),
12718
+ /* @__PURE__ */ jsx(
12719
+ IconButton,
12720
+ {
12721
+ type: "button",
12722
+ size: "small",
12723
+ onClick: editing ? onSubmit : () => {
12724
+ setEditing(true);
12725
+ },
12726
+ disabled: isPending,
12727
+ children: editing ? /* @__PURE__ */ jsx(Check, {}) : /* @__PURE__ */ jsx(PencilSquare, {})
12728
+ }
12729
+ )
12730
+ ] }) }) });
12731
+ };
12732
+ const StackedModalTrigger = ({
12733
+ type,
12734
+ setModalContent
12735
+ }) => {
12736
+ const { setIsOpen } = useStackedModal();
12737
+ const onClick = useCallback(() => {
12738
+ setModalContent(type);
12739
+ setIsOpen(STACKED_MODAL_ID, true);
12740
+ }, [setModalContent, setIsOpen, type]);
12741
+ return /* @__PURE__ */ jsx(StackedFocusModal.Trigger, { asChild: true, children: /* @__PURE__ */ jsx(DropdownMenu.Item, { onClick, children: type === "add-items" ? "Add items" : "Add custom item" }) });
12742
+ };
12743
+ const VARIANT_PREFIX = "items";
12744
+ const LIMIT = 50;
12745
+ const ExistingItemsForm = ({ orderId, items }) => {
12746
+ const { setIsOpen } = useStackedModal();
12747
+ const [rowSelection, setRowSelection] = useState(
12748
+ items.reduce((acc, item) => {
12749
+ acc[item.variant_id] = true;
12750
+ return acc;
12751
+ }, {})
12752
+ );
12753
+ useEffect(() => {
12754
+ setRowSelection(
12755
+ items.reduce((acc, item) => {
12756
+ if (item.variant_id) {
12757
+ acc[item.variant_id] = true;
12758
+ }
12759
+ return acc;
12760
+ }, {})
12761
+ );
12762
+ }, [items]);
12763
+ const { q, order, offset } = useQueryParams(
12764
+ ["q", "order", "offset"],
12765
+ VARIANT_PREFIX
12766
+ );
12767
+ const { variants, count, isPending, isError, error } = useProductVariants(
12768
+ {
12769
+ q,
12770
+ order,
12771
+ offset: offset ? parseInt(offset) : void 0,
12772
+ limit: LIMIT
12773
+ },
12774
+ {
12775
+ placeholderData: keepPreviousData
12776
+ }
12777
+ );
12778
+ const columns = useColumns();
12779
+ const { mutateAsync } = useDraftOrderAddItems(orderId);
12780
+ const onSubmit = async () => {
12781
+ const ids = Object.keys(rowSelection).filter(
12782
+ (id) => !items.find((i) => i.variant_id === id)
12783
+ );
12784
+ await mutateAsync(
12785
+ {
12786
+ items: ids.map((id) => ({
12787
+ variant_id: id,
12788
+ quantity: 1
12789
+ }))
12790
+ },
12791
+ {
12792
+ onSuccess: () => {
12793
+ setRowSelection({});
12794
+ setIsOpen(STACKED_MODAL_ID, false);
12795
+ },
12796
+ onError: (e) => {
12797
+ toast.error(e.message);
12798
+ }
12799
+ }
12800
+ );
12801
+ };
12802
+ if (isError) {
12803
+ throw error;
12804
+ }
12805
+ return /* @__PURE__ */ jsxs(
12806
+ StackedFocusModal.Content,
12807
+ {
12808
+ onOpenAutoFocus: (e) => {
12809
+ e.preventDefault();
12810
+ const searchInput = document.querySelector(
12811
+ "[data-modal-id='modal-search-input']"
12812
+ );
12813
+ if (searchInput) {
12814
+ searchInput.focus();
12815
+ }
12816
+ },
12817
+ children: [
12818
+ /* @__PURE__ */ jsxs(StackedFocusModal.Header, { children: [
12819
+ /* @__PURE__ */ jsx(StackedFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Product Variants" }) }),
12820
+ /* @__PURE__ */ jsx(StackedFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Choose product variants to add to the order." }) })
12821
+ ] }),
12822
+ /* @__PURE__ */ jsx(StackedFocusModal.Body, { className: "flex-1 overflow-hidden", children: /* @__PURE__ */ jsx(
12823
+ DataTable,
12824
+ {
12825
+ data: variants,
12826
+ columns,
12827
+ isLoading: isPending,
12828
+ getRowId: (row) => row.id,
12829
+ rowCount: count,
12830
+ prefix: VARIANT_PREFIX,
12831
+ layout: "fill",
12832
+ rowSelection: {
12833
+ state: rowSelection,
12834
+ onRowSelectionChange: setRowSelection,
12835
+ enableRowSelection: (row) => {
12836
+ return !items.find((i) => i.variant_id === row.original.id);
12837
+ }
12838
+ },
12839
+ autoFocusSearch: true
12840
+ }
12841
+ ) }),
12842
+ /* @__PURE__ */ jsx(StackedFocusModal.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-2 justify-end", children: [
12843
+ /* @__PURE__ */ jsx(StackedFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
12844
+ /* @__PURE__ */ jsx(Button, { size: "small", type: "button", onClick: onSubmit, children: "Update items" })
12845
+ ] }) })
12846
+ ]
12847
+ }
12848
+ );
12849
+ };
12850
+ const columnHelper = createDataTableColumnHelper();
12851
+ const useColumns = () => {
12852
+ return useMemo(() => {
12853
+ return [
12854
+ columnHelper.select(),
12855
+ columnHelper.accessor("product.title", {
12856
+ header: "Product",
12857
+ cell: ({ row }) => {
12858
+ var _a, _b, _c;
12859
+ return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-2", children: [
12860
+ /* @__PURE__ */ jsx(
12861
+ Thumbnail,
12862
+ {
12863
+ thumbnail: (_a = row.original.product) == null ? void 0 : _a.thumbnail,
12864
+ alt: (_b = row.original.product) == null ? void 0 : _b.title
12865
+ }
12866
+ ),
12867
+ /* @__PURE__ */ jsx("span", { children: (_c = row.original.product) == null ? void 0 : _c.title })
12868
+ ] });
12869
+ },
12870
+ enableSorting: true
12871
+ }),
12872
+ columnHelper.accessor("title", {
12873
+ header: "Variant",
12874
+ enableSorting: true
12875
+ }),
12876
+ columnHelper.accessor("sku", {
12877
+ header: "SKU",
12878
+ cell: ({ getValue }) => {
12879
+ return getValue() ?? "-";
12880
+ },
12881
+ enableSorting: true
12882
+ }),
12883
+ columnHelper.accessor("updated_at", {
12884
+ header: "Updated",
12885
+ cell: ({ getValue }) => {
12886
+ return /* @__PURE__ */ jsx(
12887
+ Tooltip,
12888
+ {
12889
+ content: getFullDate({ date: getValue(), includeTime: true }),
12890
+ children: /* @__PURE__ */ jsx("span", { children: getFullDate({ date: getValue() }) })
13010
12891
  }
13011
- ) }),
13012
- /* @__PURE__ */ jsx("clipPath", { id: "clip5_20915_38670", children: /* @__PURE__ */ jsx(
13013
- "rect",
12892
+ );
12893
+ },
12894
+ enableSorting: true,
12895
+ sortAscLabel: "Oldest first",
12896
+ sortDescLabel: "Newest first"
12897
+ }),
12898
+ columnHelper.accessor("created_at", {
12899
+ header: "Created",
12900
+ cell: ({ getValue }) => {
12901
+ return /* @__PURE__ */ jsx(
12902
+ Tooltip,
13014
12903
  {
13015
- width: "12",
13016
- height: "12",
13017
- fill: "white",
13018
- transform: "matrix(0.865865 0.500278 -0.871576 0.490261 141.709 96.4627)"
12904
+ content: getFullDate({ date: getValue(), includeTime: true }),
12905
+ children: /* @__PURE__ */ jsx("span", { children: getFullDate({ date: getValue() }) })
13019
12906
  }
13020
- ) })
13021
- ] })
13022
- ]
13023
- }
13024
- );
12907
+ );
12908
+ },
12909
+ enableSorting: true,
12910
+ sortAscLabel: "Oldest first",
12911
+ sortDescLabel: "Newest first"
12912
+ })
12913
+ ];
12914
+ }, []);
13025
12915
  };
13026
- const schema = objectType({
13027
- customer_id: stringType().min(1)
12916
+ const CustomItemForm = ({ orderId, currencyCode }) => {
12917
+ const { setIsOpen } = useStackedModal();
12918
+ const { mutateAsync: addItems } = useDraftOrderAddItems(orderId);
12919
+ const form = useForm({
12920
+ defaultValues: {
12921
+ title: "",
12922
+ quantity: 1,
12923
+ unit_price: ""
12924
+ },
12925
+ resolver: zodResolver(customItemSchema)
12926
+ });
12927
+ const onSubmit = form.handleSubmit(async (data) => {
12928
+ await addItems(
12929
+ {
12930
+ items: [
12931
+ {
12932
+ title: data.title,
12933
+ quantity: data.quantity,
12934
+ unit_price: convertNumber(data.unit_price)
12935
+ }
12936
+ ]
12937
+ },
12938
+ {
12939
+ onSuccess: () => {
12940
+ setIsOpen(STACKED_MODAL_ID, false);
12941
+ },
12942
+ onError: (e) => {
12943
+ toast.error(e.message);
12944
+ }
12945
+ }
12946
+ );
12947
+ });
12948
+ return /* @__PURE__ */ jsx(Form$2, { ...form, children: /* @__PURE__ */ jsx(KeyboundForm, { onSubmit, children: /* @__PURE__ */ jsxs(StackedFocusModal.Content, { children: [
12949
+ /* @__PURE__ */ jsx(StackedFocusModal.Header, {}),
12950
+ /* @__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: [
12951
+ /* @__PURE__ */ jsxs("div", { children: [
12952
+ /* @__PURE__ */ jsx(StackedFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Add custom item" }) }),
12953
+ /* @__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." }) })
12954
+ ] }),
12955
+ /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
12956
+ /* @__PURE__ */ jsx(
12957
+ Form$2.Field,
12958
+ {
12959
+ control: form.control,
12960
+ name: "title",
12961
+ render: ({ field }) => /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
12962
+ /* @__PURE__ */ jsxs("div", { children: [
12963
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Title" }),
12964
+ /* @__PURE__ */ jsx(Form$2.Hint, { children: "Enter the title of the item" })
12965
+ ] }),
12966
+ /* @__PURE__ */ jsxs("div", { children: [
12967
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12968
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12969
+ ] })
12970
+ ] }) })
12971
+ }
12972
+ ),
12973
+ /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
12974
+ /* @__PURE__ */ jsx(
12975
+ Form$2.Field,
12976
+ {
12977
+ control: form.control,
12978
+ name: "unit_price",
12979
+ render: ({ field: { onChange, ...field } }) => /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
12980
+ /* @__PURE__ */ jsxs("div", { children: [
12981
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Unit price" }),
12982
+ /* @__PURE__ */ jsx(Form$2.Hint, { children: "Enter the unit price of the item" })
12983
+ ] }),
12984
+ /* @__PURE__ */ jsxs("div", { children: [
12985
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
12986
+ CurrencyInput,
12987
+ {
12988
+ symbol: getNativeSymbol(currencyCode),
12989
+ code: currencyCode,
12990
+ onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value),
12991
+ ...field
12992
+ }
12993
+ ) }),
12994
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12995
+ ] })
12996
+ ] }) })
12997
+ }
12998
+ ),
12999
+ /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
13000
+ /* @__PURE__ */ jsx(
13001
+ Form$2.Field,
13002
+ {
13003
+ control: form.control,
13004
+ name: "quantity",
13005
+ render: ({ field }) => /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
13006
+ /* @__PURE__ */ jsxs("div", { children: [
13007
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Quantity" }),
13008
+ /* @__PURE__ */ jsx(Form$2.Hint, { children: "Enter the quantity of the item" })
13009
+ ] }),
13010
+ /* @__PURE__ */ jsxs("div", { className: "flex-1 w-full", children: [
13011
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx("div", { className: "flex-1 w-full", children: /* @__PURE__ */ jsx(NumberInput, { ...field, className: "w-full" }) }) }),
13012
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
13013
+ ] })
13014
+ ] }) })
13015
+ }
13016
+ )
13017
+ ] }) }) }),
13018
+ /* @__PURE__ */ jsx(StackedFocusModal.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-2 justify-end", children: [
13019
+ /* @__PURE__ */ jsx(StackedFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
13020
+ /* @__PURE__ */ jsx(Button, { size: "small", type: "button", onClick: onSubmit, children: "Add item" })
13021
+ ] }) })
13022
+ ] }) }) });
13023
+ };
13024
+ const customItemSchema = objectType({
13025
+ title: stringType().min(1),
13026
+ quantity: numberType(),
13027
+ unit_price: unionType([numberType(), stringType()])
13028
13028
  });
13029
13029
  const widgetModule = { widgets: [] };
13030
13030
  const routeModule = {
@@ -13058,21 +13058,13 @@ const routeModule = {
13058
13058
  Component: Email,
13059
13059
  path: "/draft-orders/:id/email"
13060
13060
  },
13061
- {
13062
- Component: Items,
13063
- path: "/draft-orders/:id/items"
13064
- },
13065
- {
13066
- Component: Metadata,
13067
- path: "/draft-orders/:id/metadata"
13068
- },
13069
13061
  {
13070
13062
  Component: Promotions,
13071
13063
  path: "/draft-orders/:id/promotions"
13072
13064
  },
13073
13065
  {
13074
- Component: SalesChannel,
13075
- path: "/draft-orders/:id/sales-channel"
13066
+ Component: Metadata,
13067
+ path: "/draft-orders/:id/metadata"
13076
13068
  },
13077
13069
  {
13078
13070
  Component: Shipping,
@@ -13085,6 +13077,14 @@ const routeModule = {
13085
13077
  {
13086
13078
  Component: TransferOwnership,
13087
13079
  path: "/draft-orders/:id/transfer-ownership"
13080
+ },
13081
+ {
13082
+ Component: SalesChannel,
13083
+ path: "/draft-orders/:id/sales-channel"
13084
+ },
13085
+ {
13086
+ Component: Items,
13087
+ path: "/draft-orders/:id/items"
13088
13088
  }
13089
13089
  ]
13090
13090
  }