@medusajs/draft-order 2.11.2-preview-20251026120206 → 2.11.2-preview-20251026150203

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