@medusajs/draft-order 2.10.2-preview-20250909090202 → 2.10.2-preview-20250909081836

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";
@@ -9846,1647 +9846,1767 @@ const EmailForm = ({ order }) => {
9846
9846
  const schema$3 = objectType({
9847
9847
  email: stringType().email()
9848
9848
  });
9849
- const NumberInput = forwardRef(
9850
- ({
9851
- value,
9852
- onChange,
9853
- size = "base",
9854
- min = 0,
9855
- max = 100,
9856
- step = 1,
9857
- className,
9858
- disabled,
9859
- ...props
9860
- }, ref) => {
9861
- const handleChange = (event) => {
9862
- const newValue = event.target.value === "" ? min : Number(event.target.value);
9863
- if (!isNaN(newValue) && (max === void 0 || newValue <= max) && (min === void 0 || newValue >= min)) {
9864
- onChange(newValue);
9865
- }
9866
- };
9867
- const handleIncrement = () => {
9868
- const newValue = value + step;
9869
- if (max === void 0 || newValue <= max) {
9870
- onChange(newValue);
9871
- }
9872
- };
9873
- const handleDecrement = () => {
9874
- const newValue = value - step;
9875
- if (min === void 0 || newValue >= min) {
9876
- onChange(newValue);
9877
- }
9878
- };
9849
+ const InlineTip = forwardRef(
9850
+ ({ variant = "tip", label, className, children, ...props }, ref) => {
9851
+ const labelValue = label || (variant === "warning" ? "Warning" : "Tip");
9879
9852
  return /* @__PURE__ */ jsxs(
9880
9853
  "div",
9881
9854
  {
9855
+ ref,
9882
9856
  className: clx(
9883
- "inline-flex rounded-md bg-ui-bg-field shadow-borders-base overflow-hidden divide-x transition-fg",
9884
- "[&:has(input:focus)]:shadow-borders-interactive-with-active",
9885
- {
9886
- "h-7": size === "small",
9887
- "h-8": size === "base"
9888
- },
9857
+ "bg-ui-bg-component txt-small text-ui-fg-subtle grid grid-cols-[4px_1fr] items-start gap-3 rounded-lg border p-3",
9889
9858
  className
9890
9859
  ),
9860
+ ...props,
9891
9861
  children: [
9892
9862
  /* @__PURE__ */ jsx(
9893
- "input",
9894
- {
9895
- ref,
9896
- type: "number",
9897
- value,
9898
- onChange: handleChange,
9899
- min,
9900
- max,
9901
- step,
9902
- className: clx(
9903
- "flex-1 px-2 py-1 bg-transparent txt-compact-small text-ui-fg-base outline-none [appearance:textfield]",
9904
- "[&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none",
9905
- "placeholder:text-ui-fg-muted"
9906
- ),
9907
- ...props
9908
- }
9909
- ),
9910
- /* @__PURE__ */ jsxs(
9911
- "button",
9863
+ "div",
9912
9864
  {
9913
- className: clx(
9914
- "flex items-center justify-center outline-none transition-fg",
9915
- "disabled:cursor-not-allowed disabled:text-ui-fg-muted",
9916
- "focus:bg-ui-bg-field-component-hover",
9917
- "hover:bg-ui-bg-field-component-hover",
9918
- {
9919
- "size-7": size === "small",
9920
- "size-8": size === "base"
9921
- }
9922
- ),
9923
- type: "button",
9924
- onClick: handleDecrement,
9925
- disabled: min !== void 0 && value <= min || disabled,
9926
- children: [
9927
- /* @__PURE__ */ jsx(Minus, {}),
9928
- /* @__PURE__ */ jsx("span", { className: "sr-only", children: `Decrease by ${step}` })
9929
- ]
9865
+ role: "presentation",
9866
+ className: clx("w-4px bg-ui-tag-neutral-icon h-full rounded-full", {
9867
+ "bg-ui-tag-orange-icon": variant === "warning"
9868
+ })
9930
9869
  }
9931
9870
  ),
9932
- /* @__PURE__ */ jsxs(
9933
- "button",
9934
- {
9935
- className: clx(
9936
- "flex items-center justify-center outline-none transition-fg",
9937
- "disabled:cursor-not-allowed disabled:text-ui-fg-muted",
9938
- "focus:bg-ui-bg-field-hover",
9939
- "hover:bg-ui-bg-field-hover",
9940
- {
9941
- "size-7": size === "small",
9942
- "size-8": size === "base"
9943
- }
9944
- ),
9945
- type: "button",
9946
- onClick: handleIncrement,
9947
- disabled: max !== void 0 && value >= max || disabled,
9948
- children: [
9949
- /* @__PURE__ */ jsx(Plus, {}),
9950
- /* @__PURE__ */ jsx("span", { className: "sr-only", children: `Increase by ${step}` })
9951
- ]
9952
- }
9953
- )
9871
+ /* @__PURE__ */ jsxs("div", { className: "text-pretty", children: [
9872
+ /* @__PURE__ */ jsxs("strong", { className: "txt-small-plus text-ui-fg-base", children: [
9873
+ labelValue,
9874
+ ":"
9875
+ ] }),
9876
+ " ",
9877
+ children
9878
+ ] })
9954
9879
  ]
9955
9880
  }
9956
9881
  );
9957
9882
  }
9958
9883
  );
9959
- const PRODUCT_VARIANTS_QUERY_KEY = "product-variants";
9960
- const productVariantsQueryKeys = {
9961
- list: (query2) => [
9962
- PRODUCT_VARIANTS_QUERY_KEY,
9963
- query2 ? query2 : void 0
9964
- ]
9965
- };
9966
- const useProductVariants = (query2, options) => {
9967
- const { data, ...rest } = useQuery({
9968
- queryKey: productVariantsQueryKeys.list(query2),
9969
- queryFn: async () => await sdk.admin.productVariant.list(query2),
9970
- ...options
9971
- });
9972
- return { ...data, ...rest };
9973
- };
9974
- const useCancelOrderEdit = ({ preview }) => {
9975
- const { mutateAsync: cancelOrderEdit } = useDraftOrderCancelEdit(preview == null ? void 0 : preview.id);
9976
- const onCancel = useCallback(async () => {
9977
- if (!preview) {
9978
- return true;
9979
- }
9980
- let res = false;
9981
- await cancelOrderEdit(void 0, {
9982
- onError: (e) => {
9983
- toast.error(e.message);
9984
- },
9985
- onSuccess: () => {
9986
- res = true;
9987
- }
9988
- });
9989
- return res;
9990
- }, [preview, cancelOrderEdit]);
9991
- return { onCancel };
9992
- };
9993
- let IS_REQUEST_RUNNING = false;
9994
- const useInitiateOrderEdit = ({
9995
- preview
9996
- }) => {
9997
- const navigate = useNavigate();
9998
- const { mutateAsync } = useDraftOrderBeginEdit(preview == null ? void 0 : preview.id);
9999
- useEffect(() => {
10000
- async function run() {
10001
- if (IS_REQUEST_RUNNING || !preview) {
10002
- return;
10003
- }
10004
- if (preview.order_change) {
10005
- return;
10006
- }
10007
- IS_REQUEST_RUNNING = true;
10008
- await mutateAsync(void 0, {
10009
- onError: (e) => {
10010
- toast.error(e.message);
10011
- navigate(`/draft-orders/${preview.id}`, { replace: true });
10012
- return;
10013
- }
10014
- });
10015
- IS_REQUEST_RUNNING = false;
10016
- }
10017
- run();
10018
- }, [preview, navigate, mutateAsync]);
10019
- };
10020
- function convertNumber(value) {
10021
- return typeof value === "string" ? Number(value.replace(",", ".")) : value;
10022
- }
10023
- const STACKED_MODAL_ID = "items_stacked_modal";
10024
- const Items = () => {
9884
+ InlineTip.displayName = "InlineTip";
9885
+ const MetadataFieldSchema = objectType({
9886
+ key: stringType(),
9887
+ disabled: booleanType().optional(),
9888
+ value: anyType()
9889
+ });
9890
+ const MetadataSchema = objectType({
9891
+ metadata: arrayType(MetadataFieldSchema)
9892
+ });
9893
+ const Metadata = () => {
10025
9894
  const { id } = useParams();
10026
- const {
10027
- order: preview,
10028
- isPending: isPreviewPending,
10029
- isError: isPreviewError,
10030
- error: previewError
10031
- } = useOrderPreview(id, void 0, {
10032
- placeholderData: keepPreviousData
9895
+ const { order, isPending, isError, error } = useOrder(id, {
9896
+ fields: "metadata"
10033
9897
  });
10034
- useInitiateOrderEdit({ preview });
10035
- const { draft_order, isPending, isError, error } = useDraftOrder(
10036
- id,
10037
- {
10038
- fields: "currency_code"
10039
- },
10040
- {
10041
- enabled: !!id
10042
- }
10043
- );
10044
- const { onCancel } = useCancelOrderEdit({ preview });
10045
9898
  if (isError) {
10046
9899
  throw error;
10047
9900
  }
10048
- if (isPreviewError) {
10049
- throw previewError;
10050
- }
10051
- const ready = !!preview && !isPreviewPending && !!draft_order && !isPending;
10052
- return /* @__PURE__ */ jsx(RouteFocusModal, { onClose: onCancel, children: ready ? /* @__PURE__ */ jsx(ItemsForm, { preview, currencyCode: draft_order.currency_code }) : /* @__PURE__ */ jsxs("div", { children: [
10053
- /* @__PURE__ */ jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Edit Items" }) }),
10054
- /* @__PURE__ */ jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Loading data for the draft order, please wait..." }) })
10055
- ] }) });
9901
+ const isReady = !isPending && !!order;
9902
+ return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
9903
+ /* @__PURE__ */ jsxs(RouteDrawer.Header, { children: [
9904
+ /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Metadata" }) }),
9905
+ /* @__PURE__ */ jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Add metadata to the draft order." }) })
9906
+ ] }),
9907
+ !isReady ? /* @__PURE__ */ jsx(PlaceholderInner, {}) : /* @__PURE__ */ jsx(MetadataForm, { orderId: id, metadata: order == null ? void 0 : order.metadata })
9908
+ ] });
10056
9909
  };
10057
- const ItemsForm = ({ preview, currencyCode }) => {
10058
- var _a;
10059
- const [isSubmitting, setIsSubmitting] = useState(false);
10060
- const [modalContent, setModalContent] = useState(
10061
- null
10062
- );
9910
+ const METADATA_KEY_LABEL_ID = "metadata-form-key-label";
9911
+ const METADATA_VALUE_LABEL_ID = "metadata-form-value-label";
9912
+ const MetadataForm = ({ orderId, metadata }) => {
10063
9913
  const { handleSuccess } = useRouteModal();
10064
- const { searchValue, onSearchValueChange, query: query2 } = useDebouncedSearch();
10065
- const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
10066
- const { mutateAsync: requestOrderEdit } = useDraftOrderRequestEdit(preview.id);
10067
- const itemCount = ((_a = preview.items) == null ? void 0 : _a.reduce((acc, item) => acc + item.quantity, 0)) || 0;
10068
- const matches = useMemo(() => {
10069
- return matchSorter(preview.items, query2, {
10070
- keys: ["product_title", "variant_title", "variant_sku", "title"]
10071
- });
10072
- }, [preview.items, query2]);
10073
- const onSubmit = async () => {
10074
- setIsSubmitting(true);
10075
- let requestSucceeded = false;
10076
- await requestOrderEdit(void 0, {
10077
- onError: (e) => {
10078
- toast.error(`Failed to request order edit: ${e.message}`);
10079
- },
10080
- onSuccess: () => {
10081
- requestSucceeded = true;
10082
- }
10083
- });
10084
- if (!requestSucceeded) {
10085
- setIsSubmitting(false);
10086
- return;
10087
- }
10088
- await confirmOrderEdit(void 0, {
10089
- onError: (e) => {
10090
- toast.error(`Failed to confirm order edit: ${e.message}`);
10091
- },
10092
- onSuccess: () => {
10093
- handleSuccess();
10094
- },
10095
- onSettled: () => {
10096
- setIsSubmitting(false);
10097
- }
10098
- });
10099
- };
10100
- const onKeyDown = useCallback(
10101
- (e) => {
10102
- if (e.key === "Enter" && (e.ctrlKey || e.metaKey)) {
10103
- if (modalContent || isSubmitting) {
10104
- return;
10105
- }
10106
- onSubmit();
10107
- }
10108
- },
10109
- [modalContent, isSubmitting, onSubmit]
10110
- );
10111
- useEffect(() => {
10112
- document.addEventListener("keydown", onKeyDown);
10113
- return () => {
10114
- document.removeEventListener("keydown", onKeyDown);
10115
- };
10116
- }, [onKeyDown]);
10117
- return /* @__PURE__ */ jsxs("div", { className: "flex h-full flex-col overflow-hidden", children: [
10118
- /* @__PURE__ */ jsx(RouteFocusModal.Header, {}),
10119
- /* @__PURE__ */ jsx(RouteFocusModal.Body, { className: "flex flex-1 flex-col overflow-hidden", children: /* @__PURE__ */ jsxs(
10120
- StackedFocusModal,
10121
- {
10122
- id: STACKED_MODAL_ID,
10123
- onOpenChangeCallback: (open) => {
10124
- if (!open) {
10125
- setModalContent(null);
10126
- }
10127
- },
10128
- children: [
10129
- /* @__PURE__ */ jsx("div", { className: "flex flex-1 flex-col items-center overflow-y-auto", children: /* @__PURE__ */ jsxs("div", { className: "flex w-full max-w-[720px] flex-col gap-y-6 px-6 py-16", children: [
10130
- /* @__PURE__ */ jsxs("div", { children: [
10131
- /* @__PURE__ */ jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Items" }) }),
10132
- /* @__PURE__ */ jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Edit the items in the draft order" }) })
10133
- ] }),
10134
- /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
10135
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-y-6", children: [
10136
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 items-center gap-3", children: [
10137
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
10138
- /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: "Items" }),
10139
- /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Choose items from the product catalog." })
10140
- ] }),
10141
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
10142
- /* @__PURE__ */ jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsx(
10143
- Input,
10144
- {
10145
- type: "search",
10146
- placeholder: "Search items",
10147
- value: searchValue,
10148
- onChange: (e) => onSearchValueChange(e.target.value)
10149
- }
10150
- ) }),
10151
- /* @__PURE__ */ jsxs(DropdownMenu, { children: [
10152
- /* @__PURE__ */ jsx(DropdownMenu.Trigger, { asChild: true, children: /* @__PURE__ */ jsx(IconButton, { type: "button", children: /* @__PURE__ */ jsx(Plus, {}) }) }),
10153
- /* @__PURE__ */ jsxs(DropdownMenu.Content, { children: [
10154
- /* @__PURE__ */ jsx(
10155
- StackedModalTrigger$1,
10156
- {
10157
- type: "add-items",
10158
- setModalContent
10159
- }
10160
- ),
10161
- /* @__PURE__ */ jsx(
10162
- StackedModalTrigger$1,
10163
- {
10164
- type: "add-custom-item",
10165
- setModalContent
10166
- }
10167
- )
10168
- ] })
10169
- ] })
10170
- ] })
10171
- ] }),
10172
- /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-subtle shadow-elevation-card-rest rounded-xl", children: [
10173
- /* @__PURE__ */ jsx("div", { className: "px-[5px]", children: /* @__PURE__ */ jsxs("div", { className: "text-ui-fg-muted grid grid-cols-[2fr_1fr_2fr_28px] gap-3 px-4 py-2", children: [
10174
- /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: "Item" }) }),
10175
- /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: "Quantity" }) }),
10176
- /* @__PURE__ */ jsx("div", { className: "text-right", children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: "Price" }) }),
10177
- /* @__PURE__ */ jsx("div", {})
10178
- ] }) }),
10179
- /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-y-1.5 px-[5px] pb-[5px]", children: itemCount <= 0 ? /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest flex flex-col items-center justify-center gap-1 gap-x-3 rounded-lg p-4", children: [
10180
- /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: "There are no items in this order" }),
10181
- /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Add items to the order to get started." })
10182
- ] }) : matches.length > 0 ? matches == null ? void 0 : matches.map((item) => /* @__PURE__ */ jsx(
10183
- Item,
10184
- {
10185
- item,
10186
- preview,
10187
- currencyCode
10188
- },
10189
- item.id
10190
- )) : /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest flex flex-col items-center justify-center gap-1 gap-x-3 rounded-lg p-4", children: [
10191
- /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: "No items found" }),
10192
- /* @__PURE__ */ jsxs(Text, { size: "small", className: "text-ui-fg-subtle", children: [
10193
- 'No items found for "',
10194
- query2,
10195
- '".'
10196
- ] })
10197
- ] }) })
10198
- ] })
10199
- ] }),
10200
- /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
10201
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-[1fr_0.5fr_0.5fr] gap-3", children: [
10202
- /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: "Subtotal" }) }),
10203
- /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsxs(
10204
- Text,
10205
- {
10206
- size: "small",
10207
- leading: "compact",
10208
- className: "text-ui-fg-subtle",
10209
- children: [
10210
- itemCount,
10211
- " ",
10212
- itemCount === 1 ? "item" : "items"
10213
- ]
10214
- }
10215
- ) }),
10216
- /* @__PURE__ */ jsx("div", { className: "text-right", children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: getStylizedAmount(preview.item_subtotal, currencyCode) }) })
10217
- ] })
10218
- ] }) }),
10219
- modalContent && (modalContent === "add-items" ? /* @__PURE__ */ jsx(ExistingItemsForm, { orderId: preview.id, items: preview.items }) : modalContent === "add-custom-item" ? /* @__PURE__ */ jsx(
10220
- CustomItemForm,
10221
- {
10222
- orderId: preview.id,
10223
- currencyCode
10224
- }
10225
- ) : null)
10226
- ]
10227
- }
10228
- ) }),
10229
- /* @__PURE__ */ jsx(RouteFocusModal.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
10230
- /* @__PURE__ */ jsx(RouteFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
10231
- /* @__PURE__ */ jsx(
10232
- Button,
10233
- {
10234
- size: "small",
10235
- type: "button",
10236
- onClick: onSubmit,
10237
- isLoading: isSubmitting,
10238
- children: "Save"
10239
- }
10240
- )
10241
- ] }) })
10242
- ] });
10243
- };
10244
- const Item = ({ item, preview, currencyCode }) => {
10245
- if (item.variant_id) {
10246
- return /* @__PURE__ */ jsx(VariantItem, { item, preview, currencyCode });
10247
- }
10248
- return /* @__PURE__ */ jsx(CustomItem, { item, preview, currencyCode });
10249
- };
10250
- const VariantItem = ({ item, preview, currencyCode }) => {
10251
- const [editing, setEditing] = useState(false);
9914
+ const hasUneditableRows = getHasUneditableRows(metadata);
9915
+ const { mutateAsync, isPending } = useUpdateDraftOrder(orderId);
10252
9916
  const form = useForm({
10253
9917
  defaultValues: {
10254
- quantity: item.quantity,
10255
- unit_price: item.unit_price
9918
+ metadata: getDefaultValues(metadata)
10256
9919
  },
10257
- resolver: zodResolver(variantItemSchema)
9920
+ resolver: zodResolver(MetadataSchema)
10258
9921
  });
10259
- const actionId = useMemo(() => {
10260
- var _a, _b;
10261
- return (_b = (_a = item.actions) == null ? void 0 : _a.find((a) => a.action === "ITEM_ADD")) == null ? void 0 : _b.id;
10262
- }, [item]);
10263
- const { mutateAsync: updateActionItem, isPending: isUpdatingActionItem } = useDraftOrderUpdateActionItem(preview.id);
10264
- const { mutateAsync: updateOriginalItem, isPending: isUpdatingOriginalItem } = useDraftOrderUpdateItem(preview.id);
10265
- const isPending = isUpdatingActionItem || isUpdatingOriginalItem;
10266
- const onSubmit = form.handleSubmit(async (data) => {
10267
- if (convertNumber(data.unit_price) === item.unit_price && data.quantity === item.quantity) {
10268
- setEditing(false);
10269
- return;
10270
- }
10271
- if (!actionId) {
10272
- await updateOriginalItem(
10273
- {
10274
- item_id: item.id,
10275
- quantity: data.quantity,
10276
- unit_price: convertNumber(data.unit_price)
10277
- },
10278
- {
10279
- onSuccess: () => {
10280
- setEditing(false);
10281
- },
10282
- onError: (e) => {
10283
- toast.error(e.message);
10284
- }
10285
- }
10286
- );
10287
- return;
10288
- }
10289
- await updateActionItem(
9922
+ const handleSubmit = form.handleSubmit(async (data) => {
9923
+ const parsedData = parseValues(data);
9924
+ await mutateAsync(
10290
9925
  {
10291
- action_id: actionId,
10292
- quantity: data.quantity,
10293
- unit_price: convertNumber(data.unit_price)
9926
+ metadata: parsedData
10294
9927
  },
10295
9928
  {
10296
9929
  onSuccess: () => {
10297
- setEditing(false);
9930
+ toast.success("Metadata updated");
9931
+ handleSuccess();
10298
9932
  },
10299
- onError: (e) => {
10300
- toast.error(e.message);
9933
+ onError: (error) => {
9934
+ toast.error(error.message);
10301
9935
  }
10302
9936
  }
10303
9937
  );
10304
9938
  });
10305
- return /* @__PURE__ */ jsx(Form$2, { ...form, children: /* @__PURE__ */ jsx("form", { onSubmit, children: /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest grid grid-cols-[minmax(0,2fr)_minmax(0,1fr)_minmax(0,2fr)_28px] items-center gap-3 rounded-lg px-4 py-2", children: [
10306
- /* @__PURE__ */ jsxs("div", { className: "flex w-full items-center gap-x-3", children: [
10307
- /* @__PURE__ */ jsx(
10308
- Thumbnail,
10309
- {
10310
- thumbnail: item.thumbnail,
10311
- alt: item.product_title ?? void 0
10312
- }
10313
- ),
10314
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
10315
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-1", children: [
10316
- /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: item.product_title }),
10317
- /* @__PURE__ */ jsxs(
10318
- Text,
10319
- {
10320
- size: "small",
10321
- leading: "compact",
10322
- className: "text-ui-fg-subtle",
10323
- children: [
10324
- "(",
10325
- item.variant_title,
10326
- ")"
10327
- ]
10328
- }
10329
- )
10330
- ] }),
10331
- /* @__PURE__ */ jsx(
10332
- Text,
10333
- {
10334
- size: "small",
10335
- leading: "compact",
10336
- className: "text-ui-fg-subtle",
10337
- children: item.variant_sku
10338
- }
10339
- )
10340
- ] })
10341
- ] }),
10342
- editing ? /* @__PURE__ */ jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsx(
10343
- Form$2.Field,
9939
+ const { fields, insert, remove } = useFieldArray({
9940
+ control: form.control,
9941
+ name: "metadata"
9942
+ });
9943
+ function deleteRow(index) {
9944
+ remove(index);
9945
+ if (fields.length === 1) {
9946
+ insert(0, {
9947
+ key: "",
9948
+ value: "",
9949
+ disabled: false
9950
+ });
9951
+ }
9952
+ }
9953
+ function insertRow(index, position) {
9954
+ insert(index + (position === "above" ? 0 : 1), {
9955
+ key: "",
9956
+ value: "",
9957
+ disabled: false
9958
+ });
9959
+ }
9960
+ return /* @__PURE__ */ jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxs(
9961
+ KeyboundForm,
9962
+ {
9963
+ onSubmit: handleSubmit,
9964
+ className: "flex flex-1 flex-col overflow-hidden",
9965
+ children: [
9966
+ /* @__PURE__ */ jsxs(RouteDrawer.Body, { className: "flex flex-1 flex-col gap-y-8 overflow-y-auto", children: [
9967
+ /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest grid grid-cols-1 divide-y rounded-lg", children: [
9968
+ /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-subtle grid grid-cols-2 divide-x rounded-t-lg", children: [
9969
+ /* @__PURE__ */ jsx("div", { className: "txt-compact-small-plus text-ui-fg-subtle px-2 py-1.5", children: /* @__PURE__ */ jsx("label", { id: METADATA_KEY_LABEL_ID, children: "Key" }) }),
9970
+ /* @__PURE__ */ jsx("div", { className: "txt-compact-small-plus text-ui-fg-subtle px-2 py-1.5", children: /* @__PURE__ */ jsx("label", { id: METADATA_VALUE_LABEL_ID, children: "Value" }) })
9971
+ ] }),
9972
+ fields.map((field, index) => {
9973
+ const isDisabled = field.disabled || false;
9974
+ let placeholder = "-";
9975
+ if (typeof field.value === "object") {
9976
+ placeholder = "{ ... }";
9977
+ }
9978
+ if (Array.isArray(field.value)) {
9979
+ placeholder = "[ ... ]";
9980
+ }
9981
+ return /* @__PURE__ */ jsx(
9982
+ ConditionalTooltip,
9983
+ {
9984
+ showTooltip: isDisabled,
9985
+ content: "This row is disabled because it contains non-primitive data.",
9986
+ children: /* @__PURE__ */ jsxs("div", { className: "group/table relative", children: [
9987
+ /* @__PURE__ */ jsxs(
9988
+ "div",
9989
+ {
9990
+ className: clx("grid grid-cols-2 divide-x", {
9991
+ "overflow-hidden rounded-b-lg": index === fields.length - 1
9992
+ }),
9993
+ children: [
9994
+ /* @__PURE__ */ jsx(
9995
+ Form$2.Field,
9996
+ {
9997
+ control: form.control,
9998
+ name: `metadata.${index}.key`,
9999
+ render: ({ field: field2 }) => {
10000
+ return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
10001
+ GridInput,
10002
+ {
10003
+ "aria-labelledby": METADATA_KEY_LABEL_ID,
10004
+ ...field2,
10005
+ disabled: isDisabled,
10006
+ placeholder: "Key"
10007
+ }
10008
+ ) }) });
10009
+ }
10010
+ }
10011
+ ),
10012
+ /* @__PURE__ */ jsx(
10013
+ Form$2.Field,
10014
+ {
10015
+ control: form.control,
10016
+ name: `metadata.${index}.value`,
10017
+ render: ({ field: { value, ...field2 } }) => {
10018
+ return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
10019
+ GridInput,
10020
+ {
10021
+ "aria-labelledby": METADATA_VALUE_LABEL_ID,
10022
+ ...field2,
10023
+ value: isDisabled ? placeholder : value,
10024
+ disabled: isDisabled,
10025
+ placeholder: "Value"
10026
+ }
10027
+ ) }) });
10028
+ }
10029
+ }
10030
+ )
10031
+ ]
10032
+ }
10033
+ ),
10034
+ /* @__PURE__ */ jsxs(DropdownMenu, { children: [
10035
+ /* @__PURE__ */ jsx(
10036
+ DropdownMenu.Trigger,
10037
+ {
10038
+ className: clx(
10039
+ "invisible absolute inset-y-0 -right-2.5 my-auto group-hover/table:visible data-[state='open']:visible",
10040
+ {
10041
+ hidden: isDisabled
10042
+ }
10043
+ ),
10044
+ disabled: isDisabled,
10045
+ asChild: true,
10046
+ children: /* @__PURE__ */ jsx(IconButton, { size: "2xsmall", children: /* @__PURE__ */ jsx(EllipsisVertical, {}) })
10047
+ }
10048
+ ),
10049
+ /* @__PURE__ */ jsxs(DropdownMenu.Content, { children: [
10050
+ /* @__PURE__ */ jsxs(
10051
+ DropdownMenu.Item,
10052
+ {
10053
+ className: "gap-x-2",
10054
+ onClick: () => insertRow(index, "above"),
10055
+ children: [
10056
+ /* @__PURE__ */ jsx(ArrowUpMini, { className: "text-ui-fg-subtle" }),
10057
+ "Insert row above"
10058
+ ]
10059
+ }
10060
+ ),
10061
+ /* @__PURE__ */ jsxs(
10062
+ DropdownMenu.Item,
10063
+ {
10064
+ className: "gap-x-2",
10065
+ onClick: () => insertRow(index, "below"),
10066
+ children: [
10067
+ /* @__PURE__ */ jsx(ArrowDownMini, { className: "text-ui-fg-subtle" }),
10068
+ "Insert row below"
10069
+ ]
10070
+ }
10071
+ ),
10072
+ /* @__PURE__ */ jsx(DropdownMenu.Separator, {}),
10073
+ /* @__PURE__ */ jsxs(
10074
+ DropdownMenu.Item,
10075
+ {
10076
+ className: "gap-x-2",
10077
+ onClick: () => deleteRow(index),
10078
+ children: [
10079
+ /* @__PURE__ */ jsx(Trash, { className: "text-ui-fg-subtle" }),
10080
+ "Delete row"
10081
+ ]
10082
+ }
10083
+ )
10084
+ ] })
10085
+ ] })
10086
+ ] })
10087
+ },
10088
+ field.id
10089
+ );
10090
+ })
10091
+ ] }),
10092
+ hasUneditableRows && /* @__PURE__ */ jsx(InlineTip, { variant: "warning", label: "Some rows are disabled", children: "This object contains non-primitive metadata, such as arrays or objects, that can't be edited here. To edit the disabled rows, use the API directly." })
10093
+ ] }),
10094
+ /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
10095
+ /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
10096
+ /* @__PURE__ */ jsx(Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
10097
+ ] }) })
10098
+ ]
10099
+ }
10100
+ ) });
10101
+ };
10102
+ const GridInput = forwardRef(({ className, ...props }, ref) => {
10103
+ return /* @__PURE__ */ jsx(
10104
+ "input",
10105
+ {
10106
+ ref,
10107
+ ...props,
10108
+ autoComplete: "off",
10109
+ className: clx(
10110
+ "txt-compact-small text-ui-fg-base placeholder:text-ui-fg-muted disabled:text-ui-fg-disabled disabled:bg-ui-bg-base bg-transparent px-2 py-1.5 outline-none",
10111
+ className
10112
+ )
10113
+ }
10114
+ );
10115
+ });
10116
+ GridInput.displayName = "MetadataForm.GridInput";
10117
+ const PlaceholderInner = () => {
10118
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-1 flex-col overflow-hidden", children: [
10119
+ /* @__PURE__ */ jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsx(Skeleton, { className: "h-[148ox] w-full rounded-lg" }) }),
10120
+ /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
10121
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-7 w-12 rounded-md" }),
10122
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-7 w-12 rounded-md" })
10123
+ ] }) })
10124
+ ] });
10125
+ };
10126
+ const EDITABLE_TYPES = ["string", "number", "boolean"];
10127
+ function getDefaultValues(metadata) {
10128
+ if (!metadata || !Object.keys(metadata).length) {
10129
+ return [
10344
10130
  {
10345
- control: form.control,
10346
- name: "quantity",
10347
- render: ({ field }) => {
10348
- return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(NumberInput, { ...field }) }) });
10349
- }
10131
+ key: "",
10132
+ value: "",
10133
+ disabled: false
10350
10134
  }
10351
- ) }) : /* @__PURE__ */ jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: item.quantity }) }),
10352
- editing ? /* @__PURE__ */ jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsx(
10353
- Form$2.Field,
10135
+ ];
10136
+ }
10137
+ return Object.entries(metadata).map(([key, value]) => {
10138
+ if (!EDITABLE_TYPES.includes(typeof value)) {
10139
+ return {
10140
+ key,
10141
+ value,
10142
+ disabled: true
10143
+ };
10144
+ }
10145
+ let stringValue = value;
10146
+ if (typeof value !== "string") {
10147
+ stringValue = JSON.stringify(value);
10148
+ }
10149
+ return {
10150
+ key,
10151
+ value: stringValue,
10152
+ original_key: key
10153
+ };
10154
+ });
10155
+ }
10156
+ function parseValues(values) {
10157
+ const metadata = values.metadata;
10158
+ const isEmpty = !metadata.length || metadata.length === 1 && !metadata[0].key && !metadata[0].value;
10159
+ if (isEmpty) {
10160
+ return null;
10161
+ }
10162
+ const update = {};
10163
+ metadata.forEach((field) => {
10164
+ let key = field.key;
10165
+ let value = field.value;
10166
+ const disabled = field.disabled;
10167
+ if (!key || !value) {
10168
+ return;
10169
+ }
10170
+ if (disabled) {
10171
+ update[key] = value;
10172
+ return;
10173
+ }
10174
+ key = key.trim();
10175
+ value = value.trim();
10176
+ if (value === "true") {
10177
+ update[key] = true;
10178
+ } else if (value === "false") {
10179
+ update[key] = false;
10180
+ } else {
10181
+ const parsedNumber = parseFloat(value);
10182
+ if (!isNaN(parsedNumber)) {
10183
+ update[key] = parsedNumber;
10184
+ } else {
10185
+ update[key] = value;
10186
+ }
10187
+ }
10188
+ });
10189
+ return update;
10190
+ }
10191
+ function getHasUneditableRows(metadata) {
10192
+ if (!metadata) {
10193
+ return false;
10194
+ }
10195
+ return Object.values(metadata).some(
10196
+ (value) => !EDITABLE_TYPES.includes(typeof value)
10197
+ );
10198
+ }
10199
+ const PROMOTION_QUERY_KEY = "promotions";
10200
+ const promotionsQueryKeys = {
10201
+ list: (query2) => [
10202
+ PROMOTION_QUERY_KEY,
10203
+ query2 ? query2 : void 0
10204
+ ],
10205
+ detail: (id, query2) => [
10206
+ PROMOTION_QUERY_KEY,
10207
+ id,
10208
+ query2 ? query2 : void 0
10209
+ ]
10210
+ };
10211
+ const usePromotions = (query2, options) => {
10212
+ const { data, ...rest } = useQuery({
10213
+ queryKey: promotionsQueryKeys.list(query2),
10214
+ queryFn: async () => sdk.admin.promotion.list(query2),
10215
+ ...options
10216
+ });
10217
+ return { ...data, ...rest };
10218
+ };
10219
+ const useCancelOrderEdit = ({ preview }) => {
10220
+ const { mutateAsync: cancelOrderEdit } = useDraftOrderCancelEdit(preview == null ? void 0 : preview.id);
10221
+ const onCancel = useCallback(async () => {
10222
+ if (!preview) {
10223
+ return true;
10224
+ }
10225
+ let res = false;
10226
+ await cancelOrderEdit(void 0, {
10227
+ onError: (e) => {
10228
+ toast.error(e.message);
10229
+ },
10230
+ onSuccess: () => {
10231
+ res = true;
10232
+ }
10233
+ });
10234
+ return res;
10235
+ }, [preview, cancelOrderEdit]);
10236
+ return { onCancel };
10237
+ };
10238
+ let IS_REQUEST_RUNNING = false;
10239
+ const useInitiateOrderEdit = ({
10240
+ preview
10241
+ }) => {
10242
+ const navigate = useNavigate();
10243
+ const { mutateAsync } = useDraftOrderBeginEdit(preview == null ? void 0 : preview.id);
10244
+ useEffect(() => {
10245
+ async function run() {
10246
+ if (IS_REQUEST_RUNNING || !preview) {
10247
+ return;
10248
+ }
10249
+ if (preview.order_change) {
10250
+ return;
10251
+ }
10252
+ IS_REQUEST_RUNNING = true;
10253
+ await mutateAsync(void 0, {
10254
+ onError: (e) => {
10255
+ toast.error(e.message);
10256
+ navigate(`/draft-orders/${preview.id}`, { replace: true });
10257
+ return;
10258
+ }
10259
+ });
10260
+ IS_REQUEST_RUNNING = false;
10261
+ }
10262
+ run();
10263
+ }, [preview, navigate, mutateAsync]);
10264
+ };
10265
+ const Promotions = () => {
10266
+ const { id } = useParams();
10267
+ const {
10268
+ order: preview,
10269
+ isError: isPreviewError,
10270
+ error: previewError
10271
+ } = useOrderPreview(id, void 0);
10272
+ useInitiateOrderEdit({ preview });
10273
+ const { onCancel } = useCancelOrderEdit({ preview });
10274
+ if (isPreviewError) {
10275
+ throw previewError;
10276
+ }
10277
+ const isReady = !!preview;
10278
+ return /* @__PURE__ */ jsxs(RouteDrawer, { onClose: onCancel, children: [
10279
+ /* @__PURE__ */ jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Promotions" }) }) }),
10280
+ isReady && /* @__PURE__ */ jsx(PromotionForm, { preview })
10281
+ ] });
10282
+ };
10283
+ const PromotionForm = ({ preview }) => {
10284
+ const { items, shipping_methods } = preview;
10285
+ const [isSubmitting, setIsSubmitting] = useState(false);
10286
+ const [comboboxValue, setComboboxValue] = useState("");
10287
+ const { handleSuccess } = useRouteModal();
10288
+ const { mutateAsync: addPromotions, isPending: isAddingPromotions } = useDraftOrderAddPromotions(preview.id);
10289
+ const promoIds = getPromotionIds(items, shipping_methods);
10290
+ const { promotions, isPending, isError, error } = usePromotions(
10291
+ {
10292
+ id: promoIds
10293
+ },
10294
+ {
10295
+ enabled: !!promoIds.length
10296
+ }
10297
+ );
10298
+ const comboboxData = useComboboxData({
10299
+ queryKey: ["promotions", "combobox", promoIds],
10300
+ queryFn: async (params) => {
10301
+ return await sdk.admin.promotion.list({
10302
+ ...params,
10303
+ id: {
10304
+ $nin: promoIds
10305
+ }
10306
+ });
10307
+ },
10308
+ getOptions: (data) => {
10309
+ return data.promotions.map((promotion) => ({
10310
+ label: promotion.code,
10311
+ value: promotion.code
10312
+ }));
10313
+ }
10314
+ });
10315
+ const add = async (value) => {
10316
+ if (!value) {
10317
+ return;
10318
+ }
10319
+ addPromotions(
10354
10320
  {
10355
- control: form.control,
10356
- name: "unit_price",
10357
- render: ({ field: { onChange, ...field } }) => {
10358
- return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
10359
- CurrencyInput,
10360
- {
10361
- ...field,
10362
- symbol: getNativeSymbol(currencyCode),
10363
- code: currencyCode,
10364
- onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value)
10365
- }
10366
- ) }) });
10367
- }
10368
- }
10369
- ) }) : /* @__PURE__ */ jsx("div", { className: "flex w-full flex-1 items-center justify-end", children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: getLocaleAmount(item.unit_price, currencyCode) }) }),
10370
- /* @__PURE__ */ jsx(
10371
- IconButton,
10321
+ promo_codes: [value]
10322
+ },
10372
10323
  {
10373
- type: "button",
10374
- size: "small",
10375
- onClick: editing ? onSubmit : () => {
10376
- setEditing(true);
10324
+ onError: (e) => {
10325
+ toast.error(e.message);
10326
+ comboboxData.onSearchValueChange("");
10327
+ setComboboxValue("");
10377
10328
  },
10378
- disabled: isPending,
10379
- children: editing ? /* @__PURE__ */ jsx(Check, {}) : /* @__PURE__ */ jsx(PencilSquare, {})
10329
+ onSuccess: () => {
10330
+ comboboxData.onSearchValueChange("");
10331
+ setComboboxValue("");
10332
+ }
10333
+ }
10334
+ );
10335
+ };
10336
+ const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
10337
+ const { mutateAsync: requestOrderEdit } = useOrderEditRequest(preview.id);
10338
+ const onSubmit = async () => {
10339
+ setIsSubmitting(true);
10340
+ let requestSucceeded = false;
10341
+ await requestOrderEdit(void 0, {
10342
+ onError: (e) => {
10343
+ toast.error(e.message);
10344
+ },
10345
+ onSuccess: () => {
10346
+ requestSucceeded = true;
10380
10347
  }
10381
- )
10382
- ] }) }) });
10383
- };
10384
- const variantItemSchema = objectType({
10385
- quantity: numberType(),
10386
- unit_price: unionType([numberType(), stringType()])
10387
- });
10388
- const CustomItem = ({ item, preview, currencyCode }) => {
10389
- const [editing, setEditing] = useState(false);
10390
- const { quantity, unit_price, title } = item;
10391
- const form = useForm({
10392
- defaultValues: {
10393
- title,
10394
- quantity,
10395
- unit_price
10396
- },
10397
- resolver: zodResolver(customItemSchema)
10398
- });
10399
- useEffect(() => {
10400
- form.reset({
10401
- title,
10402
- quantity,
10403
- unit_price
10404
10348
  });
10405
- }, [form, title, quantity, unit_price]);
10406
- const actionId = useMemo(() => {
10407
- var _a, _b;
10408
- return (_b = (_a = item.actions) == null ? void 0 : _a.find((a) => a.action === "ITEM_ADD")) == null ? void 0 : _b.id;
10409
- }, [item]);
10410
- const { mutateAsync: updateActionItem, isPending: isUpdatingActionItem } = useDraftOrderUpdateActionItem(preview.id);
10411
- const { mutateAsync: removeActionItem, isPending: isRemovingActionItem } = useDraftOrderRemoveActionItem(preview.id);
10412
- const { mutateAsync: updateOriginalItem, isPending: isUpdatingOriginalItem } = useDraftOrderUpdateItem(preview.id);
10413
- const isPending = isUpdatingActionItem || isUpdatingOriginalItem;
10414
- const onSubmit = form.handleSubmit(async (data) => {
10415
- if (convertNumber(data.unit_price) === item.unit_price && data.quantity === item.quantity && data.title === item.title) {
10416
- setEditing(false);
10349
+ if (!requestSucceeded) {
10350
+ setIsSubmitting(false);
10417
10351
  return;
10418
10352
  }
10419
- if (!actionId) {
10420
- await updateOriginalItem(
10353
+ await confirmOrderEdit(void 0, {
10354
+ onError: (e) => {
10355
+ toast.error(e.message);
10356
+ },
10357
+ onSuccess: () => {
10358
+ handleSuccess();
10359
+ },
10360
+ onSettled: () => {
10361
+ setIsSubmitting(false);
10362
+ }
10363
+ });
10364
+ };
10365
+ if (isError) {
10366
+ throw error;
10367
+ }
10368
+ return /* @__PURE__ */ jsxs(KeyboundForm, { className: "flex flex-1 flex-col", onSubmit, children: [
10369
+ /* @__PURE__ */ jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-4", children: [
10370
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3", children: [
10371
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
10372
+ /* @__PURE__ */ jsx(Label$1, { size: "small", weight: "plus", htmlFor: "promotion-combobox", children: "Apply promotions" }),
10373
+ /* @__PURE__ */ jsx(Hint$1, { id: "promotion-combobox-hint", children: "Manage promotions that should be applied to the order." })
10374
+ ] }),
10375
+ /* @__PURE__ */ jsx(
10376
+ Combobox,
10377
+ {
10378
+ id: "promotion-combobox",
10379
+ "aria-describedby": "promotion-combobox-hint",
10380
+ isFetchingNextPage: comboboxData.isFetchingNextPage,
10381
+ fetchNextPage: comboboxData.fetchNextPage,
10382
+ options: comboboxData.options,
10383
+ onSearchValueChange: comboboxData.onSearchValueChange,
10384
+ searchValue: comboboxData.searchValue,
10385
+ disabled: comboboxData.disabled || isAddingPromotions,
10386
+ onChange: add,
10387
+ value: comboboxValue
10388
+ }
10389
+ )
10390
+ ] }),
10391
+ /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
10392
+ /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-2", children: promotions == null ? void 0 : promotions.map((promotion) => /* @__PURE__ */ jsx(
10393
+ PromotionItem,
10421
10394
  {
10422
- item_id: item.id,
10423
- quantity: data.quantity,
10424
- unit_price: convertNumber(data.unit_price)
10395
+ promotion,
10396
+ orderId: preview.id,
10397
+ isLoading: isPending
10425
10398
  },
10399
+ promotion.id
10400
+ )) })
10401
+ ] }) }),
10402
+ /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
10403
+ /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
10404
+ /* @__PURE__ */ jsx(
10405
+ Button,
10426
10406
  {
10427
- onSuccess: () => {
10428
- setEditing(false);
10429
- },
10430
- onError: (e) => {
10431
- toast.error(e.message);
10432
- }
10407
+ size: "small",
10408
+ type: "submit",
10409
+ isLoading: isSubmitting || isAddingPromotions,
10410
+ children: "Save"
10433
10411
  }
10434
- );
10435
- return;
10436
- }
10437
- if (data.quantity === 0) {
10438
- await removeActionItem(actionId, {
10439
- onSuccess: () => {
10440
- setEditing(false);
10441
- },
10412
+ )
10413
+ ] }) })
10414
+ ] });
10415
+ };
10416
+ const PromotionItem = ({
10417
+ promotion,
10418
+ orderId,
10419
+ isLoading
10420
+ }) => {
10421
+ var _a;
10422
+ const { mutateAsync: removePromotions, isPending } = useDraftOrderRemovePromotions(orderId);
10423
+ const onRemove = async () => {
10424
+ removePromotions(
10425
+ {
10426
+ promo_codes: [promotion.code]
10427
+ },
10428
+ {
10442
10429
  onError: (e) => {
10443
10430
  toast.error(e.message);
10444
10431
  }
10445
- });
10446
- return;
10432
+ }
10433
+ );
10434
+ };
10435
+ const displayValue = getDisplayValue(promotion);
10436
+ return /* @__PURE__ */ jsxs(
10437
+ "div",
10438
+ {
10439
+ className: clx(
10440
+ "bg-ui-bg-component shadow-elevation-card-rest flex items-center justify-between rounded-lg px-3 py-2",
10441
+ {
10442
+ "animate-pulse": isLoading
10443
+ }
10444
+ ),
10445
+ children: [
10446
+ /* @__PURE__ */ jsxs("div", { children: [
10447
+ /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: promotion.code }),
10448
+ /* @__PURE__ */ jsxs("div", { className: "text-ui-fg-subtle flex items-center gap-1.5", children: [
10449
+ displayValue && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
10450
+ /* @__PURE__ */ jsx(Text, { size: "small", leading: "compact", children: displayValue }),
10451
+ /* @__PURE__ */ jsx(Text, { size: "small", leading: "compact", children: "·" })
10452
+ ] }),
10453
+ /* @__PURE__ */ jsx(Text, { size: "small", leading: "compact", className: "capitalize", children: (_a = promotion.application_method) == null ? void 0 : _a.allocation })
10454
+ ] })
10455
+ ] }),
10456
+ /* @__PURE__ */ jsx(
10457
+ IconButton,
10458
+ {
10459
+ size: "small",
10460
+ type: "button",
10461
+ variant: "transparent",
10462
+ onClick: onRemove,
10463
+ isLoading: isPending || isLoading,
10464
+ children: /* @__PURE__ */ jsx(XMark, {})
10465
+ }
10466
+ )
10467
+ ]
10468
+ },
10469
+ promotion.id
10470
+ );
10471
+ };
10472
+ function getDisplayValue(promotion) {
10473
+ var _a, _b, _c, _d;
10474
+ const value = (_a = promotion.application_method) == null ? void 0 : _a.value;
10475
+ if (!value) {
10476
+ return null;
10477
+ }
10478
+ if (((_b = promotion.application_method) == null ? void 0 : _b.type) === "fixed") {
10479
+ const currency = (_c = promotion.application_method) == null ? void 0 : _c.currency_code;
10480
+ if (!currency) {
10481
+ return null;
10482
+ }
10483
+ return getLocaleAmount(value, currency);
10484
+ } else if (((_d = promotion.application_method) == null ? void 0 : _d.type) === "percentage") {
10485
+ return formatPercentage(value);
10486
+ }
10487
+ return null;
10488
+ }
10489
+ const formatter = new Intl.NumberFormat([], {
10490
+ style: "percent",
10491
+ minimumFractionDigits: 2
10492
+ });
10493
+ const formatPercentage = (value, isPercentageValue = false) => {
10494
+ let val = value || 0;
10495
+ if (!isPercentageValue) {
10496
+ val = val / 100;
10497
+ }
10498
+ return formatter.format(val);
10499
+ };
10500
+ function getPromotionIds(items, shippingMethods) {
10501
+ const promotionIds = /* @__PURE__ */ new Set();
10502
+ for (const item of items) {
10503
+ if (item.adjustments) {
10504
+ for (const adjustment of item.adjustments) {
10505
+ if (adjustment.promotion_id) {
10506
+ promotionIds.add(adjustment.promotion_id);
10507
+ }
10508
+ }
10509
+ }
10510
+ }
10511
+ for (const shippingMethod of shippingMethods) {
10512
+ if (shippingMethod.adjustments) {
10513
+ for (const adjustment of shippingMethod.adjustments) {
10514
+ if (adjustment.promotion_id) {
10515
+ promotionIds.add(adjustment.promotion_id);
10516
+ }
10517
+ }
10447
10518
  }
10448
- await updateActionItem(
10519
+ }
10520
+ return Array.from(promotionIds);
10521
+ }
10522
+ const SalesChannel = () => {
10523
+ const { id } = useParams();
10524
+ const { draft_order, isPending, isError, error } = useDraftOrder(
10525
+ id,
10526
+ {
10527
+ fields: "+sales_channel_id"
10528
+ },
10529
+ {
10530
+ enabled: !!id
10531
+ }
10532
+ );
10533
+ if (isError) {
10534
+ throw error;
10535
+ }
10536
+ const ISrEADY = !!draft_order && !isPending;
10537
+ return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
10538
+ /* @__PURE__ */ jsxs(RouteDrawer.Header, { children: [
10539
+ /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Sales Channel" }) }),
10540
+ /* @__PURE__ */ jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Update which sales channel the draft order is associated with" }) })
10541
+ ] }),
10542
+ ISrEADY && /* @__PURE__ */ jsx(SalesChannelForm, { order: draft_order })
10543
+ ] });
10544
+ };
10545
+ const SalesChannelForm = ({ order }) => {
10546
+ const form = useForm({
10547
+ defaultValues: {
10548
+ sales_channel_id: order.sales_channel_id || ""
10549
+ },
10550
+ resolver: zodResolver(schema$2)
10551
+ });
10552
+ const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
10553
+ const { handleSuccess } = useRouteModal();
10554
+ const onSubmit = form.handleSubmit(async (data) => {
10555
+ await mutateAsync(
10449
10556
  {
10450
- action_id: actionId,
10451
- quantity: data.quantity,
10452
- unit_price: convertNumber(data.unit_price)
10557
+ sales_channel_id: data.sales_channel_id
10453
10558
  },
10454
10559
  {
10455
10560
  onSuccess: () => {
10456
- setEditing(false);
10561
+ toast.success("Sales channel updated");
10562
+ handleSuccess();
10457
10563
  },
10458
- onError: (e) => {
10459
- toast.error(e.message);
10564
+ onError: (error) => {
10565
+ toast.error(error.message);
10460
10566
  }
10461
10567
  }
10462
10568
  );
10463
10569
  });
10464
- return /* @__PURE__ */ jsx(Form$2, { ...form, children: /* @__PURE__ */ jsx("form", { onSubmit, children: /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest grid grid-cols-[minmax(0,2fr)_minmax(0,1fr)_minmax(0,2fr)_28px] items-center gap-3 rounded-lg px-4 py-2", children: [
10465
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-3", children: [
10466
- /* @__PURE__ */ jsx(
10467
- Thumbnail,
10468
- {
10469
- thumbnail: item.thumbnail,
10470
- alt: item.title ?? void 0
10471
- }
10472
- ),
10473
- editing ? /* @__PURE__ */ jsx(
10474
- Form$2.Field,
10475
- {
10476
- control: form.control,
10477
- name: "title",
10478
- render: ({ field }) => {
10479
- return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }) });
10480
- }
10481
- }
10482
- ) : /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: item.title })
10483
- ] }),
10484
- editing ? /* @__PURE__ */ jsx(
10485
- Form$2.Field,
10486
- {
10487
- control: form.control,
10488
- name: "quantity",
10489
- render: ({ field }) => {
10490
- return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(NumberInput, { ...field }) }) });
10491
- }
10492
- }
10493
- ) : /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: item.quantity }),
10494
- editing ? /* @__PURE__ */ jsx(
10495
- Form$2.Field,
10496
- {
10497
- control: form.control,
10498
- name: "unit_price",
10499
- render: ({ field: { onChange, ...field } }) => {
10500
- return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
10501
- CurrencyInput,
10570
+ return /* @__PURE__ */ jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxs(
10571
+ KeyboundForm,
10572
+ {
10573
+ className: "flex flex-1 flex-col overflow-hidden",
10574
+ onSubmit,
10575
+ children: [
10576
+ /* @__PURE__ */ jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsx(SalesChannelField, { control: form.control, order }) }),
10577
+ /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
10578
+ /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
10579
+ /* @__PURE__ */ jsx(Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
10580
+ ] }) })
10581
+ ]
10582
+ }
10583
+ ) });
10584
+ };
10585
+ const SalesChannelField = ({ control, order }) => {
10586
+ const salesChannels = useComboboxData({
10587
+ queryFn: async (params) => {
10588
+ return await sdk.admin.salesChannel.list(params);
10589
+ },
10590
+ queryKey: ["sales-channels"],
10591
+ getOptions: (data) => {
10592
+ return data.sales_channels.map((salesChannel) => ({
10593
+ label: salesChannel.name,
10594
+ value: salesChannel.id
10595
+ }));
10596
+ },
10597
+ defaultValue: order.sales_channel_id || void 0
10598
+ });
10599
+ return /* @__PURE__ */ jsx(
10600
+ Form$2.Field,
10601
+ {
10602
+ control,
10603
+ name: "sales_channel_id",
10604
+ render: ({ field }) => {
10605
+ return /* @__PURE__ */ jsxs(Form$2.Item, { children: [
10606
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Sales Channel" }),
10607
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
10608
+ Combobox,
10502
10609
  {
10503
- ...field,
10504
- symbol: getNativeSymbol(currencyCode),
10505
- code: currencyCode,
10506
- onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value)
10610
+ options: salesChannels.options,
10611
+ fetchNextPage: salesChannels.fetchNextPage,
10612
+ isFetchingNextPage: salesChannels.isFetchingNextPage,
10613
+ searchValue: salesChannels.searchValue,
10614
+ onSearchValueChange: salesChannels.onSearchValueChange,
10615
+ placeholder: "Select sales channel",
10616
+ ...field
10507
10617
  }
10508
- ) }) });
10509
- }
10618
+ ) }),
10619
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
10620
+ ] });
10510
10621
  }
10511
- ) : /* @__PURE__ */ jsx("div", { className: "flex flex-1 items-center justify-end", children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: getLocaleAmount(item.unit_price, currencyCode) }) }),
10512
- /* @__PURE__ */ jsx(
10513
- IconButton,
10622
+ }
10623
+ );
10624
+ };
10625
+ const schema$2 = objectType({
10626
+ sales_channel_id: stringType().min(1)
10627
+ });
10628
+ const NumberInput = forwardRef(
10629
+ ({
10630
+ value,
10631
+ onChange,
10632
+ size = "base",
10633
+ min = 0,
10634
+ max = 100,
10635
+ step = 1,
10636
+ className,
10637
+ disabled,
10638
+ ...props
10639
+ }, ref) => {
10640
+ const handleChange = (event) => {
10641
+ const newValue = event.target.value === "" ? min : Number(event.target.value);
10642
+ if (!isNaN(newValue) && (max === void 0 || newValue <= max) && (min === void 0 || newValue >= min)) {
10643
+ onChange(newValue);
10644
+ }
10645
+ };
10646
+ const handleIncrement = () => {
10647
+ const newValue = value + step;
10648
+ if (max === void 0 || newValue <= max) {
10649
+ onChange(newValue);
10650
+ }
10651
+ };
10652
+ const handleDecrement = () => {
10653
+ const newValue = value - step;
10654
+ if (min === void 0 || newValue >= min) {
10655
+ onChange(newValue);
10656
+ }
10657
+ };
10658
+ return /* @__PURE__ */ jsxs(
10659
+ "div",
10514
10660
  {
10515
- type: "button",
10516
- size: "small",
10517
- onClick: editing ? onSubmit : () => {
10518
- setEditing(true);
10519
- },
10520
- disabled: isPending,
10521
- children: editing ? /* @__PURE__ */ jsx(Check, {}) : /* @__PURE__ */ jsx(PencilSquare, {})
10661
+ className: clx(
10662
+ "inline-flex rounded-md bg-ui-bg-field shadow-borders-base overflow-hidden divide-x transition-fg",
10663
+ "[&:has(input:focus)]:shadow-borders-interactive-with-active",
10664
+ {
10665
+ "h-7": size === "small",
10666
+ "h-8": size === "base"
10667
+ },
10668
+ className
10669
+ ),
10670
+ children: [
10671
+ /* @__PURE__ */ jsx(
10672
+ "input",
10673
+ {
10674
+ ref,
10675
+ type: "number",
10676
+ value,
10677
+ onChange: handleChange,
10678
+ min,
10679
+ max,
10680
+ step,
10681
+ className: clx(
10682
+ "flex-1 px-2 py-1 bg-transparent txt-compact-small text-ui-fg-base outline-none [appearance:textfield]",
10683
+ "[&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none",
10684
+ "placeholder:text-ui-fg-muted"
10685
+ ),
10686
+ ...props
10687
+ }
10688
+ ),
10689
+ /* @__PURE__ */ jsxs(
10690
+ "button",
10691
+ {
10692
+ className: clx(
10693
+ "flex items-center justify-center outline-none transition-fg",
10694
+ "disabled:cursor-not-allowed disabled:text-ui-fg-muted",
10695
+ "focus:bg-ui-bg-field-component-hover",
10696
+ "hover:bg-ui-bg-field-component-hover",
10697
+ {
10698
+ "size-7": size === "small",
10699
+ "size-8": size === "base"
10700
+ }
10701
+ ),
10702
+ type: "button",
10703
+ onClick: handleDecrement,
10704
+ disabled: min !== void 0 && value <= min || disabled,
10705
+ children: [
10706
+ /* @__PURE__ */ jsx(Minus, {}),
10707
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: `Decrease by ${step}` })
10708
+ ]
10709
+ }
10710
+ ),
10711
+ /* @__PURE__ */ jsxs(
10712
+ "button",
10713
+ {
10714
+ className: clx(
10715
+ "flex items-center justify-center outline-none transition-fg",
10716
+ "disabled:cursor-not-allowed disabled:text-ui-fg-muted",
10717
+ "focus:bg-ui-bg-field-hover",
10718
+ "hover:bg-ui-bg-field-hover",
10719
+ {
10720
+ "size-7": size === "small",
10721
+ "size-8": size === "base"
10722
+ }
10723
+ ),
10724
+ type: "button",
10725
+ onClick: handleIncrement,
10726
+ disabled: max !== void 0 && value >= max || disabled,
10727
+ children: [
10728
+ /* @__PURE__ */ jsx(Plus, {}),
10729
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: `Increase by ${step}` })
10730
+ ]
10731
+ }
10732
+ )
10733
+ ]
10522
10734
  }
10523
- )
10524
- ] }) }) });
10735
+ );
10736
+ }
10737
+ );
10738
+ const PRODUCT_VARIANTS_QUERY_KEY = "product-variants";
10739
+ const productVariantsQueryKeys = {
10740
+ list: (query2) => [
10741
+ PRODUCT_VARIANTS_QUERY_KEY,
10742
+ query2 ? query2 : void 0
10743
+ ]
10525
10744
  };
10526
- const StackedModalTrigger$1 = ({
10527
- type,
10528
- setModalContent
10529
- }) => {
10530
- const { setIsOpen } = useStackedModal();
10531
- const onClick = useCallback(() => {
10532
- setModalContent(type);
10533
- setIsOpen(STACKED_MODAL_ID, true);
10534
- }, [setModalContent, setIsOpen, type]);
10535
- return /* @__PURE__ */ jsx(StackedFocusModal.Trigger, { asChild: true, children: /* @__PURE__ */ jsx(DropdownMenu.Item, { onClick, children: type === "add-items" ? "Add items" : "Add custom item" }) });
10745
+ const useProductVariants = (query2, options) => {
10746
+ const { data, ...rest } = useQuery({
10747
+ queryKey: productVariantsQueryKeys.list(query2),
10748
+ queryFn: async () => await sdk.admin.productVariant.list(query2),
10749
+ ...options
10750
+ });
10751
+ return { ...data, ...rest };
10536
10752
  };
10537
- const VARIANT_PREFIX = "items";
10538
- const LIMIT = 50;
10539
- const ExistingItemsForm = ({ orderId, items }) => {
10540
- const { setIsOpen } = useStackedModal();
10541
- const [rowSelection, setRowSelection] = useState(
10542
- items.reduce((acc, item) => {
10543
- acc[item.variant_id] = true;
10544
- return acc;
10545
- }, {})
10546
- );
10547
- useEffect(() => {
10548
- setRowSelection(
10549
- items.reduce((acc, item) => {
10550
- if (item.variant_id) {
10551
- acc[item.variant_id] = true;
10552
- }
10553
- return acc;
10554
- }, {})
10555
- );
10556
- }, [items]);
10557
- const { q, order, offset } = useQueryParams(
10558
- ["q", "order", "offset"],
10559
- VARIANT_PREFIX
10560
- );
10561
- const { variants, count, isPending, isError, error } = useProductVariants(
10753
+ function convertNumber(value) {
10754
+ return typeof value === "string" ? Number(value.replace(",", ".")) : value;
10755
+ }
10756
+ const STACKED_MODAL_ID = "items_stacked_modal";
10757
+ const Items = () => {
10758
+ const { id } = useParams();
10759
+ const {
10760
+ order: preview,
10761
+ isPending: isPreviewPending,
10762
+ isError: isPreviewError,
10763
+ error: previewError
10764
+ } = useOrderPreview(id, void 0, {
10765
+ placeholderData: keepPreviousData
10766
+ });
10767
+ useInitiateOrderEdit({ preview });
10768
+ const { draft_order, isPending, isError, error } = useDraftOrder(
10769
+ id,
10562
10770
  {
10563
- q,
10564
- order,
10565
- offset: offset ? parseInt(offset) : void 0,
10566
- limit: LIMIT
10771
+ fields: "currency_code"
10567
10772
  },
10568
10773
  {
10569
- placeholderData: keepPreviousData
10774
+ enabled: !!id
10570
10775
  }
10571
10776
  );
10572
- const columns = useColumns();
10573
- const { mutateAsync } = useDraftOrderAddItems(orderId);
10574
- const onSubmit = async () => {
10575
- const ids = Object.keys(rowSelection).filter(
10576
- (id) => !items.find((i) => i.variant_id === id)
10577
- );
10578
- await mutateAsync(
10579
- {
10580
- items: ids.map((id) => ({
10581
- variant_id: id,
10582
- quantity: 1
10583
- }))
10584
- },
10585
- {
10586
- onSuccess: () => {
10587
- setRowSelection({});
10588
- setIsOpen(STACKED_MODAL_ID, false);
10589
- },
10590
- onError: (e) => {
10591
- toast.error(e.message);
10592
- }
10593
- }
10594
- );
10595
- };
10777
+ const { onCancel } = useCancelOrderEdit({ preview });
10596
10778
  if (isError) {
10597
10779
  throw error;
10598
10780
  }
10599
- return /* @__PURE__ */ jsxs(
10600
- StackedFocusModal.Content,
10601
- {
10602
- onOpenAutoFocus: (e) => {
10603
- e.preventDefault();
10604
- const searchInput = document.querySelector(
10605
- "[data-modal-id='modal-search-input']"
10606
- );
10607
- if (searchInput) {
10608
- searchInput.focus();
10609
- }
10610
- },
10611
- children: [
10612
- /* @__PURE__ */ jsxs(StackedFocusModal.Header, { children: [
10613
- /* @__PURE__ */ jsx(StackedFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Product Variants" }) }),
10614
- /* @__PURE__ */ jsx(StackedFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Choose product variants to add to the order." }) })
10615
- ] }),
10616
- /* @__PURE__ */ jsx(StackedFocusModal.Body, { className: "flex-1 overflow-hidden", children: /* @__PURE__ */ jsx(
10617
- DataTable,
10618
- {
10619
- data: variants,
10620
- columns,
10621
- isLoading: isPending,
10622
- getRowId: (row) => row.id,
10623
- rowCount: count,
10624
- prefix: VARIANT_PREFIX,
10625
- layout: "fill",
10626
- rowSelection: {
10627
- state: rowSelection,
10628
- onRowSelectionChange: setRowSelection,
10629
- enableRowSelection: (row) => {
10630
- return !items.find((i) => i.variant_id === row.original.id);
10631
- }
10632
- },
10633
- autoFocusSearch: true
10634
- }
10635
- ) }),
10636
- /* @__PURE__ */ jsx(StackedFocusModal.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
10637
- /* @__PURE__ */ jsx(StackedFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
10638
- /* @__PURE__ */ jsx(Button, { size: "small", type: "button", onClick: onSubmit, children: "Update items" })
10639
- ] }) })
10640
- ]
10641
- }
10642
- );
10643
- };
10644
- const columnHelper = createDataTableColumnHelper();
10645
- const useColumns = () => {
10646
- return useMemo(() => {
10647
- return [
10648
- columnHelper.select(),
10649
- columnHelper.accessor("product.title", {
10650
- header: "Product",
10651
- cell: ({ row }) => {
10652
- var _a, _b, _c;
10653
- return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-2", children: [
10654
- /* @__PURE__ */ jsx(
10655
- Thumbnail,
10656
- {
10657
- thumbnail: (_a = row.original.product) == null ? void 0 : _a.thumbnail,
10658
- alt: (_b = row.original.product) == null ? void 0 : _b.title
10659
- }
10660
- ),
10661
- /* @__PURE__ */ jsx("span", { children: (_c = row.original.product) == null ? void 0 : _c.title })
10662
- ] });
10663
- },
10664
- enableSorting: true
10665
- }),
10666
- columnHelper.accessor("title", {
10667
- header: "Variant",
10668
- enableSorting: true
10669
- }),
10670
- columnHelper.accessor("sku", {
10671
- header: "SKU",
10672
- cell: ({ getValue }) => {
10673
- return getValue() ?? "-";
10674
- },
10675
- enableSorting: true
10676
- }),
10677
- columnHelper.accessor("updated_at", {
10678
- header: "Updated",
10679
- cell: ({ getValue }) => {
10680
- return /* @__PURE__ */ jsx(
10681
- Tooltip,
10682
- {
10683
- content: getFullDate({ date: getValue(), includeTime: true }),
10684
- children: /* @__PURE__ */ jsx("span", { children: getFullDate({ date: getValue() }) })
10685
- }
10686
- );
10687
- },
10688
- enableSorting: true,
10689
- sortAscLabel: "Oldest first",
10690
- sortDescLabel: "Newest first"
10691
- }),
10692
- columnHelper.accessor("created_at", {
10693
- header: "Created",
10694
- cell: ({ getValue }) => {
10695
- return /* @__PURE__ */ jsx(
10696
- Tooltip,
10697
- {
10698
- content: getFullDate({ date: getValue(), includeTime: true }),
10699
- children: /* @__PURE__ */ jsx("span", { children: getFullDate({ date: getValue() }) })
10700
- }
10701
- );
10702
- },
10703
- enableSorting: true,
10704
- sortAscLabel: "Oldest first",
10705
- sortDescLabel: "Newest first"
10706
- })
10707
- ];
10708
- }, []);
10781
+ if (isPreviewError) {
10782
+ throw previewError;
10783
+ }
10784
+ const ready = !!preview && !isPreviewPending && !!draft_order && !isPending;
10785
+ return /* @__PURE__ */ jsx(RouteFocusModal, { onClose: onCancel, children: ready ? /* @__PURE__ */ jsx(ItemsForm, { preview, currencyCode: draft_order.currency_code }) : /* @__PURE__ */ jsxs("div", { children: [
10786
+ /* @__PURE__ */ jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Edit Items" }) }),
10787
+ /* @__PURE__ */ jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Loading data for the draft order, please wait..." }) })
10788
+ ] }) });
10709
10789
  };
10710
- const CustomItemForm = ({ orderId, currencyCode }) => {
10711
- const { setIsOpen } = useStackedModal();
10712
- const { mutateAsync: addItems } = useDraftOrderAddItems(orderId);
10713
- const form = useForm({
10714
- defaultValues: {
10715
- title: "",
10716
- quantity: 1,
10717
- unit_price: ""
10790
+ const ItemsForm = ({ preview, currencyCode }) => {
10791
+ var _a;
10792
+ const [isSubmitting, setIsSubmitting] = useState(false);
10793
+ const [modalContent, setModalContent] = useState(
10794
+ null
10795
+ );
10796
+ const { handleSuccess } = useRouteModal();
10797
+ const { searchValue, onSearchValueChange, query: query2 } = useDebouncedSearch();
10798
+ const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
10799
+ const { mutateAsync: requestOrderEdit } = useDraftOrderRequestEdit(preview.id);
10800
+ const itemCount = ((_a = preview.items) == null ? void 0 : _a.reduce((acc, item) => acc + item.quantity, 0)) || 0;
10801
+ const matches = useMemo(() => {
10802
+ return matchSorter(preview.items, query2, {
10803
+ keys: ["product_title", "variant_title", "variant_sku", "title"]
10804
+ });
10805
+ }, [preview.items, query2]);
10806
+ const onSubmit = async () => {
10807
+ setIsSubmitting(true);
10808
+ let requestSucceeded = false;
10809
+ await requestOrderEdit(void 0, {
10810
+ onError: (e) => {
10811
+ toast.error(`Failed to request order edit: ${e.message}`);
10812
+ },
10813
+ onSuccess: () => {
10814
+ requestSucceeded = true;
10815
+ }
10816
+ });
10817
+ if (!requestSucceeded) {
10818
+ setIsSubmitting(false);
10819
+ return;
10820
+ }
10821
+ await confirmOrderEdit(void 0, {
10822
+ onError: (e) => {
10823
+ toast.error(`Failed to confirm order edit: ${e.message}`);
10824
+ },
10825
+ onSuccess: () => {
10826
+ handleSuccess();
10827
+ },
10828
+ onSettled: () => {
10829
+ setIsSubmitting(false);
10830
+ }
10831
+ });
10832
+ };
10833
+ const onKeyDown = useCallback(
10834
+ (e) => {
10835
+ if (e.key === "Enter" && (e.ctrlKey || e.metaKey)) {
10836
+ if (modalContent || isSubmitting) {
10837
+ return;
10838
+ }
10839
+ onSubmit();
10840
+ }
10718
10841
  },
10719
- resolver: zodResolver(customItemSchema)
10720
- });
10721
- const onSubmit = form.handleSubmit(async (data) => {
10722
- await addItems(
10842
+ [modalContent, isSubmitting, onSubmit]
10843
+ );
10844
+ useEffect(() => {
10845
+ document.addEventListener("keydown", onKeyDown);
10846
+ return () => {
10847
+ document.removeEventListener("keydown", onKeyDown);
10848
+ };
10849
+ }, [onKeyDown]);
10850
+ return /* @__PURE__ */ jsxs("div", { className: "flex h-full flex-col overflow-hidden", children: [
10851
+ /* @__PURE__ */ jsx(RouteFocusModal.Header, {}),
10852
+ /* @__PURE__ */ jsx(RouteFocusModal.Body, { className: "flex flex-1 flex-col overflow-hidden", children: /* @__PURE__ */ jsxs(
10853
+ StackedFocusModal,
10723
10854
  {
10724
- items: [
10725
- {
10726
- title: data.title,
10727
- quantity: data.quantity,
10728
- unit_price: convertNumber(data.unit_price)
10855
+ id: STACKED_MODAL_ID,
10856
+ onOpenChangeCallback: (open) => {
10857
+ if (!open) {
10858
+ setModalContent(null);
10729
10859
  }
10730
- ]
10731
- },
10732
- {
10733
- onSuccess: () => {
10734
- setIsOpen(STACKED_MODAL_ID, false);
10735
10860
  },
10736
- onError: (e) => {
10737
- toast.error(e.message);
10738
- }
10739
- }
10740
- );
10741
- });
10742
- return /* @__PURE__ */ jsx(Form$2, { ...form, children: /* @__PURE__ */ jsx(KeyboundForm, { onSubmit, children: /* @__PURE__ */ jsxs(StackedFocusModal.Content, { children: [
10743
- /* @__PURE__ */ jsx(StackedFocusModal.Header, {}),
10744
- /* @__PURE__ */ jsx(StackedFocusModal.Body, { className: "flex flex-1 flex-col overflow-hidden", children: /* @__PURE__ */ jsx("div", { className: "flex flex-1 flex-col items-center overflow-y-auto", children: /* @__PURE__ */ jsxs("div", { className: "flex w-full max-w-[720px] flex-col gap-y-6 px-2 py-16", children: [
10745
- /* @__PURE__ */ jsxs("div", { children: [
10746
- /* @__PURE__ */ jsx(StackedFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Add custom item" }) }),
10747
- /* @__PURE__ */ jsx(StackedFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Add a custom item to the order. This will add a new line item that is not associated with an existing product." }) })
10748
- ] }),
10749
- /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
10750
- /* @__PURE__ */ jsx(
10751
- Form$2.Field,
10752
- {
10753
- control: form.control,
10754
- name: "title",
10755
- render: ({ field }) => /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
10861
+ children: [
10862
+ /* @__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: [
10756
10863
  /* @__PURE__ */ jsxs("div", { children: [
10757
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Title" }),
10758
- /* @__PURE__ */ jsx(Form$2.Hint, { children: "Enter the title of the item" })
10864
+ /* @__PURE__ */ jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Items" }) }),
10865
+ /* @__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" }) })
10759
10866
  ] }),
10760
- /* @__PURE__ */ jsxs("div", { children: [
10761
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
10762
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
10763
- ] })
10764
- ] }) })
10765
- }
10766
- ),
10767
- /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
10768
- /* @__PURE__ */ jsx(
10769
- Form$2.Field,
10770
- {
10771
- control: form.control,
10772
- name: "unit_price",
10773
- render: ({ field: { onChange, ...field } }) => /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
10774
- /* @__PURE__ */ jsxs("div", { children: [
10775
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Unit price" }),
10776
- /* @__PURE__ */ jsx(Form$2.Hint, { children: "Enter the unit price of the item" })
10867
+ /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
10868
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-y-6", children: [
10869
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 items-center gap-3", children: [
10870
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
10871
+ /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: "Items" }),
10872
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Choose items from the product catalog." })
10873
+ ] }),
10874
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
10875
+ /* @__PURE__ */ jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsx(
10876
+ Input,
10877
+ {
10878
+ type: "search",
10879
+ placeholder: "Search items",
10880
+ value: searchValue,
10881
+ onChange: (e) => onSearchValueChange(e.target.value)
10882
+ }
10883
+ ) }),
10884
+ /* @__PURE__ */ jsxs(DropdownMenu, { children: [
10885
+ /* @__PURE__ */ jsx(DropdownMenu.Trigger, { asChild: true, children: /* @__PURE__ */ jsx(IconButton, { type: "button", children: /* @__PURE__ */ jsx(Plus, {}) }) }),
10886
+ /* @__PURE__ */ jsxs(DropdownMenu.Content, { children: [
10887
+ /* @__PURE__ */ jsx(
10888
+ StackedModalTrigger$1,
10889
+ {
10890
+ type: "add-items",
10891
+ setModalContent
10892
+ }
10893
+ ),
10894
+ /* @__PURE__ */ jsx(
10895
+ StackedModalTrigger$1,
10896
+ {
10897
+ type: "add-custom-item",
10898
+ setModalContent
10899
+ }
10900
+ )
10901
+ ] })
10902
+ ] })
10903
+ ] })
10904
+ ] }),
10905
+ /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-subtle shadow-elevation-card-rest rounded-xl", children: [
10906
+ /* @__PURE__ */ jsx("div", { className: "px-[5px]", children: /* @__PURE__ */ jsxs("div", { className: "text-ui-fg-muted grid grid-cols-[2fr_1fr_2fr_28px] gap-3 px-4 py-2", children: [
10907
+ /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: "Item" }) }),
10908
+ /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: "Quantity" }) }),
10909
+ /* @__PURE__ */ jsx("div", { className: "text-right", children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: "Price" }) }),
10910
+ /* @__PURE__ */ jsx("div", {})
10911
+ ] }) }),
10912
+ /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-y-1.5 px-[5px] pb-[5px]", children: itemCount <= 0 ? /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest flex flex-col items-center justify-center gap-1 gap-x-3 rounded-lg p-4", children: [
10913
+ /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: "There are no items in this order" }),
10914
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Add items to the order to get started." })
10915
+ ] }) : matches.length > 0 ? matches == null ? void 0 : matches.map((item) => /* @__PURE__ */ jsx(
10916
+ Item,
10917
+ {
10918
+ item,
10919
+ preview,
10920
+ currencyCode
10921
+ },
10922
+ item.id
10923
+ )) : /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest flex flex-col items-center justify-center gap-1 gap-x-3 rounded-lg p-4", children: [
10924
+ /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: "No items found" }),
10925
+ /* @__PURE__ */ jsxs(Text, { size: "small", className: "text-ui-fg-subtle", children: [
10926
+ 'No items found for "',
10927
+ query2,
10928
+ '".'
10929
+ ] })
10930
+ ] }) })
10931
+ ] })
10777
10932
  ] }),
10778
- /* @__PURE__ */ jsxs("div", { children: [
10779
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
10780
- CurrencyInput,
10933
+ /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
10934
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-[1fr_0.5fr_0.5fr] gap-3", children: [
10935
+ /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: "Subtotal" }) }),
10936
+ /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsxs(
10937
+ Text,
10781
10938
  {
10782
- symbol: getNativeSymbol(currencyCode),
10783
- code: currencyCode,
10784
- onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value),
10785
- ...field
10939
+ size: "small",
10940
+ leading: "compact",
10941
+ className: "text-ui-fg-subtle",
10942
+ children: [
10943
+ itemCount,
10944
+ " ",
10945
+ itemCount === 1 ? "item" : "items"
10946
+ ]
10786
10947
  }
10787
10948
  ) }),
10788
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
10789
- ] })
10790
- ] }) })
10791
- }
10792
- ),
10793
- /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
10794
- /* @__PURE__ */ jsx(
10795
- Form$2.Field,
10796
- {
10797
- control: form.control,
10798
- name: "quantity",
10799
- render: ({ field }) => /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
10800
- /* @__PURE__ */ jsxs("div", { children: [
10801
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Quantity" }),
10802
- /* @__PURE__ */ jsx(Form$2.Hint, { children: "Enter the quantity of the item" })
10803
- ] }),
10804
- /* @__PURE__ */ jsxs("div", { className: "w-full flex-1", children: [
10805
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsx(NumberInput, { ...field, className: "w-full" }) }) }),
10806
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
10949
+ /* @__PURE__ */ jsx("div", { className: "text-right", children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: getStylizedAmount(preview.item_subtotal, currencyCode) }) })
10807
10950
  ] })
10808
- ] }) })
10809
- }
10810
- )
10811
- ] }) }) }),
10812
- /* @__PURE__ */ jsx(StackedFocusModal.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
10813
- /* @__PURE__ */ jsx(StackedFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
10814
- /* @__PURE__ */ jsx(Button, { size: "small", type: "button", onClick: onSubmit, children: "Add item" })
10815
- ] }) })
10816
- ] }) }) });
10817
- };
10818
- const customItemSchema = objectType({
10819
- title: stringType().min(1),
10820
- quantity: numberType(),
10821
- unit_price: unionType([numberType(), stringType()])
10822
- });
10823
- const PROMOTION_QUERY_KEY = "promotions";
10824
- const promotionsQueryKeys = {
10825
- list: (query2) => [
10826
- PROMOTION_QUERY_KEY,
10827
- query2 ? query2 : void 0
10828
- ],
10829
- detail: (id, query2) => [
10830
- PROMOTION_QUERY_KEY,
10831
- id,
10832
- query2 ? query2 : void 0
10833
- ]
10834
- };
10835
- const usePromotions = (query2, options) => {
10836
- const { data, ...rest } = useQuery({
10837
- queryKey: promotionsQueryKeys.list(query2),
10838
- queryFn: async () => sdk.admin.promotion.list(query2),
10839
- ...options
10840
- });
10841
- return { ...data, ...rest };
10951
+ ] }) }),
10952
+ modalContent && (modalContent === "add-items" ? /* @__PURE__ */ jsx(ExistingItemsForm, { orderId: preview.id, items: preview.items }) : modalContent === "add-custom-item" ? /* @__PURE__ */ jsx(
10953
+ CustomItemForm,
10954
+ {
10955
+ orderId: preview.id,
10956
+ currencyCode
10957
+ }
10958
+ ) : null)
10959
+ ]
10960
+ }
10961
+ ) }),
10962
+ /* @__PURE__ */ jsx(RouteFocusModal.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
10963
+ /* @__PURE__ */ jsx(RouteFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
10964
+ /* @__PURE__ */ jsx(
10965
+ Button,
10966
+ {
10967
+ size: "small",
10968
+ type: "button",
10969
+ onClick: onSubmit,
10970
+ isLoading: isSubmitting,
10971
+ children: "Save"
10972
+ }
10973
+ )
10974
+ ] }) })
10975
+ ] });
10842
10976
  };
10843
- const Promotions = () => {
10844
- const { id } = useParams();
10845
- const {
10846
- order: preview,
10847
- isError: isPreviewError,
10848
- error: previewError
10849
- } = useOrderPreview(id, void 0);
10850
- useInitiateOrderEdit({ preview });
10851
- const { onCancel } = useCancelOrderEdit({ preview });
10852
- if (isPreviewError) {
10853
- throw previewError;
10977
+ const Item = ({ item, preview, currencyCode }) => {
10978
+ if (item.variant_id) {
10979
+ return /* @__PURE__ */ jsx(VariantItem, { item, preview, currencyCode });
10854
10980
  }
10855
- const isReady = !!preview;
10856
- return /* @__PURE__ */ jsxs(RouteDrawer, { onClose: onCancel, children: [
10857
- /* @__PURE__ */ jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Promotions" }) }) }),
10858
- isReady && /* @__PURE__ */ jsx(PromotionForm, { preview })
10859
- ] });
10981
+ return /* @__PURE__ */ jsx(CustomItem, { item, preview, currencyCode });
10860
10982
  };
10861
- const PromotionForm = ({ preview }) => {
10862
- const { items, shipping_methods } = preview;
10863
- const [isSubmitting, setIsSubmitting] = useState(false);
10864
- const [comboboxValue, setComboboxValue] = useState("");
10865
- const { handleSuccess } = useRouteModal();
10866
- const { mutateAsync: addPromotions, isPending: isAddingPromotions } = useDraftOrderAddPromotions(preview.id);
10867
- const promoIds = getPromotionIds(items, shipping_methods);
10868
- const { promotions, isPending, isError, error } = usePromotions(
10869
- {
10870
- id: promoIds
10983
+ const VariantItem = ({ item, preview, currencyCode }) => {
10984
+ const [editing, setEditing] = useState(false);
10985
+ const form = useForm({
10986
+ defaultValues: {
10987
+ quantity: item.quantity,
10988
+ unit_price: item.unit_price
10871
10989
  },
10872
- {
10873
- enabled: !!promoIds.length
10990
+ resolver: zodResolver(variantItemSchema)
10991
+ });
10992
+ const actionId = useMemo(() => {
10993
+ var _a, _b;
10994
+ return (_b = (_a = item.actions) == null ? void 0 : _a.find((a) => a.action === "ITEM_ADD")) == null ? void 0 : _b.id;
10995
+ }, [item]);
10996
+ const { mutateAsync: updateActionItem, isPending: isUpdatingActionItem } = useDraftOrderUpdateActionItem(preview.id);
10997
+ const { mutateAsync: updateOriginalItem, isPending: isUpdatingOriginalItem } = useDraftOrderUpdateItem(preview.id);
10998
+ const isPending = isUpdatingActionItem || isUpdatingOriginalItem;
10999
+ const onSubmit = form.handleSubmit(async (data) => {
11000
+ if (convertNumber(data.unit_price) === item.unit_price && data.quantity === item.quantity) {
11001
+ setEditing(false);
11002
+ return;
10874
11003
  }
10875
- );
10876
- const comboboxData = useComboboxData({
10877
- queryKey: ["promotions", "combobox", promoIds],
10878
- queryFn: async (params) => {
10879
- return await sdk.admin.promotion.list({
10880
- ...params,
10881
- id: {
10882
- $nin: promoIds
11004
+ if (!actionId) {
11005
+ await updateOriginalItem(
11006
+ {
11007
+ item_id: item.id,
11008
+ quantity: data.quantity,
11009
+ unit_price: convertNumber(data.unit_price)
11010
+ },
11011
+ {
11012
+ onSuccess: () => {
11013
+ setEditing(false);
11014
+ },
11015
+ onError: (e) => {
11016
+ toast.error(e.message);
11017
+ }
10883
11018
  }
10884
- });
10885
- },
10886
- getOptions: (data) => {
10887
- return data.promotions.map((promotion) => ({
10888
- label: promotion.code,
10889
- value: promotion.code
10890
- }));
10891
- }
10892
- });
10893
- const add = async (value) => {
10894
- if (!value) {
11019
+ );
10895
11020
  return;
10896
11021
  }
10897
- addPromotions(
11022
+ await updateActionItem(
10898
11023
  {
10899
- promo_codes: [value]
11024
+ action_id: actionId,
11025
+ quantity: data.quantity,
11026
+ unit_price: convertNumber(data.unit_price)
10900
11027
  },
10901
11028
  {
11029
+ onSuccess: () => {
11030
+ setEditing(false);
11031
+ },
10902
11032
  onError: (e) => {
10903
11033
  toast.error(e.message);
10904
- comboboxData.onSearchValueChange("");
10905
- setComboboxValue("");
10906
- },
10907
- onSuccess: () => {
10908
- comboboxData.onSearchValueChange("");
10909
- setComboboxValue("");
10910
11034
  }
10911
11035
  }
10912
11036
  );
10913
- };
10914
- const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
10915
- const { mutateAsync: requestOrderEdit } = useOrderEditRequest(preview.id);
10916
- const onSubmit = async () => {
10917
- setIsSubmitting(true);
10918
- let requestSucceeded = false;
10919
- await requestOrderEdit(void 0, {
10920
- onError: (e) => {
10921
- toast.error(e.message);
10922
- },
10923
- onSuccess: () => {
10924
- requestSucceeded = true;
10925
- }
10926
- });
10927
- if (!requestSucceeded) {
10928
- setIsSubmitting(false);
10929
- return;
10930
- }
10931
- await confirmOrderEdit(void 0, {
10932
- onError: (e) => {
10933
- toast.error(e.message);
10934
- },
10935
- onSuccess: () => {
10936
- handleSuccess();
10937
- },
10938
- onSettled: () => {
10939
- setIsSubmitting(false);
10940
- }
10941
- });
10942
- };
10943
- if (isError) {
10944
- throw error;
10945
- }
10946
- return /* @__PURE__ */ jsxs(KeyboundForm, { className: "flex flex-1 flex-col", onSubmit, children: [
10947
- /* @__PURE__ */ jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-4", children: [
10948
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3", children: [
10949
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
10950
- /* @__PURE__ */ jsx(Label$1, { size: "small", weight: "plus", htmlFor: "promotion-combobox", children: "Apply promotions" }),
10951
- /* @__PURE__ */ jsx(Hint$1, { id: "promotion-combobox-hint", children: "Manage promotions that should be applied to the order." })
11037
+ });
11038
+ return /* @__PURE__ */ jsx(Form$2, { ...form, children: /* @__PURE__ */ jsx("form", { onSubmit, children: /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest grid grid-cols-[minmax(0,2fr)_minmax(0,1fr)_minmax(0,2fr)_28px] items-center gap-3 rounded-lg px-4 py-2", children: [
11039
+ /* @__PURE__ */ jsxs("div", { className: "flex w-full items-center gap-x-3", children: [
11040
+ /* @__PURE__ */ jsx(
11041
+ Thumbnail,
11042
+ {
11043
+ thumbnail: item.thumbnail,
11044
+ alt: item.product_title ?? void 0
11045
+ }
11046
+ ),
11047
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
11048
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-1", children: [
11049
+ /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: item.product_title }),
11050
+ /* @__PURE__ */ jsxs(
11051
+ Text,
11052
+ {
11053
+ size: "small",
11054
+ leading: "compact",
11055
+ className: "text-ui-fg-subtle",
11056
+ children: [
11057
+ "(",
11058
+ item.variant_title,
11059
+ ")"
11060
+ ]
11061
+ }
11062
+ )
10952
11063
  ] }),
10953
11064
  /* @__PURE__ */ jsx(
10954
- Combobox,
11065
+ Text,
10955
11066
  {
10956
- id: "promotion-combobox",
10957
- "aria-describedby": "promotion-combobox-hint",
10958
- isFetchingNextPage: comboboxData.isFetchingNextPage,
10959
- fetchNextPage: comboboxData.fetchNextPage,
10960
- options: comboboxData.options,
10961
- onSearchValueChange: comboboxData.onSearchValueChange,
10962
- searchValue: comboboxData.searchValue,
10963
- disabled: comboboxData.disabled || isAddingPromotions,
10964
- onChange: add,
10965
- value: comboboxValue
11067
+ size: "small",
11068
+ leading: "compact",
11069
+ className: "text-ui-fg-subtle",
11070
+ children: item.variant_sku
10966
11071
  }
10967
11072
  )
10968
- ] }),
10969
- /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
10970
- /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-2", children: promotions == null ? void 0 : promotions.map((promotion) => /* @__PURE__ */ jsx(
10971
- PromotionItem,
11073
+ ] })
11074
+ ] }),
11075
+ editing ? /* @__PURE__ */ jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsx(
11076
+ Form$2.Field,
11077
+ {
11078
+ control: form.control,
11079
+ name: "quantity",
11080
+ render: ({ field }) => {
11081
+ return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(NumberInput, { ...field }) }) });
11082
+ }
11083
+ }
11084
+ ) }) : /* @__PURE__ */ jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: item.quantity }) }),
11085
+ editing ? /* @__PURE__ */ jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsx(
11086
+ Form$2.Field,
11087
+ {
11088
+ control: form.control,
11089
+ name: "unit_price",
11090
+ render: ({ field: { onChange, ...field } }) => {
11091
+ return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
11092
+ CurrencyInput,
11093
+ {
11094
+ ...field,
11095
+ symbol: getNativeSymbol(currencyCode),
11096
+ code: currencyCode,
11097
+ onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value)
11098
+ }
11099
+ ) }) });
11100
+ }
11101
+ }
11102
+ ) }) : /* @__PURE__ */ jsx("div", { className: "flex w-full flex-1 items-center justify-end", children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: getLocaleAmount(item.unit_price, currencyCode) }) }),
11103
+ /* @__PURE__ */ jsx(
11104
+ IconButton,
11105
+ {
11106
+ type: "button",
11107
+ size: "small",
11108
+ onClick: editing ? onSubmit : () => {
11109
+ setEditing(true);
11110
+ },
11111
+ disabled: isPending,
11112
+ children: editing ? /* @__PURE__ */ jsx(Check, {}) : /* @__PURE__ */ jsx(PencilSquare, {})
11113
+ }
11114
+ )
11115
+ ] }) }) });
11116
+ };
11117
+ const variantItemSchema = objectType({
11118
+ quantity: numberType(),
11119
+ unit_price: unionType([numberType(), stringType()])
11120
+ });
11121
+ const CustomItem = ({ item, preview, currencyCode }) => {
11122
+ const [editing, setEditing] = useState(false);
11123
+ const { quantity, unit_price, title } = item;
11124
+ const form = useForm({
11125
+ defaultValues: {
11126
+ title,
11127
+ quantity,
11128
+ unit_price
11129
+ },
11130
+ resolver: zodResolver(customItemSchema)
11131
+ });
11132
+ useEffect(() => {
11133
+ form.reset({
11134
+ title,
11135
+ quantity,
11136
+ unit_price
11137
+ });
11138
+ }, [form, title, quantity, unit_price]);
11139
+ const actionId = useMemo(() => {
11140
+ var _a, _b;
11141
+ return (_b = (_a = item.actions) == null ? void 0 : _a.find((a) => a.action === "ITEM_ADD")) == null ? void 0 : _b.id;
11142
+ }, [item]);
11143
+ const { mutateAsync: updateActionItem, isPending: isUpdatingActionItem } = useDraftOrderUpdateActionItem(preview.id);
11144
+ const { mutateAsync: removeActionItem, isPending: isRemovingActionItem } = useDraftOrderRemoveActionItem(preview.id);
11145
+ const { mutateAsync: updateOriginalItem, isPending: isUpdatingOriginalItem } = useDraftOrderUpdateItem(preview.id);
11146
+ const isPending = isUpdatingActionItem || isUpdatingOriginalItem;
11147
+ const onSubmit = form.handleSubmit(async (data) => {
11148
+ if (convertNumber(data.unit_price) === item.unit_price && data.quantity === item.quantity && data.title === item.title) {
11149
+ setEditing(false);
11150
+ return;
11151
+ }
11152
+ if (!actionId) {
11153
+ await updateOriginalItem(
10972
11154
  {
10973
- promotion,
10974
- orderId: preview.id,
10975
- isLoading: isPending
11155
+ item_id: item.id,
11156
+ quantity: data.quantity,
11157
+ unit_price: convertNumber(data.unit_price)
10976
11158
  },
10977
- promotion.id
10978
- )) })
10979
- ] }) }),
10980
- /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
10981
- /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
10982
- /* @__PURE__ */ jsx(
10983
- Button,
10984
11159
  {
10985
- size: "small",
10986
- type: "submit",
10987
- isLoading: isSubmitting || isAddingPromotions,
10988
- children: "Save"
11160
+ onSuccess: () => {
11161
+ setEditing(false);
11162
+ },
11163
+ onError: (e) => {
11164
+ toast.error(e.message);
11165
+ }
10989
11166
  }
10990
- )
10991
- ] }) })
10992
- ] });
10993
- };
10994
- const PromotionItem = ({
10995
- promotion,
10996
- orderId,
10997
- isLoading
10998
- }) => {
10999
- var _a;
11000
- const { mutateAsync: removePromotions, isPending } = useDraftOrderRemovePromotions(orderId);
11001
- const onRemove = async () => {
11002
- removePromotions(
11167
+ );
11168
+ return;
11169
+ }
11170
+ if (data.quantity === 0) {
11171
+ await removeActionItem(actionId, {
11172
+ onSuccess: () => {
11173
+ setEditing(false);
11174
+ },
11175
+ onError: (e) => {
11176
+ toast.error(e.message);
11177
+ }
11178
+ });
11179
+ return;
11180
+ }
11181
+ await updateActionItem(
11003
11182
  {
11004
- promo_codes: [promotion.code]
11183
+ action_id: actionId,
11184
+ quantity: data.quantity,
11185
+ unit_price: convertNumber(data.unit_price)
11005
11186
  },
11006
11187
  {
11188
+ onSuccess: () => {
11189
+ setEditing(false);
11190
+ },
11007
11191
  onError: (e) => {
11008
11192
  toast.error(e.message);
11009
11193
  }
11010
11194
  }
11011
11195
  );
11012
- };
11013
- const displayValue = getDisplayValue(promotion);
11014
- return /* @__PURE__ */ jsxs(
11015
- "div",
11016
- {
11017
- className: clx(
11018
- "bg-ui-bg-component shadow-elevation-card-rest flex items-center justify-between rounded-lg px-3 py-2",
11196
+ });
11197
+ return /* @__PURE__ */ jsx(Form$2, { ...form, children: /* @__PURE__ */ jsx("form", { onSubmit, children: /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest grid grid-cols-[minmax(0,2fr)_minmax(0,1fr)_minmax(0,2fr)_28px] items-center gap-3 rounded-lg px-4 py-2", children: [
11198
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-3", children: [
11199
+ /* @__PURE__ */ jsx(
11200
+ Thumbnail,
11019
11201
  {
11020
- "animate-pulse": isLoading
11202
+ thumbnail: item.thumbnail,
11203
+ alt: item.title ?? void 0
11021
11204
  }
11022
11205
  ),
11023
- children: [
11024
- /* @__PURE__ */ jsxs("div", { children: [
11025
- /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: promotion.code }),
11026
- /* @__PURE__ */ jsxs("div", { className: "text-ui-fg-subtle flex items-center gap-1.5", children: [
11027
- displayValue && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
11028
- /* @__PURE__ */ jsx(Text, { size: "small", leading: "compact", children: displayValue }),
11029
- /* @__PURE__ */ jsx(Text, { size: "small", leading: "compact", children: "·" })
11030
- ] }),
11031
- /* @__PURE__ */ jsx(Text, { size: "small", leading: "compact", className: "capitalize", children: (_a = promotion.application_method) == null ? void 0 : _a.allocation })
11032
- ] })
11033
- ] }),
11034
- /* @__PURE__ */ jsx(
11035
- IconButton,
11036
- {
11037
- size: "small",
11038
- type: "button",
11039
- variant: "transparent",
11040
- onClick: onRemove,
11041
- isLoading: isPending || isLoading,
11042
- children: /* @__PURE__ */ jsx(XMark, {})
11206
+ editing ? /* @__PURE__ */ jsx(
11207
+ Form$2.Field,
11208
+ {
11209
+ control: form.control,
11210
+ name: "title",
11211
+ render: ({ field }) => {
11212
+ return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }) });
11043
11213
  }
11044
- )
11045
- ]
11046
- },
11047
- promotion.id
11048
- );
11049
- };
11050
- function getDisplayValue(promotion) {
11051
- var _a, _b, _c, _d;
11052
- const value = (_a = promotion.application_method) == null ? void 0 : _a.value;
11053
- if (!value) {
11054
- return null;
11055
- }
11056
- if (((_b = promotion.application_method) == null ? void 0 : _b.type) === "fixed") {
11057
- const currency = (_c = promotion.application_method) == null ? void 0 : _c.currency_code;
11058
- if (!currency) {
11059
- return null;
11060
- }
11061
- return getLocaleAmount(value, currency);
11062
- } else if (((_d = promotion.application_method) == null ? void 0 : _d.type) === "percentage") {
11063
- return formatPercentage(value);
11064
- }
11065
- return null;
11066
- }
11067
- const formatter = new Intl.NumberFormat([], {
11068
- style: "percent",
11069
- minimumFractionDigits: 2
11070
- });
11071
- const formatPercentage = (value, isPercentageValue = false) => {
11072
- let val = value || 0;
11073
- if (!isPercentageValue) {
11074
- val = val / 100;
11075
- }
11076
- return formatter.format(val);
11077
- };
11078
- function getPromotionIds(items, shippingMethods) {
11079
- const promotionIds = /* @__PURE__ */ new Set();
11080
- for (const item of items) {
11081
- if (item.adjustments) {
11082
- for (const adjustment of item.adjustments) {
11083
- if (adjustment.promotion_id) {
11084
- promotionIds.add(adjustment.promotion_id);
11085
11214
  }
11086
- }
11087
- }
11088
- }
11089
- for (const shippingMethod of shippingMethods) {
11090
- if (shippingMethod.adjustments) {
11091
- for (const adjustment of shippingMethod.adjustments) {
11092
- if (adjustment.promotion_id) {
11093
- promotionIds.add(adjustment.promotion_id);
11215
+ ) : /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: item.title })
11216
+ ] }),
11217
+ editing ? /* @__PURE__ */ jsx(
11218
+ Form$2.Field,
11219
+ {
11220
+ control: form.control,
11221
+ name: "quantity",
11222
+ render: ({ field }) => {
11223
+ return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(NumberInput, { ...field }) }) });
11094
11224
  }
11095
11225
  }
11096
- }
11097
- }
11098
- return Array.from(promotionIds);
11099
- }
11100
- const InlineTip = forwardRef(
11101
- ({ variant = "tip", label, className, children, ...props }, ref) => {
11102
- const labelValue = label || (variant === "warning" ? "Warning" : "Tip");
11103
- return /* @__PURE__ */ jsxs(
11104
- "div",
11226
+ ) : /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: item.quantity }),
11227
+ editing ? /* @__PURE__ */ jsx(
11228
+ Form$2.Field,
11105
11229
  {
11106
- ref,
11107
- className: clx(
11108
- "bg-ui-bg-component txt-small text-ui-fg-subtle grid grid-cols-[4px_1fr] items-start gap-3 rounded-lg border p-3",
11109
- className
11110
- ),
11111
- ...props,
11112
- children: [
11113
- /* @__PURE__ */ jsx(
11114
- "div",
11230
+ control: form.control,
11231
+ name: "unit_price",
11232
+ render: ({ field: { onChange, ...field } }) => {
11233
+ return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
11234
+ CurrencyInput,
11115
11235
  {
11116
- role: "presentation",
11117
- className: clx("w-4px bg-ui-tag-neutral-icon h-full rounded-full", {
11118
- "bg-ui-tag-orange-icon": variant === "warning"
11119
- })
11120
- }
11121
- ),
11122
- /* @__PURE__ */ jsxs("div", { className: "text-pretty", children: [
11123
- /* @__PURE__ */ jsxs("strong", { className: "txt-small-plus text-ui-fg-base", children: [
11124
- labelValue,
11125
- ":"
11126
- ] }),
11127
- " ",
11128
- children
11129
- ] })
11130
- ]
11131
- }
11132
- );
11133
- }
11134
- );
11135
- InlineTip.displayName = "InlineTip";
11136
- const MetadataFieldSchema = objectType({
11137
- key: stringType(),
11138
- disabled: booleanType().optional(),
11139
- value: anyType()
11140
- });
11141
- const MetadataSchema = objectType({
11142
- metadata: arrayType(MetadataFieldSchema)
11143
- });
11144
- const Metadata = () => {
11145
- const { id } = useParams();
11146
- const { order, isPending, isError, error } = useOrder(id, {
11147
- fields: "metadata"
11148
- });
11149
- if (isError) {
11150
- throw error;
11151
- }
11152
- const isReady = !isPending && !!order;
11153
- return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
11154
- /* @__PURE__ */ jsxs(RouteDrawer.Header, { children: [
11155
- /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Metadata" }) }),
11156
- /* @__PURE__ */ jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Add metadata to the draft order." }) })
11157
- ] }),
11158
- !isReady ? /* @__PURE__ */ jsx(PlaceholderInner, {}) : /* @__PURE__ */ jsx(MetadataForm, { orderId: id, metadata: order == null ? void 0 : order.metadata })
11159
- ] });
11236
+ ...field,
11237
+ symbol: getNativeSymbol(currencyCode),
11238
+ code: currencyCode,
11239
+ onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value)
11240
+ }
11241
+ ) }) });
11242
+ }
11243
+ }
11244
+ ) : /* @__PURE__ */ jsx("div", { className: "flex flex-1 items-center justify-end", children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: getLocaleAmount(item.unit_price, currencyCode) }) }),
11245
+ /* @__PURE__ */ jsx(
11246
+ IconButton,
11247
+ {
11248
+ type: "button",
11249
+ size: "small",
11250
+ onClick: editing ? onSubmit : () => {
11251
+ setEditing(true);
11252
+ },
11253
+ disabled: isPending,
11254
+ children: editing ? /* @__PURE__ */ jsx(Check, {}) : /* @__PURE__ */ jsx(PencilSquare, {})
11255
+ }
11256
+ )
11257
+ ] }) }) });
11160
11258
  };
11161
- const METADATA_KEY_LABEL_ID = "metadata-form-key-label";
11162
- const METADATA_VALUE_LABEL_ID = "metadata-form-value-label";
11163
- const MetadataForm = ({ orderId, metadata }) => {
11164
- const { handleSuccess } = useRouteModal();
11165
- const hasUneditableRows = getHasUneditableRows(metadata);
11166
- const { mutateAsync, isPending } = useUpdateDraftOrder(orderId);
11167
- const form = useForm({
11168
- defaultValues: {
11169
- metadata: getDefaultValues(metadata)
11259
+ const StackedModalTrigger$1 = ({
11260
+ type,
11261
+ setModalContent
11262
+ }) => {
11263
+ const { setIsOpen } = useStackedModal();
11264
+ const onClick = useCallback(() => {
11265
+ setModalContent(type);
11266
+ setIsOpen(STACKED_MODAL_ID, true);
11267
+ }, [setModalContent, setIsOpen, type]);
11268
+ return /* @__PURE__ */ jsx(StackedFocusModal.Trigger, { asChild: true, children: /* @__PURE__ */ jsx(DropdownMenu.Item, { onClick, children: type === "add-items" ? "Add items" : "Add custom item" }) });
11269
+ };
11270
+ const VARIANT_PREFIX = "items";
11271
+ const LIMIT = 50;
11272
+ const ExistingItemsForm = ({ orderId, items }) => {
11273
+ const { setIsOpen } = useStackedModal();
11274
+ const [rowSelection, setRowSelection] = useState(
11275
+ items.reduce((acc, item) => {
11276
+ acc[item.variant_id] = true;
11277
+ return acc;
11278
+ }, {})
11279
+ );
11280
+ useEffect(() => {
11281
+ setRowSelection(
11282
+ items.reduce((acc, item) => {
11283
+ if (item.variant_id) {
11284
+ acc[item.variant_id] = true;
11285
+ }
11286
+ return acc;
11287
+ }, {})
11288
+ );
11289
+ }, [items]);
11290
+ const { q, order, offset } = useQueryParams(
11291
+ ["q", "order", "offset"],
11292
+ VARIANT_PREFIX
11293
+ );
11294
+ const { variants, count, isPending, isError, error } = useProductVariants(
11295
+ {
11296
+ q,
11297
+ order,
11298
+ offset: offset ? parseInt(offset) : void 0,
11299
+ limit: LIMIT
11170
11300
  },
11171
- resolver: zodResolver(MetadataSchema)
11172
- });
11173
- const handleSubmit = form.handleSubmit(async (data) => {
11174
- const parsedData = parseValues(data);
11301
+ {
11302
+ placeholderData: keepPreviousData
11303
+ }
11304
+ );
11305
+ const columns = useColumns();
11306
+ const { mutateAsync } = useDraftOrderAddItems(orderId);
11307
+ const onSubmit = async () => {
11308
+ const ids = Object.keys(rowSelection).filter(
11309
+ (id) => !items.find((i) => i.variant_id === id)
11310
+ );
11175
11311
  await mutateAsync(
11176
11312
  {
11177
- metadata: parsedData
11313
+ items: ids.map((id) => ({
11314
+ variant_id: id,
11315
+ quantity: 1
11316
+ }))
11178
11317
  },
11179
11318
  {
11180
11319
  onSuccess: () => {
11181
- toast.success("Metadata updated");
11182
- handleSuccess();
11320
+ setRowSelection({});
11321
+ setIsOpen(STACKED_MODAL_ID, false);
11183
11322
  },
11184
- onError: (error) => {
11185
- toast.error(error.message);
11323
+ onError: (e) => {
11324
+ toast.error(e.message);
11186
11325
  }
11187
- }
11188
- );
11189
- });
11190
- const { fields, insert, remove } = useFieldArray({
11191
- control: form.control,
11192
- name: "metadata"
11193
- });
11194
- function deleteRow(index) {
11195
- remove(index);
11196
- if (fields.length === 1) {
11197
- insert(0, {
11198
- key: "",
11199
- value: "",
11200
- disabled: false
11201
- });
11202
- }
11203
- }
11204
- function insertRow(index, position) {
11205
- insert(index + (position === "above" ? 0 : 1), {
11206
- key: "",
11207
- value: "",
11208
- disabled: false
11209
- });
11210
- }
11211
- return /* @__PURE__ */ jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxs(
11212
- KeyboundForm,
11213
- {
11214
- onSubmit: handleSubmit,
11215
- className: "flex flex-1 flex-col overflow-hidden",
11216
- children: [
11217
- /* @__PURE__ */ jsxs(RouteDrawer.Body, { className: "flex flex-1 flex-col gap-y-8 overflow-y-auto", children: [
11218
- /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest grid grid-cols-1 divide-y rounded-lg", children: [
11219
- /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-subtle grid grid-cols-2 divide-x rounded-t-lg", children: [
11220
- /* @__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" }) }),
11221
- /* @__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" }) })
11222
- ] }),
11223
- fields.map((field, index) => {
11224
- const isDisabled = field.disabled || false;
11225
- let placeholder = "-";
11226
- if (typeof field.value === "object") {
11227
- placeholder = "{ ... }";
11228
- }
11229
- if (Array.isArray(field.value)) {
11230
- placeholder = "[ ... ]";
11231
- }
11232
- return /* @__PURE__ */ jsx(
11233
- ConditionalTooltip,
11234
- {
11235
- showTooltip: isDisabled,
11236
- content: "This row is disabled because it contains non-primitive data.",
11237
- children: /* @__PURE__ */ jsxs("div", { className: "group/table relative", children: [
11238
- /* @__PURE__ */ jsxs(
11239
- "div",
11240
- {
11241
- className: clx("grid grid-cols-2 divide-x", {
11242
- "overflow-hidden rounded-b-lg": index === fields.length - 1
11243
- }),
11244
- children: [
11245
- /* @__PURE__ */ jsx(
11246
- Form$2.Field,
11247
- {
11248
- control: form.control,
11249
- name: `metadata.${index}.key`,
11250
- render: ({ field: field2 }) => {
11251
- return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
11252
- GridInput,
11253
- {
11254
- "aria-labelledby": METADATA_KEY_LABEL_ID,
11255
- ...field2,
11256
- disabled: isDisabled,
11257
- placeholder: "Key"
11258
- }
11259
- ) }) });
11260
- }
11261
- }
11262
- ),
11263
- /* @__PURE__ */ jsx(
11264
- Form$2.Field,
11265
- {
11266
- control: form.control,
11267
- name: `metadata.${index}.value`,
11268
- render: ({ field: { value, ...field2 } }) => {
11269
- return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
11270
- GridInput,
11271
- {
11272
- "aria-labelledby": METADATA_VALUE_LABEL_ID,
11273
- ...field2,
11274
- value: isDisabled ? placeholder : value,
11275
- disabled: isDisabled,
11276
- placeholder: "Value"
11277
- }
11278
- ) }) });
11279
- }
11280
- }
11281
- )
11282
- ]
11283
- }
11284
- ),
11285
- /* @__PURE__ */ jsxs(DropdownMenu, { children: [
11286
- /* @__PURE__ */ jsx(
11287
- DropdownMenu.Trigger,
11288
- {
11289
- className: clx(
11290
- "invisible absolute inset-y-0 -right-2.5 my-auto group-hover/table:visible data-[state='open']:visible",
11291
- {
11292
- hidden: isDisabled
11293
- }
11294
- ),
11295
- disabled: isDisabled,
11296
- asChild: true,
11297
- children: /* @__PURE__ */ jsx(IconButton, { size: "2xsmall", children: /* @__PURE__ */ jsx(EllipsisVertical, {}) })
11298
- }
11299
- ),
11300
- /* @__PURE__ */ jsxs(DropdownMenu.Content, { children: [
11301
- /* @__PURE__ */ jsxs(
11302
- DropdownMenu.Item,
11303
- {
11304
- className: "gap-x-2",
11305
- onClick: () => insertRow(index, "above"),
11306
- children: [
11307
- /* @__PURE__ */ jsx(ArrowUpMini, { className: "text-ui-fg-subtle" }),
11308
- "Insert row above"
11309
- ]
11310
- }
11311
- ),
11312
- /* @__PURE__ */ jsxs(
11313
- DropdownMenu.Item,
11314
- {
11315
- className: "gap-x-2",
11316
- onClick: () => insertRow(index, "below"),
11317
- children: [
11318
- /* @__PURE__ */ jsx(ArrowDownMini, { className: "text-ui-fg-subtle" }),
11319
- "Insert row below"
11320
- ]
11321
- }
11322
- ),
11323
- /* @__PURE__ */ jsx(DropdownMenu.Separator, {}),
11324
- /* @__PURE__ */ jsxs(
11325
- DropdownMenu.Item,
11326
- {
11327
- className: "gap-x-2",
11328
- onClick: () => deleteRow(index),
11329
- children: [
11330
- /* @__PURE__ */ jsx(Trash, { className: "text-ui-fg-subtle" }),
11331
- "Delete row"
11332
- ]
11333
- }
11334
- )
11335
- ] })
11336
- ] })
11337
- ] })
11338
- },
11339
- field.id
11340
- );
11341
- })
11342
- ] }),
11343
- 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." })
11326
+ }
11327
+ );
11328
+ };
11329
+ if (isError) {
11330
+ throw error;
11331
+ }
11332
+ return /* @__PURE__ */ jsxs(
11333
+ StackedFocusModal.Content,
11334
+ {
11335
+ onOpenAutoFocus: (e) => {
11336
+ e.preventDefault();
11337
+ const searchInput = document.querySelector(
11338
+ "[data-modal-id='modal-search-input']"
11339
+ );
11340
+ if (searchInput) {
11341
+ searchInput.focus();
11342
+ }
11343
+ },
11344
+ children: [
11345
+ /* @__PURE__ */ jsxs(StackedFocusModal.Header, { children: [
11346
+ /* @__PURE__ */ jsx(StackedFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Product Variants" }) }),
11347
+ /* @__PURE__ */ jsx(StackedFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Choose product variants to add to the order." }) })
11344
11348
  ] }),
11345
- /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
11346
- /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
11347
- /* @__PURE__ */ jsx(Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
11349
+ /* @__PURE__ */ jsx(StackedFocusModal.Body, { className: "flex-1 overflow-hidden", children: /* @__PURE__ */ jsx(
11350
+ DataTable,
11351
+ {
11352
+ data: variants,
11353
+ columns,
11354
+ isLoading: isPending,
11355
+ getRowId: (row) => row.id,
11356
+ rowCount: count,
11357
+ prefix: VARIANT_PREFIX,
11358
+ layout: "fill",
11359
+ rowSelection: {
11360
+ state: rowSelection,
11361
+ onRowSelectionChange: setRowSelection,
11362
+ enableRowSelection: (row) => {
11363
+ return !items.find((i) => i.variant_id === row.original.id);
11364
+ }
11365
+ },
11366
+ autoFocusSearch: true
11367
+ }
11368
+ ) }),
11369
+ /* @__PURE__ */ jsx(StackedFocusModal.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
11370
+ /* @__PURE__ */ jsx(StackedFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
11371
+ /* @__PURE__ */ jsx(Button, { size: "small", type: "button", onClick: onSubmit, children: "Update items" })
11348
11372
  ] }) })
11349
11373
  ]
11350
11374
  }
11351
- ) });
11352
- };
11353
- const GridInput = forwardRef(({ className, ...props }, ref) => {
11354
- return /* @__PURE__ */ jsx(
11355
- "input",
11356
- {
11357
- ref,
11358
- ...props,
11359
- autoComplete: "off",
11360
- className: clx(
11361
- "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",
11362
- className
11363
- )
11364
- }
11365
11375
  );
11366
- });
11367
- GridInput.displayName = "MetadataForm.GridInput";
11368
- const PlaceholderInner = () => {
11369
- return /* @__PURE__ */ jsxs("div", { className: "flex flex-1 flex-col overflow-hidden", children: [
11370
- /* @__PURE__ */ jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsx(Skeleton, { className: "h-[148ox] w-full rounded-lg" }) }),
11371
- /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
11372
- /* @__PURE__ */ jsx(Skeleton, { className: "h-7 w-12 rounded-md" }),
11373
- /* @__PURE__ */ jsx(Skeleton, { className: "h-7 w-12 rounded-md" })
11374
- ] }) })
11375
- ] });
11376
11376
  };
11377
- const EDITABLE_TYPES = ["string", "number", "boolean"];
11378
- function getDefaultValues(metadata) {
11379
- if (!metadata || !Object.keys(metadata).length) {
11377
+ const columnHelper = createDataTableColumnHelper();
11378
+ const useColumns = () => {
11379
+ return useMemo(() => {
11380
11380
  return [
11381
- {
11382
- key: "",
11383
- value: "",
11384
- disabled: false
11385
- }
11381
+ columnHelper.select(),
11382
+ columnHelper.accessor("product.title", {
11383
+ header: "Product",
11384
+ cell: ({ row }) => {
11385
+ var _a, _b, _c;
11386
+ return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-2", children: [
11387
+ /* @__PURE__ */ jsx(
11388
+ Thumbnail,
11389
+ {
11390
+ thumbnail: (_a = row.original.product) == null ? void 0 : _a.thumbnail,
11391
+ alt: (_b = row.original.product) == null ? void 0 : _b.title
11392
+ }
11393
+ ),
11394
+ /* @__PURE__ */ jsx("span", { children: (_c = row.original.product) == null ? void 0 : _c.title })
11395
+ ] });
11396
+ },
11397
+ enableSorting: true
11398
+ }),
11399
+ columnHelper.accessor("title", {
11400
+ header: "Variant",
11401
+ enableSorting: true
11402
+ }),
11403
+ columnHelper.accessor("sku", {
11404
+ header: "SKU",
11405
+ cell: ({ getValue }) => {
11406
+ return getValue() ?? "-";
11407
+ },
11408
+ enableSorting: true
11409
+ }),
11410
+ columnHelper.accessor("updated_at", {
11411
+ header: "Updated",
11412
+ cell: ({ getValue }) => {
11413
+ return /* @__PURE__ */ jsx(
11414
+ Tooltip,
11415
+ {
11416
+ content: getFullDate({ date: getValue(), includeTime: true }),
11417
+ children: /* @__PURE__ */ jsx("span", { children: getFullDate({ date: getValue() }) })
11418
+ }
11419
+ );
11420
+ },
11421
+ enableSorting: true,
11422
+ sortAscLabel: "Oldest first",
11423
+ sortDescLabel: "Newest first"
11424
+ }),
11425
+ columnHelper.accessor("created_at", {
11426
+ header: "Created",
11427
+ cell: ({ getValue }) => {
11428
+ return /* @__PURE__ */ jsx(
11429
+ Tooltip,
11430
+ {
11431
+ content: getFullDate({ date: getValue(), includeTime: true }),
11432
+ children: /* @__PURE__ */ jsx("span", { children: getFullDate({ date: getValue() }) })
11433
+ }
11434
+ );
11435
+ },
11436
+ enableSorting: true,
11437
+ sortAscLabel: "Oldest first",
11438
+ sortDescLabel: "Newest first"
11439
+ })
11386
11440
  ];
11387
- }
11388
- return Object.entries(metadata).map(([key, value]) => {
11389
- if (!EDITABLE_TYPES.includes(typeof value)) {
11390
- return {
11391
- key,
11392
- value,
11393
- disabled: true
11394
- };
11395
- }
11396
- let stringValue = value;
11397
- if (typeof value !== "string") {
11398
- stringValue = JSON.stringify(value);
11399
- }
11400
- return {
11401
- key,
11402
- value: stringValue,
11403
- original_key: key
11404
- };
11441
+ }, []);
11442
+ };
11443
+ const CustomItemForm = ({ orderId, currencyCode }) => {
11444
+ const { setIsOpen } = useStackedModal();
11445
+ const { mutateAsync: addItems } = useDraftOrderAddItems(orderId);
11446
+ const form = useForm({
11447
+ defaultValues: {
11448
+ title: "",
11449
+ quantity: 1,
11450
+ unit_price: ""
11451
+ },
11452
+ resolver: zodResolver(customItemSchema)
11405
11453
  });
11406
- }
11407
- function parseValues(values) {
11408
- const metadata = values.metadata;
11409
- const isEmpty = !metadata.length || metadata.length === 1 && !metadata[0].key && !metadata[0].value;
11410
- if (isEmpty) {
11411
- return null;
11412
- }
11413
- const update = {};
11414
- metadata.forEach((field) => {
11415
- let key = field.key;
11416
- let value = field.value;
11417
- const disabled = field.disabled;
11418
- if (!key || !value) {
11419
- return;
11420
- }
11421
- if (disabled) {
11422
- update[key] = value;
11423
- return;
11424
- }
11425
- key = key.trim();
11426
- value = value.trim();
11427
- if (value === "true") {
11428
- update[key] = true;
11429
- } else if (value === "false") {
11430
- update[key] = false;
11431
- } else {
11432
- const parsedNumber = parseFloat(value);
11433
- if (!isNaN(parsedNumber)) {
11434
- update[key] = parsedNumber;
11435
- } else {
11436
- update[key] = value;
11454
+ const onSubmit = form.handleSubmit(async (data) => {
11455
+ await addItems(
11456
+ {
11457
+ items: [
11458
+ {
11459
+ title: data.title,
11460
+ quantity: data.quantity,
11461
+ unit_price: convertNumber(data.unit_price)
11462
+ }
11463
+ ]
11464
+ },
11465
+ {
11466
+ onSuccess: () => {
11467
+ setIsOpen(STACKED_MODAL_ID, false);
11468
+ },
11469
+ onError: (e) => {
11470
+ toast.error(e.message);
11471
+ }
11437
11472
  }
11438
- }
11473
+ );
11439
11474
  });
11440
- return update;
11441
- }
11442
- function getHasUneditableRows(metadata) {
11443
- if (!metadata) {
11444
- return false;
11445
- }
11446
- return Object.values(metadata).some(
11447
- (value) => !EDITABLE_TYPES.includes(typeof value)
11448
- );
11449
- }
11450
- const SalesChannel = () => {
11475
+ return /* @__PURE__ */ jsx(Form$2, { ...form, children: /* @__PURE__ */ jsx(KeyboundForm, { onSubmit, children: /* @__PURE__ */ jsxs(StackedFocusModal.Content, { children: [
11476
+ /* @__PURE__ */ jsx(StackedFocusModal.Header, {}),
11477
+ /* @__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: [
11478
+ /* @__PURE__ */ jsxs("div", { children: [
11479
+ /* @__PURE__ */ jsx(StackedFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Add custom item" }) }),
11480
+ /* @__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." }) })
11481
+ ] }),
11482
+ /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
11483
+ /* @__PURE__ */ jsx(
11484
+ Form$2.Field,
11485
+ {
11486
+ control: form.control,
11487
+ name: "title",
11488
+ render: ({ field }) => /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
11489
+ /* @__PURE__ */ jsxs("div", { children: [
11490
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Title" }),
11491
+ /* @__PURE__ */ jsx(Form$2.Hint, { children: "Enter the title of the item" })
11492
+ ] }),
11493
+ /* @__PURE__ */ jsxs("div", { children: [
11494
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
11495
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11496
+ ] })
11497
+ ] }) })
11498
+ }
11499
+ ),
11500
+ /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
11501
+ /* @__PURE__ */ jsx(
11502
+ Form$2.Field,
11503
+ {
11504
+ control: form.control,
11505
+ name: "unit_price",
11506
+ render: ({ field: { onChange, ...field } }) => /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
11507
+ /* @__PURE__ */ jsxs("div", { children: [
11508
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Unit price" }),
11509
+ /* @__PURE__ */ jsx(Form$2.Hint, { children: "Enter the unit price of the item" })
11510
+ ] }),
11511
+ /* @__PURE__ */ jsxs("div", { children: [
11512
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
11513
+ CurrencyInput,
11514
+ {
11515
+ symbol: getNativeSymbol(currencyCode),
11516
+ code: currencyCode,
11517
+ onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value),
11518
+ ...field
11519
+ }
11520
+ ) }),
11521
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11522
+ ] })
11523
+ ] }) })
11524
+ }
11525
+ ),
11526
+ /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
11527
+ /* @__PURE__ */ jsx(
11528
+ Form$2.Field,
11529
+ {
11530
+ control: form.control,
11531
+ name: "quantity",
11532
+ render: ({ field }) => /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
11533
+ /* @__PURE__ */ jsxs("div", { children: [
11534
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Quantity" }),
11535
+ /* @__PURE__ */ jsx(Form$2.Hint, { children: "Enter the quantity of the item" })
11536
+ ] }),
11537
+ /* @__PURE__ */ jsxs("div", { className: "w-full flex-1", children: [
11538
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsx(NumberInput, { ...field, className: "w-full" }) }) }),
11539
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11540
+ ] })
11541
+ ] }) })
11542
+ }
11543
+ )
11544
+ ] }) }) }),
11545
+ /* @__PURE__ */ jsx(StackedFocusModal.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
11546
+ /* @__PURE__ */ jsx(StackedFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
11547
+ /* @__PURE__ */ jsx(Button, { size: "small", type: "button", onClick: onSubmit, children: "Add item" })
11548
+ ] }) })
11549
+ ] }) }) });
11550
+ };
11551
+ const customItemSchema = objectType({
11552
+ title: stringType().min(1),
11553
+ quantity: numberType(),
11554
+ unit_price: unionType([numberType(), stringType()])
11555
+ });
11556
+ const ShippingAddress = () => {
11451
11557
  const { id } = useParams();
11452
- const { draft_order, isPending, isError, error } = useDraftOrder(
11453
- id,
11454
- {
11455
- fields: "+sales_channel_id"
11456
- },
11457
- {
11458
- enabled: !!id
11459
- }
11460
- );
11558
+ const { order, isPending, isError, error } = useOrder(id, {
11559
+ fields: "+shipping_address"
11560
+ });
11461
11561
  if (isError) {
11462
11562
  throw error;
11463
11563
  }
11464
- const ISrEADY = !!draft_order && !isPending;
11564
+ const isReady = !isPending && !!order;
11465
11565
  return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
11466
11566
  /* @__PURE__ */ jsxs(RouteDrawer.Header, { children: [
11467
- /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Sales Channel" }) }),
11468
- /* @__PURE__ */ jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Update which sales channel the draft order is associated with" }) })
11567
+ /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Shipping Address" }) }),
11568
+ /* @__PURE__ */ jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Edit the shipping address for the draft order" }) })
11469
11569
  ] }),
11470
- ISrEADY && /* @__PURE__ */ jsx(SalesChannelForm, { order: draft_order })
11570
+ isReady && /* @__PURE__ */ jsx(ShippingAddressForm, { order })
11471
11571
  ] });
11472
11572
  };
11473
- const SalesChannelForm = ({ order }) => {
11573
+ const ShippingAddressForm = ({ order }) => {
11574
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
11474
11575
  const form = useForm({
11475
11576
  defaultValues: {
11476
- sales_channel_id: order.sales_channel_id || ""
11577
+ first_name: ((_a = order.shipping_address) == null ? void 0 : _a.first_name) ?? "",
11578
+ last_name: ((_b = order.shipping_address) == null ? void 0 : _b.last_name) ?? "",
11579
+ company: ((_c = order.shipping_address) == null ? void 0 : _c.company) ?? "",
11580
+ address_1: ((_d = order.shipping_address) == null ? void 0 : _d.address_1) ?? "",
11581
+ address_2: ((_e = order.shipping_address) == null ? void 0 : _e.address_2) ?? "",
11582
+ city: ((_f = order.shipping_address) == null ? void 0 : _f.city) ?? "",
11583
+ province: ((_g = order.shipping_address) == null ? void 0 : _g.province) ?? "",
11584
+ country_code: ((_h = order.shipping_address) == null ? void 0 : _h.country_code) ?? "",
11585
+ postal_code: ((_i = order.shipping_address) == null ? void 0 : _i.postal_code) ?? "",
11586
+ phone: ((_j = order.shipping_address) == null ? void 0 : _j.phone) ?? ""
11477
11587
  },
11478
- resolver: zodResolver(schema$2)
11588
+ resolver: zodResolver(schema$1)
11479
11589
  });
11480
11590
  const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
11481
11591
  const { handleSuccess } = useRouteModal();
11482
11592
  const onSubmit = form.handleSubmit(async (data) => {
11483
11593
  await mutateAsync(
11484
11594
  {
11485
- sales_channel_id: data.sales_channel_id
11595
+ shipping_address: {
11596
+ first_name: data.first_name,
11597
+ last_name: data.last_name,
11598
+ company: data.company,
11599
+ address_1: data.address_1,
11600
+ address_2: data.address_2,
11601
+ city: data.city,
11602
+ province: data.province,
11603
+ country_code: data.country_code,
11604
+ postal_code: data.postal_code,
11605
+ phone: data.phone
11606
+ }
11486
11607
  },
11487
11608
  {
11488
11609
  onSuccess: () => {
11489
- toast.success("Sales channel updated");
11490
11610
  handleSuccess();
11491
11611
  },
11492
11612
  onError: (error) => {
@@ -11501,58 +11621,141 @@ const SalesChannelForm = ({ order }) => {
11501
11621
  className: "flex flex-1 flex-col overflow-hidden",
11502
11622
  onSubmit,
11503
11623
  children: [
11504
- /* @__PURE__ */ jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsx(SalesChannelField, { control: form.control, order }) }),
11505
- /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
11506
- /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
11507
- /* @__PURE__ */ jsx(Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
11508
- ] }) })
11509
- ]
11510
- }
11511
- ) });
11512
- };
11513
- const SalesChannelField = ({ control, order }) => {
11514
- const salesChannels = useComboboxData({
11515
- queryFn: async (params) => {
11516
- return await sdk.admin.salesChannel.list(params);
11517
- },
11518
- queryKey: ["sales-channels"],
11519
- getOptions: (data) => {
11520
- return data.sales_channels.map((salesChannel) => ({
11521
- label: salesChannel.name,
11522
- value: salesChannel.id
11523
- }));
11524
- },
11525
- defaultValue: order.sales_channel_id || void 0
11526
- });
11527
- return /* @__PURE__ */ jsx(
11528
- Form$2.Field,
11529
- {
11530
- control,
11531
- name: "sales_channel_id",
11532
- render: ({ field }) => {
11533
- return /* @__PURE__ */ jsxs(Form$2.Item, { children: [
11534
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Sales Channel" }),
11535
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
11536
- Combobox,
11624
+ /* @__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: [
11625
+ /* @__PURE__ */ jsx(
11626
+ Form$2.Field,
11627
+ {
11628
+ control: form.control,
11629
+ name: "country_code",
11630
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
11631
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Country" }),
11632
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(CountrySelect, { ...field }) }),
11633
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11634
+ ] })
11635
+ }
11636
+ ),
11637
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
11638
+ /* @__PURE__ */ jsx(
11639
+ Form$2.Field,
11640
+ {
11641
+ control: form.control,
11642
+ name: "first_name",
11643
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
11644
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "First name" }),
11645
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
11646
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11647
+ ] })
11648
+ }
11649
+ ),
11650
+ /* @__PURE__ */ jsx(
11651
+ Form$2.Field,
11652
+ {
11653
+ control: form.control,
11654
+ name: "last_name",
11655
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
11656
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Last name" }),
11657
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
11658
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11659
+ ] })
11660
+ }
11661
+ )
11662
+ ] }),
11663
+ /* @__PURE__ */ jsx(
11664
+ Form$2.Field,
11665
+ {
11666
+ control: form.control,
11667
+ name: "company",
11668
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
11669
+ /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Company" }),
11670
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
11671
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11672
+ ] })
11673
+ }
11674
+ ),
11675
+ /* @__PURE__ */ jsx(
11676
+ Form$2.Field,
11677
+ {
11678
+ control: form.control,
11679
+ name: "address_1",
11680
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
11681
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Address" }),
11682
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
11683
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11684
+ ] })
11685
+ }
11686
+ ),
11687
+ /* @__PURE__ */ jsx(
11688
+ Form$2.Field,
11689
+ {
11690
+ control: form.control,
11691
+ name: "address_2",
11692
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
11693
+ /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Apartment, suite, etc." }),
11694
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
11695
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11696
+ ] })
11697
+ }
11698
+ ),
11699
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
11700
+ /* @__PURE__ */ jsx(
11701
+ Form$2.Field,
11702
+ {
11703
+ control: form.control,
11704
+ name: "postal_code",
11705
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
11706
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Postal code" }),
11707
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
11708
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11709
+ ] })
11710
+ }
11711
+ ),
11712
+ /* @__PURE__ */ jsx(
11713
+ Form$2.Field,
11714
+ {
11715
+ control: form.control,
11716
+ name: "city",
11717
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
11718
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "City" }),
11719
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
11720
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11721
+ ] })
11722
+ }
11723
+ )
11724
+ ] }),
11725
+ /* @__PURE__ */ jsx(
11726
+ Form$2.Field,
11727
+ {
11728
+ control: form.control,
11729
+ name: "province",
11730
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
11731
+ /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Province / State" }),
11732
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
11733
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11734
+ ] })
11735
+ }
11736
+ ),
11737
+ /* @__PURE__ */ jsx(
11738
+ Form$2.Field,
11537
11739
  {
11538
- options: salesChannels.options,
11539
- fetchNextPage: salesChannels.fetchNextPage,
11540
- isFetchingNextPage: salesChannels.isFetchingNextPage,
11541
- searchValue: salesChannels.searchValue,
11542
- onSearchValueChange: salesChannels.onSearchValueChange,
11543
- placeholder: "Select sales channel",
11544
- ...field
11740
+ control: form.control,
11741
+ name: "phone",
11742
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
11743
+ /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Phone" }),
11744
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
11745
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11746
+ ] })
11545
11747
  }
11546
- ) }),
11547
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11548
- ] });
11549
- }
11748
+ )
11749
+ ] }) }),
11750
+ /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
11751
+ /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
11752
+ /* @__PURE__ */ jsx(Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
11753
+ ] }) })
11754
+ ]
11550
11755
  }
11551
- );
11756
+ ) });
11552
11757
  };
11553
- const schema$2 = objectType({
11554
- sales_channel_id: stringType().min(1)
11555
- });
11758
+ const schema$1 = addressSchema;
11556
11759
  const STACKED_FOCUS_MODAL_ID = "shipping-form";
11557
11760
  const Shipping = () => {
11558
11761
  var _a;
@@ -12383,7 +12586,7 @@ const TransferOwnershipForm = ({ order }) => {
12383
12586
  defaultValues: {
12384
12587
  customer_id: order.customer_id || ""
12385
12588
  },
12386
- resolver: zodResolver(schema$1)
12589
+ resolver: zodResolver(schema)
12387
12590
  });
12388
12591
  const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
12389
12592
  const { handleSuccess } = useRouteModal();
@@ -12833,212 +13036,9 @@ const Illustration = () => {
12833
13036
  }
12834
13037
  );
12835
13038
  };
12836
- const schema$1 = objectType({
13039
+ const schema = objectType({
12837
13040
  customer_id: stringType().min(1)
12838
13041
  });
12839
- const ShippingAddress = () => {
12840
- const { id } = useParams();
12841
- const { order, isPending, isError, error } = useOrder(id, {
12842
- fields: "+shipping_address"
12843
- });
12844
- if (isError) {
12845
- throw error;
12846
- }
12847
- const isReady = !isPending && !!order;
12848
- return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
12849
- /* @__PURE__ */ jsxs(RouteDrawer.Header, { children: [
12850
- /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Shipping Address" }) }),
12851
- /* @__PURE__ */ jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Edit the shipping address for the draft order" }) })
12852
- ] }),
12853
- isReady && /* @__PURE__ */ jsx(ShippingAddressForm, { order })
12854
- ] });
12855
- };
12856
- const ShippingAddressForm = ({ order }) => {
12857
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
12858
- const form = useForm({
12859
- defaultValues: {
12860
- first_name: ((_a = order.shipping_address) == null ? void 0 : _a.first_name) ?? "",
12861
- last_name: ((_b = order.shipping_address) == null ? void 0 : _b.last_name) ?? "",
12862
- company: ((_c = order.shipping_address) == null ? void 0 : _c.company) ?? "",
12863
- address_1: ((_d = order.shipping_address) == null ? void 0 : _d.address_1) ?? "",
12864
- address_2: ((_e = order.shipping_address) == null ? void 0 : _e.address_2) ?? "",
12865
- city: ((_f = order.shipping_address) == null ? void 0 : _f.city) ?? "",
12866
- province: ((_g = order.shipping_address) == null ? void 0 : _g.province) ?? "",
12867
- country_code: ((_h = order.shipping_address) == null ? void 0 : _h.country_code) ?? "",
12868
- postal_code: ((_i = order.shipping_address) == null ? void 0 : _i.postal_code) ?? "",
12869
- phone: ((_j = order.shipping_address) == null ? void 0 : _j.phone) ?? ""
12870
- },
12871
- resolver: zodResolver(schema)
12872
- });
12873
- const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
12874
- const { handleSuccess } = useRouteModal();
12875
- const onSubmit = form.handleSubmit(async (data) => {
12876
- await mutateAsync(
12877
- {
12878
- shipping_address: {
12879
- first_name: data.first_name,
12880
- last_name: data.last_name,
12881
- company: data.company,
12882
- address_1: data.address_1,
12883
- address_2: data.address_2,
12884
- city: data.city,
12885
- province: data.province,
12886
- country_code: data.country_code,
12887
- postal_code: data.postal_code,
12888
- phone: data.phone
12889
- }
12890
- },
12891
- {
12892
- onSuccess: () => {
12893
- handleSuccess();
12894
- },
12895
- onError: (error) => {
12896
- toast.error(error.message);
12897
- }
12898
- }
12899
- );
12900
- });
12901
- return /* @__PURE__ */ jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxs(
12902
- KeyboundForm,
12903
- {
12904
- className: "flex flex-1 flex-col overflow-hidden",
12905
- onSubmit,
12906
- children: [
12907
- /* @__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: [
12908
- /* @__PURE__ */ jsx(
12909
- Form$2.Field,
12910
- {
12911
- control: form.control,
12912
- name: "country_code",
12913
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12914
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Country" }),
12915
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(CountrySelect, { ...field }) }),
12916
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12917
- ] })
12918
- }
12919
- ),
12920
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
12921
- /* @__PURE__ */ jsx(
12922
- Form$2.Field,
12923
- {
12924
- control: form.control,
12925
- name: "first_name",
12926
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12927
- /* @__PURE__ */ jsx(Form$2.Label, { children: "First name" }),
12928
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12929
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12930
- ] })
12931
- }
12932
- ),
12933
- /* @__PURE__ */ jsx(
12934
- Form$2.Field,
12935
- {
12936
- control: form.control,
12937
- name: "last_name",
12938
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12939
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Last name" }),
12940
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12941
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12942
- ] })
12943
- }
12944
- )
12945
- ] }),
12946
- /* @__PURE__ */ jsx(
12947
- Form$2.Field,
12948
- {
12949
- control: form.control,
12950
- name: "company",
12951
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12952
- /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Company" }),
12953
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12954
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12955
- ] })
12956
- }
12957
- ),
12958
- /* @__PURE__ */ jsx(
12959
- Form$2.Field,
12960
- {
12961
- control: form.control,
12962
- name: "address_1",
12963
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12964
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Address" }),
12965
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12966
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12967
- ] })
12968
- }
12969
- ),
12970
- /* @__PURE__ */ jsx(
12971
- Form$2.Field,
12972
- {
12973
- control: form.control,
12974
- name: "address_2",
12975
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12976
- /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Apartment, suite, etc." }),
12977
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12978
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12979
- ] })
12980
- }
12981
- ),
12982
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
12983
- /* @__PURE__ */ jsx(
12984
- Form$2.Field,
12985
- {
12986
- control: form.control,
12987
- name: "postal_code",
12988
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12989
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Postal code" }),
12990
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12991
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12992
- ] })
12993
- }
12994
- ),
12995
- /* @__PURE__ */ jsx(
12996
- Form$2.Field,
12997
- {
12998
- control: form.control,
12999
- name: "city",
13000
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
13001
- /* @__PURE__ */ jsx(Form$2.Label, { children: "City" }),
13002
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
13003
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
13004
- ] })
13005
- }
13006
- )
13007
- ] }),
13008
- /* @__PURE__ */ jsx(
13009
- Form$2.Field,
13010
- {
13011
- control: form.control,
13012
- name: "province",
13013
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
13014
- /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Province / State" }),
13015
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
13016
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
13017
- ] })
13018
- }
13019
- ),
13020
- /* @__PURE__ */ jsx(
13021
- Form$2.Field,
13022
- {
13023
- control: form.control,
13024
- name: "phone",
13025
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
13026
- /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Phone" }),
13027
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
13028
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
13029
- ] })
13030
- }
13031
- )
13032
- ] }) }),
13033
- /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
13034
- /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
13035
- /* @__PURE__ */ jsx(Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
13036
- ] }) })
13037
- ]
13038
- }
13039
- ) });
13040
- };
13041
- const schema = addressSchema;
13042
13042
  const widgetModule = { widgets: [] };
13043
13043
  const routeModule = {
13044
13044
  routes: [
@@ -13072,21 +13072,25 @@ const routeModule = {
13072
13072
  path: "/draft-orders/:id/email"
13073
13073
  },
13074
13074
  {
13075
- Component: Items,
13076
- path: "/draft-orders/:id/items"
13075
+ Component: Metadata,
13076
+ path: "/draft-orders/:id/metadata"
13077
13077
  },
13078
13078
  {
13079
13079
  Component: Promotions,
13080
13080
  path: "/draft-orders/:id/promotions"
13081
13081
  },
13082
- {
13083
- Component: Metadata,
13084
- path: "/draft-orders/:id/metadata"
13085
- },
13086
13082
  {
13087
13083
  Component: SalesChannel,
13088
13084
  path: "/draft-orders/:id/sales-channel"
13089
13085
  },
13086
+ {
13087
+ Component: Items,
13088
+ path: "/draft-orders/:id/items"
13089
+ },
13090
+ {
13091
+ Component: ShippingAddress,
13092
+ path: "/draft-orders/:id/shipping-address"
13093
+ },
13090
13094
  {
13091
13095
  Component: Shipping,
13092
13096
  path: "/draft-orders/:id/shipping"
@@ -13094,10 +13098,6 @@ const routeModule = {
13094
13098
  {
13095
13099
  Component: TransferOwnership,
13096
13100
  path: "/draft-orders/:id/transfer-ownership"
13097
- },
13098
- {
13099
- Component: ShippingAddress,
13100
- path: "/draft-orders/:id/shipping-address"
13101
13101
  }
13102
13102
  ]
13103
13103
  }