@medusajs/draft-order 2.10.0-snapshot-20250828141936 → 2.10.0-snapshot-20250904131418

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