@medusajs/draft-order 2.11.4-preview-20251116150130 → 2.11.4-preview-20251116210130

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";
@@ -9844,573 +9844,775 @@ const EmailForm = ({ order }) => {
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
- ] }) });
9899
+ const isReady = !isPending && !!order;
9900
+ return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
9901
+ /* @__PURE__ */ jsxs(RouteDrawer.Header, { children: [
9902
+ /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Metadata" }) }),
9903
+ /* @__PURE__ */ jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Add metadata to the draft order." }) })
9904
+ ] }),
9905
+ !isReady ? /* @__PURE__ */ jsx(PlaceholderInner, {}) : /* @__PURE__ */ jsx(MetadataForm, { orderId: id, metadata: order == null ? void 0 : order.metadata })
9906
+ ] });
10054
9907
  };
10055
- const ItemsForm = ({ preview, currencyCode }) => {
10056
- var _a;
10057
- const [isSubmitting, setIsSubmitting] = useState(false);
10058
- const [modalContent, setModalContent] = useState(
10059
- null
10060
- );
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 }) => {
10061
9911
  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
- ] }) })
10240
- ] });
10241
- };
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);
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,
9937
+ const { fields, insert, remove } = useFieldArray({
9938
+ control: form.control,
9939
+ name: "metadata"
9940
+ });
9941
+ function deleteRow(index) {
9942
+ remove(index);
9943
+ if (fields.length === 1) {
9944
+ insert(0, {
9945
+ key: "",
9946
+ value: "",
9947
+ disabled: false
9948
+ });
9949
+ }
9950
+ }
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,
9960
+ {
9961
+ onSubmit: handleSubmit,
9962
+ className: "flex flex-1 flex-col overflow-hidden",
9963
+ children: [
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 = "{ ... }";
9975
+ }
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" })
10095
+ ] }) })
10096
+ ]
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
+ }
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
+ ] });
10123
+ };
10124
+ const EDITABLE_TYPES = ["string", "number", "boolean"];
10125
+ function getDefaultValues(metadata) {
10126
+ if (!metadata || !Object.keys(metadata).length) {
10127
+ return [
10342
10128
  {
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 }) }) });
10129
+ key: "",
10130
+ value: "",
10131
+ disabled: false
10132
+ }
10133
+ ];
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 NumberInput = forwardRef(
10198
+ ({
10199
+ value,
10200
+ onChange,
10201
+ size = "base",
10202
+ min = 0,
10203
+ max = 100,
10204
+ step = 1,
10205
+ className,
10206
+ disabled,
10207
+ ...props
10208
+ }, ref) => {
10209
+ const handleChange = (event) => {
10210
+ const newValue = event.target.value === "" ? min : Number(event.target.value);
10211
+ if (!isNaN(newValue) && (max === void 0 || newValue <= max) && (min === void 0 || newValue >= min)) {
10212
+ onChange(newValue);
10213
+ }
10214
+ };
10215
+ const handleIncrement = () => {
10216
+ const newValue = value + step;
10217
+ if (max === void 0 || newValue <= max) {
10218
+ onChange(newValue);
10219
+ }
10220
+ };
10221
+ const handleDecrement = () => {
10222
+ const newValue = value - step;
10223
+ if (min === void 0 || newValue >= min) {
10224
+ onChange(newValue);
10225
+ }
10226
+ };
10227
+ return /* @__PURE__ */ jsxs(
10228
+ "div",
10229
+ {
10230
+ className: clx(
10231
+ "inline-flex rounded-md bg-ui-bg-field shadow-borders-base overflow-hidden divide-x transition-fg",
10232
+ "[&:has(input:focus)]:shadow-borders-interactive-with-active",
10233
+ {
10234
+ "h-7": size === "small",
10235
+ "h-8": size === "base"
10236
+ },
10237
+ className
10238
+ ),
10239
+ children: [
10240
+ /* @__PURE__ */ jsx(
10241
+ "input",
10242
+ {
10243
+ ref,
10244
+ type: "number",
10245
+ value,
10246
+ onChange: handleChange,
10247
+ min,
10248
+ max,
10249
+ step,
10250
+ className: clx(
10251
+ "flex-1 px-2 py-1 bg-transparent txt-compact-small text-ui-fg-base outline-none [appearance:textfield]",
10252
+ "[&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none",
10253
+ "placeholder:text-ui-fg-muted"
10254
+ ),
10255
+ ...props
10256
+ }
10257
+ ),
10258
+ /* @__PURE__ */ jsxs(
10259
+ "button",
10260
+ {
10261
+ className: clx(
10262
+ "flex items-center justify-center outline-none transition-fg",
10263
+ "disabled:cursor-not-allowed disabled:text-ui-fg-muted",
10264
+ "focus:bg-ui-bg-field-component-hover",
10265
+ "hover:bg-ui-bg-field-component-hover",
10266
+ {
10267
+ "size-7": size === "small",
10268
+ "size-8": size === "base"
10269
+ }
10270
+ ),
10271
+ type: "button",
10272
+ onClick: handleDecrement,
10273
+ disabled: min !== void 0 && value <= min || disabled,
10274
+ children: [
10275
+ /* @__PURE__ */ jsx(Minus, {}),
10276
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: `Decrease by ${step}` })
10277
+ ]
10278
+ }
10279
+ ),
10280
+ /* @__PURE__ */ jsxs(
10281
+ "button",
10282
+ {
10283
+ className: clx(
10284
+ "flex items-center justify-center outline-none transition-fg",
10285
+ "disabled:cursor-not-allowed disabled:text-ui-fg-muted",
10286
+ "focus:bg-ui-bg-field-hover",
10287
+ "hover:bg-ui-bg-field-hover",
10288
+ {
10289
+ "size-7": size === "small",
10290
+ "size-8": size === "base"
10291
+ }
10292
+ ),
10293
+ type: "button",
10294
+ onClick: handleIncrement,
10295
+ disabled: max !== void 0 && value >= max || disabled,
10296
+ children: [
10297
+ /* @__PURE__ */ jsx(Plus, {}),
10298
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: `Increase by ${step}` })
10299
+ ]
10300
+ }
10301
+ )
10302
+ ]
10303
+ }
10304
+ );
10305
+ }
10306
+ );
10307
+ const PRODUCT_VARIANTS_QUERY_KEY = "product-variants";
10308
+ const productVariantsQueryKeys = {
10309
+ list: (query2) => [
10310
+ PRODUCT_VARIANTS_QUERY_KEY,
10311
+ query2 ? query2 : void 0
10312
+ ]
10313
+ };
10314
+ const useProductVariants = (query2, options) => {
10315
+ const { data, ...rest } = useQuery({
10316
+ queryKey: productVariantsQueryKeys.list(query2),
10317
+ queryFn: async () => await sdk.admin.productVariant.list(query2),
10318
+ ...options
10319
+ });
10320
+ return { ...data, ...rest };
10321
+ };
10322
+ const useCancelOrderEdit = ({ preview }) => {
10323
+ const { mutateAsync: cancelOrderEdit } = useDraftOrderCancelEdit(preview == null ? void 0 : preview.id);
10324
+ const onCancel = useCallback(async () => {
10325
+ if (!preview) {
10326
+ return true;
10327
+ }
10328
+ let res = false;
10329
+ await cancelOrderEdit(void 0, {
10330
+ onError: (e) => {
10331
+ toast.error(e.message);
10332
+ },
10333
+ onSuccess: () => {
10334
+ res = true;
10335
+ }
10336
+ });
10337
+ return res;
10338
+ }, [preview, cancelOrderEdit]);
10339
+ return { onCancel };
10340
+ };
10341
+ let IS_REQUEST_RUNNING = false;
10342
+ const useInitiateOrderEdit = ({
10343
+ preview
10344
+ }) => {
10345
+ const navigate = useNavigate();
10346
+ const { mutateAsync } = useDraftOrderBeginEdit(preview == null ? void 0 : preview.id);
10347
+ useEffect(() => {
10348
+ async function run() {
10349
+ if (IS_REQUEST_RUNNING || !preview) {
10350
+ return;
10351
+ }
10352
+ if (preview.order_change) {
10353
+ return;
10354
+ }
10355
+ IS_REQUEST_RUNNING = true;
10356
+ await mutateAsync(void 0, {
10357
+ onError: (e) => {
10358
+ toast.error(e.message);
10359
+ navigate(`/draft-orders/${preview.id}`, { replace: true });
10360
+ return;
10347
10361
  }
10362
+ });
10363
+ IS_REQUEST_RUNNING = false;
10364
+ }
10365
+ run();
10366
+ }, [preview, navigate, mutateAsync]);
10367
+ };
10368
+ function convertNumber(value) {
10369
+ return typeof value === "string" ? Number(value.replace(",", ".")) : value;
10370
+ }
10371
+ const STACKED_MODAL_ID = "items_stacked_modal";
10372
+ const Items = () => {
10373
+ const { id } = useParams();
10374
+ const {
10375
+ order: preview,
10376
+ isPending: isPreviewPending,
10377
+ isError: isPreviewError,
10378
+ error: previewError
10379
+ } = useOrderPreview(id, void 0, {
10380
+ placeholderData: keepPreviousData
10381
+ });
10382
+ useInitiateOrderEdit({ preview });
10383
+ const { draft_order, isPending, isError, error } = useDraftOrder(
10384
+ id,
10385
+ {
10386
+ fields: "currency_code"
10387
+ },
10388
+ {
10389
+ enabled: !!id
10390
+ }
10391
+ );
10392
+ const { onCancel } = useCancelOrderEdit({ preview });
10393
+ if (isError) {
10394
+ throw error;
10395
+ }
10396
+ if (isPreviewError) {
10397
+ throw previewError;
10398
+ }
10399
+ const ready = !!preview && !isPreviewPending && !!draft_order && !isPending;
10400
+ return /* @__PURE__ */ jsx(RouteFocusModal, { onClose: onCancel, children: ready ? /* @__PURE__ */ jsx(ItemsForm, { preview, currencyCode: draft_order.currency_code }) : /* @__PURE__ */ jsxs("div", { children: [
10401
+ /* @__PURE__ */ jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Edit Items" }) }),
10402
+ /* @__PURE__ */ jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Loading data for the draft order, please wait..." }) })
10403
+ ] }) });
10404
+ };
10405
+ const ItemsForm = ({ preview, currencyCode }) => {
10406
+ var _a;
10407
+ const [isSubmitting, setIsSubmitting] = useState(false);
10408
+ const [modalContent, setModalContent] = useState(
10409
+ null
10410
+ );
10411
+ const { handleSuccess } = useRouteModal();
10412
+ const { searchValue, onSearchValueChange, query: query2 } = useDebouncedSearch();
10413
+ const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
10414
+ const { mutateAsync: requestOrderEdit } = useDraftOrderRequestEdit(preview.id);
10415
+ const itemCount = ((_a = preview.items) == null ? void 0 : _a.reduce((acc, item) => acc + item.quantity, 0)) || 0;
10416
+ const matches = useMemo(() => {
10417
+ return matchSorter(preview.items, query2, {
10418
+ keys: ["product_title", "variant_title", "variant_sku", "title"]
10419
+ });
10420
+ }, [preview.items, query2]);
10421
+ const onSubmit = async () => {
10422
+ setIsSubmitting(true);
10423
+ let requestSucceeded = false;
10424
+ await requestOrderEdit(void 0, {
10425
+ onError: (e) => {
10426
+ toast.error(`Failed to request order edit: ${e.message}`);
10427
+ },
10428
+ onSuccess: () => {
10429
+ requestSucceeded = true;
10348
10430
  }
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
- ) }) });
10431
+ });
10432
+ if (!requestSucceeded) {
10433
+ setIsSubmitting(false);
10434
+ return;
10435
+ }
10436
+ await confirmOrderEdit(void 0, {
10437
+ onError: (e) => {
10438
+ toast.error(`Failed to confirm order edit: ${e.message}`);
10439
+ },
10440
+ onSuccess: () => {
10441
+ handleSuccess();
10442
+ },
10443
+ onSettled: () => {
10444
+ setIsSubmitting(false);
10445
+ }
10446
+ });
10447
+ };
10448
+ const onKeyDown = useCallback(
10449
+ (e) => {
10450
+ if (e.key === "Enter" && (e.ctrlKey || e.metaKey)) {
10451
+ if (modalContent || isSubmitting) {
10452
+ return;
10365
10453
  }
10454
+ onSubmit();
10366
10455
  }
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,
10456
+ },
10457
+ [modalContent, isSubmitting, onSubmit]
10458
+ );
10459
+ useEffect(() => {
10460
+ document.addEventListener("keydown", onKeyDown);
10461
+ return () => {
10462
+ document.removeEventListener("keydown", onKeyDown);
10463
+ };
10464
+ }, [onKeyDown]);
10465
+ return /* @__PURE__ */ jsxs("div", { className: "flex h-full flex-col overflow-hidden", children: [
10466
+ /* @__PURE__ */ jsx(RouteFocusModal.Header, {}),
10467
+ /* @__PURE__ */ jsx(RouteFocusModal.Body, { className: "flex flex-1 flex-col overflow-hidden", children: /* @__PURE__ */ jsxs(
10468
+ StackedFocusModal,
10370
10469
  {
10371
- type: "button",
10372
- size: "small",
10373
- onClick: editing ? onSubmit : () => {
10374
- setEditing(true);
10470
+ id: STACKED_MODAL_ID,
10471
+ onOpenChangeCallback: (open) => {
10472
+ if (!open) {
10473
+ setModalContent(null);
10474
+ }
10375
10475
  },
10376
- disabled: isPending,
10377
- children: editing ? /* @__PURE__ */ jsx(Check, {}) : /* @__PURE__ */ jsx(PencilSquare, {})
10476
+ children: [
10477
+ /* @__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: [
10478
+ /* @__PURE__ */ jsxs("div", { children: [
10479
+ /* @__PURE__ */ jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Items" }) }),
10480
+ /* @__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" }) })
10481
+ ] }),
10482
+ /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
10483
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-y-6", children: [
10484
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 items-center gap-3", children: [
10485
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
10486
+ /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: "Items" }),
10487
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Choose items from the product catalog." })
10488
+ ] }),
10489
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
10490
+ /* @__PURE__ */ jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsx(
10491
+ Input,
10492
+ {
10493
+ type: "search",
10494
+ placeholder: "Search items",
10495
+ value: searchValue,
10496
+ onChange: (e) => onSearchValueChange(e.target.value)
10497
+ }
10498
+ ) }),
10499
+ /* @__PURE__ */ jsxs(DropdownMenu, { children: [
10500
+ /* @__PURE__ */ jsx(DropdownMenu.Trigger, { asChild: true, children: /* @__PURE__ */ jsx(IconButton, { type: "button", children: /* @__PURE__ */ jsx(Plus, {}) }) }),
10501
+ /* @__PURE__ */ jsxs(DropdownMenu.Content, { children: [
10502
+ /* @__PURE__ */ jsx(
10503
+ StackedModalTrigger$1,
10504
+ {
10505
+ type: "add-items",
10506
+ setModalContent
10507
+ }
10508
+ ),
10509
+ /* @__PURE__ */ jsx(
10510
+ StackedModalTrigger$1,
10511
+ {
10512
+ type: "add-custom-item",
10513
+ setModalContent
10514
+ }
10515
+ )
10516
+ ] })
10517
+ ] })
10518
+ ] })
10519
+ ] }),
10520
+ /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-subtle shadow-elevation-card-rest rounded-xl", children: [
10521
+ /* @__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: [
10522
+ /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: "Item" }) }),
10523
+ /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: "Quantity" }) }),
10524
+ /* @__PURE__ */ jsx("div", { className: "text-right", children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: "Price" }) }),
10525
+ /* @__PURE__ */ jsx("div", {})
10526
+ ] }) }),
10527
+ /* @__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: [
10528
+ /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: "There are no items in this order" }),
10529
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Add items to the order to get started." })
10530
+ ] }) : matches.length > 0 ? matches == null ? void 0 : matches.map((item) => /* @__PURE__ */ jsx(
10531
+ Item,
10532
+ {
10533
+ item,
10534
+ preview,
10535
+ currencyCode
10536
+ },
10537
+ item.id
10538
+ )) : /* @__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: [
10539
+ /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: "No items found" }),
10540
+ /* @__PURE__ */ jsxs(Text, { size: "small", className: "text-ui-fg-subtle", children: [
10541
+ 'No items found for "',
10542
+ query2,
10543
+ '".'
10544
+ ] })
10545
+ ] }) })
10546
+ ] })
10547
+ ] }),
10548
+ /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
10549
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-[1fr_0.5fr_0.5fr] gap-3", children: [
10550
+ /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: "Subtotal" }) }),
10551
+ /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsxs(
10552
+ Text,
10553
+ {
10554
+ size: "small",
10555
+ leading: "compact",
10556
+ className: "text-ui-fg-subtle",
10557
+ children: [
10558
+ itemCount,
10559
+ " ",
10560
+ itemCount === 1 ? "item" : "items"
10561
+ ]
10562
+ }
10563
+ ) }),
10564
+ /* @__PURE__ */ jsx("div", { className: "text-right", children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: getStylizedAmount(preview.item_subtotal, currencyCode) }) })
10565
+ ] })
10566
+ ] }) }),
10567
+ modalContent && (modalContent === "add-items" ? /* @__PURE__ */ jsx(ExistingItemsForm, { orderId: preview.id, items: preview.items }) : modalContent === "add-custom-item" ? /* @__PURE__ */ jsx(
10568
+ CustomItemForm,
10569
+ {
10570
+ orderId: preview.id,
10571
+ currencyCode
10572
+ }
10573
+ ) : null)
10574
+ ]
10378
10575
  }
10379
- )
10380
- ] }) }) });
10576
+ ) }),
10577
+ /* @__PURE__ */ jsx(RouteFocusModal.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
10578
+ /* @__PURE__ */ jsx(RouteFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
10579
+ /* @__PURE__ */ jsx(
10580
+ Button,
10581
+ {
10582
+ size: "small",
10583
+ type: "button",
10584
+ onClick: onSubmit,
10585
+ isLoading: isSubmitting,
10586
+ children: "Save"
10587
+ }
10588
+ )
10589
+ ] }) })
10590
+ ] });
10381
10591
  };
10382
- const variantItemSchema = objectType({
10383
- quantity: numberType(),
10384
- unit_price: unionType([numberType(), stringType()])
10385
- });
10386
- const CustomItem = ({ item, preview, currencyCode }) => {
10592
+ const Item = ({ item, preview, currencyCode }) => {
10593
+ if (item.variant_id) {
10594
+ return /* @__PURE__ */ jsx(VariantItem, { item, preview, currencyCode });
10595
+ }
10596
+ return /* @__PURE__ */ jsx(CustomItem, { item, preview, currencyCode });
10597
+ };
10598
+ const VariantItem = ({ item, preview, currencyCode }) => {
10387
10599
  const [editing, setEditing] = useState(false);
10388
- const { quantity, unit_price, title } = item;
10389
10600
  const form = useForm({
10390
10601
  defaultValues: {
10391
- title,
10392
- quantity,
10393
- unit_price
10602
+ quantity: item.quantity,
10603
+ unit_price: item.unit_price
10394
10604
  },
10395
- resolver: zodResolver(customItemSchema)
10605
+ resolver: zodResolver(variantItemSchema)
10396
10606
  });
10397
- useEffect(() => {
10398
- form.reset({
10399
- title,
10400
- quantity,
10401
- unit_price
10402
- });
10403
- }, [form, title, quantity, unit_price]);
10404
10607
  const actionId = useMemo(() => {
10405
10608
  var _a, _b;
10406
10609
  return (_b = (_a = item.actions) == null ? void 0 : _a.find((a) => a.action === "ITEM_ADD")) == null ? void 0 : _b.id;
10407
10610
  }, [item]);
10408
10611
  const { mutateAsync: updateActionItem, isPending: isUpdatingActionItem } = useDraftOrderUpdateActionItem(preview.id);
10409
- const { mutateAsync: removeActionItem, isPending: isRemovingActionItem } = useDraftOrderRemoveActionItem(preview.id);
10410
10612
  const { mutateAsync: updateOriginalItem, isPending: isUpdatingOriginalItem } = useDraftOrderUpdateItem(preview.id);
10411
10613
  const isPending = isUpdatingActionItem || isUpdatingOriginalItem;
10412
10614
  const onSubmit = form.handleSubmit(async (data) => {
10413
- if (convertNumber(data.unit_price) === item.unit_price && data.quantity === item.quantity && data.title === item.title) {
10615
+ if (convertNumber(data.unit_price) === item.unit_price && data.quantity === item.quantity) {
10414
10616
  setEditing(false);
10415
10617
  return;
10416
10618
  }
@@ -10432,17 +10634,6 @@ const CustomItem = ({ item, preview, currencyCode }) => {
10432
10634
  );
10433
10635
  return;
10434
10636
  }
10435
- if (data.quantity === 0) {
10436
- await removeActionItem(actionId, {
10437
- onSuccess: () => {
10438
- setEditing(false);
10439
- },
10440
- onError: (e) => {
10441
- toast.error(e.message);
10442
- }
10443
- });
10444
- return;
10445
- }
10446
10637
  await updateActionItem(
10447
10638
  {
10448
10639
  action_id: actionId,
@@ -10460,26 +10651,43 @@ const CustomItem = ({ item, preview, currencyCode }) => {
10460
10651
  );
10461
10652
  });
10462
10653
  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: [
10654
+ /* @__PURE__ */ jsxs("div", { className: "flex w-full items-center gap-x-3", children: [
10464
10655
  /* @__PURE__ */ jsx(
10465
10656
  Thumbnail,
10466
10657
  {
10467
10658
  thumbnail: item.thumbnail,
10468
- alt: item.title ?? void 0
10659
+ alt: item.product_title ?? void 0
10469
10660
  }
10470
10661
  ),
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 }) }) });
10662
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
10663
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-1", children: [
10664
+ /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: item.product_title }),
10665
+ /* @__PURE__ */ jsxs(
10666
+ Text,
10667
+ {
10668
+ size: "small",
10669
+ leading: "compact",
10670
+ className: "text-ui-fg-subtle",
10671
+ children: [
10672
+ "(",
10673
+ item.variant_title,
10674
+ ")"
10675
+ ]
10676
+ }
10677
+ )
10678
+ ] }),
10679
+ /* @__PURE__ */ jsx(
10680
+ Text,
10681
+ {
10682
+ size: "small",
10683
+ leading: "compact",
10684
+ className: "text-ui-fg-subtle",
10685
+ children: item.variant_sku
10478
10686
  }
10479
- }
10480
- ) : /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: item.title })
10687
+ )
10688
+ ] })
10481
10689
  ] }),
10482
- editing ? /* @__PURE__ */ jsx(
10690
+ editing ? /* @__PURE__ */ jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsx(
10483
10691
  Form$2.Field,
10484
10692
  {
10485
10693
  control: form.control,
@@ -10488,8 +10696,8 @@ const CustomItem = ({ item, preview, currencyCode }) => {
10488
10696
  return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(NumberInput, { ...field }) }) });
10489
10697
  }
10490
10698
  }
10491
- ) : /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: item.quantity }),
10492
- editing ? /* @__PURE__ */ jsx(
10699
+ ) }) : /* @__PURE__ */ jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: item.quantity }) }),
10700
+ editing ? /* @__PURE__ */ jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsx(
10493
10701
  Form$2.Field,
10494
10702
  {
10495
10703
  control: form.control,
@@ -10506,7 +10714,7 @@ const CustomItem = ({ item, preview, currencyCode }) => {
10506
10714
  ) }) });
10507
10715
  }
10508
10716
  }
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) }) }),
10717
+ ) }) : /* @__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) }) }),
10510
10718
  /* @__PURE__ */ jsx(
10511
10719
  IconButton,
10512
10720
  {
@@ -10516,220 +10724,84 @@ const CustomItem = ({ item, preview, currencyCode }) => {
10516
10724
  setEditing(true);
10517
10725
  },
10518
10726
  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
- }
10597
- return /* @__PURE__ */ jsxs(
10598
- StackedFocusModal.Content,
10599
- {
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
- },
10609
- 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);
10629
- }
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" })
10637
- ] }) })
10638
- ]
10639
- }
10640
- );
10641
- };
10642
- const columnHelper = createDataTableColumnHelper();
10643
- const useColumns = () => {
10644
- return useMemo(() => {
10645
- 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
- })
10705
- ];
10706
- }, []);
10727
+ children: editing ? /* @__PURE__ */ jsx(Check, {}) : /* @__PURE__ */ jsx(PencilSquare, {})
10728
+ }
10729
+ )
10730
+ ] }) }) });
10707
10731
  };
10708
- const CustomItemForm = ({ orderId, currencyCode }) => {
10709
- const { setIsOpen } = useStackedModal();
10710
- const { mutateAsync: addItems } = useDraftOrderAddItems(orderId);
10732
+ const variantItemSchema = objectType({
10733
+ quantity: numberType(),
10734
+ unit_price: unionType([numberType(), stringType()])
10735
+ });
10736
+ const CustomItem = ({ item, preview, currencyCode }) => {
10737
+ const [editing, setEditing] = useState(false);
10738
+ const { quantity, unit_price, title } = item;
10711
10739
  const form = useForm({
10712
10740
  defaultValues: {
10713
- title: "",
10714
- quantity: 1,
10715
- unit_price: ""
10741
+ title,
10742
+ quantity,
10743
+ unit_price
10716
10744
  },
10717
10745
  resolver: zodResolver(customItemSchema)
10718
10746
  });
10747
+ useEffect(() => {
10748
+ form.reset({
10749
+ title,
10750
+ quantity,
10751
+ unit_price
10752
+ });
10753
+ }, [form, title, quantity, unit_price]);
10754
+ const actionId = useMemo(() => {
10755
+ var _a, _b;
10756
+ return (_b = (_a = item.actions) == null ? void 0 : _a.find((a) => a.action === "ITEM_ADD")) == null ? void 0 : _b.id;
10757
+ }, [item]);
10758
+ const { mutateAsync: updateActionItem, isPending: isUpdatingActionItem } = useDraftOrderUpdateActionItem(preview.id);
10759
+ const { mutateAsync: removeActionItem, isPending: isRemovingActionItem } = useDraftOrderRemoveActionItem(preview.id);
10760
+ const { mutateAsync: updateOriginalItem, isPending: isUpdatingOriginalItem } = useDraftOrderUpdateItem(preview.id);
10761
+ const isPending = isUpdatingActionItem || isUpdatingOriginalItem;
10719
10762
  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)
10763
+ if (convertNumber(data.unit_price) === item.unit_price && data.quantity === item.quantity && data.title === item.title) {
10764
+ setEditing(false);
10765
+ return;
10766
+ }
10767
+ if (!actionId) {
10768
+ await updateOriginalItem(
10769
+ {
10770
+ item_id: item.id,
10771
+ quantity: data.quantity,
10772
+ unit_price: convertNumber(data.unit_price)
10773
+ },
10774
+ {
10775
+ onSuccess: () => {
10776
+ setEditing(false);
10777
+ },
10778
+ onError: (e) => {
10779
+ toast.error(e.message);
10727
10780
  }
10728
- ]
10781
+ }
10782
+ );
10783
+ return;
10784
+ }
10785
+ if (data.quantity === 0) {
10786
+ await removeActionItem(actionId, {
10787
+ onSuccess: () => {
10788
+ setEditing(false);
10789
+ },
10790
+ onError: (e) => {
10791
+ toast.error(e.message);
10792
+ }
10793
+ });
10794
+ return;
10795
+ }
10796
+ await updateActionItem(
10797
+ {
10798
+ action_id: actionId,
10799
+ quantity: data.quantity,
10800
+ unit_price: convertNumber(data.unit_price)
10729
10801
  },
10730
10802
  {
10731
10803
  onSuccess: () => {
10732
- setIsOpen(STACKED_MODAL_ID, false);
10804
+ setEditing(false);
10733
10805
  },
10734
10806
  onError: (e) => {
10735
10807
  toast.error(e.message);
@@ -10737,437 +10809,365 @@ const CustomItemForm = ({ orderId, currencyCode }) => {
10737
10809
  }
10738
10810
  );
10739
10811
  });
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" }),
10812
+ 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: [
10813
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-3", children: [
10748
10814
  /* @__PURE__ */ jsx(
10749
- Form$2.Field,
10815
+ Thumbnail,
10750
10816
  {
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
- ] }) })
10817
+ thumbnail: item.thumbnail,
10818
+ alt: item.title ?? void 0
10763
10819
  }
10764
10820
  ),
10765
- /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
10766
- /* @__PURE__ */ jsx(
10821
+ editing ? /* @__PURE__ */ jsx(
10767
10822
  Form$2.Field,
10768
10823
  {
10769
10824
  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
- ] }) })
10825
+ name: "title",
10826
+ render: ({ field }) => {
10827
+ return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }) });
10828
+ }
10789
10829
  }
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
- ] }) })
10830
+ ) : /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: item.title })
10831
+ ] }),
10832
+ editing ? /* @__PURE__ */ jsx(
10833
+ Form$2.Field,
10834
+ {
10835
+ control: form.control,
10836
+ name: "quantity",
10837
+ render: ({ field }) => {
10838
+ return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(NumberInput, { ...field }) }) });
10807
10839
  }
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
- ] }) }) });
10815
- };
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",
10840
+ }
10841
+ ) : /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: item.quantity }),
10842
+ editing ? /* @__PURE__ */ jsx(
10843
+ Form$2.Field,
10826
10844
  {
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",
10845
+ control: form.control,
10846
+ name: "unit_price",
10847
+ render: ({ field: { onChange, ...field } }) => {
10848
+ return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
10849
+ CurrencyInput,
10836
10850
  {
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
- })
10851
+ ...field,
10852
+ symbol: getNativeSymbol(currencyCode),
10853
+ code: currencyCode,
10854
+ onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value)
10841
10855
  }
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
- ]
10856
+ ) }) });
10857
+ }
10852
10858
  }
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 = () => {
10866
- const { id } = useParams();
10867
- const { order, isPending, isError, error } = useOrder(id, {
10868
- fields: "metadata"
10869
- });
10870
- if (isError) {
10871
- throw error;
10872
- }
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 })
10880
- ] });
10859
+ ) : /* @__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) }) }),
10860
+ /* @__PURE__ */ jsx(
10861
+ IconButton,
10862
+ {
10863
+ type: "button",
10864
+ size: "small",
10865
+ onClick: editing ? onSubmit : () => {
10866
+ setEditing(true);
10867
+ },
10868
+ disabled: isPending,
10869
+ children: editing ? /* @__PURE__ */ jsx(Check, {}) : /* @__PURE__ */ jsx(PencilSquare, {})
10870
+ }
10871
+ )
10872
+ ] }) }) });
10881
10873
  };
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 }) => {
10885
- const { handleSuccess } = useRouteModal();
10886
- const hasUneditableRows = getHasUneditableRows(metadata);
10887
- const { mutateAsync, isPending } = useUpdateDraftOrder(orderId);
10888
- const form = useForm({
10889
- defaultValues: {
10890
- metadata: getDefaultValues(metadata)
10874
+ const StackedModalTrigger$1 = ({
10875
+ type,
10876
+ setModalContent
10877
+ }) => {
10878
+ const { setIsOpen } = useStackedModal();
10879
+ const onClick = useCallback(() => {
10880
+ setModalContent(type);
10881
+ setIsOpen(STACKED_MODAL_ID, true);
10882
+ }, [setModalContent, setIsOpen, type]);
10883
+ return /* @__PURE__ */ jsx(StackedFocusModal.Trigger, { asChild: true, children: /* @__PURE__ */ jsx(DropdownMenu.Item, { onClick, children: type === "add-items" ? "Add items" : "Add custom item" }) });
10884
+ };
10885
+ const VARIANT_PREFIX = "items";
10886
+ const LIMIT = 50;
10887
+ const ExistingItemsForm = ({ orderId, items }) => {
10888
+ const { setIsOpen } = useStackedModal();
10889
+ const [rowSelection, setRowSelection] = useState(
10890
+ items.reduce((acc, item) => {
10891
+ acc[item.variant_id] = true;
10892
+ return acc;
10893
+ }, {})
10894
+ );
10895
+ useEffect(() => {
10896
+ setRowSelection(
10897
+ items.reduce((acc, item) => {
10898
+ if (item.variant_id) {
10899
+ acc[item.variant_id] = true;
10900
+ }
10901
+ return acc;
10902
+ }, {})
10903
+ );
10904
+ }, [items]);
10905
+ const { q, order, offset } = useQueryParams(
10906
+ ["q", "order", "offset"],
10907
+ VARIANT_PREFIX
10908
+ );
10909
+ const { variants, count, isPending, isError, error } = useProductVariants(
10910
+ {
10911
+ q,
10912
+ order,
10913
+ offset: offset ? parseInt(offset) : void 0,
10914
+ limit: LIMIT
10891
10915
  },
10892
- resolver: zodResolver(MetadataSchema)
10893
- });
10894
- const handleSubmit = form.handleSubmit(async (data) => {
10895
- const parsedData = parseValues(data);
10916
+ {
10917
+ placeholderData: keepPreviousData
10918
+ }
10919
+ );
10920
+ const columns = useColumns();
10921
+ const { mutateAsync } = useDraftOrderAddItems(orderId);
10922
+ const onSubmit = async () => {
10923
+ const ids = Object.keys(rowSelection).filter(
10924
+ (id) => !items.find((i) => i.variant_id === id)
10925
+ );
10896
10926
  await mutateAsync(
10897
10927
  {
10898
- metadata: parsedData
10928
+ items: ids.map((id) => ({
10929
+ variant_id: id,
10930
+ quantity: 1
10931
+ }))
10899
10932
  },
10900
10933
  {
10901
10934
  onSuccess: () => {
10902
- toast.success("Metadata updated");
10903
- handleSuccess();
10935
+ setRowSelection({});
10936
+ setIsOpen(STACKED_MODAL_ID, false);
10904
10937
  },
10905
- onError: (error) => {
10906
- toast.error(error.message);
10938
+ onError: (e) => {
10939
+ toast.error(e.message);
10907
10940
  }
10908
10941
  }
10909
10942
  );
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
- });
10923
- }
10924
- }
10925
- function insertRow(index, position) {
10926
- insert(index + (position === "above" ? 0 : 1), {
10927
- key: "",
10928
- value: "",
10929
- disabled: false
10930
- });
10943
+ };
10944
+ if (isError) {
10945
+ throw error;
10931
10946
  }
10932
- return /* @__PURE__ */ jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxs(
10933
- KeyboundForm,
10947
+ return /* @__PURE__ */ jsxs(
10948
+ StackedFocusModal.Content,
10934
10949
  {
10935
- onSubmit: handleSubmit,
10936
- className: "flex flex-1 flex-col overflow-hidden",
10950
+ onOpenAutoFocus: (e) => {
10951
+ e.preventDefault();
10952
+ const searchInput = document.querySelector(
10953
+ "[data-modal-id='modal-search-input']"
10954
+ );
10955
+ if (searchInput) {
10956
+ searchInput.focus();
10957
+ }
10958
+ },
10937
10959
  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." })
10960
+ /* @__PURE__ */ jsxs(StackedFocusModal.Header, { children: [
10961
+ /* @__PURE__ */ jsx(StackedFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Product Variants" }) }),
10962
+ /* @__PURE__ */ jsx(StackedFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Choose product variants to add to the order." }) })
11065
10963
  ] }),
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" })
10964
+ /* @__PURE__ */ jsx(StackedFocusModal.Body, { className: "flex-1 overflow-hidden", children: /* @__PURE__ */ jsx(
10965
+ DataTable,
10966
+ {
10967
+ data: variants,
10968
+ columns,
10969
+ isLoading: isPending,
10970
+ getRowId: (row) => row.id,
10971
+ rowCount: count,
10972
+ prefix: VARIANT_PREFIX,
10973
+ layout: "fill",
10974
+ rowSelection: {
10975
+ state: rowSelection,
10976
+ onRowSelectionChange: setRowSelection,
10977
+ enableRowSelection: (row) => {
10978
+ return !items.find((i) => i.variant_id === row.original.id);
10979
+ }
10980
+ },
10981
+ autoFocusSearch: true
10982
+ }
10983
+ ) }),
10984
+ /* @__PURE__ */ jsx(StackedFocusModal.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
10985
+ /* @__PURE__ */ jsx(StackedFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
10986
+ /* @__PURE__ */ jsx(Button, { size: "small", type: "button", onClick: onSubmit, children: "Update items" })
11069
10987
  ] }) })
11070
10988
  ]
11071
10989
  }
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
11084
- )
11085
- }
11086
10990
  );
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
- ] }) })
11096
- ] });
11097
10991
  };
11098
- const EDITABLE_TYPES = ["string", "number", "boolean"];
11099
- function getDefaultValues(metadata) {
11100
- if (!metadata || !Object.keys(metadata).length) {
10992
+ const columnHelper = createDataTableColumnHelper();
10993
+ const useColumns = () => {
10994
+ return useMemo(() => {
11101
10995
  return [
11102
- {
11103
- key: "",
11104
- value: "",
11105
- disabled: false
11106
- }
10996
+ columnHelper.select(),
10997
+ columnHelper.accessor("product.title", {
10998
+ header: "Product",
10999
+ cell: ({ row }) => {
11000
+ var _a, _b, _c;
11001
+ return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-2", children: [
11002
+ /* @__PURE__ */ jsx(
11003
+ Thumbnail,
11004
+ {
11005
+ thumbnail: (_a = row.original.product) == null ? void 0 : _a.thumbnail,
11006
+ alt: (_b = row.original.product) == null ? void 0 : _b.title
11007
+ }
11008
+ ),
11009
+ /* @__PURE__ */ jsx("span", { children: (_c = row.original.product) == null ? void 0 : _c.title })
11010
+ ] });
11011
+ },
11012
+ enableSorting: true
11013
+ }),
11014
+ columnHelper.accessor("title", {
11015
+ header: "Variant",
11016
+ enableSorting: true
11017
+ }),
11018
+ columnHelper.accessor("sku", {
11019
+ header: "SKU",
11020
+ cell: ({ getValue }) => {
11021
+ return getValue() ?? "-";
11022
+ },
11023
+ enableSorting: true
11024
+ }),
11025
+ columnHelper.accessor("updated_at", {
11026
+ header: "Updated",
11027
+ cell: ({ getValue }) => {
11028
+ return /* @__PURE__ */ jsx(
11029
+ Tooltip,
11030
+ {
11031
+ content: getFullDate({ date: getValue(), includeTime: true }),
11032
+ children: /* @__PURE__ */ jsx("span", { children: getFullDate({ date: getValue() }) })
11033
+ }
11034
+ );
11035
+ },
11036
+ enableSorting: true,
11037
+ sortAscLabel: "Oldest first",
11038
+ sortDescLabel: "Newest first"
11039
+ }),
11040
+ columnHelper.accessor("created_at", {
11041
+ header: "Created",
11042
+ cell: ({ getValue }) => {
11043
+ return /* @__PURE__ */ jsx(
11044
+ Tooltip,
11045
+ {
11046
+ content: getFullDate({ date: getValue(), includeTime: true }),
11047
+ children: /* @__PURE__ */ jsx("span", { children: getFullDate({ date: getValue() }) })
11048
+ }
11049
+ );
11050
+ },
11051
+ enableSorting: true,
11052
+ sortAscLabel: "Oldest first",
11053
+ sortDescLabel: "Newest first"
11054
+ })
11107
11055
  ];
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
- };
11056
+ }, []);
11057
+ };
11058
+ const CustomItemForm = ({ orderId, currencyCode }) => {
11059
+ const { setIsOpen } = useStackedModal();
11060
+ const { mutateAsync: addItems } = useDraftOrderAddItems(orderId);
11061
+ const form = useForm({
11062
+ defaultValues: {
11063
+ title: "",
11064
+ quantity: 1,
11065
+ unit_price: ""
11066
+ },
11067
+ resolver: zodResolver(customItemSchema)
11126
11068
  });
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) {
11132
- return null;
11133
- }
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;
11141
- }
11142
- if (disabled) {
11143
- update[key] = value;
11144
- return;
11145
- }
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;
11069
+ const onSubmit = form.handleSubmit(async (data) => {
11070
+ await addItems(
11071
+ {
11072
+ items: [
11073
+ {
11074
+ title: data.title,
11075
+ quantity: data.quantity,
11076
+ unit_price: convertNumber(data.unit_price)
11077
+ }
11078
+ ]
11079
+ },
11080
+ {
11081
+ onSuccess: () => {
11082
+ setIsOpen(STACKED_MODAL_ID, false);
11083
+ },
11084
+ onError: (e) => {
11085
+ toast.error(e.message);
11086
+ }
11158
11087
  }
11159
- }
11088
+ );
11160
11089
  });
11161
- return update;
11162
- }
11163
- function getHasUneditableRows(metadata) {
11164
- if (!metadata) {
11165
- return false;
11166
- }
11167
- return Object.values(metadata).some(
11168
- (value) => !EDITABLE_TYPES.includes(typeof value)
11169
- );
11170
- }
11090
+ return /* @__PURE__ */ jsx(Form$2, { ...form, children: /* @__PURE__ */ jsx(KeyboundForm, { onSubmit, children: /* @__PURE__ */ jsxs(StackedFocusModal.Content, { children: [
11091
+ /* @__PURE__ */ jsx(StackedFocusModal.Header, {}),
11092
+ /* @__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: [
11093
+ /* @__PURE__ */ jsxs("div", { children: [
11094
+ /* @__PURE__ */ jsx(StackedFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Add custom item" }) }),
11095
+ /* @__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." }) })
11096
+ ] }),
11097
+ /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
11098
+ /* @__PURE__ */ jsx(
11099
+ Form$2.Field,
11100
+ {
11101
+ control: form.control,
11102
+ name: "title",
11103
+ render: ({ field }) => /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
11104
+ /* @__PURE__ */ jsxs("div", { children: [
11105
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Title" }),
11106
+ /* @__PURE__ */ jsx(Form$2.Hint, { children: "Enter the title of the item" })
11107
+ ] }),
11108
+ /* @__PURE__ */ jsxs("div", { children: [
11109
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
11110
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11111
+ ] })
11112
+ ] }) })
11113
+ }
11114
+ ),
11115
+ /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
11116
+ /* @__PURE__ */ jsx(
11117
+ Form$2.Field,
11118
+ {
11119
+ control: form.control,
11120
+ name: "unit_price",
11121
+ render: ({ field: { onChange, ...field } }) => /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
11122
+ /* @__PURE__ */ jsxs("div", { children: [
11123
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Unit price" }),
11124
+ /* @__PURE__ */ jsx(Form$2.Hint, { children: "Enter the unit price of the item" })
11125
+ ] }),
11126
+ /* @__PURE__ */ jsxs("div", { children: [
11127
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
11128
+ CurrencyInput,
11129
+ {
11130
+ symbol: getNativeSymbol(currencyCode),
11131
+ code: currencyCode,
11132
+ onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value),
11133
+ ...field
11134
+ }
11135
+ ) }),
11136
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11137
+ ] })
11138
+ ] }) })
11139
+ }
11140
+ ),
11141
+ /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
11142
+ /* @__PURE__ */ jsx(
11143
+ Form$2.Field,
11144
+ {
11145
+ control: form.control,
11146
+ name: "quantity",
11147
+ render: ({ field }) => /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
11148
+ /* @__PURE__ */ jsxs("div", { children: [
11149
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Quantity" }),
11150
+ /* @__PURE__ */ jsx(Form$2.Hint, { children: "Enter the quantity of the item" })
11151
+ ] }),
11152
+ /* @__PURE__ */ jsxs("div", { className: "w-full flex-1", children: [
11153
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsx(NumberInput, { ...field, className: "w-full" }) }) }),
11154
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11155
+ ] })
11156
+ ] }) })
11157
+ }
11158
+ )
11159
+ ] }) }) }),
11160
+ /* @__PURE__ */ jsx(StackedFocusModal.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
11161
+ /* @__PURE__ */ jsx(StackedFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
11162
+ /* @__PURE__ */ jsx(Button, { size: "small", type: "button", onClick: onSubmit, children: "Add item" })
11163
+ ] }) })
11164
+ ] }) }) });
11165
+ };
11166
+ const customItemSchema = objectType({
11167
+ title: stringType().min(1),
11168
+ quantity: numberType(),
11169
+ unit_price: unionType([numberType(), stringType()])
11170
+ });
11171
11171
  const PROMOTION_QUERY_KEY = "promotions";
11172
11172
  const promotionsQueryKeys = {
11173
11173
  list: (query2) => [
@@ -11445,6 +11445,112 @@ function getPromotionIds(items, shippingMethods) {
11445
11445
  }
11446
11446
  return Array.from(promotionIds);
11447
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
+ },
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
+ });
11448
11554
  const STACKED_FOCUS_MODAL_ID = "shipping-form";
11449
11555
  const Shipping = () => {
11450
11556
  var _a;
@@ -12252,112 +12358,6 @@ const CustomAmountField = ({
12252
12358
  }
12253
12359
  );
12254
12360
  };
12255
- const SalesChannel = () => {
12256
- const { id } = useParams();
12257
- const { draft_order, isPending, isError, error } = useDraftOrder(
12258
- id,
12259
- {
12260
- fields: "+sales_channel_id"
12261
- },
12262
- {
12263
- enabled: !!id
12264
- }
12265
- );
12266
- if (isError) {
12267
- throw error;
12268
- }
12269
- const ISrEADY = !!draft_order && !isPending;
12270
- return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
12271
- /* @__PURE__ */ jsxs(RouteDrawer.Header, { children: [
12272
- /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Sales Channel" }) }),
12273
- /* @__PURE__ */ jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Update which sales channel the draft order is associated with" }) })
12274
- ] }),
12275
- ISrEADY && /* @__PURE__ */ jsx(SalesChannelForm, { order: draft_order })
12276
- ] });
12277
- };
12278
- const SalesChannelForm = ({ order }) => {
12279
- const form = useForm({
12280
- defaultValues: {
12281
- sales_channel_id: order.sales_channel_id || ""
12282
- },
12283
- resolver: zodResolver(schema$2)
12284
- });
12285
- const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
12286
- const { handleSuccess } = useRouteModal();
12287
- const onSubmit = form.handleSubmit(async (data) => {
12288
- await mutateAsync(
12289
- {
12290
- sales_channel_id: data.sales_channel_id
12291
- },
12292
- {
12293
- onSuccess: () => {
12294
- toast.success("Sales channel updated");
12295
- handleSuccess();
12296
- },
12297
- onError: (error) => {
12298
- toast.error(error.message);
12299
- }
12300
- }
12301
- );
12302
- });
12303
- return /* @__PURE__ */ jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxs(
12304
- KeyboundForm,
12305
- {
12306
- className: "flex flex-1 flex-col overflow-hidden",
12307
- onSubmit,
12308
- children: [
12309
- /* @__PURE__ */ jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsx(SalesChannelField, { control: form.control, order }) }),
12310
- /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
12311
- /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
12312
- /* @__PURE__ */ jsx(Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
12313
- ] }) })
12314
- ]
12315
- }
12316
- ) });
12317
- };
12318
- const SalesChannelField = ({ control, order }) => {
12319
- const salesChannels = useComboboxData({
12320
- queryFn: async (params) => {
12321
- return await sdk.admin.salesChannel.list(params);
12322
- },
12323
- queryKey: ["sales-channels"],
12324
- getOptions: (data) => {
12325
- return data.sales_channels.map((salesChannel) => ({
12326
- label: salesChannel.name,
12327
- value: salesChannel.id
12328
- }));
12329
- },
12330
- defaultValue: order.sales_channel_id || void 0
12331
- });
12332
- return /* @__PURE__ */ jsx(
12333
- Form$2.Field,
12334
- {
12335
- control,
12336
- name: "sales_channel_id",
12337
- render: ({ field }) => {
12338
- return /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12339
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Sales Channel" }),
12340
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
12341
- Combobox,
12342
- {
12343
- options: salesChannels.options,
12344
- fetchNextPage: salesChannels.fetchNextPage,
12345
- isFetchingNextPage: salesChannels.isFetchingNextPage,
12346
- searchValue: salesChannels.searchValue,
12347
- onSearchValueChange: salesChannels.onSearchValueChange,
12348
- placeholder: "Select sales channel",
12349
- ...field
12350
- }
12351
- ) }),
12352
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12353
- ] });
12354
- }
12355
- }
12356
- );
12357
- };
12358
- const schema$2 = objectType({
12359
- sales_channel_id: stringType().min(1)
12360
- });
12361
12361
  const ShippingAddress = () => {
12362
12362
  const { id } = useParams();
12363
12363
  const { order, isPending, isError, error } = useOrder(id, {
@@ -13069,26 +13069,26 @@ const routeModule = {
13069
13069
  Component: Email,
13070
13070
  path: "/draft-orders/:id/email"
13071
13071
  },
13072
- {
13073
- Component: Items,
13074
- path: "/draft-orders/:id/items"
13075
- },
13076
13072
  {
13077
13073
  Component: Metadata,
13078
13074
  path: "/draft-orders/:id/metadata"
13079
13075
  },
13080
13076
  {
13081
- Component: Promotions,
13082
- path: "/draft-orders/:id/promotions"
13077
+ Component: Items,
13078
+ path: "/draft-orders/:id/items"
13083
13079
  },
13084
13080
  {
13085
- Component: Shipping,
13086
- path: "/draft-orders/:id/shipping"
13081
+ Component: Promotions,
13082
+ path: "/draft-orders/:id/promotions"
13087
13083
  },
13088
13084
  {
13089
13085
  Component: SalesChannel,
13090
13086
  path: "/draft-orders/:id/sales-channel"
13091
13087
  },
13088
+ {
13089
+ Component: Shipping,
13090
+ path: "/draft-orders/:id/shipping"
13091
+ },
13092
13092
  {
13093
13093
  Component: ShippingAddress,
13094
13094
  path: "/draft-orders/:id/shipping-address"