@medusajs/draft-order 2.11.1-snapshot-20251021115115 → 2.11.1-snapshot-20251021125705

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