@medusajs/draft-order 2.10.2-snapshot-20250904142832 → 2.10.2-snapshot-20250905121828

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";
@@ -7567,12 +7567,12 @@ const addressSchema = objectType({
7567
7567
  first_name: stringType().min(1),
7568
7568
  last_name: stringType().min(1),
7569
7569
  address_1: stringType().min(1),
7570
- address_2: stringType().optional(),
7571
- company: stringType().optional(),
7570
+ address_2: stringType().nullish(),
7571
+ company: stringType().nullish(),
7572
7572
  city: stringType().min(1),
7573
- province: stringType().optional(),
7573
+ province: stringType().nullish(),
7574
7574
  postal_code: stringType().min(1),
7575
- phone: stringType().optional()
7575
+ phone: stringType().nullish()
7576
7576
  });
7577
7577
  const Create = () => {
7578
7578
  return /* @__PURE__ */ jsx(RouteFocusModal, { children: /* @__PURE__ */ jsx(CreateForm, {}) });
@@ -8322,7 +8322,7 @@ const ActivitySection = ({ order, changes }) => {
8322
8322
  () => getActivityItems(order, changes),
8323
8323
  [order, changes]
8324
8324
  );
8325
- return /* @__PURE__ */ jsxs(Container, { className: "p-0 overflow-hidden", children: [
8325
+ return /* @__PURE__ */ jsxs(Container, { className: "overflow-hidden p-0", children: [
8326
8326
  /* @__PURE__ */ jsx("div", { className: "px-6 py-4", children: /* @__PURE__ */ jsx(Heading, { children: "Activity" }) }),
8327
8327
  /* @__PURE__ */ jsx(ActivityItemList, { items: activityItems })
8328
8328
  ] });
@@ -8353,8 +8353,8 @@ const CollapsibleActivityItemList = ({
8353
8353
  const [open, setOpen] = useState(false);
8354
8354
  return /* @__PURE__ */ jsxs(Collapsible.Root, { open, onOpenChange: setOpen, children: [
8355
8355
  !open && /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-[20px_1fr] items-start gap-2", children: [
8356
- /* @__PURE__ */ jsx("div", { className: "flex size-full flex-col items-center", children: /* @__PURE__ */ jsx("div", { className: "border-ui-border-strong w-px flex-1 bg-[linear-gradient(var(--border-strong)_33%,rgba(255,255,255,0)_0%)] bg-[length:1px_3px] bg-right bg-repeat-y bg-clip-content" }) }),
8357
- /* @__PURE__ */ jsx(Collapsible.Trigger, { className: "text-left p-0 m-0 pb-4 text-ui-fg-muted hover:text-ui-fg-base focus:text-ui-fg-base outline-none transition-colors", children: /* @__PURE__ */ jsx(Text, { size: "small", leading: "compact", weight: "plus", children: `Show ${items.length} more ${items.length === 1 ? "activity" : "activities"}` }) })
8356
+ /* @__PURE__ */ jsx("div", { className: "flex size-full flex-col items-center", children: /* @__PURE__ */ jsx("div", { className: "border-ui-border-strong w-px flex-1 bg-[linear-gradient(var(--border-strong)_33%,rgba(255,255,255,0)_0%)] bg-[length:1px_3px] bg-clip-content bg-right bg-repeat-y" }) }),
8357
+ /* @__PURE__ */ jsx(Collapsible.Trigger, { className: "text-ui-fg-muted hover:text-ui-fg-base focus:text-ui-fg-base m-0 p-0 pb-4 text-left outline-none transition-colors", children: /* @__PURE__ */ jsx(Text, { size: "small", leading: "compact", weight: "plus", children: `Show ${items.length} more ${items.length === 1 ? "activity" : "activities"}` }) })
8358
8358
  ] }),
8359
8359
  /* @__PURE__ */ jsx(Collapsible.Content, { children: /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-y-0.5", children: items.map((item, idx) => {
8360
8360
  return /* @__PURE__ */ jsx(ActivityItem, { item }, idx);
@@ -8372,14 +8372,14 @@ const ActivityItem = ({ item, isFirst = false }) => {
8372
8372
  return /* @__PURE__ */ jsxs(
8373
8373
  "div",
8374
8374
  {
8375
- className: clx("grid grid-cols-[20px_1fr] items-start gap-x-2 w-full"),
8375
+ className: clx("grid w-full grid-cols-[20px_1fr] items-start gap-x-2"),
8376
8376
  children: [
8377
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-0.5 h-full", children: [
8378
- /* @__PURE__ */ jsx("div", { className: "size-5 flex items-center justify-center", children: /* @__PURE__ */ jsx("div", { className: "size-2.5 rounded-full shadow-borders-base flex items-center justify-center", children: /* @__PURE__ */ jsx("div", { className: "size-1.5 rounded-full bg-ui-tag-neutral-icon" }) }) }),
8379
- !isFirst && /* @__PURE__ */ jsx("div", { className: "flex flex-1 items-center justify-center", children: /* @__PURE__ */ jsx("div", { className: "h-full w-px bg-ui-border-base" }) })
8377
+ /* @__PURE__ */ jsxs("div", { className: "flex h-full flex-col items-center gap-0.5", children: [
8378
+ /* @__PURE__ */ jsx("div", { className: "flex size-5 items-center justify-center", children: /* @__PURE__ */ jsx("div", { className: "shadow-borders-base flex size-2.5 items-center justify-center rounded-full", children: /* @__PURE__ */ jsx("div", { className: "bg-ui-tag-neutral-icon size-1.5 rounded-full" }) }) }),
8379
+ !isFirst && /* @__PURE__ */ jsx("div", { className: "flex flex-1 items-center justify-center", children: /* @__PURE__ */ jsx("div", { className: "bg-ui-border-base h-full w-px" }) })
8380
8380
  ] }),
8381
8381
  /* @__PURE__ */ jsxs("div", { className: clx("flex flex-col", !isFirst && "pb-4"), children: [
8382
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-2 justify-between", children: [
8382
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-x-2", children: [
8383
8383
  /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: item.label }),
8384
8384
  /* @__PURE__ */ jsx(
8385
8385
  Tooltip,
@@ -8390,7 +8390,7 @@ const ActivityItem = ({ item, isFirst = false }) => {
8390
8390
  )
8391
8391
  ] }),
8392
8392
  item.content && renderContent(item.content),
8393
- item.userId && /* @__PURE__ */ jsx("div", { className: "pt-2 text-ui-fg-muted", children: isUserLoaded ? /* @__PURE__ */ jsx(Link, { to: `/settings/users/${user.id}`, className: "w-fit", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-1.5 w-fit", children: [
8393
+ item.userId && /* @__PURE__ */ jsx("div", { className: "text-ui-fg-muted pt-2", children: isUserLoaded ? /* @__PURE__ */ jsx(Link, { to: `/settings/users/${user.id}`, className: "w-fit", children: /* @__PURE__ */ jsxs("div", { className: "flex w-fit items-center gap-x-1.5", children: [
8394
8394
  /* @__PURE__ */ jsx(Text, { size: "small", children: "By" }),
8395
8395
  /* @__PURE__ */ jsx(
8396
8396
  Avatar,
@@ -8406,8 +8406,8 @@ const ActivityItem = ({ item, isFirst = false }) => {
8406
8406
  ] })
8407
8407
  ] }) }) : /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-1.5", children: [
8408
8408
  /* @__PURE__ */ jsx(Text, { size: "small", children: "By" }),
8409
- /* @__PURE__ */ jsx(Skeleton, { className: "rounded-full w-5 h-5" }),
8410
- /* @__PURE__ */ jsx(Skeleton, { className: "w-[75px] h-4" })
8409
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-5 w-5 rounded-full" }),
8410
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-[75px]" })
8411
8411
  ] }) })
8412
8412
  ] })
8413
8413
  ]
@@ -8430,7 +8430,12 @@ function getEditActivityItems(change) {
8430
8430
  promotionsAdded: 0,
8431
8431
  promotionsRemoved: 0
8432
8432
  };
8433
- for (const action of change.actions) {
8433
+ const orderedActions = change.actions.sort((a, b) => {
8434
+ return a.ordering - b.ordering;
8435
+ });
8436
+ const addedPromotionMap = /* @__PURE__ */ new Map();
8437
+ const removedPromotionMap = /* @__PURE__ */ new Map();
8438
+ for (const action of orderedActions) {
8434
8439
  if (!action.details) {
8435
8440
  continue;
8436
8441
  }
@@ -8448,13 +8453,21 @@ function getEditActivityItems(change) {
8448
8453
  case "SHIPPING_REMOVE":
8449
8454
  counts.shippingMethodsRemoved += 1;
8450
8455
  break;
8451
- case "PROMOTION_ADD":
8452
- counts.promotionsAdded += 1;
8456
+ case "PROMOTION_ADD": {
8457
+ addedPromotionMap.set(action.reference_id, true);
8453
8458
  break;
8454
- case "PROMOTION_REMOVE":
8455
- counts.promotionsRemoved += 1;
8459
+ }
8460
+ case "PROMOTION_REMOVE": {
8461
+ if (addedPromotionMap.has(action.reference_id)) {
8462
+ addedPromotionMap.delete(action.reference_id);
8463
+ } else {
8464
+ removedPromotionMap.set(action.reference_id, true);
8465
+ }
8456
8466
  break;
8467
+ }
8457
8468
  }
8469
+ counts.promotionsAdded = addedPromotionMap.size;
8470
+ counts.promotionsRemoved = removedPromotionMap.size;
8458
8471
  }
8459
8472
  const createActivityItem = (type, added, removed) => {
8460
8473
  if (added === 0 && removed === 0) return;
@@ -9833,573 +9846,775 @@ const EmailForm = ({ order }) => {
9833
9846
  const schema$3 = objectType({
9834
9847
  email: stringType().email()
9835
9848
  });
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
- };
9849
+ const InlineTip = forwardRef(
9850
+ ({ variant = "tip", label, className, children, ...props }, ref) => {
9851
+ const labelValue = label || (variant === "warning" ? "Warning" : "Tip");
9866
9852
  return /* @__PURE__ */ jsxs(
9867
9853
  "div",
9868
9854
  {
9855
+ ref,
9869
9856
  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
- },
9857
+ "bg-ui-bg-component txt-small text-ui-fg-subtle grid grid-cols-[4px_1fr] items-start gap-3 rounded-lg border p-3",
9876
9858
  className
9877
9859
  ),
9860
+ ...props,
9878
9861
  children: [
9879
9862
  /* @__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",
9863
+ "div",
9899
9864
  {
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
- ]
9865
+ role: "presentation",
9866
+ className: clx("w-4px bg-ui-tag-neutral-icon h-full rounded-full", {
9867
+ "bg-ui-tag-orange-icon": variant === "warning"
9868
+ })
9917
9869
  }
9918
9870
  ),
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
- )
9871
+ /* @__PURE__ */ jsxs("div", { className: "text-pretty", children: [
9872
+ /* @__PURE__ */ jsxs("strong", { className: "txt-small-plus text-ui-fg-base", children: [
9873
+ labelValue,
9874
+ ":"
9875
+ ] }),
9876
+ " ",
9877
+ children
9878
+ ] })
9941
9879
  ]
9942
9880
  }
9943
9881
  );
9944
9882
  }
9945
9883
  );
9946
- const PRODUCT_VARIANTS_QUERY_KEY = "product-variants";
9947
- const productVariantsQueryKeys = {
9948
- list: (query2) => [
9949
- PRODUCT_VARIANTS_QUERY_KEY,
9950
- query2 ? query2 : void 0
9951
- ]
9952
- };
9953
- const useProductVariants = (query2, options) => {
9954
- const { data, ...rest } = useQuery({
9955
- queryKey: productVariantsQueryKeys.list(query2),
9956
- queryFn: async () => await sdk.admin.productVariant.list(query2),
9957
- ...options
9958
- });
9959
- return { ...data, ...rest };
9960
- };
9961
- const useCancelOrderEdit = ({ preview }) => {
9962
- const { mutateAsync: cancelOrderEdit } = useDraftOrderCancelEdit(preview == null ? void 0 : preview.id);
9963
- const onCancel = useCallback(async () => {
9964
- if (!preview) {
9965
- return true;
9966
- }
9967
- let res = false;
9968
- await cancelOrderEdit(void 0, {
9969
- onError: (e) => {
9970
- toast.error(e.message);
9971
- },
9972
- onSuccess: () => {
9973
- res = true;
9974
- }
9975
- });
9976
- return res;
9977
- }, [preview, cancelOrderEdit]);
9978
- return { onCancel };
9979
- };
9980
- let IS_REQUEST_RUNNING = false;
9981
- const useInitiateOrderEdit = ({
9982
- preview
9983
- }) => {
9984
- const navigate = useNavigate();
9985
- const { mutateAsync } = useDraftOrderBeginEdit(preview == null ? void 0 : preview.id);
9986
- useEffect(() => {
9987
- async function run() {
9988
- if (IS_REQUEST_RUNNING || !preview) {
9989
- return;
9990
- }
9991
- if (preview.order_change) {
9992
- return;
9993
- }
9994
- IS_REQUEST_RUNNING = true;
9995
- await mutateAsync(void 0, {
9996
- onError: (e) => {
9997
- toast.error(e.message);
9998
- navigate(`/draft-orders/${preview.id}`, { replace: true });
9999
- return;
10000
- }
10001
- });
10002
- IS_REQUEST_RUNNING = false;
10003
- }
10004
- run();
10005
- }, [preview, navigate, mutateAsync]);
10006
- };
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 = () => {
9884
+ InlineTip.displayName = "InlineTip";
9885
+ const MetadataFieldSchema = objectType({
9886
+ key: stringType(),
9887
+ disabled: booleanType().optional(),
9888
+ value: anyType()
9889
+ });
9890
+ const MetadataSchema = objectType({
9891
+ metadata: arrayType(MetadataFieldSchema)
9892
+ });
9893
+ const Metadata = () => {
10012
9894
  const { id } = useParams();
10013
- const {
10014
- order: preview,
10015
- isPending: isPreviewPending,
10016
- isError: isPreviewError,
10017
- error: previewError
10018
- } = useOrderPreview(id, void 0, {
10019
- placeholderData: keepPreviousData
9895
+ const { order, isPending, isError, error } = useOrder(id, {
9896
+ fields: "metadata"
10020
9897
  });
10021
- 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
- const { onCancel } = useCancelOrderEdit({ preview });
10032
9898
  if (isError) {
10033
9899
  throw error;
10034
9900
  }
10035
- if (isPreviewError) {
10036
- throw previewError;
10037
- }
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
- ] }) });
9901
+ const isReady = !isPending && !!order;
9902
+ return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
9903
+ /* @__PURE__ */ jsxs(RouteDrawer.Header, { children: [
9904
+ /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Metadata" }) }),
9905
+ /* @__PURE__ */ jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Add metadata to the draft order." }) })
9906
+ ] }),
9907
+ !isReady ? /* @__PURE__ */ jsx(PlaceholderInner, {}) : /* @__PURE__ */ jsx(MetadataForm, { orderId: id, metadata: order == null ? void 0 : order.metadata })
9908
+ ] });
10043
9909
  };
10044
- const ItemsForm = ({ preview, currencyCode }) => {
10045
- var _a;
10046
- const [isSubmitting, setIsSubmitting] = useState(false);
10047
- const [modalContent, setModalContent] = useState(
10048
- null
10049
- );
9910
+ const METADATA_KEY_LABEL_ID = "metadata-form-key-label";
9911
+ const METADATA_VALUE_LABEL_ID = "metadata-form-value-label";
9912
+ const MetadataForm = ({ orderId, metadata }) => {
10050
9913
  const { handleSuccess } = useRouteModal();
10051
- const { searchValue, onSearchValueChange, query: query2 } = useDebouncedSearch();
10052
- 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]);
10060
- const onSubmit = async () => {
10061
- setIsSubmitting(true);
10062
- let requestSucceeded = false;
10063
- await requestOrderEdit(void 0, {
10064
- onError: (e) => {
10065
- toast.error(`Failed to request order edit: ${e.message}`);
10066
- },
10067
- onSuccess: () => {
10068
- requestSucceeded = true;
10069
- }
10070
- });
10071
- if (!requestSucceeded) {
10072
- setIsSubmitting(false);
10073
- return;
10074
- }
10075
- await confirmOrderEdit(void 0, {
10076
- onError: (e) => {
10077
- toast.error(`Failed to confirm order edit: ${e.message}`);
10078
- },
10079
- onSuccess: () => {
10080
- handleSuccess();
10081
- },
10082
- onSettled: () => {
10083
- setIsSubmitting(false);
10084
- }
10085
- });
10086
- };
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
- }
10114
- },
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" }) }),
10218
- /* @__PURE__ */ jsx(
10219
- Button,
10220
- {
10221
- size: "small",
10222
- type: "button",
10223
- onClick: onSubmit,
10224
- isLoading: isSubmitting,
10225
- children: "Save"
10226
- }
10227
- )
10228
- ] }) })
10229
- ] });
10230
- };
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);
9914
+ const hasUneditableRows = getHasUneditableRows(metadata);
9915
+ const { mutateAsync, isPending } = useUpdateDraftOrder(orderId);
10239
9916
  const form = useForm({
10240
9917
  defaultValues: {
10241
- quantity: item.quantity,
10242
- unit_price: item.unit_price
9918
+ metadata: getDefaultValues(metadata)
10243
9919
  },
10244
- resolver: zodResolver(variantItemSchema)
9920
+ resolver: zodResolver(MetadataSchema)
10245
9921
  });
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(
9922
+ const handleSubmit = form.handleSubmit(async (data) => {
9923
+ const parsedData = parseValues(data);
9924
+ await mutateAsync(
10277
9925
  {
10278
- action_id: actionId,
10279
- quantity: data.quantity,
10280
- unit_price: convertNumber(data.unit_price)
9926
+ metadata: parsedData
10281
9927
  },
10282
9928
  {
10283
9929
  onSuccess: () => {
10284
- setEditing(false);
9930
+ toast.success("Metadata updated");
9931
+ handleSuccess();
10285
9932
  },
10286
- onError: (e) => {
10287
- toast.error(e.message);
9933
+ onError: (error) => {
9934
+ toast.error(error.message);
10288
9935
  }
10289
9936
  }
10290
9937
  );
10291
9938
  });
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,
10296
- {
10297
- thumbnail: item.thumbnail,
10298
- alt: item.product_title ?? void 0
10299
- }
10300
- ),
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
- )
10317
- ] }),
10318
- /* @__PURE__ */ jsx(
10319
- Text,
10320
- {
10321
- 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 }) }) });
9939
+ const { fields, insert, remove } = useFieldArray({
9940
+ control: form.control,
9941
+ name: "metadata"
9942
+ });
9943
+ function deleteRow(index) {
9944
+ remove(index);
9945
+ if (fields.length === 1) {
9946
+ insert(0, {
9947
+ key: "",
9948
+ value: "",
9949
+ disabled: false
9950
+ });
9951
+ }
9952
+ }
9953
+ function insertRow(index, position) {
9954
+ insert(index + (position === "above" ? 0 : 1), {
9955
+ key: "",
9956
+ value: "",
9957
+ disabled: false
9958
+ });
9959
+ }
9960
+ return /* @__PURE__ */ jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxs(
9961
+ KeyboundForm,
9962
+ {
9963
+ onSubmit: handleSubmit,
9964
+ className: "flex flex-1 flex-col overflow-hidden",
9965
+ children: [
9966
+ /* @__PURE__ */ jsxs(RouteDrawer.Body, { className: "flex flex-1 flex-col gap-y-8 overflow-y-auto", children: [
9967
+ /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest grid grid-cols-1 divide-y rounded-lg", children: [
9968
+ /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-subtle grid grid-cols-2 divide-x rounded-t-lg", children: [
9969
+ /* @__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" }) }),
9970
+ /* @__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" }) })
9971
+ ] }),
9972
+ fields.map((field, index) => {
9973
+ const isDisabled = field.disabled || false;
9974
+ let placeholder = "-";
9975
+ if (typeof field.value === "object") {
9976
+ placeholder = "{ ... }";
9977
+ }
9978
+ if (Array.isArray(field.value)) {
9979
+ placeholder = "[ ... ]";
9980
+ }
9981
+ return /* @__PURE__ */ jsx(
9982
+ ConditionalTooltip,
9983
+ {
9984
+ showTooltip: isDisabled,
9985
+ content: "This row is disabled because it contains non-primitive data.",
9986
+ children: /* @__PURE__ */ jsxs("div", { className: "group/table relative", children: [
9987
+ /* @__PURE__ */ jsxs(
9988
+ "div",
9989
+ {
9990
+ className: clx("grid grid-cols-2 divide-x", {
9991
+ "overflow-hidden rounded-b-lg": index === fields.length - 1
9992
+ }),
9993
+ children: [
9994
+ /* @__PURE__ */ jsx(
9995
+ Form$2.Field,
9996
+ {
9997
+ control: form.control,
9998
+ name: `metadata.${index}.key`,
9999
+ render: ({ field: field2 }) => {
10000
+ return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
10001
+ GridInput,
10002
+ {
10003
+ "aria-labelledby": METADATA_KEY_LABEL_ID,
10004
+ ...field2,
10005
+ disabled: isDisabled,
10006
+ placeholder: "Key"
10007
+ }
10008
+ ) }) });
10009
+ }
10010
+ }
10011
+ ),
10012
+ /* @__PURE__ */ jsx(
10013
+ Form$2.Field,
10014
+ {
10015
+ control: form.control,
10016
+ name: `metadata.${index}.value`,
10017
+ render: ({ field: { value, ...field2 } }) => {
10018
+ return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
10019
+ GridInput,
10020
+ {
10021
+ "aria-labelledby": METADATA_VALUE_LABEL_ID,
10022
+ ...field2,
10023
+ value: isDisabled ? placeholder : value,
10024
+ disabled: isDisabled,
10025
+ placeholder: "Value"
10026
+ }
10027
+ ) }) });
10028
+ }
10029
+ }
10030
+ )
10031
+ ]
10032
+ }
10033
+ ),
10034
+ /* @__PURE__ */ jsxs(DropdownMenu, { children: [
10035
+ /* @__PURE__ */ jsx(
10036
+ DropdownMenu.Trigger,
10037
+ {
10038
+ className: clx(
10039
+ "invisible absolute inset-y-0 -right-2.5 my-auto group-hover/table:visible data-[state='open']:visible",
10040
+ {
10041
+ hidden: isDisabled
10042
+ }
10043
+ ),
10044
+ disabled: isDisabled,
10045
+ asChild: true,
10046
+ children: /* @__PURE__ */ jsx(IconButton, { size: "2xsmall", children: /* @__PURE__ */ jsx(EllipsisVertical, {}) })
10047
+ }
10048
+ ),
10049
+ /* @__PURE__ */ jsxs(DropdownMenu.Content, { children: [
10050
+ /* @__PURE__ */ jsxs(
10051
+ DropdownMenu.Item,
10052
+ {
10053
+ className: "gap-x-2",
10054
+ onClick: () => insertRow(index, "above"),
10055
+ children: [
10056
+ /* @__PURE__ */ jsx(ArrowUpMini, { className: "text-ui-fg-subtle" }),
10057
+ "Insert row above"
10058
+ ]
10059
+ }
10060
+ ),
10061
+ /* @__PURE__ */ jsxs(
10062
+ DropdownMenu.Item,
10063
+ {
10064
+ className: "gap-x-2",
10065
+ onClick: () => insertRow(index, "below"),
10066
+ children: [
10067
+ /* @__PURE__ */ jsx(ArrowDownMini, { className: "text-ui-fg-subtle" }),
10068
+ "Insert row below"
10069
+ ]
10070
+ }
10071
+ ),
10072
+ /* @__PURE__ */ jsx(DropdownMenu.Separator, {}),
10073
+ /* @__PURE__ */ jsxs(
10074
+ DropdownMenu.Item,
10075
+ {
10076
+ className: "gap-x-2",
10077
+ onClick: () => deleteRow(index),
10078
+ children: [
10079
+ /* @__PURE__ */ jsx(Trash, { className: "text-ui-fg-subtle" }),
10080
+ "Delete row"
10081
+ ]
10082
+ }
10083
+ )
10084
+ ] })
10085
+ ] })
10086
+ ] })
10087
+ },
10088
+ field.id
10089
+ );
10090
+ })
10091
+ ] }),
10092
+ hasUneditableRows && /* @__PURE__ */ jsx(InlineTip, { variant: "warning", label: "Some rows are disabled", children: "This object contains non-primitive metadata, such as arrays or objects, that can't be edited here. To edit the disabled rows, use the API directly." })
10093
+ ] }),
10094
+ /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
10095
+ /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
10096
+ /* @__PURE__ */ jsx(Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
10097
+ ] }) })
10098
+ ]
10099
+ }
10100
+ ) });
10101
+ };
10102
+ const GridInput = forwardRef(({ className, ...props }, ref) => {
10103
+ return /* @__PURE__ */ jsx(
10104
+ "input",
10105
+ {
10106
+ ref,
10107
+ ...props,
10108
+ autoComplete: "off",
10109
+ className: clx(
10110
+ "txt-compact-small text-ui-fg-base placeholder:text-ui-fg-muted disabled:text-ui-fg-disabled disabled:bg-ui-bg-base bg-transparent px-2 py-1.5 outline-none",
10111
+ className
10112
+ )
10113
+ }
10114
+ );
10115
+ });
10116
+ GridInput.displayName = "MetadataForm.GridInput";
10117
+ const PlaceholderInner = () => {
10118
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-1 flex-col overflow-hidden", children: [
10119
+ /* @__PURE__ */ jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsx(Skeleton, { className: "h-[148ox] w-full rounded-lg" }) }),
10120
+ /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
10121
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-7 w-12 rounded-md" }),
10122
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-7 w-12 rounded-md" })
10123
+ ] }) })
10124
+ ] });
10125
+ };
10126
+ const EDITABLE_TYPES = ["string", "number", "boolean"];
10127
+ function getDefaultValues(metadata) {
10128
+ if (!metadata || !Object.keys(metadata).length) {
10129
+ return [
10130
+ {
10131
+ key: "",
10132
+ value: "",
10133
+ disabled: false
10134
+ }
10135
+ ];
10136
+ }
10137
+ return Object.entries(metadata).map(([key, value]) => {
10138
+ if (!EDITABLE_TYPES.includes(typeof value)) {
10139
+ return {
10140
+ key,
10141
+ value,
10142
+ disabled: true
10143
+ };
10144
+ }
10145
+ let stringValue = value;
10146
+ if (typeof value !== "string") {
10147
+ stringValue = JSON.stringify(value);
10148
+ }
10149
+ return {
10150
+ key,
10151
+ value: stringValue,
10152
+ original_key: key
10153
+ };
10154
+ });
10155
+ }
10156
+ function parseValues(values) {
10157
+ const metadata = values.metadata;
10158
+ const isEmpty = !metadata.length || metadata.length === 1 && !metadata[0].key && !metadata[0].value;
10159
+ if (isEmpty) {
10160
+ return null;
10161
+ }
10162
+ const update = {};
10163
+ metadata.forEach((field) => {
10164
+ let key = field.key;
10165
+ let value = field.value;
10166
+ const disabled = field.disabled;
10167
+ if (!key || !value) {
10168
+ return;
10169
+ }
10170
+ if (disabled) {
10171
+ update[key] = value;
10172
+ return;
10173
+ }
10174
+ key = key.trim();
10175
+ value = value.trim();
10176
+ if (value === "true") {
10177
+ update[key] = true;
10178
+ } else if (value === "false") {
10179
+ update[key] = false;
10180
+ } else {
10181
+ const parsedNumber = parseFloat(value);
10182
+ if (!isNaN(parsedNumber)) {
10183
+ update[key] = parsedNumber;
10184
+ } else {
10185
+ update[key] = value;
10186
+ }
10187
+ }
10188
+ });
10189
+ return update;
10190
+ }
10191
+ function getHasUneditableRows(metadata) {
10192
+ if (!metadata) {
10193
+ return false;
10194
+ }
10195
+ return Object.values(metadata).some(
10196
+ (value) => !EDITABLE_TYPES.includes(typeof value)
10197
+ );
10198
+ }
10199
+ const NumberInput = forwardRef(
10200
+ ({
10201
+ value,
10202
+ onChange,
10203
+ size = "base",
10204
+ min = 0,
10205
+ max = 100,
10206
+ step = 1,
10207
+ className,
10208
+ disabled,
10209
+ ...props
10210
+ }, ref) => {
10211
+ const handleChange = (event) => {
10212
+ const newValue = event.target.value === "" ? min : Number(event.target.value);
10213
+ if (!isNaN(newValue) && (max === void 0 || newValue <= max) && (min === void 0 || newValue >= min)) {
10214
+ onChange(newValue);
10215
+ }
10216
+ };
10217
+ const handleIncrement = () => {
10218
+ const newValue = value + step;
10219
+ if (max === void 0 || newValue <= max) {
10220
+ onChange(newValue);
10221
+ }
10222
+ };
10223
+ const handleDecrement = () => {
10224
+ const newValue = value - step;
10225
+ if (min === void 0 || newValue >= min) {
10226
+ onChange(newValue);
10227
+ }
10228
+ };
10229
+ return /* @__PURE__ */ jsxs(
10230
+ "div",
10231
+ {
10232
+ className: clx(
10233
+ "inline-flex rounded-md bg-ui-bg-field shadow-borders-base overflow-hidden divide-x transition-fg",
10234
+ "[&:has(input:focus)]:shadow-borders-interactive-with-active",
10235
+ {
10236
+ "h-7": size === "small",
10237
+ "h-8": size === "base"
10238
+ },
10239
+ className
10240
+ ),
10241
+ children: [
10242
+ /* @__PURE__ */ jsx(
10243
+ "input",
10244
+ {
10245
+ ref,
10246
+ type: "number",
10247
+ value,
10248
+ onChange: handleChange,
10249
+ min,
10250
+ max,
10251
+ step,
10252
+ className: clx(
10253
+ "flex-1 px-2 py-1 bg-transparent txt-compact-small text-ui-fg-base outline-none [appearance:textfield]",
10254
+ "[&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none",
10255
+ "placeholder:text-ui-fg-muted"
10256
+ ),
10257
+ ...props
10258
+ }
10259
+ ),
10260
+ /* @__PURE__ */ jsxs(
10261
+ "button",
10262
+ {
10263
+ className: clx(
10264
+ "flex items-center justify-center outline-none transition-fg",
10265
+ "disabled:cursor-not-allowed disabled:text-ui-fg-muted",
10266
+ "focus:bg-ui-bg-field-component-hover",
10267
+ "hover:bg-ui-bg-field-component-hover",
10268
+ {
10269
+ "size-7": size === "small",
10270
+ "size-8": size === "base"
10271
+ }
10272
+ ),
10273
+ type: "button",
10274
+ onClick: handleDecrement,
10275
+ disabled: min !== void 0 && value <= min || disabled,
10276
+ children: [
10277
+ /* @__PURE__ */ jsx(Minus, {}),
10278
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: `Decrease by ${step}` })
10279
+ ]
10280
+ }
10281
+ ),
10282
+ /* @__PURE__ */ jsxs(
10283
+ "button",
10284
+ {
10285
+ className: clx(
10286
+ "flex items-center justify-center outline-none transition-fg",
10287
+ "disabled:cursor-not-allowed disabled:text-ui-fg-muted",
10288
+ "focus:bg-ui-bg-field-hover",
10289
+ "hover:bg-ui-bg-field-hover",
10290
+ {
10291
+ "size-7": size === "small",
10292
+ "size-8": size === "base"
10293
+ }
10294
+ ),
10295
+ type: "button",
10296
+ onClick: handleIncrement,
10297
+ disabled: max !== void 0 && value >= max || disabled,
10298
+ children: [
10299
+ /* @__PURE__ */ jsx(Plus, {}),
10300
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: `Increase by ${step}` })
10301
+ ]
10302
+ }
10303
+ )
10304
+ ]
10305
+ }
10306
+ );
10307
+ }
10308
+ );
10309
+ const PRODUCT_VARIANTS_QUERY_KEY = "product-variants";
10310
+ const productVariantsQueryKeys = {
10311
+ list: (query2) => [
10312
+ PRODUCT_VARIANTS_QUERY_KEY,
10313
+ query2 ? query2 : void 0
10314
+ ]
10315
+ };
10316
+ const useProductVariants = (query2, options) => {
10317
+ const { data, ...rest } = useQuery({
10318
+ queryKey: productVariantsQueryKeys.list(query2),
10319
+ queryFn: async () => await sdk.admin.productVariant.list(query2),
10320
+ ...options
10321
+ });
10322
+ return { ...data, ...rest };
10323
+ };
10324
+ const useCancelOrderEdit = ({ preview }) => {
10325
+ const { mutateAsync: cancelOrderEdit } = useDraftOrderCancelEdit(preview == null ? void 0 : preview.id);
10326
+ const onCancel = useCallback(async () => {
10327
+ if (!preview) {
10328
+ return true;
10329
+ }
10330
+ let res = false;
10331
+ await cancelOrderEdit(void 0, {
10332
+ onError: (e) => {
10333
+ toast.error(e.message);
10334
+ },
10335
+ onSuccess: () => {
10336
+ res = true;
10337
+ }
10338
+ });
10339
+ return res;
10340
+ }, [preview, cancelOrderEdit]);
10341
+ return { onCancel };
10342
+ };
10343
+ let IS_REQUEST_RUNNING = false;
10344
+ const useInitiateOrderEdit = ({
10345
+ preview
10346
+ }) => {
10347
+ const navigate = useNavigate();
10348
+ const { mutateAsync } = useDraftOrderBeginEdit(preview == null ? void 0 : preview.id);
10349
+ useEffect(() => {
10350
+ async function run() {
10351
+ if (IS_REQUEST_RUNNING || !preview) {
10352
+ return;
10353
+ }
10354
+ if (preview.order_change) {
10355
+ return;
10356
+ }
10357
+ IS_REQUEST_RUNNING = true;
10358
+ await mutateAsync(void 0, {
10359
+ onError: (e) => {
10360
+ toast.error(e.message);
10361
+ navigate(`/draft-orders/${preview.id}`, { replace: true });
10362
+ return;
10336
10363
  }
10364
+ });
10365
+ IS_REQUEST_RUNNING = false;
10366
+ }
10367
+ run();
10368
+ }, [preview, navigate, mutateAsync]);
10369
+ };
10370
+ function convertNumber(value) {
10371
+ return typeof value === "string" ? Number(value.replace(",", ".")) : value;
10372
+ }
10373
+ const STACKED_MODAL_ID = "items_stacked_modal";
10374
+ const Items = () => {
10375
+ const { id } = useParams();
10376
+ const {
10377
+ order: preview,
10378
+ isPending: isPreviewPending,
10379
+ isError: isPreviewError,
10380
+ error: previewError
10381
+ } = useOrderPreview(id, void 0, {
10382
+ placeholderData: keepPreviousData
10383
+ });
10384
+ useInitiateOrderEdit({ preview });
10385
+ const { draft_order, isPending, isError, error } = useDraftOrder(
10386
+ id,
10387
+ {
10388
+ fields: "currency_code"
10389
+ },
10390
+ {
10391
+ enabled: !!id
10392
+ }
10393
+ );
10394
+ const { onCancel } = useCancelOrderEdit({ preview });
10395
+ if (isError) {
10396
+ throw error;
10397
+ }
10398
+ if (isPreviewError) {
10399
+ throw previewError;
10400
+ }
10401
+ const ready = !!preview && !isPreviewPending && !!draft_order && !isPending;
10402
+ return /* @__PURE__ */ jsx(RouteFocusModal, { onClose: onCancel, children: ready ? /* @__PURE__ */ jsx(ItemsForm, { preview, currencyCode: draft_order.currency_code }) : /* @__PURE__ */ jsxs("div", { children: [
10403
+ /* @__PURE__ */ jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Edit Items" }) }),
10404
+ /* @__PURE__ */ jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Loading data for the draft order, please wait..." }) })
10405
+ ] }) });
10406
+ };
10407
+ const ItemsForm = ({ preview, currencyCode }) => {
10408
+ var _a;
10409
+ const [isSubmitting, setIsSubmitting] = useState(false);
10410
+ const [modalContent, setModalContent] = useState(
10411
+ null
10412
+ );
10413
+ const { handleSuccess } = useRouteModal();
10414
+ const { searchValue, onSearchValueChange, query: query2 } = useDebouncedSearch();
10415
+ const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
10416
+ const { mutateAsync: requestOrderEdit } = useDraftOrderRequestEdit(preview.id);
10417
+ const itemCount = ((_a = preview.items) == null ? void 0 : _a.reduce((acc, item) => acc + item.quantity, 0)) || 0;
10418
+ const matches = useMemo(() => {
10419
+ return matchSorter(preview.items, query2, {
10420
+ keys: ["product_title", "variant_title", "variant_sku", "title"]
10421
+ });
10422
+ }, [preview.items, query2]);
10423
+ const onSubmit = async () => {
10424
+ setIsSubmitting(true);
10425
+ let requestSucceeded = false;
10426
+ await requestOrderEdit(void 0, {
10427
+ onError: (e) => {
10428
+ toast.error(`Failed to request order edit: ${e.message}`);
10429
+ },
10430
+ onSuccess: () => {
10431
+ requestSucceeded = true;
10337
10432
  }
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
- ) }) });
10433
+ });
10434
+ if (!requestSucceeded) {
10435
+ setIsSubmitting(false);
10436
+ return;
10437
+ }
10438
+ await confirmOrderEdit(void 0, {
10439
+ onError: (e) => {
10440
+ toast.error(`Failed to confirm order edit: ${e.message}`);
10441
+ },
10442
+ onSuccess: () => {
10443
+ handleSuccess();
10444
+ },
10445
+ onSettled: () => {
10446
+ setIsSubmitting(false);
10447
+ }
10448
+ });
10449
+ };
10450
+ const onKeyDown = useCallback(
10451
+ (e) => {
10452
+ if (e.key === "Enter" && (e.ctrlKey || e.metaKey)) {
10453
+ if (modalContent || isSubmitting) {
10454
+ return;
10354
10455
  }
10456
+ onSubmit();
10355
10457
  }
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,
10458
+ },
10459
+ [modalContent, isSubmitting, onSubmit]
10460
+ );
10461
+ useEffect(() => {
10462
+ document.addEventListener("keydown", onKeyDown);
10463
+ return () => {
10464
+ document.removeEventListener("keydown", onKeyDown);
10465
+ };
10466
+ }, [onKeyDown]);
10467
+ return /* @__PURE__ */ jsxs("div", { className: "flex h-full flex-col overflow-hidden", children: [
10468
+ /* @__PURE__ */ jsx(RouteFocusModal.Header, {}),
10469
+ /* @__PURE__ */ jsx(RouteFocusModal.Body, { className: "flex flex-1 flex-col overflow-hidden", children: /* @__PURE__ */ jsxs(
10470
+ StackedFocusModal,
10359
10471
  {
10360
- type: "button",
10361
- size: "small",
10362
- onClick: editing ? onSubmit : () => {
10363
- setEditing(true);
10472
+ id: STACKED_MODAL_ID,
10473
+ onOpenChangeCallback: (open) => {
10474
+ if (!open) {
10475
+ setModalContent(null);
10476
+ }
10364
10477
  },
10365
- disabled: isPending,
10366
- children: editing ? /* @__PURE__ */ jsx(Check, {}) : /* @__PURE__ */ jsx(PencilSquare, {})
10478
+ children: [
10479
+ /* @__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: [
10480
+ /* @__PURE__ */ jsxs("div", { children: [
10481
+ /* @__PURE__ */ jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Items" }) }),
10482
+ /* @__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" }) })
10483
+ ] }),
10484
+ /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
10485
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-y-6", children: [
10486
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 items-center gap-3", children: [
10487
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
10488
+ /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: "Items" }),
10489
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Choose items from the product catalog." })
10490
+ ] }),
10491
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
10492
+ /* @__PURE__ */ jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsx(
10493
+ Input,
10494
+ {
10495
+ type: "search",
10496
+ placeholder: "Search items",
10497
+ value: searchValue,
10498
+ onChange: (e) => onSearchValueChange(e.target.value)
10499
+ }
10500
+ ) }),
10501
+ /* @__PURE__ */ jsxs(DropdownMenu, { children: [
10502
+ /* @__PURE__ */ jsx(DropdownMenu.Trigger, { asChild: true, children: /* @__PURE__ */ jsx(IconButton, { type: "button", children: /* @__PURE__ */ jsx(Plus, {}) }) }),
10503
+ /* @__PURE__ */ jsxs(DropdownMenu.Content, { children: [
10504
+ /* @__PURE__ */ jsx(
10505
+ StackedModalTrigger$1,
10506
+ {
10507
+ type: "add-items",
10508
+ setModalContent
10509
+ }
10510
+ ),
10511
+ /* @__PURE__ */ jsx(
10512
+ StackedModalTrigger$1,
10513
+ {
10514
+ type: "add-custom-item",
10515
+ setModalContent
10516
+ }
10517
+ )
10518
+ ] })
10519
+ ] })
10520
+ ] })
10521
+ ] }),
10522
+ /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-subtle shadow-elevation-card-rest rounded-xl", children: [
10523
+ /* @__PURE__ */ jsx("div", { className: "px-[5px]", children: /* @__PURE__ */ jsxs("div", { className: "text-ui-fg-muted grid grid-cols-[2fr_1fr_2fr_28px] gap-3 px-4 py-2", children: [
10524
+ /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: "Item" }) }),
10525
+ /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: "Quantity" }) }),
10526
+ /* @__PURE__ */ jsx("div", { className: "text-right", children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: "Price" }) }),
10527
+ /* @__PURE__ */ jsx("div", {})
10528
+ ] }) }),
10529
+ /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-y-1.5 px-[5px] pb-[5px]", children: itemCount <= 0 ? /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest flex flex-col items-center justify-center gap-1 gap-x-3 rounded-lg p-4", children: [
10530
+ /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: "There are no items in this order" }),
10531
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Add items to the order to get started." })
10532
+ ] }) : matches.length > 0 ? matches == null ? void 0 : matches.map((item) => /* @__PURE__ */ jsx(
10533
+ Item,
10534
+ {
10535
+ item,
10536
+ preview,
10537
+ currencyCode
10538
+ },
10539
+ item.id
10540
+ )) : /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest flex flex-col items-center justify-center gap-1 gap-x-3 rounded-lg p-4", children: [
10541
+ /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: "No items found" }),
10542
+ /* @__PURE__ */ jsxs(Text, { size: "small", className: "text-ui-fg-subtle", children: [
10543
+ 'No items found for "',
10544
+ query2,
10545
+ '".'
10546
+ ] })
10547
+ ] }) })
10548
+ ] })
10549
+ ] }),
10550
+ /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
10551
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-[1fr_0.5fr_0.5fr] gap-3", children: [
10552
+ /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: "Subtotal" }) }),
10553
+ /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsxs(
10554
+ Text,
10555
+ {
10556
+ size: "small",
10557
+ leading: "compact",
10558
+ className: "text-ui-fg-subtle",
10559
+ children: [
10560
+ itemCount,
10561
+ " ",
10562
+ itemCount === 1 ? "item" : "items"
10563
+ ]
10564
+ }
10565
+ ) }),
10566
+ /* @__PURE__ */ jsx("div", { className: "text-right", children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: getStylizedAmount(preview.item_subtotal, currencyCode) }) })
10567
+ ] })
10568
+ ] }) }),
10569
+ modalContent && (modalContent === "add-items" ? /* @__PURE__ */ jsx(ExistingItemsForm, { orderId: preview.id, items: preview.items }) : modalContent === "add-custom-item" ? /* @__PURE__ */ jsx(
10570
+ CustomItemForm,
10571
+ {
10572
+ orderId: preview.id,
10573
+ currencyCode
10574
+ }
10575
+ ) : null)
10576
+ ]
10367
10577
  }
10368
- )
10369
- ] }) }) });
10578
+ ) }),
10579
+ /* @__PURE__ */ jsx(RouteFocusModal.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
10580
+ /* @__PURE__ */ jsx(RouteFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
10581
+ /* @__PURE__ */ jsx(
10582
+ Button,
10583
+ {
10584
+ size: "small",
10585
+ type: "button",
10586
+ onClick: onSubmit,
10587
+ isLoading: isSubmitting,
10588
+ children: "Save"
10589
+ }
10590
+ )
10591
+ ] }) })
10592
+ ] });
10370
10593
  };
10371
- const variantItemSchema = objectType({
10372
- quantity: numberType(),
10373
- unit_price: unionType([numberType(), stringType()])
10374
- });
10375
- const CustomItem = ({ item, preview, currencyCode }) => {
10594
+ const Item = ({ item, preview, currencyCode }) => {
10595
+ if (item.variant_id) {
10596
+ return /* @__PURE__ */ jsx(VariantItem, { item, preview, currencyCode });
10597
+ }
10598
+ return /* @__PURE__ */ jsx(CustomItem, { item, preview, currencyCode });
10599
+ };
10600
+ const VariantItem = ({ item, preview, currencyCode }) => {
10376
10601
  const [editing, setEditing] = useState(false);
10377
- const { quantity, unit_price, title } = item;
10378
10602
  const form = useForm({
10379
10603
  defaultValues: {
10380
- title,
10381
- quantity,
10382
- unit_price
10604
+ quantity: item.quantity,
10605
+ unit_price: item.unit_price
10383
10606
  },
10384
- resolver: zodResolver(customItemSchema)
10607
+ resolver: zodResolver(variantItemSchema)
10385
10608
  });
10386
- useEffect(() => {
10387
- form.reset({
10388
- title,
10389
- quantity,
10390
- unit_price
10391
- });
10392
- }, [form, title, quantity, unit_price]);
10393
10609
  const actionId = useMemo(() => {
10394
10610
  var _a, _b;
10395
10611
  return (_b = (_a = item.actions) == null ? void 0 : _a.find((a) => a.action === "ITEM_ADD")) == null ? void 0 : _b.id;
10396
10612
  }, [item]);
10397
10613
  const { mutateAsync: updateActionItem, isPending: isUpdatingActionItem } = useDraftOrderUpdateActionItem(preview.id);
10398
- const { mutateAsync: removeActionItem, isPending: isRemovingActionItem } = useDraftOrderRemoveActionItem(preview.id);
10399
10614
  const { mutateAsync: updateOriginalItem, isPending: isUpdatingOriginalItem } = useDraftOrderUpdateItem(preview.id);
10400
10615
  const isPending = isUpdatingActionItem || isUpdatingOriginalItem;
10401
10616
  const onSubmit = form.handleSubmit(async (data) => {
10402
- if (convertNumber(data.unit_price) === item.unit_price && data.quantity === item.quantity && data.title === item.title) {
10617
+ if (convertNumber(data.unit_price) === item.unit_price && data.quantity === item.quantity) {
10403
10618
  setEditing(false);
10404
10619
  return;
10405
10620
  }
@@ -10421,17 +10636,6 @@ const CustomItem = ({ item, preview, currencyCode }) => {
10421
10636
  );
10422
10637
  return;
10423
10638
  }
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
10639
  await updateActionItem(
10436
10640
  {
10437
10641
  action_id: actionId,
@@ -10448,27 +10652,44 @@ const CustomItem = ({ item, preview, currencyCode }) => {
10448
10652
  }
10449
10653
  );
10450
10654
  });
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: [
10655
+ return /* @__PURE__ */ jsx(Form$2, { ...form, children: /* @__PURE__ */ jsx("form", { onSubmit, children: /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest grid grid-cols-[minmax(0,2fr)_minmax(0,1fr)_minmax(0,2fr)_28px] items-center gap-3 rounded-lg px-4 py-2", children: [
10656
+ /* @__PURE__ */ jsxs("div", { className: "flex w-full items-center gap-x-3", children: [
10453
10657
  /* @__PURE__ */ jsx(
10454
10658
  Thumbnail,
10455
10659
  {
10456
10660
  thumbnail: item.thumbnail,
10457
- alt: item.title ?? void 0
10661
+ alt: item.product_title ?? void 0
10458
10662
  }
10459
10663
  ),
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 }) }) });
10664
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
10665
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-1", children: [
10666
+ /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: item.product_title }),
10667
+ /* @__PURE__ */ jsxs(
10668
+ Text,
10669
+ {
10670
+ size: "small",
10671
+ leading: "compact",
10672
+ className: "text-ui-fg-subtle",
10673
+ children: [
10674
+ "(",
10675
+ item.variant_title,
10676
+ ")"
10677
+ ]
10678
+ }
10679
+ )
10680
+ ] }),
10681
+ /* @__PURE__ */ jsx(
10682
+ Text,
10683
+ {
10684
+ size: "small",
10685
+ leading: "compact",
10686
+ className: "text-ui-fg-subtle",
10687
+ children: item.variant_sku
10467
10688
  }
10468
- }
10469
- ) : /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: item.title })
10689
+ )
10690
+ ] })
10470
10691
  ] }),
10471
- editing ? /* @__PURE__ */ jsx(
10692
+ editing ? /* @__PURE__ */ jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsx(
10472
10693
  Form$2.Field,
10473
10694
  {
10474
10695
  control: form.control,
@@ -10477,8 +10698,8 @@ const CustomItem = ({ item, preview, currencyCode }) => {
10477
10698
  return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(NumberInput, { ...field }) }) });
10478
10699
  }
10479
10700
  }
10480
- ) : /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: item.quantity }),
10481
- editing ? /* @__PURE__ */ jsx(
10701
+ ) }) : /* @__PURE__ */ jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: item.quantity }) }),
10702
+ editing ? /* @__PURE__ */ jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsx(
10482
10703
  Form$2.Field,
10483
10704
  {
10484
10705
  control: form.control,
@@ -10488,237 +10709,101 @@ const CustomItem = ({ item, preview, currencyCode }) => {
10488
10709
  CurrencyInput,
10489
10710
  {
10490
10711
  ...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
10557
- }
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
- }
10586
- return /* @__PURE__ */ jsxs(
10587
- StackedFocusModal.Content,
10588
- {
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
- },
10598
- 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);
10618
- }
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() }) })
10712
+ symbol: getNativeSymbol(currencyCode),
10713
+ code: currencyCode,
10714
+ onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value)
10687
10715
  }
10688
- );
10716
+ ) }) });
10717
+ }
10718
+ }
10719
+ ) }) : /* @__PURE__ */ jsx("div", { className: "flex w-full flex-1 items-center justify-end", children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: getLocaleAmount(item.unit_price, currencyCode) }) }),
10720
+ /* @__PURE__ */ jsx(
10721
+ IconButton,
10722
+ {
10723
+ type: "button",
10724
+ size: "small",
10725
+ onClick: editing ? onSubmit : () => {
10726
+ setEditing(true);
10689
10727
  },
10690
- enableSorting: true,
10691
- sortAscLabel: "Oldest first",
10692
- sortDescLabel: "Newest first"
10693
- })
10694
- ];
10695
- }, []);
10728
+ disabled: isPending,
10729
+ children: editing ? /* @__PURE__ */ jsx(Check, {}) : /* @__PURE__ */ jsx(PencilSquare, {})
10730
+ }
10731
+ )
10732
+ ] }) }) });
10696
10733
  };
10697
- const CustomItemForm = ({ orderId, currencyCode }) => {
10698
- const { setIsOpen } = useStackedModal();
10699
- const { mutateAsync: addItems } = useDraftOrderAddItems(orderId);
10734
+ const variantItemSchema = objectType({
10735
+ quantity: numberType(),
10736
+ unit_price: unionType([numberType(), stringType()])
10737
+ });
10738
+ const CustomItem = ({ item, preview, currencyCode }) => {
10739
+ const [editing, setEditing] = useState(false);
10740
+ const { quantity, unit_price, title } = item;
10700
10741
  const form = useForm({
10701
10742
  defaultValues: {
10702
- title: "",
10703
- quantity: 1,
10704
- unit_price: ""
10743
+ title,
10744
+ quantity,
10745
+ unit_price
10705
10746
  },
10706
10747
  resolver: zodResolver(customItemSchema)
10707
10748
  });
10749
+ useEffect(() => {
10750
+ form.reset({
10751
+ title,
10752
+ quantity,
10753
+ unit_price
10754
+ });
10755
+ }, [form, title, quantity, unit_price]);
10756
+ const actionId = useMemo(() => {
10757
+ var _a, _b;
10758
+ return (_b = (_a = item.actions) == null ? void 0 : _a.find((a) => a.action === "ITEM_ADD")) == null ? void 0 : _b.id;
10759
+ }, [item]);
10760
+ const { mutateAsync: updateActionItem, isPending: isUpdatingActionItem } = useDraftOrderUpdateActionItem(preview.id);
10761
+ const { mutateAsync: removeActionItem, isPending: isRemovingActionItem } = useDraftOrderRemoveActionItem(preview.id);
10762
+ const { mutateAsync: updateOriginalItem, isPending: isUpdatingOriginalItem } = useDraftOrderUpdateItem(preview.id);
10763
+ const isPending = isUpdatingActionItem || isUpdatingOriginalItem;
10708
10764
  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)
10765
+ if (convertNumber(data.unit_price) === item.unit_price && data.quantity === item.quantity && data.title === item.title) {
10766
+ setEditing(false);
10767
+ return;
10768
+ }
10769
+ if (!actionId) {
10770
+ await updateOriginalItem(
10771
+ {
10772
+ item_id: item.id,
10773
+ quantity: data.quantity,
10774
+ unit_price: convertNumber(data.unit_price)
10775
+ },
10776
+ {
10777
+ onSuccess: () => {
10778
+ setEditing(false);
10779
+ },
10780
+ onError: (e) => {
10781
+ toast.error(e.message);
10716
10782
  }
10717
- ]
10783
+ }
10784
+ );
10785
+ return;
10786
+ }
10787
+ if (data.quantity === 0) {
10788
+ await removeActionItem(actionId, {
10789
+ onSuccess: () => {
10790
+ setEditing(false);
10791
+ },
10792
+ onError: (e) => {
10793
+ toast.error(e.message);
10794
+ }
10795
+ });
10796
+ return;
10797
+ }
10798
+ await updateActionItem(
10799
+ {
10800
+ action_id: actionId,
10801
+ quantity: data.quantity,
10802
+ unit_price: convertNumber(data.unit_price)
10718
10803
  },
10719
10804
  {
10720
10805
  onSuccess: () => {
10721
- setIsOpen(STACKED_MODAL_ID, false);
10806
+ setEditing(false);
10722
10807
  },
10723
10808
  onError: (e) => {
10724
10809
  toast.error(e.message);
@@ -10726,437 +10811,365 @@ const CustomItemForm = ({ orderId, currencyCode }) => {
10726
10811
  }
10727
10812
  );
10728
10813
  });
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" }),
10814
+ return /* @__PURE__ */ jsx(Form$2, { ...form, children: /* @__PURE__ */ jsx("form", { onSubmit, children: /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest grid grid-cols-[minmax(0,2fr)_minmax(0,1fr)_minmax(0,2fr)_28px] items-center gap-3 rounded-lg px-4 py-2", children: [
10815
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-3", children: [
10755
10816
  /* @__PURE__ */ jsx(
10756
- Form$2.Field,
10817
+ Thumbnail,
10757
10818
  {
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
- ] }) })
10819
+ thumbnail: item.thumbnail,
10820
+ alt: item.title ?? void 0
10778
10821
  }
10779
10822
  ),
10780
- /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
10781
- /* @__PURE__ */ jsx(
10823
+ editing ? /* @__PURE__ */ jsx(
10782
10824
  Form$2.Field,
10783
10825
  {
10784
10826
  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
- ] }) })
10827
+ name: "title",
10828
+ render: ({ field }) => {
10829
+ return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }) });
10830
+ }
10796
10831
  }
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",
10832
+ ) : /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: item.title })
10833
+ ] }),
10834
+ editing ? /* @__PURE__ */ jsx(
10835
+ Form$2.Field,
10815
10836
  {
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
- ]
10837
+ control: form.control,
10838
+ name: "quantity",
10839
+ render: ({ field }) => {
10840
+ return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(NumberInput, { ...field }) }) });
10841
+ }
10841
10842
  }
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
- ] });
10843
+ ) : /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: item.quantity }),
10844
+ editing ? /* @__PURE__ */ jsx(
10845
+ Form$2.Field,
10846
+ {
10847
+ control: form.control,
10848
+ name: "unit_price",
10849
+ render: ({ field: { onChange, ...field } }) => {
10850
+ return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
10851
+ CurrencyInput,
10852
+ {
10853
+ ...field,
10854
+ symbol: getNativeSymbol(currencyCode),
10855
+ code: currencyCode,
10856
+ onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value)
10857
+ }
10858
+ ) }) });
10859
+ }
10860
+ }
10861
+ ) : /* @__PURE__ */ jsx("div", { className: "flex flex-1 items-center justify-end", children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: getLocaleAmount(item.unit_price, currencyCode) }) }),
10862
+ /* @__PURE__ */ jsx(
10863
+ IconButton,
10864
+ {
10865
+ type: "button",
10866
+ size: "small",
10867
+ onClick: editing ? onSubmit : () => {
10868
+ setEditing(true);
10869
+ },
10870
+ disabled: isPending,
10871
+ children: editing ? /* @__PURE__ */ jsx(Check, {}) : /* @__PURE__ */ jsx(PencilSquare, {})
10872
+ }
10873
+ )
10874
+ ] }) }) });
10870
10875
  };
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)
10876
+ const StackedModalTrigger$1 = ({
10877
+ type,
10878
+ setModalContent
10879
+ }) => {
10880
+ const { setIsOpen } = useStackedModal();
10881
+ const onClick = useCallback(() => {
10882
+ setModalContent(type);
10883
+ setIsOpen(STACKED_MODAL_ID, true);
10884
+ }, [setModalContent, setIsOpen, type]);
10885
+ return /* @__PURE__ */ jsx(StackedFocusModal.Trigger, { asChild: true, children: /* @__PURE__ */ jsx(DropdownMenu.Item, { onClick, children: type === "add-items" ? "Add items" : "Add custom item" }) });
10886
+ };
10887
+ const VARIANT_PREFIX = "items";
10888
+ const LIMIT = 50;
10889
+ const ExistingItemsForm = ({ orderId, items }) => {
10890
+ const { setIsOpen } = useStackedModal();
10891
+ const [rowSelection, setRowSelection] = useState(
10892
+ items.reduce((acc, item) => {
10893
+ acc[item.variant_id] = true;
10894
+ return acc;
10895
+ }, {})
10896
+ );
10897
+ useEffect(() => {
10898
+ setRowSelection(
10899
+ items.reduce((acc, item) => {
10900
+ if (item.variant_id) {
10901
+ acc[item.variant_id] = true;
10902
+ }
10903
+ return acc;
10904
+ }, {})
10905
+ );
10906
+ }, [items]);
10907
+ const { q, order, offset } = useQueryParams(
10908
+ ["q", "order", "offset"],
10909
+ VARIANT_PREFIX
10910
+ );
10911
+ const { variants, count, isPending, isError, error } = useProductVariants(
10912
+ {
10913
+ q,
10914
+ order,
10915
+ offset: offset ? parseInt(offset) : void 0,
10916
+ limit: LIMIT
10880
10917
  },
10881
- resolver: zodResolver(MetadataSchema)
10882
- });
10883
- const handleSubmit = form.handleSubmit(async (data) => {
10884
- const parsedData = parseValues(data);
10918
+ {
10919
+ placeholderData: keepPreviousData
10920
+ }
10921
+ );
10922
+ const columns = useColumns();
10923
+ const { mutateAsync } = useDraftOrderAddItems(orderId);
10924
+ const onSubmit = async () => {
10925
+ const ids = Object.keys(rowSelection).filter(
10926
+ (id) => !items.find((i) => i.variant_id === id)
10927
+ );
10885
10928
  await mutateAsync(
10886
10929
  {
10887
- metadata: parsedData
10930
+ items: ids.map((id) => ({
10931
+ variant_id: id,
10932
+ quantity: 1
10933
+ }))
10888
10934
  },
10889
10935
  {
10890
10936
  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 = "[ ... ]";
10941
- }
10942
- return /* @__PURE__ */ jsx(
10943
- ConditionalTooltip,
10944
- {
10945
- showTooltip: isDisabled,
10946
- content: "This row is disabled because it contains non-primitive data.",
10947
- children: /* @__PURE__ */ jsxs("div", { className: "group/table relative", children: [
10948
- /* @__PURE__ */ jsxs(
10949
- "div",
10950
- {
10951
- className: clx("grid grid-cols-2 divide-x", {
10952
- "overflow-hidden rounded-b-lg": index === fields.length - 1
10953
- }),
10954
- children: [
10955
- /* @__PURE__ */ jsx(
10956
- Form$2.Field,
10957
- {
10958
- control: form.control,
10959
- name: `metadata.${index}.key`,
10960
- render: ({ field: field2 }) => {
10961
- return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
10962
- GridInput,
10963
- {
10964
- "aria-labelledby": METADATA_KEY_LABEL_ID,
10965
- ...field2,
10966
- disabled: isDisabled,
10967
- placeholder: "Key"
10968
- }
10969
- ) }) });
10970
- }
10971
- }
10972
- ),
10973
- /* @__PURE__ */ jsx(
10974
- Form$2.Field,
10975
- {
10976
- control: form.control,
10977
- name: `metadata.${index}.value`,
10978
- render: ({ field: { value, ...field2 } }) => {
10979
- return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
10980
- GridInput,
10981
- {
10982
- "aria-labelledby": METADATA_VALUE_LABEL_ID,
10983
- ...field2,
10984
- value: isDisabled ? placeholder : value,
10985
- disabled: isDisabled,
10986
- placeholder: "Value"
10987
- }
10988
- ) }) });
10989
- }
10990
- }
10991
- )
10992
- ]
10993
- }
10994
- ),
10995
- /* @__PURE__ */ jsxs(DropdownMenu, { children: [
10996
- /* @__PURE__ */ jsx(
10997
- DropdownMenu.Trigger,
10998
- {
10999
- className: clx(
11000
- "invisible absolute inset-y-0 -right-2.5 my-auto group-hover/table:visible data-[state='open']:visible",
11001
- {
11002
- hidden: isDisabled
11003
- }
11004
- ),
11005
- disabled: isDisabled,
11006
- asChild: true,
11007
- children: /* @__PURE__ */ jsx(IconButton, { size: "2xsmall", children: /* @__PURE__ */ jsx(EllipsisVertical, {}) })
11008
- }
11009
- ),
11010
- /* @__PURE__ */ jsxs(DropdownMenu.Content, { children: [
11011
- /* @__PURE__ */ jsxs(
11012
- DropdownMenu.Item,
11013
- {
11014
- className: "gap-x-2",
11015
- onClick: () => insertRow(index, "above"),
11016
- children: [
11017
- /* @__PURE__ */ jsx(ArrowUpMini, { className: "text-ui-fg-subtle" }),
11018
- "Insert row above"
11019
- ]
11020
- }
11021
- ),
11022
- /* @__PURE__ */ jsxs(
11023
- DropdownMenu.Item,
11024
- {
11025
- className: "gap-x-2",
11026
- onClick: () => insertRow(index, "below"),
11027
- children: [
11028
- /* @__PURE__ */ jsx(ArrowDownMini, { className: "text-ui-fg-subtle" }),
11029
- "Insert row below"
11030
- ]
11031
- }
11032
- ),
11033
- /* @__PURE__ */ jsx(DropdownMenu.Separator, {}),
11034
- /* @__PURE__ */ jsxs(
11035
- DropdownMenu.Item,
11036
- {
11037
- className: "gap-x-2",
11038
- onClick: () => deleteRow(index),
11039
- children: [
11040
- /* @__PURE__ */ jsx(Trash, { className: "text-ui-fg-subtle" }),
11041
- "Delete row"
11042
- ]
11043
- }
11044
- )
11045
- ] })
11046
- ] })
11047
- ] })
11048
- },
11049
- field.id
11050
- );
11051
- })
11052
- ] }),
11053
- hasUneditableRows && /* @__PURE__ */ jsx(InlineTip, { variant: "warning", label: "Some rows are disabled", children: "This object contains non-primitive metadata, such as arrays or objects, that can't be edited here. To edit the disabled rows, use the API directly." })
10937
+ setRowSelection({});
10938
+ setIsOpen(STACKED_MODAL_ID, false);
10939
+ },
10940
+ onError: (e) => {
10941
+ toast.error(e.message);
10942
+ }
10943
+ }
10944
+ );
10945
+ };
10946
+ if (isError) {
10947
+ throw error;
10948
+ }
10949
+ return /* @__PURE__ */ jsxs(
10950
+ StackedFocusModal.Content,
10951
+ {
10952
+ onOpenAutoFocus: (e) => {
10953
+ e.preventDefault();
10954
+ const searchInput = document.querySelector(
10955
+ "[data-modal-id='modal-search-input']"
10956
+ );
10957
+ if (searchInput) {
10958
+ searchInput.focus();
10959
+ }
10960
+ },
10961
+ children: [
10962
+ /* @__PURE__ */ jsxs(StackedFocusModal.Header, { children: [
10963
+ /* @__PURE__ */ jsx(StackedFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Product Variants" }) }),
10964
+ /* @__PURE__ */ jsx(StackedFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Choose product variants to add to the order." }) })
11054
10965
  ] }),
11055
- /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
11056
- /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
11057
- /* @__PURE__ */ jsx(Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
10966
+ /* @__PURE__ */ jsx(StackedFocusModal.Body, { className: "flex-1 overflow-hidden", children: /* @__PURE__ */ jsx(
10967
+ DataTable,
10968
+ {
10969
+ data: variants,
10970
+ columns,
10971
+ isLoading: isPending,
10972
+ getRowId: (row) => row.id,
10973
+ rowCount: count,
10974
+ prefix: VARIANT_PREFIX,
10975
+ layout: "fill",
10976
+ rowSelection: {
10977
+ state: rowSelection,
10978
+ onRowSelectionChange: setRowSelection,
10979
+ enableRowSelection: (row) => {
10980
+ return !items.find((i) => i.variant_id === row.original.id);
10981
+ }
10982
+ },
10983
+ autoFocusSearch: true
10984
+ }
10985
+ ) }),
10986
+ /* @__PURE__ */ jsx(StackedFocusModal.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
10987
+ /* @__PURE__ */ jsx(StackedFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
10988
+ /* @__PURE__ */ jsx(Button, { size: "small", type: "button", onClick: onSubmit, children: "Update items" })
11058
10989
  ] }) })
11059
10990
  ]
11060
10991
  }
11061
- ) });
11062
- };
11063
- const GridInput = forwardRef(({ className, ...props }, ref) => {
11064
- return /* @__PURE__ */ jsx(
11065
- "input",
11066
- {
11067
- ref,
11068
- ...props,
11069
- autoComplete: "off",
11070
- className: clx(
11071
- "txt-compact-small text-ui-fg-base placeholder:text-ui-fg-muted disabled:text-ui-fg-disabled disabled:bg-ui-bg-base bg-transparent px-2 py-1.5 outline-none",
11072
- className
11073
- )
11074
- }
11075
10992
  );
11076
- });
11077
- GridInput.displayName = "MetadataForm.GridInput";
11078
- const PlaceholderInner = () => {
11079
- return /* @__PURE__ */ jsxs("div", { className: "flex flex-1 flex-col overflow-hidden", children: [
11080
- /* @__PURE__ */ jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsx(Skeleton, { className: "h-[148ox] w-full rounded-lg" }) }),
11081
- /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
11082
- /* @__PURE__ */ jsx(Skeleton, { className: "h-7 w-12 rounded-md" }),
11083
- /* @__PURE__ */ jsx(Skeleton, { className: "h-7 w-12 rounded-md" })
11084
- ] }) })
11085
- ] });
11086
10993
  };
11087
- const EDITABLE_TYPES = ["string", "number", "boolean"];
11088
- function getDefaultValues(metadata) {
11089
- if (!metadata || !Object.keys(metadata).length) {
10994
+ const columnHelper = createDataTableColumnHelper();
10995
+ const useColumns = () => {
10996
+ return useMemo(() => {
11090
10997
  return [
11091
- {
11092
- key: "",
11093
- value: "",
11094
- disabled: false
11095
- }
10998
+ columnHelper.select(),
10999
+ columnHelper.accessor("product.title", {
11000
+ header: "Product",
11001
+ cell: ({ row }) => {
11002
+ var _a, _b, _c;
11003
+ return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-2", children: [
11004
+ /* @__PURE__ */ jsx(
11005
+ Thumbnail,
11006
+ {
11007
+ thumbnail: (_a = row.original.product) == null ? void 0 : _a.thumbnail,
11008
+ alt: (_b = row.original.product) == null ? void 0 : _b.title
11009
+ }
11010
+ ),
11011
+ /* @__PURE__ */ jsx("span", { children: (_c = row.original.product) == null ? void 0 : _c.title })
11012
+ ] });
11013
+ },
11014
+ enableSorting: true
11015
+ }),
11016
+ columnHelper.accessor("title", {
11017
+ header: "Variant",
11018
+ enableSorting: true
11019
+ }),
11020
+ columnHelper.accessor("sku", {
11021
+ header: "SKU",
11022
+ cell: ({ getValue }) => {
11023
+ return getValue() ?? "-";
11024
+ },
11025
+ enableSorting: true
11026
+ }),
11027
+ columnHelper.accessor("updated_at", {
11028
+ header: "Updated",
11029
+ cell: ({ getValue }) => {
11030
+ return /* @__PURE__ */ jsx(
11031
+ Tooltip,
11032
+ {
11033
+ content: getFullDate({ date: getValue(), includeTime: true }),
11034
+ children: /* @__PURE__ */ jsx("span", { children: getFullDate({ date: getValue() }) })
11035
+ }
11036
+ );
11037
+ },
11038
+ enableSorting: true,
11039
+ sortAscLabel: "Oldest first",
11040
+ sortDescLabel: "Newest first"
11041
+ }),
11042
+ columnHelper.accessor("created_at", {
11043
+ header: "Created",
11044
+ cell: ({ getValue }) => {
11045
+ return /* @__PURE__ */ jsx(
11046
+ Tooltip,
11047
+ {
11048
+ content: getFullDate({ date: getValue(), includeTime: true }),
11049
+ children: /* @__PURE__ */ jsx("span", { children: getFullDate({ date: getValue() }) })
11050
+ }
11051
+ );
11052
+ },
11053
+ enableSorting: true,
11054
+ sortAscLabel: "Oldest first",
11055
+ sortDescLabel: "Newest first"
11056
+ })
11096
11057
  ];
11097
- }
11098
- return Object.entries(metadata).map(([key, value]) => {
11099
- if (!EDITABLE_TYPES.includes(typeof value)) {
11100
- return {
11101
- key,
11102
- value,
11103
- disabled: true
11104
- };
11105
- }
11106
- let stringValue = value;
11107
- if (typeof value !== "string") {
11108
- stringValue = JSON.stringify(value);
11109
- }
11110
- return {
11111
- key,
11112
- value: stringValue,
11113
- original_key: key
11114
- };
11058
+ }, []);
11059
+ };
11060
+ const CustomItemForm = ({ orderId, currencyCode }) => {
11061
+ const { setIsOpen } = useStackedModal();
11062
+ const { mutateAsync: addItems } = useDraftOrderAddItems(orderId);
11063
+ const form = useForm({
11064
+ defaultValues: {
11065
+ title: "",
11066
+ quantity: 1,
11067
+ unit_price: ""
11068
+ },
11069
+ resolver: zodResolver(customItemSchema)
11115
11070
  });
11116
- }
11117
- function parseValues(values) {
11118
- const metadata = values.metadata;
11119
- const isEmpty = !metadata.length || metadata.length === 1 && !metadata[0].key && !metadata[0].value;
11120
- if (isEmpty) {
11121
- return null;
11122
- }
11123
- const update = {};
11124
- metadata.forEach((field) => {
11125
- let key = field.key;
11126
- let value = field.value;
11127
- const disabled = field.disabled;
11128
- if (!key || !value) {
11129
- return;
11130
- }
11131
- if (disabled) {
11132
- update[key] = value;
11133
- return;
11134
- }
11135
- key = key.trim();
11136
- value = value.trim();
11137
- if (value === "true") {
11138
- update[key] = true;
11139
- } else if (value === "false") {
11140
- update[key] = false;
11141
- } else {
11142
- const parsedNumber = parseFloat(value);
11143
- if (!isNaN(parsedNumber)) {
11144
- update[key] = parsedNumber;
11145
- } else {
11146
- update[key] = value;
11071
+ const onSubmit = form.handleSubmit(async (data) => {
11072
+ await addItems(
11073
+ {
11074
+ items: [
11075
+ {
11076
+ title: data.title,
11077
+ quantity: data.quantity,
11078
+ unit_price: convertNumber(data.unit_price)
11079
+ }
11080
+ ]
11081
+ },
11082
+ {
11083
+ onSuccess: () => {
11084
+ setIsOpen(STACKED_MODAL_ID, false);
11085
+ },
11086
+ onError: (e) => {
11087
+ toast.error(e.message);
11088
+ }
11147
11089
  }
11148
- }
11090
+ );
11149
11091
  });
11150
- return update;
11151
- }
11152
- function getHasUneditableRows(metadata) {
11153
- if (!metadata) {
11154
- return false;
11155
- }
11156
- return Object.values(metadata).some(
11157
- (value) => !EDITABLE_TYPES.includes(typeof value)
11158
- );
11159
- }
11092
+ return /* @__PURE__ */ jsx(Form$2, { ...form, children: /* @__PURE__ */ jsx(KeyboundForm, { onSubmit, children: /* @__PURE__ */ jsxs(StackedFocusModal.Content, { children: [
11093
+ /* @__PURE__ */ jsx(StackedFocusModal.Header, {}),
11094
+ /* @__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: [
11095
+ /* @__PURE__ */ jsxs("div", { children: [
11096
+ /* @__PURE__ */ jsx(StackedFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Add custom item" }) }),
11097
+ /* @__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." }) })
11098
+ ] }),
11099
+ /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
11100
+ /* @__PURE__ */ jsx(
11101
+ Form$2.Field,
11102
+ {
11103
+ control: form.control,
11104
+ name: "title",
11105
+ render: ({ field }) => /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
11106
+ /* @__PURE__ */ jsxs("div", { children: [
11107
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Title" }),
11108
+ /* @__PURE__ */ jsx(Form$2.Hint, { children: "Enter the title of the item" })
11109
+ ] }),
11110
+ /* @__PURE__ */ jsxs("div", { children: [
11111
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
11112
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11113
+ ] })
11114
+ ] }) })
11115
+ }
11116
+ ),
11117
+ /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
11118
+ /* @__PURE__ */ jsx(
11119
+ Form$2.Field,
11120
+ {
11121
+ control: form.control,
11122
+ name: "unit_price",
11123
+ render: ({ field: { onChange, ...field } }) => /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
11124
+ /* @__PURE__ */ jsxs("div", { children: [
11125
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Unit price" }),
11126
+ /* @__PURE__ */ jsx(Form$2.Hint, { children: "Enter the unit price of the item" })
11127
+ ] }),
11128
+ /* @__PURE__ */ jsxs("div", { children: [
11129
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
11130
+ CurrencyInput,
11131
+ {
11132
+ symbol: getNativeSymbol(currencyCode),
11133
+ code: currencyCode,
11134
+ onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value),
11135
+ ...field
11136
+ }
11137
+ ) }),
11138
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11139
+ ] })
11140
+ ] }) })
11141
+ }
11142
+ ),
11143
+ /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
11144
+ /* @__PURE__ */ jsx(
11145
+ Form$2.Field,
11146
+ {
11147
+ control: form.control,
11148
+ name: "quantity",
11149
+ render: ({ field }) => /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
11150
+ /* @__PURE__ */ jsxs("div", { children: [
11151
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Quantity" }),
11152
+ /* @__PURE__ */ jsx(Form$2.Hint, { children: "Enter the quantity of the item" })
11153
+ ] }),
11154
+ /* @__PURE__ */ jsxs("div", { className: "w-full flex-1", children: [
11155
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsx(NumberInput, { ...field, className: "w-full" }) }) }),
11156
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11157
+ ] })
11158
+ ] }) })
11159
+ }
11160
+ )
11161
+ ] }) }) }),
11162
+ /* @__PURE__ */ jsx(StackedFocusModal.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
11163
+ /* @__PURE__ */ jsx(StackedFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
11164
+ /* @__PURE__ */ jsx(Button, { size: "small", type: "button", onClick: onSubmit, children: "Add item" })
11165
+ ] }) })
11166
+ ] }) }) });
11167
+ };
11168
+ const customItemSchema = objectType({
11169
+ title: stringType().min(1),
11170
+ quantity: numberType(),
11171
+ unit_price: unionType([numberType(), stringType()])
11172
+ });
11160
11173
  const PROMOTION_QUERY_KEY = "promotions";
11161
11174
  const promotionsQueryKeys = {
11162
11175
  list: (query2) => [
@@ -11201,22 +11214,22 @@ const PromotionForm = ({ preview }) => {
11201
11214
  const [comboboxValue, setComboboxValue] = useState("");
11202
11215
  const { handleSuccess } = useRouteModal();
11203
11216
  const { mutateAsync: addPromotions, isPending: isAddingPromotions } = useDraftOrderAddPromotions(preview.id);
11204
- const promoCodes = getPromotionCodes(items, shipping_methods);
11217
+ const promoIds = getPromotionIds(items, shipping_methods);
11205
11218
  const { promotions, isPending, isError, error } = usePromotions(
11206
11219
  {
11207
- code: promoCodes
11220
+ id: promoIds
11208
11221
  },
11209
11222
  {
11210
- enabled: !!promoCodes.length
11223
+ enabled: !!promoIds.length
11211
11224
  }
11212
11225
  );
11213
11226
  const comboboxData = useComboboxData({
11214
- queryKey: ["promotions", "combobox", promoCodes],
11227
+ queryKey: ["promotions", "combobox", promoIds],
11215
11228
  queryFn: async (params) => {
11216
11229
  return await sdk.admin.promotion.list({
11217
11230
  ...params,
11218
- code: {
11219
- $nin: promoCodes
11231
+ id: {
11232
+ $nin: promoIds
11220
11233
  }
11221
11234
  });
11222
11235
  },
@@ -11352,7 +11365,7 @@ const PromotionItem = ({
11352
11365
  "div",
11353
11366
  {
11354
11367
  className: clx(
11355
- "px-3 py-2 rounded-lg bg-ui-bg-component shadow-elevation-card-rest flex items-center justify-between",
11368
+ "bg-ui-bg-component shadow-elevation-card-rest flex items-center justify-between rounded-lg px-3 py-2",
11356
11369
  {
11357
11370
  "animate-pulse": isLoading
11358
11371
  }
@@ -11360,7 +11373,7 @@ const PromotionItem = ({
11360
11373
  children: [
11361
11374
  /* @__PURE__ */ jsxs("div", { children: [
11362
11375
  /* @__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: [
11376
+ /* @__PURE__ */ jsxs("div", { className: "text-ui-fg-subtle flex items-center gap-1.5", children: [
11364
11377
  displayValue && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
11365
11378
  /* @__PURE__ */ jsx(Text, { size: "small", leading: "compact", children: displayValue }),
11366
11379
  /* @__PURE__ */ jsx(Text, { size: "small", leading: "compact", children: "·" })
@@ -11412,13 +11425,13 @@ const formatPercentage = (value, isPercentageValue = false) => {
11412
11425
  }
11413
11426
  return formatter.format(val);
11414
11427
  };
11415
- function getPromotionCodes(items, shippingMethods) {
11416
- const codes = /* @__PURE__ */ new Set();
11428
+ function getPromotionIds(items, shippingMethods) {
11429
+ const promotionIds = /* @__PURE__ */ new Set();
11417
11430
  for (const item of items) {
11418
11431
  if (item.adjustments) {
11419
11432
  for (const adjustment of item.adjustments) {
11420
- if (adjustment.code) {
11421
- codes.add(adjustment.code);
11433
+ if (adjustment.promotion_id) {
11434
+ promotionIds.add(adjustment.promotion_id);
11422
11435
  }
11423
11436
  }
11424
11437
  }
@@ -11426,13 +11439,13 @@ function getPromotionCodes(items, shippingMethods) {
11426
11439
  for (const shippingMethod of shippingMethods) {
11427
11440
  if (shippingMethod.adjustments) {
11428
11441
  for (const adjustment of shippingMethod.adjustments) {
11429
- if (adjustment.code) {
11430
- codes.add(adjustment.code);
11442
+ if (adjustment.promotion_id) {
11443
+ promotionIds.add(adjustment.promotion_id);
11431
11444
  }
11432
11445
  }
11433
11446
  }
11434
11447
  }
11435
- return Array.from(codes);
11448
+ return Array.from(promotionIds);
11436
11449
  }
11437
11450
  const SalesChannel = () => {
11438
11451
  const { id } = useParams();
@@ -11522,24 +11535,227 @@ const SalesChannelField = ({ control, order }) => {
11522
11535
  /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
11523
11536
  Combobox,
11524
11537
  {
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
11538
+ options: salesChannels.options,
11539
+ fetchNextPage: salesChannels.fetchNextPage,
11540
+ isFetchingNextPage: salesChannels.isFetchingNextPage,
11541
+ searchValue: salesChannels.searchValue,
11542
+ onSearchValueChange: salesChannels.onSearchValueChange,
11543
+ placeholder: "Select sales channel",
11544
+ ...field
11545
+ }
11546
+ ) }),
11547
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11548
+ ] });
11549
+ }
11550
+ }
11551
+ );
11552
+ };
11553
+ const schema$2 = objectType({
11554
+ sales_channel_id: stringType().min(1)
11555
+ });
11556
+ const ShippingAddress = () => {
11557
+ const { id } = useParams();
11558
+ const { order, isPending, isError, error } = useOrder(id, {
11559
+ fields: "+shipping_address"
11560
+ });
11561
+ if (isError) {
11562
+ throw error;
11563
+ }
11564
+ const isReady = !isPending && !!order;
11565
+ return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
11566
+ /* @__PURE__ */ jsxs(RouteDrawer.Header, { children: [
11567
+ /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Shipping Address" }) }),
11568
+ /* @__PURE__ */ jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Edit the shipping address for the draft order" }) })
11569
+ ] }),
11570
+ isReady && /* @__PURE__ */ jsx(ShippingAddressForm, { order })
11571
+ ] });
11572
+ };
11573
+ const ShippingAddressForm = ({ order }) => {
11574
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
11575
+ const form = useForm({
11576
+ defaultValues: {
11577
+ first_name: ((_a = order.shipping_address) == null ? void 0 : _a.first_name) ?? "",
11578
+ last_name: ((_b = order.shipping_address) == null ? void 0 : _b.last_name) ?? "",
11579
+ company: ((_c = order.shipping_address) == null ? void 0 : _c.company) ?? "",
11580
+ address_1: ((_d = order.shipping_address) == null ? void 0 : _d.address_1) ?? "",
11581
+ address_2: ((_e = order.shipping_address) == null ? void 0 : _e.address_2) ?? "",
11582
+ city: ((_f = order.shipping_address) == null ? void 0 : _f.city) ?? "",
11583
+ province: ((_g = order.shipping_address) == null ? void 0 : _g.province) ?? "",
11584
+ country_code: ((_h = order.shipping_address) == null ? void 0 : _h.country_code) ?? "",
11585
+ postal_code: ((_i = order.shipping_address) == null ? void 0 : _i.postal_code) ?? "",
11586
+ phone: ((_j = order.shipping_address) == null ? void 0 : _j.phone) ?? ""
11587
+ },
11588
+ resolver: zodResolver(schema$1)
11589
+ });
11590
+ const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
11591
+ const { handleSuccess } = useRouteModal();
11592
+ const onSubmit = form.handleSubmit(async (data) => {
11593
+ await mutateAsync(
11594
+ {
11595
+ shipping_address: {
11596
+ first_name: data.first_name,
11597
+ last_name: data.last_name,
11598
+ company: data.company,
11599
+ address_1: data.address_1,
11600
+ address_2: data.address_2,
11601
+ city: data.city,
11602
+ province: data.province,
11603
+ country_code: data.country_code,
11604
+ postal_code: data.postal_code,
11605
+ phone: data.phone
11606
+ }
11607
+ },
11608
+ {
11609
+ onSuccess: () => {
11610
+ handleSuccess();
11611
+ },
11612
+ onError: (error) => {
11613
+ toast.error(error.message);
11614
+ }
11615
+ }
11616
+ );
11617
+ });
11618
+ return /* @__PURE__ */ jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxs(
11619
+ KeyboundForm,
11620
+ {
11621
+ className: "flex flex-1 flex-col overflow-hidden",
11622
+ onSubmit,
11623
+ children: [
11624
+ /* @__PURE__ */ jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-y-4", children: [
11625
+ /* @__PURE__ */ jsx(
11626
+ Form$2.Field,
11627
+ {
11628
+ control: form.control,
11629
+ name: "country_code",
11630
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
11631
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Country" }),
11632
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(CountrySelect, { ...field }) }),
11633
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11634
+ ] })
11635
+ }
11636
+ ),
11637
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
11638
+ /* @__PURE__ */ jsx(
11639
+ Form$2.Field,
11640
+ {
11641
+ control: form.control,
11642
+ name: "first_name",
11643
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
11644
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "First name" }),
11645
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
11646
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11647
+ ] })
11648
+ }
11649
+ ),
11650
+ /* @__PURE__ */ jsx(
11651
+ Form$2.Field,
11652
+ {
11653
+ control: form.control,
11654
+ name: "last_name",
11655
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
11656
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Last name" }),
11657
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
11658
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11659
+ ] })
11660
+ }
11661
+ )
11662
+ ] }),
11663
+ /* @__PURE__ */ jsx(
11664
+ Form$2.Field,
11665
+ {
11666
+ control: form.control,
11667
+ name: "company",
11668
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
11669
+ /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Company" }),
11670
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
11671
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11672
+ ] })
11673
+ }
11674
+ ),
11675
+ /* @__PURE__ */ jsx(
11676
+ Form$2.Field,
11677
+ {
11678
+ control: form.control,
11679
+ name: "address_1",
11680
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
11681
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Address" }),
11682
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
11683
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11684
+ ] })
11685
+ }
11686
+ ),
11687
+ /* @__PURE__ */ jsx(
11688
+ Form$2.Field,
11689
+ {
11690
+ control: form.control,
11691
+ name: "address_2",
11692
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
11693
+ /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Apartment, suite, etc." }),
11694
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
11695
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11696
+ ] })
11697
+ }
11698
+ ),
11699
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
11700
+ /* @__PURE__ */ jsx(
11701
+ Form$2.Field,
11702
+ {
11703
+ control: form.control,
11704
+ name: "postal_code",
11705
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
11706
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Postal code" }),
11707
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
11708
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11709
+ ] })
11710
+ }
11711
+ ),
11712
+ /* @__PURE__ */ jsx(
11713
+ Form$2.Field,
11714
+ {
11715
+ control: form.control,
11716
+ name: "city",
11717
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
11718
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "City" }),
11719
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
11720
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11721
+ ] })
11722
+ }
11723
+ )
11724
+ ] }),
11725
+ /* @__PURE__ */ jsx(
11726
+ Form$2.Field,
11727
+ {
11728
+ control: form.control,
11729
+ name: "province",
11730
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
11731
+ /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Province / State" }),
11732
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
11733
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11734
+ ] })
11735
+ }
11736
+ ),
11737
+ /* @__PURE__ */ jsx(
11738
+ Form$2.Field,
11739
+ {
11740
+ control: form.control,
11741
+ name: "phone",
11742
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
11743
+ /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Phone" }),
11744
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
11745
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11746
+ ] })
11532
11747
  }
11533
- ) }),
11534
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11535
- ] });
11536
- }
11748
+ )
11749
+ ] }) }),
11750
+ /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
11751
+ /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
11752
+ /* @__PURE__ */ jsx(Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
11753
+ ] }) })
11754
+ ]
11537
11755
  }
11538
- );
11756
+ ) });
11539
11757
  };
11540
- const schema$2 = objectType({
11541
- sales_channel_id: stringType().min(1)
11542
- });
11758
+ const schema$1 = addressSchema;
11543
11759
  const STACKED_FOCUS_MODAL_ID = "shipping-form";
11544
11760
  const Shipping = () => {
11545
11761
  var _a;
@@ -12347,209 +12563,6 @@ const CustomAmountField = ({
12347
12563
  }
12348
12564
  );
12349
12565
  };
12350
- const ShippingAddress = () => {
12351
- const { id } = useParams();
12352
- const { order, isPending, isError, error } = useOrder(id, {
12353
- fields: "+shipping_address"
12354
- });
12355
- if (isError) {
12356
- throw error;
12357
- }
12358
- const isReady = !isPending && !!order;
12359
- return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
12360
- /* @__PURE__ */ jsxs(RouteDrawer.Header, { children: [
12361
- /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Shipping Address" }) }),
12362
- /* @__PURE__ */ jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Edit the shipping address for the draft order" }) })
12363
- ] }),
12364
- isReady && /* @__PURE__ */ jsx(ShippingAddressForm, { order })
12365
- ] });
12366
- };
12367
- const ShippingAddressForm = ({ order }) => {
12368
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
12369
- const form = useForm({
12370
- defaultValues: {
12371
- first_name: ((_a = order.shipping_address) == null ? void 0 : _a.first_name) ?? "",
12372
- last_name: ((_b = order.shipping_address) == null ? void 0 : _b.last_name) ?? "",
12373
- company: ((_c = order.shipping_address) == null ? void 0 : _c.company) ?? "",
12374
- address_1: ((_d = order.shipping_address) == null ? void 0 : _d.address_1) ?? "",
12375
- address_2: ((_e = order.shipping_address) == null ? void 0 : _e.address_2) ?? "",
12376
- city: ((_f = order.shipping_address) == null ? void 0 : _f.city) ?? "",
12377
- province: ((_g = order.shipping_address) == null ? void 0 : _g.province) ?? "",
12378
- country_code: ((_h = order.shipping_address) == null ? void 0 : _h.country_code) ?? "",
12379
- postal_code: ((_i = order.shipping_address) == null ? void 0 : _i.postal_code) ?? "",
12380
- phone: ((_j = order.shipping_address) == null ? void 0 : _j.phone) ?? ""
12381
- },
12382
- resolver: zodResolver(schema$1)
12383
- });
12384
- const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
12385
- const { handleSuccess } = useRouteModal();
12386
- const onSubmit = form.handleSubmit(async (data) => {
12387
- await mutateAsync(
12388
- {
12389
- shipping_address: {
12390
- first_name: data.first_name,
12391
- last_name: data.last_name,
12392
- company: data.company,
12393
- address_1: data.address_1,
12394
- address_2: data.address_2,
12395
- city: data.city,
12396
- province: data.province,
12397
- country_code: data.country_code,
12398
- postal_code: data.postal_code,
12399
- phone: data.phone
12400
- }
12401
- },
12402
- {
12403
- onSuccess: () => {
12404
- handleSuccess();
12405
- },
12406
- onError: (error) => {
12407
- toast.error(error.message);
12408
- }
12409
- }
12410
- );
12411
- });
12412
- return /* @__PURE__ */ jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxs(
12413
- KeyboundForm,
12414
- {
12415
- className: "flex flex-1 flex-col overflow-hidden",
12416
- onSubmit,
12417
- children: [
12418
- /* @__PURE__ */ jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-y-4", children: [
12419
- /* @__PURE__ */ jsx(
12420
- Form$2.Field,
12421
- {
12422
- control: form.control,
12423
- name: "country_code",
12424
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12425
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Country" }),
12426
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(CountrySelect, { ...field }) }),
12427
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12428
- ] })
12429
- }
12430
- ),
12431
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
12432
- /* @__PURE__ */ jsx(
12433
- Form$2.Field,
12434
- {
12435
- control: form.control,
12436
- name: "first_name",
12437
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12438
- /* @__PURE__ */ jsx(Form$2.Label, { children: "First name" }),
12439
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12440
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12441
- ] })
12442
- }
12443
- ),
12444
- /* @__PURE__ */ jsx(
12445
- Form$2.Field,
12446
- {
12447
- control: form.control,
12448
- name: "last_name",
12449
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12450
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Last name" }),
12451
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12452
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12453
- ] })
12454
- }
12455
- )
12456
- ] }),
12457
- /* @__PURE__ */ jsx(
12458
- Form$2.Field,
12459
- {
12460
- control: form.control,
12461
- name: "company",
12462
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12463
- /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Company" }),
12464
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12465
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12466
- ] })
12467
- }
12468
- ),
12469
- /* @__PURE__ */ jsx(
12470
- Form$2.Field,
12471
- {
12472
- control: form.control,
12473
- name: "address_1",
12474
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12475
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Address" }),
12476
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12477
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12478
- ] })
12479
- }
12480
- ),
12481
- /* @__PURE__ */ jsx(
12482
- Form$2.Field,
12483
- {
12484
- control: form.control,
12485
- name: "address_2",
12486
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12487
- /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Apartment, suite, etc." }),
12488
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12489
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12490
- ] })
12491
- }
12492
- ),
12493
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
12494
- /* @__PURE__ */ jsx(
12495
- Form$2.Field,
12496
- {
12497
- control: form.control,
12498
- name: "postal_code",
12499
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12500
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Postal code" }),
12501
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12502
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12503
- ] })
12504
- }
12505
- ),
12506
- /* @__PURE__ */ jsx(
12507
- Form$2.Field,
12508
- {
12509
- control: form.control,
12510
- name: "city",
12511
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12512
- /* @__PURE__ */ jsx(Form$2.Label, { children: "City" }),
12513
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12514
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12515
- ] })
12516
- }
12517
- )
12518
- ] }),
12519
- /* @__PURE__ */ jsx(
12520
- Form$2.Field,
12521
- {
12522
- control: form.control,
12523
- name: "province",
12524
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12525
- /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Province / State" }),
12526
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12527
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12528
- ] })
12529
- }
12530
- ),
12531
- /* @__PURE__ */ jsx(
12532
- Form$2.Field,
12533
- {
12534
- control: form.control,
12535
- name: "phone",
12536
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12537
- /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Phone" }),
12538
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12539
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12540
- ] })
12541
- }
12542
- )
12543
- ] }) }),
12544
- /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
12545
- /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
12546
- /* @__PURE__ */ jsx(Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
12547
- ] }) })
12548
- ]
12549
- }
12550
- ) });
12551
- };
12552
- const schema$1 = addressSchema;
12553
12566
  const TransferOwnership = () => {
12554
12567
  const { id } = useParams();
12555
12568
  const { draft_order, isPending, isError, error } = useDraftOrder(id, {
@@ -13058,14 +13071,14 @@ const routeModule = {
13058
13071
  Component: Email,
13059
13072
  path: "/draft-orders/:id/email"
13060
13073
  },
13061
- {
13062
- Component: Items,
13063
- path: "/draft-orders/:id/items"
13064
- },
13065
13074
  {
13066
13075
  Component: Metadata,
13067
13076
  path: "/draft-orders/:id/metadata"
13068
13077
  },
13078
+ {
13079
+ Component: Items,
13080
+ path: "/draft-orders/:id/items"
13081
+ },
13069
13082
  {
13070
13083
  Component: Promotions,
13071
13084
  path: "/draft-orders/:id/promotions"
@@ -13074,14 +13087,14 @@ const routeModule = {
13074
13087
  Component: SalesChannel,
13075
13088
  path: "/draft-orders/:id/sales-channel"
13076
13089
  },
13077
- {
13078
- Component: Shipping,
13079
- path: "/draft-orders/:id/shipping"
13080
- },
13081
13090
  {
13082
13091
  Component: ShippingAddress,
13083
13092
  path: "/draft-orders/:id/shipping-address"
13084
13093
  },
13094
+ {
13095
+ Component: Shipping,
13096
+ path: "/draft-orders/:id/shipping"
13097
+ },
13085
13098
  {
13086
13099
  Component: TransferOwnership,
13087
13100
  path: "/draft-orders/:id/transfer-ownership"