@medusajs/draft-order 2.11.0-preview-20251015180203 → 2.11.0-preview-20251016000321

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";
@@ -9567,6 +9567,27 @@ const ID = () => {
9567
9567
  /* @__PURE__ */ jsx(Outlet, {})
9568
9568
  ] });
9569
9569
  };
9570
+ const CustomItems = () => {
9571
+ return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
9572
+ /* @__PURE__ */ jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Custom Items" }) }) }),
9573
+ /* @__PURE__ */ jsx(CustomItemsForm, {})
9574
+ ] });
9575
+ };
9576
+ const CustomItemsForm = () => {
9577
+ const form = useForm({
9578
+ resolver: zodResolver(schema$5)
9579
+ });
9580
+ return /* @__PURE__ */ jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxs(KeyboundForm, { className: "flex flex-1 flex-col", children: [
9581
+ /* @__PURE__ */ jsx(RouteDrawer.Body, {}),
9582
+ /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
9583
+ /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
9584
+ /* @__PURE__ */ jsx(Button, { size: "small", type: "submit", children: "Save" })
9585
+ ] }) })
9586
+ ] }) });
9587
+ };
9588
+ const schema$5 = objectType({
9589
+ email: stringType().email()
9590
+ });
9570
9591
  const BillingAddress = () => {
9571
9592
  const { id } = useParams();
9572
9593
  const { order, isPending, isError, error } = useOrder(id, {
@@ -9599,7 +9620,7 @@ const BillingAddressForm = ({ order }) => {
9599
9620
  postal_code: ((_i = order.billing_address) == null ? void 0 : _i.postal_code) ?? "",
9600
9621
  phone: ((_j = order.billing_address) == null ? void 0 : _j.phone) ?? ""
9601
9622
  },
9602
- resolver: zodResolver(schema$5)
9623
+ resolver: zodResolver(schema$4)
9603
9624
  });
9604
9625
  const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
9605
9626
  const { handleSuccess } = useRouteModal();
@@ -9756,28 +9777,7 @@ const BillingAddressForm = ({ order }) => {
9756
9777
  }
9757
9778
  ) });
9758
9779
  };
9759
- const schema$5 = addressSchema;
9760
- const CustomItems = () => {
9761
- return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
9762
- /* @__PURE__ */ jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Custom Items" }) }) }),
9763
- /* @__PURE__ */ jsx(CustomItemsForm, {})
9764
- ] });
9765
- };
9766
- const CustomItemsForm = () => {
9767
- const form = useForm({
9768
- resolver: zodResolver(schema$4)
9769
- });
9770
- return /* @__PURE__ */ jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxs(KeyboundForm, { className: "flex flex-1 flex-col", children: [
9771
- /* @__PURE__ */ jsx(RouteDrawer.Body, {}),
9772
- /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
9773
- /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
9774
- /* @__PURE__ */ jsx(Button, { size: "small", type: "submit", children: "Save" })
9775
- ] }) })
9776
- ] }) });
9777
- };
9778
- const schema$4 = objectType({
9779
- email: stringType().email()
9780
- });
9780
+ const schema$4 = addressSchema;
9781
9781
  const Email = () => {
9782
9782
  const { id } = useParams();
9783
9783
  const { order, isPending, isError, error } = useOrder(id, {
@@ -9846,573 +9846,775 @@ const EmailForm = ({ order }) => {
9846
9846
  const schema$3 = objectType({
9847
9847
  email: stringType().email()
9848
9848
  });
9849
- const NumberInput = forwardRef(
9850
- ({
9851
- value,
9852
- onChange,
9853
- size = "base",
9854
- min = 0,
9855
- max = 100,
9856
- step = 1,
9857
- className,
9858
- disabled,
9859
- ...props
9860
- }, ref) => {
9861
- const handleChange = (event) => {
9862
- const newValue = event.target.value === "" ? min : Number(event.target.value);
9863
- if (!isNaN(newValue) && (max === void 0 || newValue <= max) && (min === void 0 || newValue >= min)) {
9864
- onChange(newValue);
9865
- }
9866
- };
9867
- const handleIncrement = () => {
9868
- const newValue = value + step;
9869
- if (max === void 0 || newValue <= max) {
9870
- onChange(newValue);
9871
- }
9872
- };
9873
- const handleDecrement = () => {
9874
- const newValue = value - step;
9875
- if (min === void 0 || newValue >= min) {
9876
- onChange(newValue);
9877
- }
9878
- };
9849
+ const InlineTip = forwardRef(
9850
+ ({ variant = "tip", label, className, children, ...props }, ref) => {
9851
+ const labelValue = label || (variant === "warning" ? "Warning" : "Tip");
9879
9852
  return /* @__PURE__ */ jsxs(
9880
9853
  "div",
9881
9854
  {
9855
+ ref,
9882
9856
  className: clx(
9883
- "inline-flex rounded-md bg-ui-bg-field shadow-borders-base overflow-hidden divide-x transition-fg",
9884
- "[&:has(input:focus)]:shadow-borders-interactive-with-active",
9885
- {
9886
- "h-7": size === "small",
9887
- "h-8": size === "base"
9888
- },
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",
9889
9858
  className
9890
9859
  ),
9860
+ ...props,
9891
9861
  children: [
9892
9862
  /* @__PURE__ */ jsx(
9893
- "input",
9894
- {
9895
- ref,
9896
- type: "number",
9897
- value,
9898
- onChange: handleChange,
9899
- min,
9900
- max,
9901
- step,
9902
- className: clx(
9903
- "flex-1 px-2 py-1 bg-transparent txt-compact-small text-ui-fg-base outline-none [appearance:textfield]",
9904
- "[&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none",
9905
- "placeholder:text-ui-fg-muted"
9906
- ),
9907
- ...props
9908
- }
9909
- ),
9910
- /* @__PURE__ */ jsxs(
9911
- "button",
9863
+ "div",
9912
9864
  {
9913
- className: clx(
9914
- "flex items-center justify-center outline-none transition-fg",
9915
- "disabled:cursor-not-allowed disabled:text-ui-fg-muted",
9916
- "focus:bg-ui-bg-field-component-hover",
9917
- "hover:bg-ui-bg-field-component-hover",
9918
- {
9919
- "size-7": size === "small",
9920
- "size-8": size === "base"
9921
- }
9922
- ),
9923
- type: "button",
9924
- onClick: handleDecrement,
9925
- disabled: min !== void 0 && value <= min || disabled,
9926
- children: [
9927
- /* @__PURE__ */ jsx(Minus, {}),
9928
- /* @__PURE__ */ jsx("span", { className: "sr-only", children: `Decrease by ${step}` })
9929
- ]
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
+ })
9930
9869
  }
9931
9870
  ),
9932
- /* @__PURE__ */ jsxs(
9933
- "button",
9934
- {
9935
- className: clx(
9936
- "flex items-center justify-center outline-none transition-fg",
9937
- "disabled:cursor-not-allowed disabled:text-ui-fg-muted",
9938
- "focus:bg-ui-bg-field-hover",
9939
- "hover:bg-ui-bg-field-hover",
9940
- {
9941
- "size-7": size === "small",
9942
- "size-8": size === "base"
9943
- }
9944
- ),
9945
- type: "button",
9946
- onClick: handleIncrement,
9947
- disabled: max !== void 0 && value >= max || disabled,
9948
- children: [
9949
- /* @__PURE__ */ jsx(Plus, {}),
9950
- /* @__PURE__ */ jsx("span", { className: "sr-only", children: `Increase by ${step}` })
9951
- ]
9952
- }
9953
- )
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
+ ] })
9954
9879
  ]
9955
9880
  }
9956
9881
  );
9957
9882
  }
9958
9883
  );
9959
- const PRODUCT_VARIANTS_QUERY_KEY = "product-variants";
9960
- const productVariantsQueryKeys = {
9961
- list: (query2) => [
9962
- PRODUCT_VARIANTS_QUERY_KEY,
9963
- query2 ? query2 : void 0
9964
- ]
9965
- };
9966
- const useProductVariants = (query2, options) => {
9967
- const { data, ...rest } = useQuery({
9968
- queryKey: productVariantsQueryKeys.list(query2),
9969
- queryFn: async () => await sdk.admin.productVariant.list(query2),
9970
- ...options
9971
- });
9972
- return { ...data, ...rest };
9973
- };
9974
- const useCancelOrderEdit = ({ preview }) => {
9975
- const { mutateAsync: cancelOrderEdit } = useDraftOrderCancelEdit(preview == null ? void 0 : preview.id);
9976
- const onCancel = useCallback(async () => {
9977
- if (!preview) {
9978
- return true;
9979
- }
9980
- let res = false;
9981
- await cancelOrderEdit(void 0, {
9982
- onError: (e) => {
9983
- toast.error(e.message);
9984
- },
9985
- onSuccess: () => {
9986
- res = true;
9987
- }
9988
- });
9989
- return res;
9990
- }, [preview, cancelOrderEdit]);
9991
- return { onCancel };
9992
- };
9993
- let IS_REQUEST_RUNNING = false;
9994
- const useInitiateOrderEdit = ({
9995
- preview
9996
- }) => {
9997
- const navigate = useNavigate();
9998
- const { mutateAsync } = useDraftOrderBeginEdit(preview == null ? void 0 : preview.id);
9999
- useEffect(() => {
10000
- async function run() {
10001
- if (IS_REQUEST_RUNNING || !preview) {
10002
- return;
10003
- }
10004
- if (preview.order_change) {
10005
- return;
10006
- }
10007
- IS_REQUEST_RUNNING = true;
10008
- await mutateAsync(void 0, {
10009
- onError: (e) => {
10010
- toast.error(e.message);
10011
- navigate(`/draft-orders/${preview.id}`, { replace: true });
10012
- return;
10013
- }
10014
- });
10015
- IS_REQUEST_RUNNING = false;
10016
- }
10017
- run();
10018
- }, [preview, navigate, mutateAsync]);
10019
- };
10020
- function convertNumber(value) {
10021
- return typeof value === "string" ? Number(value.replace(",", ".")) : value;
10022
- }
10023
- const STACKED_MODAL_ID = "items_stacked_modal";
10024
- 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 = () => {
10025
9894
  const { id } = useParams();
10026
- const {
10027
- order: preview,
10028
- isPending: isPreviewPending,
10029
- isError: isPreviewError,
10030
- error: previewError
10031
- } = useOrderPreview(id, void 0, {
10032
- placeholderData: keepPreviousData
9895
+ const { order, isPending, isError, error } = useOrder(id, {
9896
+ fields: "metadata"
10033
9897
  });
10034
- useInitiateOrderEdit({ preview });
10035
- const { draft_order, isPending, isError, error } = useDraftOrder(
10036
- id,
10037
- {
10038
- fields: "currency_code"
10039
- },
10040
- {
10041
- enabled: !!id
10042
- }
10043
- );
10044
- const { onCancel } = useCancelOrderEdit({ preview });
10045
9898
  if (isError) {
10046
9899
  throw error;
10047
9900
  }
10048
- if (isPreviewError) {
10049
- throw previewError;
10050
- }
10051
- const ready = !!preview && !isPreviewPending && !!draft_order && !isPending;
10052
- return /* @__PURE__ */ jsx(RouteFocusModal, { onClose: onCancel, children: ready ? /* @__PURE__ */ jsx(ItemsForm, { preview, currencyCode: draft_order.currency_code }) : /* @__PURE__ */ jsxs("div", { children: [
10053
- /* @__PURE__ */ jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Edit Items" }) }),
10054
- /* @__PURE__ */ jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Loading data for the draft order, please wait..." }) })
10055
- ] }) });
10056
- };
10057
- const ItemsForm = ({ preview, currencyCode }) => {
10058
- var _a;
10059
- const [isSubmitting, setIsSubmitting] = useState(false);
10060
- const [modalContent, setModalContent] = useState(
10061
- null
10062
- );
10063
- const { handleSuccess } = useRouteModal();
10064
- const { searchValue, onSearchValueChange, query: query2 } = useDebouncedSearch();
10065
- const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
10066
- const { mutateAsync: requestOrderEdit } = useDraftOrderRequestEdit(preview.id);
10067
- const itemCount = ((_a = preview.items) == null ? void 0 : _a.reduce((acc, item) => acc + item.quantity, 0)) || 0;
10068
- const matches = useMemo(() => {
10069
- return matchSorter(preview.items, query2, {
10070
- keys: ["product_title", "variant_title", "variant_sku", "title"]
10071
- });
10072
- }, [preview.items, query2]);
10073
- const onSubmit = async () => {
10074
- setIsSubmitting(true);
10075
- let requestSucceeded = false;
10076
- await requestOrderEdit(void 0, {
10077
- onError: (e) => {
10078
- toast.error(`Failed to request order edit: ${e.message}`);
10079
- },
10080
- onSuccess: () => {
10081
- requestSucceeded = true;
10082
- }
10083
- });
10084
- if (!requestSucceeded) {
10085
- setIsSubmitting(false);
10086
- return;
10087
- }
10088
- await confirmOrderEdit(void 0, {
10089
- onError: (e) => {
10090
- toast.error(`Failed to confirm order edit: ${e.message}`);
10091
- },
10092
- onSuccess: () => {
10093
- handleSuccess();
10094
- },
10095
- onSettled: () => {
10096
- setIsSubmitting(false);
10097
- }
10098
- });
10099
- };
10100
- const onKeyDown = useCallback(
10101
- (e) => {
10102
- if (e.key === "Enter" && (e.ctrlKey || e.metaKey)) {
10103
- if (modalContent || isSubmitting) {
10104
- return;
10105
- }
10106
- onSubmit();
10107
- }
10108
- },
10109
- [modalContent, isSubmitting, onSubmit]
10110
- );
10111
- useEffect(() => {
10112
- document.addEventListener("keydown", onKeyDown);
10113
- return () => {
10114
- document.removeEventListener("keydown", onKeyDown);
10115
- };
10116
- }, [onKeyDown]);
10117
- return /* @__PURE__ */ jsxs("div", { className: "flex h-full flex-col overflow-hidden", children: [
10118
- /* @__PURE__ */ jsx(RouteFocusModal.Header, {}),
10119
- /* @__PURE__ */ jsx(RouteFocusModal.Body, { className: "flex flex-1 flex-col overflow-hidden", children: /* @__PURE__ */ jsxs(
10120
- StackedFocusModal,
10121
- {
10122
- id: STACKED_MODAL_ID,
10123
- onOpenChangeCallback: (open) => {
10124
- if (!open) {
10125
- setModalContent(null);
10126
- }
10127
- },
10128
- children: [
10129
- /* @__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: [
10130
- /* @__PURE__ */ jsxs("div", { children: [
10131
- /* @__PURE__ */ jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Items" }) }),
10132
- /* @__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" }) })
10133
- ] }),
10134
- /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
10135
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-y-6", children: [
10136
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 items-center gap-3", children: [
10137
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
10138
- /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: "Items" }),
10139
- /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Choose items from the product catalog." })
10140
- ] }),
10141
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
10142
- /* @__PURE__ */ jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsx(
10143
- Input,
10144
- {
10145
- type: "search",
10146
- placeholder: "Search items",
10147
- value: searchValue,
10148
- onChange: (e) => onSearchValueChange(e.target.value)
10149
- }
10150
- ) }),
10151
- /* @__PURE__ */ jsxs(DropdownMenu, { children: [
10152
- /* @__PURE__ */ jsx(DropdownMenu.Trigger, { asChild: true, children: /* @__PURE__ */ jsx(IconButton, { type: "button", children: /* @__PURE__ */ jsx(Plus, {}) }) }),
10153
- /* @__PURE__ */ jsxs(DropdownMenu.Content, { children: [
10154
- /* @__PURE__ */ jsx(
10155
- StackedModalTrigger$1,
10156
- {
10157
- type: "add-items",
10158
- setModalContent
10159
- }
10160
- ),
10161
- /* @__PURE__ */ jsx(
10162
- StackedModalTrigger$1,
10163
- {
10164
- type: "add-custom-item",
10165
- setModalContent
10166
- }
10167
- )
10168
- ] })
10169
- ] })
10170
- ] })
10171
- ] }),
10172
- /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-subtle shadow-elevation-card-rest rounded-xl", children: [
10173
- /* @__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: [
10174
- /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: "Item" }) }),
10175
- /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: "Quantity" }) }),
10176
- /* @__PURE__ */ jsx("div", { className: "text-right", children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: "Price" }) }),
10177
- /* @__PURE__ */ jsx("div", {})
10178
- ] }) }),
10179
- /* @__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: [
10180
- /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: "There are no items in this order" }),
10181
- /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Add items to the order to get started." })
10182
- ] }) : matches.length > 0 ? matches == null ? void 0 : matches.map((item) => /* @__PURE__ */ jsx(
10183
- Item,
10184
- {
10185
- item,
10186
- preview,
10187
- currencyCode
10188
- },
10189
- item.id
10190
- )) : /* @__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: [
10191
- /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: "No items found" }),
10192
- /* @__PURE__ */ jsxs(Text, { size: "small", className: "text-ui-fg-subtle", children: [
10193
- 'No items found for "',
10194
- query2,
10195
- '".'
10196
- ] })
10197
- ] }) })
10198
- ] })
10199
- ] }),
10200
- /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
10201
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-[1fr_0.5fr_0.5fr] gap-3", children: [
10202
- /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: "Subtotal" }) }),
10203
- /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsxs(
10204
- Text,
10205
- {
10206
- size: "small",
10207
- leading: "compact",
10208
- className: "text-ui-fg-subtle",
10209
- children: [
10210
- itemCount,
10211
- " ",
10212
- itemCount === 1 ? "item" : "items"
10213
- ]
10214
- }
10215
- ) }),
10216
- /* @__PURE__ */ jsx("div", { className: "text-right", children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: getStylizedAmount(preview.item_subtotal, currencyCode) }) })
10217
- ] })
10218
- ] }) }),
10219
- modalContent && (modalContent === "add-items" ? /* @__PURE__ */ jsx(ExistingItemsForm, { orderId: preview.id, items: preview.items }) : modalContent === "add-custom-item" ? /* @__PURE__ */ jsx(
10220
- CustomItemForm,
10221
- {
10222
- orderId: preview.id,
10223
- currencyCode
10224
- }
10225
- ) : null)
10226
- ]
10227
- }
10228
- ) }),
10229
- /* @__PURE__ */ jsx(RouteFocusModal.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
10230
- /* @__PURE__ */ jsx(RouteFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
10231
- /* @__PURE__ */ jsx(
10232
- Button,
10233
- {
10234
- size: "small",
10235
- type: "button",
10236
- onClick: onSubmit,
10237
- isLoading: isSubmitting,
10238
- children: "Save"
10239
- }
10240
- )
10241
- ] }) })
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 })
10242
9908
  ] });
10243
9909
  };
10244
- const Item = ({ item, preview, currencyCode }) => {
10245
- if (item.variant_id) {
10246
- return /* @__PURE__ */ jsx(VariantItem, { item, preview, currencyCode });
10247
- }
10248
- return /* @__PURE__ */ jsx(CustomItem, { item, preview, currencyCode });
10249
- };
10250
- const VariantItem = ({ item, preview, currencyCode }) => {
10251
- const [editing, setEditing] = useState(false);
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 }) => {
9913
+ const { handleSuccess } = useRouteModal();
9914
+ const hasUneditableRows = getHasUneditableRows(metadata);
9915
+ const { mutateAsync, isPending } = useUpdateDraftOrder(orderId);
10252
9916
  const form = useForm({
10253
9917
  defaultValues: {
10254
- quantity: item.quantity,
10255
- unit_price: item.unit_price
9918
+ metadata: getDefaultValues(metadata)
10256
9919
  },
10257
- resolver: zodResolver(variantItemSchema)
9920
+ resolver: zodResolver(MetadataSchema)
10258
9921
  });
10259
- const actionId = useMemo(() => {
10260
- var _a, _b;
10261
- return (_b = (_a = item.actions) == null ? void 0 : _a.find((a) => a.action === "ITEM_ADD")) == null ? void 0 : _b.id;
10262
- }, [item]);
10263
- const { mutateAsync: updateActionItem, isPending: isUpdatingActionItem } = useDraftOrderUpdateActionItem(preview.id);
10264
- const { mutateAsync: updateOriginalItem, isPending: isUpdatingOriginalItem } = useDraftOrderUpdateItem(preview.id);
10265
- const isPending = isUpdatingActionItem || isUpdatingOriginalItem;
10266
- const onSubmit = form.handleSubmit(async (data) => {
10267
- if (convertNumber(data.unit_price) === item.unit_price && data.quantity === item.quantity) {
10268
- setEditing(false);
10269
- return;
10270
- }
10271
- if (!actionId) {
10272
- await updateOriginalItem(
10273
- {
10274
- item_id: item.id,
10275
- quantity: data.quantity,
10276
- unit_price: convertNumber(data.unit_price)
10277
- },
10278
- {
10279
- onSuccess: () => {
10280
- setEditing(false);
10281
- },
10282
- onError: (e) => {
10283
- toast.error(e.message);
10284
- }
10285
- }
10286
- );
10287
- return;
10288
- }
10289
- await updateActionItem(
9922
+ const handleSubmit = form.handleSubmit(async (data) => {
9923
+ const parsedData = parseValues(data);
9924
+ await mutateAsync(
10290
9925
  {
10291
- action_id: actionId,
10292
- quantity: data.quantity,
10293
- unit_price: convertNumber(data.unit_price)
9926
+ metadata: parsedData
10294
9927
  },
10295
9928
  {
10296
9929
  onSuccess: () => {
10297
- setEditing(false);
9930
+ toast.success("Metadata updated");
9931
+ handleSuccess();
10298
9932
  },
9933
+ onError: (error) => {
9934
+ toast.error(error.message);
9935
+ }
9936
+ }
9937
+ );
9938
+ });
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, {
10299
10359
  onError: (e) => {
10300
10360
  toast.error(e.message);
10361
+ navigate(`/draft-orders/${preview.id}`, { replace: true });
10362
+ return;
10301
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;
10302
10432
  }
10303
- );
10304
- });
10305
- 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: [
10306
- /* @__PURE__ */ jsxs("div", { className: "flex w-full items-center gap-x-3", children: [
10307
- /* @__PURE__ */ jsx(
10308
- Thumbnail,
10309
- {
10310
- thumbnail: item.thumbnail,
10311
- alt: item.product_title ?? void 0
10312
- }
10313
- ),
10314
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
10315
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-1", children: [
10316
- /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: item.product_title }),
10317
- /* @__PURE__ */ jsxs(
10318
- Text,
10319
- {
10320
- size: "small",
10321
- leading: "compact",
10322
- className: "text-ui-fg-subtle",
10323
- children: [
10324
- "(",
10325
- item.variant_title,
10326
- ")"
10327
- ]
10328
- }
10329
- )
10330
- ] }),
10331
- /* @__PURE__ */ jsx(
10332
- Text,
10333
- {
10334
- size: "small",
10335
- leading: "compact",
10336
- className: "text-ui-fg-subtle",
10337
- children: item.variant_sku
10338
- }
10339
- )
10340
- ] })
10341
- ] }),
10342
- editing ? /* @__PURE__ */ jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsx(
10343
- Form$2.Field,
10344
- {
10345
- control: form.control,
10346
- name: "quantity",
10347
- render: ({ field }) => {
10348
- return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(NumberInput, { ...field }) }) });
10349
- }
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);
10350
10447
  }
10351
- ) }) : /* @__PURE__ */ jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: item.quantity }) }),
10352
- editing ? /* @__PURE__ */ jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsx(
10353
- Form$2.Field,
10354
- {
10355
- control: form.control,
10356
- name: "unit_price",
10357
- render: ({ field: { onChange, ...field } }) => {
10358
- return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
10359
- CurrencyInput,
10360
- {
10361
- ...field,
10362
- symbol: getNativeSymbol(currencyCode),
10363
- code: currencyCode,
10364
- onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value)
10365
- }
10366
- ) }) });
10448
+ });
10449
+ };
10450
+ const onKeyDown = useCallback(
10451
+ (e) => {
10452
+ if (e.key === "Enter" && (e.ctrlKey || e.metaKey)) {
10453
+ if (modalContent || isSubmitting) {
10454
+ return;
10367
10455
  }
10456
+ onSubmit();
10368
10457
  }
10369
- ) }) : /* @__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) }) }),
10370
- /* @__PURE__ */ jsx(
10371
- 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,
10372
10471
  {
10373
- type: "button",
10374
- size: "small",
10375
- onClick: editing ? onSubmit : () => {
10376
- setEditing(true);
10472
+ id: STACKED_MODAL_ID,
10473
+ onOpenChangeCallback: (open) => {
10474
+ if (!open) {
10475
+ setModalContent(null);
10476
+ }
10377
10477
  },
10378
- disabled: isPending,
10379
- 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
+ ]
10380
10577
  }
10381
- )
10382
- ] }) }) });
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
+ ] });
10383
10593
  };
10384
- const variantItemSchema = objectType({
10385
- quantity: numberType(),
10386
- unit_price: unionType([numberType(), stringType()])
10387
- });
10388
- 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 }) => {
10389
10601
  const [editing, setEditing] = useState(false);
10390
- const { quantity, unit_price, title } = item;
10391
10602
  const form = useForm({
10392
10603
  defaultValues: {
10393
- title,
10394
- quantity,
10395
- unit_price
10396
- },
10397
- resolver: zodResolver(customItemSchema)
10398
- });
10399
- useEffect(() => {
10400
- form.reset({
10401
- title,
10402
- quantity,
10403
- unit_price
10404
- });
10405
- }, [form, title, quantity, unit_price]);
10604
+ quantity: item.quantity,
10605
+ unit_price: item.unit_price
10606
+ },
10607
+ resolver: zodResolver(variantItemSchema)
10608
+ });
10406
10609
  const actionId = useMemo(() => {
10407
10610
  var _a, _b;
10408
10611
  return (_b = (_a = item.actions) == null ? void 0 : _a.find((a) => a.action === "ITEM_ADD")) == null ? void 0 : _b.id;
10409
10612
  }, [item]);
10410
10613
  const { mutateAsync: updateActionItem, isPending: isUpdatingActionItem } = useDraftOrderUpdateActionItem(preview.id);
10411
- const { mutateAsync: removeActionItem, isPending: isRemovingActionItem } = useDraftOrderRemoveActionItem(preview.id);
10412
10614
  const { mutateAsync: updateOriginalItem, isPending: isUpdatingOriginalItem } = useDraftOrderUpdateItem(preview.id);
10413
10615
  const isPending = isUpdatingActionItem || isUpdatingOriginalItem;
10414
10616
  const onSubmit = form.handleSubmit(async (data) => {
10415
- 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) {
10416
10618
  setEditing(false);
10417
10619
  return;
10418
10620
  }
@@ -10434,17 +10636,6 @@ const CustomItem = ({ item, preview, currencyCode }) => {
10434
10636
  );
10435
10637
  return;
10436
10638
  }
10437
- if (data.quantity === 0) {
10438
- await removeActionItem(actionId, {
10439
- onSuccess: () => {
10440
- setEditing(false);
10441
- },
10442
- onError: (e) => {
10443
- toast.error(e.message);
10444
- }
10445
- });
10446
- return;
10447
- }
10448
10639
  await updateActionItem(
10449
10640
  {
10450
10641
  action_id: actionId,
@@ -10462,26 +10653,43 @@ const CustomItem = ({ item, preview, currencyCode }) => {
10462
10653
  );
10463
10654
  });
10464
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: [
10465
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-3", children: [
10656
+ /* @__PURE__ */ jsxs("div", { className: "flex w-full items-center gap-x-3", children: [
10466
10657
  /* @__PURE__ */ jsx(
10467
10658
  Thumbnail,
10468
10659
  {
10469
10660
  thumbnail: item.thumbnail,
10470
- alt: item.title ?? void 0
10661
+ alt: item.product_title ?? void 0
10471
10662
  }
10472
10663
  ),
10473
- editing ? /* @__PURE__ */ jsx(
10474
- Form$2.Field,
10475
- {
10476
- control: form.control,
10477
- name: "title",
10478
- render: ({ field }) => {
10479
- 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
10480
10688
  }
10481
- }
10482
- ) : /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: item.title })
10689
+ )
10690
+ ] })
10483
10691
  ] }),
10484
- editing ? /* @__PURE__ */ jsx(
10692
+ editing ? /* @__PURE__ */ jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsx(
10485
10693
  Form$2.Field,
10486
10694
  {
10487
10695
  control: form.control,
@@ -10490,8 +10698,8 @@ const CustomItem = ({ item, preview, currencyCode }) => {
10490
10698
  return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(NumberInput, { ...field }) }) });
10491
10699
  }
10492
10700
  }
10493
- ) : /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: item.quantity }),
10494
- 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(
10495
10703
  Form$2.Field,
10496
10704
  {
10497
10705
  control: form.control,
@@ -10508,7 +10716,7 @@ const CustomItem = ({ item, preview, currencyCode }) => {
10508
10716
  ) }) });
10509
10717
  }
10510
10718
  }
10511
- ) : /* @__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) }) }),
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) }) }),
10512
10720
  /* @__PURE__ */ jsx(
10513
10721
  IconButton,
10514
10722
  {
@@ -10523,215 +10731,79 @@ const CustomItem = ({ item, preview, currencyCode }) => {
10523
10731
  )
10524
10732
  ] }) }) });
10525
10733
  };
10526
- const StackedModalTrigger$1 = ({
10527
- type,
10528
- setModalContent
10529
- }) => {
10530
- const { setIsOpen } = useStackedModal();
10531
- const onClick = useCallback(() => {
10532
- setModalContent(type);
10533
- setIsOpen(STACKED_MODAL_ID, true);
10534
- }, [setModalContent, setIsOpen, type]);
10535
- return /* @__PURE__ */ jsx(StackedFocusModal.Trigger, { asChild: true, children: /* @__PURE__ */ jsx(DropdownMenu.Item, { onClick, children: type === "add-items" ? "Add items" : "Add custom item" }) });
10536
- };
10537
- const VARIANT_PREFIX = "items";
10538
- const LIMIT = 50;
10539
- const ExistingItemsForm = ({ orderId, items }) => {
10540
- const { setIsOpen } = useStackedModal();
10541
- const [rowSelection, setRowSelection] = useState(
10542
- items.reduce((acc, item) => {
10543
- acc[item.variant_id] = true;
10544
- return acc;
10545
- }, {})
10546
- );
10547
- useEffect(() => {
10548
- setRowSelection(
10549
- items.reduce((acc, item) => {
10550
- if (item.variant_id) {
10551
- acc[item.variant_id] = true;
10552
- }
10553
- return acc;
10554
- }, {})
10555
- );
10556
- }, [items]);
10557
- const { q, order, offset } = useQueryParams(
10558
- ["q", "order", "offset"],
10559
- VARIANT_PREFIX
10560
- );
10561
- const { variants, count, isPending, isError, error } = useProductVariants(
10562
- {
10563
- q,
10564
- order,
10565
- offset: offset ? parseInt(offset) : void 0,
10566
- limit: LIMIT
10567
- },
10568
- {
10569
- placeholderData: keepPreviousData
10570
- }
10571
- );
10572
- const columns = useColumns();
10573
- const { mutateAsync } = useDraftOrderAddItems(orderId);
10574
- const onSubmit = async () => {
10575
- const ids = Object.keys(rowSelection).filter(
10576
- (id) => !items.find((i) => i.variant_id === id)
10577
- );
10578
- await mutateAsync(
10579
- {
10580
- items: ids.map((id) => ({
10581
- variant_id: id,
10582
- quantity: 1
10583
- }))
10584
- },
10585
- {
10586
- onSuccess: () => {
10587
- setRowSelection({});
10588
- setIsOpen(STACKED_MODAL_ID, false);
10589
- },
10590
- onError: (e) => {
10591
- toast.error(e.message);
10592
- }
10593
- }
10594
- );
10595
- };
10596
- if (isError) {
10597
- throw error;
10598
- }
10599
- return /* @__PURE__ */ jsxs(
10600
- StackedFocusModal.Content,
10601
- {
10602
- onOpenAutoFocus: (e) => {
10603
- e.preventDefault();
10604
- const searchInput = document.querySelector(
10605
- "[data-modal-id='modal-search-input']"
10606
- );
10607
- if (searchInput) {
10608
- searchInput.focus();
10609
- }
10610
- },
10611
- children: [
10612
- /* @__PURE__ */ jsxs(StackedFocusModal.Header, { children: [
10613
- /* @__PURE__ */ jsx(StackedFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Product Variants" }) }),
10614
- /* @__PURE__ */ jsx(StackedFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Choose product variants to add to the order." }) })
10615
- ] }),
10616
- /* @__PURE__ */ jsx(StackedFocusModal.Body, { className: "flex-1 overflow-hidden", children: /* @__PURE__ */ jsx(
10617
- DataTable,
10618
- {
10619
- data: variants,
10620
- columns,
10621
- isLoading: isPending,
10622
- getRowId: (row) => row.id,
10623
- rowCount: count,
10624
- prefix: VARIANT_PREFIX,
10625
- layout: "fill",
10626
- rowSelection: {
10627
- state: rowSelection,
10628
- onRowSelectionChange: setRowSelection,
10629
- enableRowSelection: (row) => {
10630
- return !items.find((i) => i.variant_id === row.original.id);
10631
- }
10632
- },
10633
- autoFocusSearch: true
10634
- }
10635
- ) }),
10636
- /* @__PURE__ */ jsx(StackedFocusModal.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
10637
- /* @__PURE__ */ jsx(StackedFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
10638
- /* @__PURE__ */ jsx(Button, { size: "small", type: "button", onClick: onSubmit, children: "Update items" })
10639
- ] }) })
10640
- ]
10641
- }
10642
- );
10643
- };
10644
- const columnHelper = createDataTableColumnHelper();
10645
- const useColumns = () => {
10646
- return useMemo(() => {
10647
- return [
10648
- columnHelper.select(),
10649
- columnHelper.accessor("product.title", {
10650
- header: "Product",
10651
- cell: ({ row }) => {
10652
- var _a, _b, _c;
10653
- return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-2", children: [
10654
- /* @__PURE__ */ jsx(
10655
- Thumbnail,
10656
- {
10657
- thumbnail: (_a = row.original.product) == null ? void 0 : _a.thumbnail,
10658
- alt: (_b = row.original.product) == null ? void 0 : _b.title
10659
- }
10660
- ),
10661
- /* @__PURE__ */ jsx("span", { children: (_c = row.original.product) == null ? void 0 : _c.title })
10662
- ] });
10663
- },
10664
- enableSorting: true
10665
- }),
10666
- columnHelper.accessor("title", {
10667
- header: "Variant",
10668
- enableSorting: true
10669
- }),
10670
- columnHelper.accessor("sku", {
10671
- header: "SKU",
10672
- cell: ({ getValue }) => {
10673
- return getValue() ?? "-";
10674
- },
10675
- enableSorting: true
10676
- }),
10677
- columnHelper.accessor("updated_at", {
10678
- header: "Updated",
10679
- cell: ({ getValue }) => {
10680
- return /* @__PURE__ */ jsx(
10681
- Tooltip,
10682
- {
10683
- content: getFullDate({ date: getValue(), includeTime: true }),
10684
- children: /* @__PURE__ */ jsx("span", { children: getFullDate({ date: getValue() }) })
10685
- }
10686
- );
10687
- },
10688
- enableSorting: true,
10689
- sortAscLabel: "Oldest first",
10690
- sortDescLabel: "Newest first"
10691
- }),
10692
- columnHelper.accessor("created_at", {
10693
- header: "Created",
10694
- cell: ({ getValue }) => {
10695
- return /* @__PURE__ */ jsx(
10696
- Tooltip,
10697
- {
10698
- content: getFullDate({ date: getValue(), includeTime: true }),
10699
- children: /* @__PURE__ */ jsx("span", { children: getFullDate({ date: getValue() }) })
10700
- }
10701
- );
10702
- },
10703
- enableSorting: true,
10704
- sortAscLabel: "Oldest first",
10705
- sortDescLabel: "Newest first"
10706
- })
10707
- ];
10708
- }, []);
10709
- };
10710
- const CustomItemForm = ({ orderId, currencyCode }) => {
10711
- const { setIsOpen } = useStackedModal();
10712
- 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;
10713
10741
  const form = useForm({
10714
10742
  defaultValues: {
10715
- title: "",
10716
- quantity: 1,
10717
- unit_price: ""
10743
+ title,
10744
+ quantity,
10745
+ unit_price
10718
10746
  },
10719
10747
  resolver: zodResolver(customItemSchema)
10720
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;
10721
10764
  const onSubmit = form.handleSubmit(async (data) => {
10722
- await addItems(
10723
- {
10724
- items: [
10725
- {
10726
- title: data.title,
10727
- quantity: data.quantity,
10728
- 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);
10729
10782
  }
10730
- ]
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)
10731
10803
  },
10732
10804
  {
10733
10805
  onSuccess: () => {
10734
- setIsOpen(STACKED_MODAL_ID, false);
10806
+ setEditing(false);
10735
10807
  },
10736
10808
  onError: (e) => {
10737
10809
  toast.error(e.message);
@@ -10739,437 +10811,365 @@ const CustomItemForm = ({ orderId, currencyCode }) => {
10739
10811
  }
10740
10812
  );
10741
10813
  });
10742
- return /* @__PURE__ */ jsx(Form$2, { ...form, children: /* @__PURE__ */ jsx(KeyboundForm, { onSubmit, children: /* @__PURE__ */ jsxs(StackedFocusModal.Content, { children: [
10743
- /* @__PURE__ */ jsx(StackedFocusModal.Header, {}),
10744
- /* @__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: [
10745
- /* @__PURE__ */ jsxs("div", { children: [
10746
- /* @__PURE__ */ jsx(StackedFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Add custom item" }) }),
10747
- /* @__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." }) })
10748
- ] }),
10749
- /* @__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: [
10750
10816
  /* @__PURE__ */ jsx(
10751
- Form$2.Field,
10817
+ Thumbnail,
10752
10818
  {
10753
- control: form.control,
10754
- name: "title",
10755
- render: ({ field }) => /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
10756
- /* @__PURE__ */ jsxs("div", { children: [
10757
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Title" }),
10758
- /* @__PURE__ */ jsx(Form$2.Hint, { children: "Enter the title of the item" })
10759
- ] }),
10760
- /* @__PURE__ */ jsxs("div", { children: [
10761
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
10762
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
10763
- ] })
10764
- ] }) })
10819
+ thumbnail: item.thumbnail,
10820
+ alt: item.title ?? void 0
10765
10821
  }
10766
10822
  ),
10767
- /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
10768
- /* @__PURE__ */ jsx(
10823
+ editing ? /* @__PURE__ */ jsx(
10769
10824
  Form$2.Field,
10770
10825
  {
10771
10826
  control: form.control,
10772
- name: "unit_price",
10773
- render: ({ field: { onChange, ...field } }) => /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
10774
- /* @__PURE__ */ jsxs("div", { children: [
10775
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Unit price" }),
10776
- /* @__PURE__ */ jsx(Form$2.Hint, { children: "Enter the unit price of the item" })
10777
- ] }),
10778
- /* @__PURE__ */ jsxs("div", { children: [
10779
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
10780
- CurrencyInput,
10781
- {
10782
- symbol: getNativeSymbol(currencyCode),
10783
- code: currencyCode,
10784
- onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value),
10785
- ...field
10786
- }
10787
- ) }),
10788
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
10789
- ] })
10790
- ] }) })
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
+ }
10791
10831
  }
10792
- ),
10793
- /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
10794
- /* @__PURE__ */ jsx(
10795
- Form$2.Field,
10796
- {
10797
- control: form.control,
10798
- name: "quantity",
10799
- render: ({ field }) => /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
10800
- /* @__PURE__ */ jsxs("div", { children: [
10801
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Quantity" }),
10802
- /* @__PURE__ */ jsx(Form$2.Hint, { children: "Enter the quantity of the item" })
10803
- ] }),
10804
- /* @__PURE__ */ jsxs("div", { className: "w-full flex-1", children: [
10805
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsx(NumberInput, { ...field, className: "w-full" }) }) }),
10806
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
10807
- ] })
10808
- ] }) })
10832
+ ) : /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: item.title })
10833
+ ] }),
10834
+ editing ? /* @__PURE__ */ jsx(
10835
+ Form$2.Field,
10836
+ {
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 }) }) });
10809
10841
  }
10810
- )
10811
- ] }) }) }),
10812
- /* @__PURE__ */ jsx(StackedFocusModal.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
10813
- /* @__PURE__ */ jsx(StackedFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
10814
- /* @__PURE__ */ jsx(Button, { size: "small", type: "button", onClick: onSubmit, children: "Add item" })
10815
- ] }) })
10816
- ] }) }) });
10817
- };
10818
- const customItemSchema = objectType({
10819
- title: stringType().min(1),
10820
- quantity: numberType(),
10821
- unit_price: unionType([numberType(), stringType()])
10822
- });
10823
- const InlineTip = forwardRef(
10824
- ({ variant = "tip", label, className, children, ...props }, ref) => {
10825
- const labelValue = label || (variant === "warning" ? "Warning" : "Tip");
10826
- return /* @__PURE__ */ jsxs(
10827
- "div",
10842
+ }
10843
+ ) : /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: item.quantity }),
10844
+ editing ? /* @__PURE__ */ jsx(
10845
+ Form$2.Field,
10828
10846
  {
10829
- ref,
10830
- className: clx(
10831
- "bg-ui-bg-component txt-small text-ui-fg-subtle grid grid-cols-[4px_1fr] items-start gap-3 rounded-lg border p-3",
10832
- className
10833
- ),
10834
- ...props,
10835
- children: [
10836
- /* @__PURE__ */ jsx(
10837
- "div",
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,
10838
10852
  {
10839
- role: "presentation",
10840
- className: clx("w-4px bg-ui-tag-neutral-icon h-full rounded-full", {
10841
- "bg-ui-tag-orange-icon": variant === "warning"
10842
- })
10853
+ ...field,
10854
+ symbol: getNativeSymbol(currencyCode),
10855
+ code: currencyCode,
10856
+ onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value)
10843
10857
  }
10844
- ),
10845
- /* @__PURE__ */ jsxs("div", { className: "text-pretty", children: [
10846
- /* @__PURE__ */ jsxs("strong", { className: "txt-small-plus text-ui-fg-base", children: [
10847
- labelValue,
10848
- ":"
10849
- ] }),
10850
- " ",
10851
- children
10852
- ] })
10853
- ]
10858
+ ) }) });
10859
+ }
10854
10860
  }
10855
- );
10856
- }
10857
- );
10858
- InlineTip.displayName = "InlineTip";
10859
- const MetadataFieldSchema = objectType({
10860
- key: stringType(),
10861
- disabled: booleanType().optional(),
10862
- value: anyType()
10863
- });
10864
- const MetadataSchema = objectType({
10865
- metadata: arrayType(MetadataFieldSchema)
10866
- });
10867
- const Metadata = () => {
10868
- const { id } = useParams();
10869
- const { order, isPending, isError, error } = useOrder(id, {
10870
- fields: "metadata"
10871
- });
10872
- if (isError) {
10873
- throw error;
10874
- }
10875
- const isReady = !isPending && !!order;
10876
- return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
10877
- /* @__PURE__ */ jsxs(RouteDrawer.Header, { children: [
10878
- /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Metadata" }) }),
10879
- /* @__PURE__ */ jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Add metadata to the draft order." }) })
10880
- ] }),
10881
- !isReady ? /* @__PURE__ */ jsx(PlaceholderInner, {}) : /* @__PURE__ */ jsx(MetadataForm, { orderId: id, metadata: order == null ? void 0 : order.metadata })
10882
- ] });
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
+ ] }) }) });
10875
+ };
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" }) });
10883
10886
  };
10884
- const METADATA_KEY_LABEL_ID = "metadata-form-key-label";
10885
- const METADATA_VALUE_LABEL_ID = "metadata-form-value-label";
10886
- const MetadataForm = ({ orderId, metadata }) => {
10887
- const { handleSuccess } = useRouteModal();
10888
- const hasUneditableRows = getHasUneditableRows(metadata);
10889
- const { mutateAsync, isPending } = useUpdateDraftOrder(orderId);
10890
- const form = useForm({
10891
- defaultValues: {
10892
- metadata: getDefaultValues(metadata)
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
10893
10917
  },
10894
- resolver: zodResolver(MetadataSchema)
10895
- });
10896
- const handleSubmit = form.handleSubmit(async (data) => {
10897
- 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
+ );
10898
10928
  await mutateAsync(
10899
10929
  {
10900
- metadata: parsedData
10930
+ items: ids.map((id) => ({
10931
+ variant_id: id,
10932
+ quantity: 1
10933
+ }))
10901
10934
  },
10902
10935
  {
10903
10936
  onSuccess: () => {
10904
- toast.success("Metadata updated");
10905
- handleSuccess();
10937
+ setRowSelection({});
10938
+ setIsOpen(STACKED_MODAL_ID, false);
10906
10939
  },
10907
- onError: (error) => {
10908
- toast.error(error.message);
10940
+ onError: (e) => {
10941
+ toast.error(e.message);
10909
10942
  }
10910
10943
  }
10911
10944
  );
10912
- });
10913
- const { fields, insert, remove } = useFieldArray({
10914
- control: form.control,
10915
- name: "metadata"
10916
- });
10917
- function deleteRow(index) {
10918
- remove(index);
10919
- if (fields.length === 1) {
10920
- insert(0, {
10921
- key: "",
10922
- value: "",
10923
- disabled: false
10924
- });
10925
- }
10926
- }
10927
- function insertRow(index, position) {
10928
- insert(index + (position === "above" ? 0 : 1), {
10929
- key: "",
10930
- value: "",
10931
- disabled: false
10932
- });
10945
+ };
10946
+ if (isError) {
10947
+ throw error;
10933
10948
  }
10934
- return /* @__PURE__ */ jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxs(
10935
- KeyboundForm,
10949
+ return /* @__PURE__ */ jsxs(
10950
+ StackedFocusModal.Content,
10936
10951
  {
10937
- onSubmit: handleSubmit,
10938
- className: "flex flex-1 flex-col overflow-hidden",
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
+ },
10939
10961
  children: [
10940
- /* @__PURE__ */ jsxs(RouteDrawer.Body, { className: "flex flex-1 flex-col gap-y-8 overflow-y-auto", children: [
10941
- /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest grid grid-cols-1 divide-y rounded-lg", children: [
10942
- /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-subtle grid grid-cols-2 divide-x rounded-t-lg", children: [
10943
- /* @__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" }) }),
10944
- /* @__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" }) })
10945
- ] }),
10946
- fields.map((field, index) => {
10947
- const isDisabled = field.disabled || false;
10948
- let placeholder = "-";
10949
- if (typeof field.value === "object") {
10950
- placeholder = "{ ... }";
10951
- }
10952
- if (Array.isArray(field.value)) {
10953
- placeholder = "[ ... ]";
10954
- }
10955
- return /* @__PURE__ */ jsx(
10956
- ConditionalTooltip,
10957
- {
10958
- showTooltip: isDisabled,
10959
- content: "This row is disabled because it contains non-primitive data.",
10960
- children: /* @__PURE__ */ jsxs("div", { className: "group/table relative", children: [
10961
- /* @__PURE__ */ jsxs(
10962
- "div",
10963
- {
10964
- className: clx("grid grid-cols-2 divide-x", {
10965
- "overflow-hidden rounded-b-lg": index === fields.length - 1
10966
- }),
10967
- children: [
10968
- /* @__PURE__ */ jsx(
10969
- Form$2.Field,
10970
- {
10971
- control: form.control,
10972
- name: `metadata.${index}.key`,
10973
- render: ({ field: field2 }) => {
10974
- return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
10975
- GridInput,
10976
- {
10977
- "aria-labelledby": METADATA_KEY_LABEL_ID,
10978
- ...field2,
10979
- disabled: isDisabled,
10980
- placeholder: "Key"
10981
- }
10982
- ) }) });
10983
- }
10984
- }
10985
- ),
10986
- /* @__PURE__ */ jsx(
10987
- Form$2.Field,
10988
- {
10989
- control: form.control,
10990
- name: `metadata.${index}.value`,
10991
- render: ({ field: { value, ...field2 } }) => {
10992
- return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
10993
- GridInput,
10994
- {
10995
- "aria-labelledby": METADATA_VALUE_LABEL_ID,
10996
- ...field2,
10997
- value: isDisabled ? placeholder : value,
10998
- disabled: isDisabled,
10999
- placeholder: "Value"
11000
- }
11001
- ) }) });
11002
- }
11003
- }
11004
- )
11005
- ]
11006
- }
11007
- ),
11008
- /* @__PURE__ */ jsxs(DropdownMenu, { children: [
11009
- /* @__PURE__ */ jsx(
11010
- DropdownMenu.Trigger,
11011
- {
11012
- className: clx(
11013
- "invisible absolute inset-y-0 -right-2.5 my-auto group-hover/table:visible data-[state='open']:visible",
11014
- {
11015
- hidden: isDisabled
11016
- }
11017
- ),
11018
- disabled: isDisabled,
11019
- asChild: true,
11020
- children: /* @__PURE__ */ jsx(IconButton, { size: "2xsmall", children: /* @__PURE__ */ jsx(EllipsisVertical, {}) })
11021
- }
11022
- ),
11023
- /* @__PURE__ */ jsxs(DropdownMenu.Content, { children: [
11024
- /* @__PURE__ */ jsxs(
11025
- DropdownMenu.Item,
11026
- {
11027
- className: "gap-x-2",
11028
- onClick: () => insertRow(index, "above"),
11029
- children: [
11030
- /* @__PURE__ */ jsx(ArrowUpMini, { className: "text-ui-fg-subtle" }),
11031
- "Insert row above"
11032
- ]
11033
- }
11034
- ),
11035
- /* @__PURE__ */ jsxs(
11036
- DropdownMenu.Item,
11037
- {
11038
- className: "gap-x-2",
11039
- onClick: () => insertRow(index, "below"),
11040
- children: [
11041
- /* @__PURE__ */ jsx(ArrowDownMini, { className: "text-ui-fg-subtle" }),
11042
- "Insert row below"
11043
- ]
11044
- }
11045
- ),
11046
- /* @__PURE__ */ jsx(DropdownMenu.Separator, {}),
11047
- /* @__PURE__ */ jsxs(
11048
- DropdownMenu.Item,
11049
- {
11050
- className: "gap-x-2",
11051
- onClick: () => deleteRow(index),
11052
- children: [
11053
- /* @__PURE__ */ jsx(Trash, { className: "text-ui-fg-subtle" }),
11054
- "Delete row"
11055
- ]
11056
- }
11057
- )
11058
- ] })
11059
- ] })
11060
- ] })
11061
- },
11062
- field.id
11063
- );
11064
- })
11065
- ] }),
11066
- 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." })
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." }) })
11067
10965
  ] }),
11068
- /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
11069
- /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
11070
- /* @__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" })
11071
10989
  ] }) })
11072
10990
  ]
11073
10991
  }
11074
- ) });
11075
- };
11076
- const GridInput = forwardRef(({ className, ...props }, ref) => {
11077
- return /* @__PURE__ */ jsx(
11078
- "input",
11079
- {
11080
- ref,
11081
- ...props,
11082
- autoComplete: "off",
11083
- className: clx(
11084
- "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",
11085
- className
11086
- )
11087
- }
11088
10992
  );
11089
- });
11090
- GridInput.displayName = "MetadataForm.GridInput";
11091
- const PlaceholderInner = () => {
11092
- return /* @__PURE__ */ jsxs("div", { className: "flex flex-1 flex-col overflow-hidden", children: [
11093
- /* @__PURE__ */ jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsx(Skeleton, { className: "h-[148ox] w-full rounded-lg" }) }),
11094
- /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
11095
- /* @__PURE__ */ jsx(Skeleton, { className: "h-7 w-12 rounded-md" }),
11096
- /* @__PURE__ */ jsx(Skeleton, { className: "h-7 w-12 rounded-md" })
11097
- ] }) })
11098
- ] });
11099
10993
  };
11100
- const EDITABLE_TYPES = ["string", "number", "boolean"];
11101
- function getDefaultValues(metadata) {
11102
- if (!metadata || !Object.keys(metadata).length) {
10994
+ const columnHelper = createDataTableColumnHelper();
10995
+ const useColumns = () => {
10996
+ return useMemo(() => {
11103
10997
  return [
11104
- {
11105
- key: "",
11106
- value: "",
11107
- disabled: false
11108
- }
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
+ })
11109
11057
  ];
11110
- }
11111
- return Object.entries(metadata).map(([key, value]) => {
11112
- if (!EDITABLE_TYPES.includes(typeof value)) {
11113
- return {
11114
- key,
11115
- value,
11116
- disabled: true
11117
- };
11118
- }
11119
- let stringValue = value;
11120
- if (typeof value !== "string") {
11121
- stringValue = JSON.stringify(value);
11122
- }
11123
- return {
11124
- key,
11125
- value: stringValue,
11126
- original_key: key
11127
- };
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)
11128
11070
  });
11129
- }
11130
- function parseValues(values) {
11131
- const metadata = values.metadata;
11132
- const isEmpty = !metadata.length || metadata.length === 1 && !metadata[0].key && !metadata[0].value;
11133
- if (isEmpty) {
11134
- return null;
11135
- }
11136
- const update = {};
11137
- metadata.forEach((field) => {
11138
- let key = field.key;
11139
- let value = field.value;
11140
- const disabled = field.disabled;
11141
- if (!key || !value) {
11142
- return;
11143
- }
11144
- if (disabled) {
11145
- update[key] = value;
11146
- return;
11147
- }
11148
- key = key.trim();
11149
- value = value.trim();
11150
- if (value === "true") {
11151
- update[key] = true;
11152
- } else if (value === "false") {
11153
- update[key] = false;
11154
- } else {
11155
- const parsedNumber = parseFloat(value);
11156
- if (!isNaN(parsedNumber)) {
11157
- update[key] = parsedNumber;
11158
- } else {
11159
- 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
+ }
11160
11089
  }
11161
- }
11090
+ );
11162
11091
  });
11163
- return update;
11164
- }
11165
- function getHasUneditableRows(metadata) {
11166
- if (!metadata) {
11167
- return false;
11168
- }
11169
- return Object.values(metadata).some(
11170
- (value) => !EDITABLE_TYPES.includes(typeof value)
11171
- );
11172
- }
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
+ });
11173
11173
  const PROMOTION_QUERY_KEY = "promotions";
11174
11174
  const promotionsQueryKeys = {
11175
11175
  list: (query2) => [
@@ -11447,6 +11447,112 @@ function getPromotionIds(items, shippingMethods) {
11447
11447
  }
11448
11448
  return Array.from(promotionIds);
11449
11449
  }
11450
+ const SalesChannel = () => {
11451
+ const { id } = useParams();
11452
+ const { draft_order, isPending, isError, error } = useDraftOrder(
11453
+ id,
11454
+ {
11455
+ fields: "+sales_channel_id"
11456
+ },
11457
+ {
11458
+ enabled: !!id
11459
+ }
11460
+ );
11461
+ if (isError) {
11462
+ throw error;
11463
+ }
11464
+ const ISrEADY = !!draft_order && !isPending;
11465
+ return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
11466
+ /* @__PURE__ */ jsxs(RouteDrawer.Header, { children: [
11467
+ /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Sales Channel" }) }),
11468
+ /* @__PURE__ */ jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Update which sales channel the draft order is associated with" }) })
11469
+ ] }),
11470
+ ISrEADY && /* @__PURE__ */ jsx(SalesChannelForm, { order: draft_order })
11471
+ ] });
11472
+ };
11473
+ const SalesChannelForm = ({ order }) => {
11474
+ const form = useForm({
11475
+ defaultValues: {
11476
+ sales_channel_id: order.sales_channel_id || ""
11477
+ },
11478
+ resolver: zodResolver(schema$2)
11479
+ });
11480
+ const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
11481
+ const { handleSuccess } = useRouteModal();
11482
+ const onSubmit = form.handleSubmit(async (data) => {
11483
+ await mutateAsync(
11484
+ {
11485
+ sales_channel_id: data.sales_channel_id
11486
+ },
11487
+ {
11488
+ onSuccess: () => {
11489
+ toast.success("Sales channel updated");
11490
+ handleSuccess();
11491
+ },
11492
+ onError: (error) => {
11493
+ toast.error(error.message);
11494
+ }
11495
+ }
11496
+ );
11497
+ });
11498
+ return /* @__PURE__ */ jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxs(
11499
+ KeyboundForm,
11500
+ {
11501
+ className: "flex flex-1 flex-col overflow-hidden",
11502
+ onSubmit,
11503
+ children: [
11504
+ /* @__PURE__ */ jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsx(SalesChannelField, { control: form.control, order }) }),
11505
+ /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
11506
+ /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
11507
+ /* @__PURE__ */ jsx(Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
11508
+ ] }) })
11509
+ ]
11510
+ }
11511
+ ) });
11512
+ };
11513
+ const SalesChannelField = ({ control, order }) => {
11514
+ const salesChannels = useComboboxData({
11515
+ queryFn: async (params) => {
11516
+ return await sdk.admin.salesChannel.list(params);
11517
+ },
11518
+ queryKey: ["sales-channels"],
11519
+ getOptions: (data) => {
11520
+ return data.sales_channels.map((salesChannel) => ({
11521
+ label: salesChannel.name,
11522
+ value: salesChannel.id
11523
+ }));
11524
+ },
11525
+ defaultValue: order.sales_channel_id || void 0
11526
+ });
11527
+ return /* @__PURE__ */ jsx(
11528
+ Form$2.Field,
11529
+ {
11530
+ control,
11531
+ name: "sales_channel_id",
11532
+ render: ({ field }) => {
11533
+ return /* @__PURE__ */ jsxs(Form$2.Item, { children: [
11534
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Sales Channel" }),
11535
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
11536
+ Combobox,
11537
+ {
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
+ });
11450
11556
  const STACKED_FOCUS_MODAL_ID = "shipping-form";
11451
11557
  const Shipping = () => {
11452
11558
  var _a;
@@ -12286,7 +12392,7 @@ const ShippingAddressForm = ({ order }) => {
12286
12392
  postal_code: ((_i = order.shipping_address) == null ? void 0 : _i.postal_code) ?? "",
12287
12393
  phone: ((_j = order.shipping_address) == null ? void 0 : _j.phone) ?? ""
12288
12394
  },
12289
- resolver: zodResolver(schema$2)
12395
+ resolver: zodResolver(schema$1)
12290
12396
  });
12291
12397
  const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
12292
12398
  const { handleSuccess } = useRouteModal();
@@ -12456,7 +12562,7 @@ const ShippingAddressForm = ({ order }) => {
12456
12562
  }
12457
12563
  ) });
12458
12564
  };
12459
- const schema$2 = addressSchema;
12565
+ const schema$1 = addressSchema;
12460
12566
  const TransferOwnership = () => {
12461
12567
  const { id } = useParams();
12462
12568
  const { draft_order, isPending, isError, error } = useDraftOrder(id, {
@@ -12480,7 +12586,7 @@ const TransferOwnershipForm = ({ order }) => {
12480
12586
  defaultValues: {
12481
12587
  customer_id: order.customer_id || ""
12482
12588
  },
12483
- resolver: zodResolver(schema$1)
12589
+ resolver: zodResolver(schema)
12484
12590
  });
12485
12591
  const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
12486
12592
  const { handleSuccess } = useRouteModal();
@@ -12930,114 +13036,8 @@ const Illustration = () => {
12930
13036
  }
12931
13037
  );
12932
13038
  };
12933
- const schema$1 = objectType({
12934
- customer_id: stringType().min(1)
12935
- });
12936
- const SalesChannel = () => {
12937
- const { id } = useParams();
12938
- const { draft_order, isPending, isError, error } = useDraftOrder(
12939
- id,
12940
- {
12941
- fields: "+sales_channel_id"
12942
- },
12943
- {
12944
- enabled: !!id
12945
- }
12946
- );
12947
- if (isError) {
12948
- throw error;
12949
- }
12950
- const ISrEADY = !!draft_order && !isPending;
12951
- return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
12952
- /* @__PURE__ */ jsxs(RouteDrawer.Header, { children: [
12953
- /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Sales Channel" }) }),
12954
- /* @__PURE__ */ jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Update which sales channel the draft order is associated with" }) })
12955
- ] }),
12956
- ISrEADY && /* @__PURE__ */ jsx(SalesChannelForm, { order: draft_order })
12957
- ] });
12958
- };
12959
- const SalesChannelForm = ({ order }) => {
12960
- const form = useForm({
12961
- defaultValues: {
12962
- sales_channel_id: order.sales_channel_id || ""
12963
- },
12964
- resolver: zodResolver(schema)
12965
- });
12966
- const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
12967
- const { handleSuccess } = useRouteModal();
12968
- const onSubmit = form.handleSubmit(async (data) => {
12969
- await mutateAsync(
12970
- {
12971
- sales_channel_id: data.sales_channel_id
12972
- },
12973
- {
12974
- onSuccess: () => {
12975
- toast.success("Sales channel updated");
12976
- handleSuccess();
12977
- },
12978
- onError: (error) => {
12979
- toast.error(error.message);
12980
- }
12981
- }
12982
- );
12983
- });
12984
- return /* @__PURE__ */ jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxs(
12985
- KeyboundForm,
12986
- {
12987
- className: "flex flex-1 flex-col overflow-hidden",
12988
- onSubmit,
12989
- children: [
12990
- /* @__PURE__ */ jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsx(SalesChannelField, { control: form.control, order }) }),
12991
- /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
12992
- /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
12993
- /* @__PURE__ */ jsx(Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
12994
- ] }) })
12995
- ]
12996
- }
12997
- ) });
12998
- };
12999
- const SalesChannelField = ({ control, order }) => {
13000
- const salesChannels = useComboboxData({
13001
- queryFn: async (params) => {
13002
- return await sdk.admin.salesChannel.list(params);
13003
- },
13004
- queryKey: ["sales-channels"],
13005
- getOptions: (data) => {
13006
- return data.sales_channels.map((salesChannel) => ({
13007
- label: salesChannel.name,
13008
- value: salesChannel.id
13009
- }));
13010
- },
13011
- defaultValue: order.sales_channel_id || void 0
13012
- });
13013
- return /* @__PURE__ */ jsx(
13014
- Form$2.Field,
13015
- {
13016
- control,
13017
- name: "sales_channel_id",
13018
- render: ({ field }) => {
13019
- return /* @__PURE__ */ jsxs(Form$2.Item, { children: [
13020
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Sales Channel" }),
13021
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
13022
- Combobox,
13023
- {
13024
- options: salesChannels.options,
13025
- fetchNextPage: salesChannels.fetchNextPage,
13026
- isFetchingNextPage: salesChannels.isFetchingNextPage,
13027
- searchValue: salesChannels.searchValue,
13028
- onSearchValueChange: salesChannels.onSearchValueChange,
13029
- placeholder: "Select sales channel",
13030
- ...field
13031
- }
13032
- ) }),
13033
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
13034
- ] });
13035
- }
13036
- }
13037
- );
13038
- };
13039
13039
  const schema = objectType({
13040
- sales_channel_id: stringType().min(1)
13040
+ customer_id: stringType().min(1)
13041
13041
  });
13042
13042
  const widgetModule = { widgets: [] };
13043
13043
  const routeModule = {
@@ -13059,30 +13059,34 @@ const routeModule = {
13059
13059
  handle,
13060
13060
  loader,
13061
13061
  children: [
13062
- {
13063
- Component: BillingAddress,
13064
- path: "/draft-orders/:id/billing-address"
13065
- },
13066
13062
  {
13067
13063
  Component: CustomItems,
13068
13064
  path: "/draft-orders/:id/custom-items"
13069
13065
  },
13070
13066
  {
13071
- Component: Email,
13072
- path: "/draft-orders/:id/email"
13067
+ Component: BillingAddress,
13068
+ path: "/draft-orders/:id/billing-address"
13073
13069
  },
13074
13070
  {
13075
- Component: Items,
13076
- path: "/draft-orders/:id/items"
13071
+ Component: Email,
13072
+ path: "/draft-orders/:id/email"
13077
13073
  },
13078
13074
  {
13079
13075
  Component: Metadata,
13080
13076
  path: "/draft-orders/:id/metadata"
13081
13077
  },
13078
+ {
13079
+ Component: Items,
13080
+ path: "/draft-orders/:id/items"
13081
+ },
13082
13082
  {
13083
13083
  Component: Promotions,
13084
13084
  path: "/draft-orders/:id/promotions"
13085
13085
  },
13086
+ {
13087
+ Component: SalesChannel,
13088
+ path: "/draft-orders/:id/sales-channel"
13089
+ },
13086
13090
  {
13087
13091
  Component: Shipping,
13088
13092
  path: "/draft-orders/:id/shipping"
@@ -13094,10 +13098,6 @@ const routeModule = {
13094
13098
  {
13095
13099
  Component: TransferOwnership,
13096
13100
  path: "/draft-orders/:id/transfer-ownership"
13097
- },
13098
- {
13099
- Component: SalesChannel,
13100
- path: "/draft-orders/:id/sales-channel"
13101
13101
  }
13102
13102
  ]
13103
13103
  }