@medusajs/draft-order 2.11.4-preview-20251106090134 → 2.11.4-preview-20251106120154

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, EllipsisVertical, ArrowUpMini, ArrowDownMini, Minus, PencilSquare } 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, Minus, PencilSquare, EllipsisVertical, ArrowUpMini, ArrowDownMini } 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";
@@ -9561,6 +9561,27 @@ const ID = () => {
9561
9561
  /* @__PURE__ */ jsx(Outlet, {})
9562
9562
  ] });
9563
9563
  };
9564
+ const CustomItems = () => {
9565
+ return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
9566
+ /* @__PURE__ */ jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Custom Items" }) }) }),
9567
+ /* @__PURE__ */ jsx(CustomItemsForm, {})
9568
+ ] });
9569
+ };
9570
+ const CustomItemsForm = () => {
9571
+ const form = useForm({
9572
+ resolver: zodResolver(schema$5)
9573
+ });
9574
+ return /* @__PURE__ */ jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxs(KeyboundForm, { className: "flex flex-1 flex-col", children: [
9575
+ /* @__PURE__ */ jsx(RouteDrawer.Body, {}),
9576
+ /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
9577
+ /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
9578
+ /* @__PURE__ */ jsx(Button, { size: "small", type: "submit", children: "Save" })
9579
+ ] }) })
9580
+ ] }) });
9581
+ };
9582
+ const schema$5 = objectType({
9583
+ email: stringType().email()
9584
+ });
9564
9585
  const BillingAddress = () => {
9565
9586
  const { id } = useParams();
9566
9587
  const { order, isPending, isError, error } = useOrder(id, {
@@ -9593,7 +9614,7 @@ const BillingAddressForm = ({ order }) => {
9593
9614
  postal_code: ((_i = order.billing_address) == null ? void 0 : _i.postal_code) ?? "",
9594
9615
  phone: ((_j = order.billing_address) == null ? void 0 : _j.phone) ?? ""
9595
9616
  },
9596
- resolver: zodResolver(schema$5)
9617
+ resolver: zodResolver(schema$4)
9597
9618
  });
9598
9619
  const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
9599
9620
  const { handleSuccess } = useRouteModal();
@@ -9750,28 +9771,7 @@ const BillingAddressForm = ({ order }) => {
9750
9771
  }
9751
9772
  ) });
9752
9773
  };
9753
- const schema$5 = addressSchema;
9754
- const CustomItems = () => {
9755
- return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
9756
- /* @__PURE__ */ jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Custom Items" }) }) }),
9757
- /* @__PURE__ */ jsx(CustomItemsForm, {})
9758
- ] });
9759
- };
9760
- const CustomItemsForm = () => {
9761
- const form = useForm({
9762
- resolver: zodResolver(schema$4)
9763
- });
9764
- return /* @__PURE__ */ jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxs(KeyboundForm, { className: "flex flex-1 flex-col", children: [
9765
- /* @__PURE__ */ jsx(RouteDrawer.Body, {}),
9766
- /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
9767
- /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
9768
- /* @__PURE__ */ jsx(Button, { size: "small", type: "submit", children: "Save" })
9769
- ] }) })
9770
- ] }) });
9771
- };
9772
- const schema$4 = objectType({
9773
- email: stringType().email()
9774
- });
9774
+ const schema$4 = addressSchema;
9775
9775
  const Email = () => {
9776
9776
  const { id } = useParams();
9777
9777
  const { order, isPending, isError, error } = useOrder(id, {
@@ -9840,501 +9840,236 @@ const EmailForm = ({ order }) => {
9840
9840
  const schema$3 = objectType({
9841
9841
  email: stringType().email()
9842
9842
  });
9843
- const InlineTip = forwardRef(
9844
- ({ variant = "tip", label, className, children, ...props }, ref) => {
9845
- const labelValue = label || (variant === "warning" ? "Warning" : "Tip");
9843
+ const NumberInput = forwardRef(
9844
+ ({
9845
+ value,
9846
+ onChange,
9847
+ size = "base",
9848
+ min = 0,
9849
+ max = 100,
9850
+ step = 1,
9851
+ className,
9852
+ disabled,
9853
+ ...props
9854
+ }, ref) => {
9855
+ const handleChange = (event) => {
9856
+ const newValue = event.target.value === "" ? min : Number(event.target.value);
9857
+ if (!isNaN(newValue) && (max === void 0 || newValue <= max) && (min === void 0 || newValue >= min)) {
9858
+ onChange(newValue);
9859
+ }
9860
+ };
9861
+ const handleIncrement = () => {
9862
+ const newValue = value + step;
9863
+ if (max === void 0 || newValue <= max) {
9864
+ onChange(newValue);
9865
+ }
9866
+ };
9867
+ const handleDecrement = () => {
9868
+ const newValue = value - step;
9869
+ if (min === void 0 || newValue >= min) {
9870
+ onChange(newValue);
9871
+ }
9872
+ };
9846
9873
  return /* @__PURE__ */ jsxs(
9847
9874
  "div",
9848
9875
  {
9849
- ref,
9850
9876
  className: clx(
9851
- "bg-ui-bg-component txt-small text-ui-fg-subtle grid grid-cols-[4px_1fr] items-start gap-3 rounded-lg border p-3",
9877
+ "inline-flex rounded-md bg-ui-bg-field shadow-borders-base overflow-hidden divide-x transition-fg",
9878
+ "[&:has(input:focus)]:shadow-borders-interactive-with-active",
9879
+ {
9880
+ "h-7": size === "small",
9881
+ "h-8": size === "base"
9882
+ },
9852
9883
  className
9853
9884
  ),
9854
- ...props,
9855
9885
  children: [
9856
9886
  /* @__PURE__ */ jsx(
9857
- "div",
9887
+ "input",
9858
9888
  {
9859
- role: "presentation",
9860
- className: clx("w-4px bg-ui-tag-neutral-icon h-full rounded-full", {
9861
- "bg-ui-tag-orange-icon": variant === "warning"
9862
- })
9889
+ ref,
9890
+ type: "number",
9891
+ value,
9892
+ onChange: handleChange,
9893
+ min,
9894
+ max,
9895
+ step,
9896
+ className: clx(
9897
+ "flex-1 px-2 py-1 bg-transparent txt-compact-small text-ui-fg-base outline-none [appearance:textfield]",
9898
+ "[&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none",
9899
+ "placeholder:text-ui-fg-muted"
9900
+ ),
9901
+ ...props
9863
9902
  }
9864
9903
  ),
9865
- /* @__PURE__ */ jsxs("div", { className: "text-pretty", children: [
9866
- /* @__PURE__ */ jsxs("strong", { className: "txt-small-plus text-ui-fg-base", children: [
9867
- labelValue,
9868
- ":"
9869
- ] }),
9870
- " ",
9871
- children
9872
- ] })
9904
+ /* @__PURE__ */ jsxs(
9905
+ "button",
9906
+ {
9907
+ className: clx(
9908
+ "flex items-center justify-center outline-none transition-fg",
9909
+ "disabled:cursor-not-allowed disabled:text-ui-fg-muted",
9910
+ "focus:bg-ui-bg-field-component-hover",
9911
+ "hover:bg-ui-bg-field-component-hover",
9912
+ {
9913
+ "size-7": size === "small",
9914
+ "size-8": size === "base"
9915
+ }
9916
+ ),
9917
+ type: "button",
9918
+ onClick: handleDecrement,
9919
+ disabled: min !== void 0 && value <= min || disabled,
9920
+ children: [
9921
+ /* @__PURE__ */ jsx(Minus, {}),
9922
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: `Decrease by ${step}` })
9923
+ ]
9924
+ }
9925
+ ),
9926
+ /* @__PURE__ */ jsxs(
9927
+ "button",
9928
+ {
9929
+ className: clx(
9930
+ "flex items-center justify-center outline-none transition-fg",
9931
+ "disabled:cursor-not-allowed disabled:text-ui-fg-muted",
9932
+ "focus:bg-ui-bg-field-hover",
9933
+ "hover:bg-ui-bg-field-hover",
9934
+ {
9935
+ "size-7": size === "small",
9936
+ "size-8": size === "base"
9937
+ }
9938
+ ),
9939
+ type: "button",
9940
+ onClick: handleIncrement,
9941
+ disabled: max !== void 0 && value >= max || disabled,
9942
+ children: [
9943
+ /* @__PURE__ */ jsx(Plus, {}),
9944
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: `Increase by ${step}` })
9945
+ ]
9946
+ }
9947
+ )
9873
9948
  ]
9874
9949
  }
9875
9950
  );
9876
9951
  }
9877
9952
  );
9878
- InlineTip.displayName = "InlineTip";
9879
- const MetadataFieldSchema = objectType({
9880
- key: stringType(),
9881
- disabled: booleanType().optional(),
9882
- value: anyType()
9883
- });
9884
- const MetadataSchema = objectType({
9885
- metadata: arrayType(MetadataFieldSchema)
9886
- });
9887
- const Metadata = () => {
9888
- const { id } = useParams();
9889
- const { order, isPending, isError, error } = useOrder(id, {
9890
- fields: "metadata"
9891
- });
9892
- if (isError) {
9893
- throw error;
9894
- }
9895
- const isReady = !isPending && !!order;
9896
- return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
9897
- /* @__PURE__ */ jsxs(RouteDrawer.Header, { children: [
9898
- /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Metadata" }) }),
9899
- /* @__PURE__ */ jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Add metadata to the draft order." }) })
9900
- ] }),
9901
- !isReady ? /* @__PURE__ */ jsx(PlaceholderInner, {}) : /* @__PURE__ */ jsx(MetadataForm, { orderId: id, metadata: order == null ? void 0 : order.metadata })
9902
- ] });
9953
+ const PRODUCT_VARIANTS_QUERY_KEY = "product-variants";
9954
+ const productVariantsQueryKeys = {
9955
+ list: (query2) => [
9956
+ PRODUCT_VARIANTS_QUERY_KEY,
9957
+ query2 ? query2 : void 0
9958
+ ]
9903
9959
  };
9904
- const METADATA_KEY_LABEL_ID = "metadata-form-key-label";
9905
- const METADATA_VALUE_LABEL_ID = "metadata-form-value-label";
9906
- const MetadataForm = ({ orderId, metadata }) => {
9907
- const { handleSuccess } = useRouteModal();
9908
- const hasUneditableRows = getHasUneditableRows(metadata);
9909
- const { mutateAsync, isPending } = useUpdateDraftOrder(orderId);
9910
- const form = useForm({
9911
- defaultValues: {
9912
- metadata: getDefaultValues(metadata)
9913
- },
9914
- resolver: zodResolver(MetadataSchema)
9960
+ const useProductVariants = (query2, options) => {
9961
+ const { data, ...rest } = useQuery({
9962
+ queryKey: productVariantsQueryKeys.list(query2),
9963
+ queryFn: async () => await sdk.admin.productVariant.list(query2),
9964
+ ...options
9915
9965
  });
9916
- const handleSubmit = form.handleSubmit(async (data) => {
9917
- const parsedData = parseValues(data);
9918
- await mutateAsync(
9919
- {
9920
- metadata: parsedData
9966
+ return { ...data, ...rest };
9967
+ };
9968
+ const useCancelOrderEdit = ({ preview }) => {
9969
+ const { mutateAsync: cancelOrderEdit } = useDraftOrderCancelEdit(preview == null ? void 0 : preview.id);
9970
+ const onCancel = useCallback(async () => {
9971
+ if (!preview) {
9972
+ return true;
9973
+ }
9974
+ let res = false;
9975
+ await cancelOrderEdit(void 0, {
9976
+ onError: (e) => {
9977
+ toast.error(e.message);
9921
9978
  },
9922
- {
9923
- onSuccess: () => {
9924
- toast.success("Metadata updated");
9925
- handleSuccess();
9926
- },
9927
- onError: (error) => {
9928
- toast.error(error.message);
9929
- }
9979
+ onSuccess: () => {
9980
+ res = true;
9930
9981
  }
9931
- );
9932
- });
9933
- const { fields, insert, remove } = useFieldArray({
9934
- control: form.control,
9935
- name: "metadata"
9936
- });
9937
- function deleteRow(index) {
9938
- remove(index);
9939
- if (fields.length === 1) {
9940
- insert(0, {
9941
- key: "",
9942
- value: "",
9943
- disabled: false
9944
- });
9945
- }
9946
- }
9947
- function insertRow(index, position) {
9948
- insert(index + (position === "above" ? 0 : 1), {
9949
- key: "",
9950
- value: "",
9951
- disabled: false
9952
9982
  });
9953
- }
9954
- return /* @__PURE__ */ jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxs(
9955
- KeyboundForm,
9956
- {
9957
- onSubmit: handleSubmit,
9958
- className: "flex flex-1 flex-col overflow-hidden",
9959
- children: [
9960
- /* @__PURE__ */ jsxs(RouteDrawer.Body, { className: "flex flex-1 flex-col gap-y-8 overflow-y-auto", children: [
9961
- /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest grid grid-cols-1 divide-y rounded-lg", children: [
9962
- /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-subtle grid grid-cols-2 divide-x rounded-t-lg", children: [
9963
- /* @__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" }) }),
9964
- /* @__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" }) })
9965
- ] }),
9966
- fields.map((field, index) => {
9967
- const isDisabled = field.disabled || false;
9968
- let placeholder = "-";
9969
- if (typeof field.value === "object") {
9970
- placeholder = "{ ... }";
9971
- }
9972
- if (Array.isArray(field.value)) {
9973
- placeholder = "[ ... ]";
9974
- }
9975
- return /* @__PURE__ */ jsx(
9976
- ConditionalTooltip,
9977
- {
9978
- showTooltip: isDisabled,
9979
- content: "This row is disabled because it contains non-primitive data.",
9980
- children: /* @__PURE__ */ jsxs("div", { className: "group/table relative", children: [
9981
- /* @__PURE__ */ jsxs(
9982
- "div",
9983
- {
9984
- className: clx("grid grid-cols-2 divide-x", {
9985
- "overflow-hidden rounded-b-lg": index === fields.length - 1
9986
- }),
9987
- children: [
9988
- /* @__PURE__ */ jsx(
9989
- Form$2.Field,
9990
- {
9991
- control: form.control,
9992
- name: `metadata.${index}.key`,
9993
- render: ({ field: field2 }) => {
9994
- return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
9995
- GridInput,
9996
- {
9997
- "aria-labelledby": METADATA_KEY_LABEL_ID,
9998
- ...field2,
9999
- disabled: isDisabled,
10000
- placeholder: "Key"
10001
- }
10002
- ) }) });
10003
- }
10004
- }
10005
- ),
10006
- /* @__PURE__ */ jsx(
10007
- Form$2.Field,
10008
- {
10009
- control: form.control,
10010
- name: `metadata.${index}.value`,
10011
- render: ({ field: { value, ...field2 } }) => {
10012
- return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
10013
- GridInput,
10014
- {
10015
- "aria-labelledby": METADATA_VALUE_LABEL_ID,
10016
- ...field2,
10017
- value: isDisabled ? placeholder : value,
10018
- disabled: isDisabled,
10019
- placeholder: "Value"
10020
- }
10021
- ) }) });
10022
- }
10023
- }
10024
- )
10025
- ]
10026
- }
10027
- ),
10028
- /* @__PURE__ */ jsxs(DropdownMenu, { children: [
10029
- /* @__PURE__ */ jsx(
10030
- DropdownMenu.Trigger,
10031
- {
10032
- className: clx(
10033
- "invisible absolute inset-y-0 -right-2.5 my-auto group-hover/table:visible data-[state='open']:visible",
10034
- {
10035
- hidden: isDisabled
10036
- }
10037
- ),
10038
- disabled: isDisabled,
10039
- asChild: true,
10040
- children: /* @__PURE__ */ jsx(IconButton, { size: "2xsmall", children: /* @__PURE__ */ jsx(EllipsisVertical, {}) })
10041
- }
10042
- ),
10043
- /* @__PURE__ */ jsxs(DropdownMenu.Content, { children: [
10044
- /* @__PURE__ */ jsxs(
10045
- DropdownMenu.Item,
10046
- {
10047
- className: "gap-x-2",
10048
- onClick: () => insertRow(index, "above"),
10049
- children: [
10050
- /* @__PURE__ */ jsx(ArrowUpMini, { className: "text-ui-fg-subtle" }),
10051
- "Insert row above"
10052
- ]
10053
- }
10054
- ),
10055
- /* @__PURE__ */ jsxs(
10056
- DropdownMenu.Item,
10057
- {
10058
- className: "gap-x-2",
10059
- onClick: () => insertRow(index, "below"),
10060
- children: [
10061
- /* @__PURE__ */ jsx(ArrowDownMini, { className: "text-ui-fg-subtle" }),
10062
- "Insert row below"
10063
- ]
10064
- }
10065
- ),
10066
- /* @__PURE__ */ jsx(DropdownMenu.Separator, {}),
10067
- /* @__PURE__ */ jsxs(
10068
- DropdownMenu.Item,
10069
- {
10070
- className: "gap-x-2",
10071
- onClick: () => deleteRow(index),
10072
- children: [
10073
- /* @__PURE__ */ jsx(Trash, { className: "text-ui-fg-subtle" }),
10074
- "Delete row"
10075
- ]
10076
- }
10077
- )
10078
- ] })
10079
- ] })
10080
- ] })
10081
- },
10082
- field.id
10083
- );
10084
- })
10085
- ] }),
10086
- 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." })
10087
- ] }),
10088
- /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
10089
- /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
10090
- /* @__PURE__ */ jsx(Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
10091
- ] }) })
10092
- ]
9983
+ return res;
9984
+ }, [preview, cancelOrderEdit]);
9985
+ return { onCancel };
9986
+ };
9987
+ let IS_REQUEST_RUNNING = false;
9988
+ const useInitiateOrderEdit = ({
9989
+ preview
9990
+ }) => {
9991
+ const navigate = useNavigate();
9992
+ const { mutateAsync } = useDraftOrderBeginEdit(preview == null ? void 0 : preview.id);
9993
+ useEffect(() => {
9994
+ async function run() {
9995
+ if (IS_REQUEST_RUNNING || !preview) {
9996
+ return;
9997
+ }
9998
+ if (preview.order_change) {
9999
+ return;
10000
+ }
10001
+ IS_REQUEST_RUNNING = true;
10002
+ await mutateAsync(void 0, {
10003
+ onError: (e) => {
10004
+ toast.error(e.message);
10005
+ navigate(`/draft-orders/${preview.id}`, { replace: true });
10006
+ return;
10007
+ }
10008
+ });
10009
+ IS_REQUEST_RUNNING = false;
10093
10010
  }
10094
- ) });
10011
+ run();
10012
+ }, [preview, navigate, mutateAsync]);
10095
10013
  };
10096
- const GridInput = forwardRef(({ className, ...props }, ref) => {
10097
- return /* @__PURE__ */ jsx(
10098
- "input",
10014
+ function convertNumber(value) {
10015
+ return typeof value === "string" ? Number(value.replace(",", ".")) : value;
10016
+ }
10017
+ const STACKED_MODAL_ID = "items_stacked_modal";
10018
+ const Items = () => {
10019
+ const { id } = useParams();
10020
+ const {
10021
+ order: preview,
10022
+ isPending: isPreviewPending,
10023
+ isError: isPreviewError,
10024
+ error: previewError
10025
+ } = useOrderPreview(id, void 0, {
10026
+ placeholderData: keepPreviousData
10027
+ });
10028
+ useInitiateOrderEdit({ preview });
10029
+ const { draft_order, isPending, isError, error } = useDraftOrder(
10030
+ id,
10099
10031
  {
10100
- ref,
10101
- ...props,
10102
- autoComplete: "off",
10103
- className: clx(
10104
- "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",
10105
- className
10106
- )
10032
+ fields: "currency_code"
10033
+ },
10034
+ {
10035
+ enabled: !!id
10107
10036
  }
10108
10037
  );
10109
- });
10110
- GridInput.displayName = "MetadataForm.GridInput";
10111
- const PlaceholderInner = () => {
10112
- return /* @__PURE__ */ jsxs("div", { className: "flex flex-1 flex-col overflow-hidden", children: [
10113
- /* @__PURE__ */ jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsx(Skeleton, { className: "h-[148ox] w-full rounded-lg" }) }),
10114
- /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
10115
- /* @__PURE__ */ jsx(Skeleton, { className: "h-7 w-12 rounded-md" }),
10116
- /* @__PURE__ */ jsx(Skeleton, { className: "h-7 w-12 rounded-md" })
10117
- ] }) })
10118
- ] });
10119
- };
10120
- const EDITABLE_TYPES = ["string", "number", "boolean"];
10121
- function getDefaultValues(metadata) {
10122
- if (!metadata || !Object.keys(metadata).length) {
10123
- return [
10124
- {
10125
- key: "",
10126
- value: "",
10127
- disabled: false
10128
- }
10129
- ];
10038
+ const { onCancel } = useCancelOrderEdit({ preview });
10039
+ if (isError) {
10040
+ throw error;
10130
10041
  }
10131
- return Object.entries(metadata).map(([key, value]) => {
10132
- if (!EDITABLE_TYPES.includes(typeof value)) {
10133
- return {
10134
- key,
10135
- value,
10136
- disabled: true
10137
- };
10138
- }
10139
- let stringValue = value;
10140
- if (typeof value !== "string") {
10141
- stringValue = JSON.stringify(value);
10142
- }
10143
- return {
10144
- key,
10145
- value: stringValue,
10146
- original_key: key
10147
- };
10148
- });
10149
- }
10150
- function parseValues(values) {
10151
- const metadata = values.metadata;
10152
- const isEmpty = !metadata.length || metadata.length === 1 && !metadata[0].key && !metadata[0].value;
10153
- if (isEmpty) {
10154
- return null;
10042
+ if (isPreviewError) {
10043
+ throw previewError;
10155
10044
  }
10156
- const update = {};
10157
- metadata.forEach((field) => {
10158
- let key = field.key;
10159
- let value = field.value;
10160
- const disabled = field.disabled;
10161
- if (!key || !value) {
10162
- return;
10163
- }
10164
- if (disabled) {
10165
- update[key] = value;
10166
- return;
10167
- }
10168
- key = key.trim();
10169
- value = value.trim();
10170
- if (value === "true") {
10171
- update[key] = true;
10172
- } else if (value === "false") {
10173
- update[key] = false;
10174
- } else {
10175
- const parsedNumber = parseFloat(value);
10176
- if (!isNaN(parsedNumber)) {
10177
- update[key] = parsedNumber;
10178
- } else {
10179
- update[key] = value;
10180
- }
10181
- }
10182
- });
10183
- return update;
10184
- }
10185
- function getHasUneditableRows(metadata) {
10186
- if (!metadata) {
10187
- return false;
10188
- }
10189
- return Object.values(metadata).some(
10190
- (value) => !EDITABLE_TYPES.includes(typeof value)
10191
- );
10192
- }
10193
- const PROMOTION_QUERY_KEY = "promotions";
10194
- const promotionsQueryKeys = {
10195
- list: (query2) => [
10196
- PROMOTION_QUERY_KEY,
10197
- query2 ? query2 : void 0
10198
- ],
10199
- detail: (id, query2) => [
10200
- PROMOTION_QUERY_KEY,
10201
- id,
10202
- query2 ? query2 : void 0
10203
- ]
10204
- };
10205
- const usePromotions = (query2, options) => {
10206
- const { data, ...rest } = useQuery({
10207
- queryKey: promotionsQueryKeys.list(query2),
10208
- queryFn: async () => sdk.admin.promotion.list(query2),
10209
- ...options
10210
- });
10211
- return { ...data, ...rest };
10212
- };
10213
- const useCancelOrderEdit = ({ preview }) => {
10214
- const { mutateAsync: cancelOrderEdit } = useDraftOrderCancelEdit(preview == null ? void 0 : preview.id);
10215
- const onCancel = useCallback(async () => {
10216
- if (!preview) {
10217
- return true;
10218
- }
10219
- let res = false;
10220
- await cancelOrderEdit(void 0, {
10221
- onError: (e) => {
10222
- toast.error(e.message);
10223
- },
10224
- onSuccess: () => {
10225
- res = true;
10226
- }
10227
- });
10228
- return res;
10229
- }, [preview, cancelOrderEdit]);
10230
- return { onCancel };
10231
- };
10232
- let IS_REQUEST_RUNNING = false;
10233
- const useInitiateOrderEdit = ({
10234
- preview
10235
- }) => {
10236
- const navigate = useNavigate();
10237
- const { mutateAsync } = useDraftOrderBeginEdit(preview == null ? void 0 : preview.id);
10238
- useEffect(() => {
10239
- async function run() {
10240
- if (IS_REQUEST_RUNNING || !preview) {
10241
- return;
10242
- }
10243
- if (preview.order_change) {
10244
- return;
10245
- }
10246
- IS_REQUEST_RUNNING = true;
10247
- await mutateAsync(void 0, {
10248
- onError: (e) => {
10249
- toast.error(e.message);
10250
- navigate(`/draft-orders/${preview.id}`, { replace: true });
10251
- return;
10252
- }
10253
- });
10254
- IS_REQUEST_RUNNING = false;
10255
- }
10256
- run();
10257
- }, [preview, navigate, mutateAsync]);
10258
- };
10259
- const Promotions = () => {
10260
- const { id } = useParams();
10261
- const {
10262
- order: preview,
10263
- isError: isPreviewError,
10264
- error: previewError
10265
- } = useOrderPreview(id, void 0);
10266
- useInitiateOrderEdit({ preview });
10267
- const { onCancel } = useCancelOrderEdit({ preview });
10268
- if (isPreviewError) {
10269
- throw previewError;
10270
- }
10271
- const isReady = !!preview;
10272
- return /* @__PURE__ */ jsxs(RouteDrawer, { onClose: onCancel, children: [
10273
- /* @__PURE__ */ jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Promotions" }) }) }),
10274
- isReady && /* @__PURE__ */ jsx(PromotionForm, { preview })
10275
- ] });
10045
+ const ready = !!preview && !isPreviewPending && !!draft_order && !isPending;
10046
+ return /* @__PURE__ */ jsx(RouteFocusModal, { onClose: onCancel, children: ready ? /* @__PURE__ */ jsx(ItemsForm, { preview, currencyCode: draft_order.currency_code }) : /* @__PURE__ */ jsxs("div", { children: [
10047
+ /* @__PURE__ */ jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Edit Items" }) }),
10048
+ /* @__PURE__ */ jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Loading data for the draft order, please wait..." }) })
10049
+ ] }) });
10276
10050
  };
10277
- const PromotionForm = ({ preview }) => {
10278
- const { items, shipping_methods } = preview;
10051
+ const ItemsForm = ({ preview, currencyCode }) => {
10052
+ var _a;
10279
10053
  const [isSubmitting, setIsSubmitting] = useState(false);
10280
- const [comboboxValue, setComboboxValue] = useState("");
10281
- const { handleSuccess } = useRouteModal();
10282
- const { mutateAsync: addPromotions, isPending: isAddingPromotions } = useDraftOrderAddPromotions(preview.id);
10283
- const promoIds = getPromotionIds(items, shipping_methods);
10284
- const { promotions, isPending, isError, error } = usePromotions(
10285
- {
10286
- id: promoIds
10287
- },
10288
- {
10289
- enabled: !!promoIds.length
10290
- }
10054
+ const [modalContent, setModalContent] = useState(
10055
+ null
10291
10056
  );
10292
- const comboboxData = useComboboxData({
10293
- queryKey: ["promotions", "combobox", promoIds],
10294
- queryFn: async (params) => {
10295
- return await sdk.admin.promotion.list({
10296
- ...params,
10297
- id: {
10298
- $nin: promoIds
10299
- }
10300
- });
10301
- },
10302
- getOptions: (data) => {
10303
- return data.promotions.map((promotion) => ({
10304
- label: promotion.code,
10305
- value: promotion.code
10306
- }));
10307
- }
10308
- });
10309
- const add = async (value) => {
10310
- if (!value) {
10311
- return;
10312
- }
10313
- addPromotions(
10314
- {
10315
- promo_codes: [value]
10316
- },
10317
- {
10318
- onError: (e) => {
10319
- toast.error(e.message);
10320
- comboboxData.onSearchValueChange("");
10321
- setComboboxValue("");
10322
- },
10323
- onSuccess: () => {
10324
- comboboxData.onSearchValueChange("");
10325
- setComboboxValue("");
10326
- }
10327
- }
10328
- );
10329
- };
10057
+ const { handleSuccess } = useRouteModal();
10058
+ const { searchValue, onSearchValueChange, query: query2 } = useDebouncedSearch();
10330
10059
  const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
10331
- const { mutateAsync: requestOrderEdit } = useOrderEditRequest(preview.id);
10060
+ const { mutateAsync: requestOrderEdit } = useDraftOrderRequestEdit(preview.id);
10061
+ const itemCount = ((_a = preview.items) == null ? void 0 : _a.reduce((acc, item) => acc + item.quantity, 0)) || 0;
10062
+ const matches = useMemo(() => {
10063
+ return matchSorter(preview.items, query2, {
10064
+ keys: ["product_title", "variant_title", "variant_sku", "title"]
10065
+ });
10066
+ }, [preview.items, query2]);
10332
10067
  const onSubmit = async () => {
10333
10068
  setIsSubmitting(true);
10334
10069
  let requestSucceeded = false;
10335
10070
  await requestOrderEdit(void 0, {
10336
10071
  onError: (e) => {
10337
- toast.error(e.message);
10072
+ toast.error(`Failed to request order edit: ${e.message}`);
10338
10073
  },
10339
10074
  onSuccess: () => {
10340
10075
  requestSucceeded = true;
@@ -10346,7 +10081,7 @@ const PromotionForm = ({ preview }) => {
10346
10081
  }
10347
10082
  await confirmOrderEdit(void 0, {
10348
10083
  onError: (e) => {
10349
- toast.error(e.message);
10084
+ toast.error(`Failed to confirm order edit: ${e.message}`);
10350
10085
  },
10351
10086
  onSuccess: () => {
10352
10087
  handleSuccess();
@@ -10356,566 +10091,641 @@ const PromotionForm = ({ preview }) => {
10356
10091
  }
10357
10092
  });
10358
10093
  };
10359
- if (isError) {
10360
- throw error;
10361
- }
10362
- return /* @__PURE__ */ jsxs(KeyboundForm, { className: "flex flex-1 flex-col", onSubmit, children: [
10363
- /* @__PURE__ */ jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-4", children: [
10364
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3", children: [
10365
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
10366
- /* @__PURE__ */ jsx(Label$1, { size: "small", weight: "plus", htmlFor: "promotion-combobox", children: "Apply promotions" }),
10367
- /* @__PURE__ */ jsx(Hint$1, { id: "promotion-combobox-hint", children: "Manage promotions that should be applied to the order." })
10368
- ] }),
10369
- /* @__PURE__ */ jsx(
10370
- Combobox,
10371
- {
10372
- id: "promotion-combobox",
10373
- "aria-describedby": "promotion-combobox-hint",
10374
- isFetchingNextPage: comboboxData.isFetchingNextPage,
10375
- fetchNextPage: comboboxData.fetchNextPage,
10376
- options: comboboxData.options,
10377
- onSearchValueChange: comboboxData.onSearchValueChange,
10378
- searchValue: comboboxData.searchValue,
10379
- disabled: comboboxData.disabled || isAddingPromotions,
10380
- onChange: add,
10381
- value: comboboxValue
10382
- }
10383
- )
10384
- ] }),
10385
- /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
10386
- /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-2", children: promotions == null ? void 0 : promotions.map((promotion) => /* @__PURE__ */ jsx(
10387
- PromotionItem,
10388
- {
10389
- promotion,
10390
- orderId: preview.id,
10391
- isLoading: isPending
10392
- },
10393
- promotion.id
10394
- )) })
10395
- ] }) }),
10396
- /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
10397
- /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
10398
- /* @__PURE__ */ jsx(
10399
- Button,
10400
- {
10401
- size: "small",
10402
- type: "submit",
10403
- isLoading: isSubmitting || isAddingPromotions,
10404
- children: "Save"
10405
- }
10406
- )
10407
- ] }) })
10408
- ] });
10409
- };
10410
- const PromotionItem = ({
10411
- promotion,
10412
- orderId,
10413
- isLoading
10414
- }) => {
10415
- var _a;
10416
- const { mutateAsync: removePromotions, isPending } = useDraftOrderRemovePromotions(orderId);
10417
- const onRemove = async () => {
10418
- removePromotions(
10419
- {
10420
- promo_codes: [promotion.code]
10421
- },
10422
- {
10423
- onError: (e) => {
10424
- toast.error(e.message);
10094
+ const onKeyDown = useCallback(
10095
+ (e) => {
10096
+ if (e.key === "Enter" && (e.ctrlKey || e.metaKey)) {
10097
+ if (modalContent || isSubmitting) {
10098
+ return;
10425
10099
  }
10100
+ onSubmit();
10426
10101
  }
10427
- );
10428
- };
10429
- const displayValue = getDisplayValue(promotion);
10430
- return /* @__PURE__ */ jsxs(
10431
- "div",
10432
- {
10433
- className: clx(
10434
- "bg-ui-bg-component shadow-elevation-card-rest flex items-center justify-between rounded-lg px-3 py-2",
10102
+ },
10103
+ [modalContent, isSubmitting, onSubmit]
10104
+ );
10105
+ useEffect(() => {
10106
+ document.addEventListener("keydown", onKeyDown);
10107
+ return () => {
10108
+ document.removeEventListener("keydown", onKeyDown);
10109
+ };
10110
+ }, [onKeyDown]);
10111
+ return /* @__PURE__ */ jsxs("div", { className: "flex h-full flex-col overflow-hidden", children: [
10112
+ /* @__PURE__ */ jsx(RouteFocusModal.Header, {}),
10113
+ /* @__PURE__ */ jsx(RouteFocusModal.Body, { className: "flex flex-1 flex-col overflow-hidden", children: /* @__PURE__ */ jsxs(
10114
+ StackedFocusModal,
10115
+ {
10116
+ id: STACKED_MODAL_ID,
10117
+ onOpenChangeCallback: (open) => {
10118
+ if (!open) {
10119
+ setModalContent(null);
10120
+ }
10121
+ },
10122
+ children: [
10123
+ /* @__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: [
10124
+ /* @__PURE__ */ jsxs("div", { children: [
10125
+ /* @__PURE__ */ jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Items" }) }),
10126
+ /* @__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" }) })
10127
+ ] }),
10128
+ /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
10129
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-y-6", children: [
10130
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 items-center gap-3", children: [
10131
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
10132
+ /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: "Items" }),
10133
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Choose items from the product catalog." })
10134
+ ] }),
10135
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
10136
+ /* @__PURE__ */ jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsx(
10137
+ Input,
10138
+ {
10139
+ type: "search",
10140
+ placeholder: "Search items",
10141
+ value: searchValue,
10142
+ onChange: (e) => onSearchValueChange(e.target.value)
10143
+ }
10144
+ ) }),
10145
+ /* @__PURE__ */ jsxs(DropdownMenu, { children: [
10146
+ /* @__PURE__ */ jsx(DropdownMenu.Trigger, { asChild: true, children: /* @__PURE__ */ jsx(IconButton, { type: "button", children: /* @__PURE__ */ jsx(Plus, {}) }) }),
10147
+ /* @__PURE__ */ jsxs(DropdownMenu.Content, { children: [
10148
+ /* @__PURE__ */ jsx(
10149
+ StackedModalTrigger$1,
10150
+ {
10151
+ type: "add-items",
10152
+ setModalContent
10153
+ }
10154
+ ),
10155
+ /* @__PURE__ */ jsx(
10156
+ StackedModalTrigger$1,
10157
+ {
10158
+ type: "add-custom-item",
10159
+ setModalContent
10160
+ }
10161
+ )
10162
+ ] })
10163
+ ] })
10164
+ ] })
10165
+ ] }),
10166
+ /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-subtle shadow-elevation-card-rest rounded-xl", children: [
10167
+ /* @__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: [
10168
+ /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: "Item" }) }),
10169
+ /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: "Quantity" }) }),
10170
+ /* @__PURE__ */ jsx("div", { className: "text-right", children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: "Price" }) }),
10171
+ /* @__PURE__ */ jsx("div", {})
10172
+ ] }) }),
10173
+ /* @__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: [
10174
+ /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: "There are no items in this order" }),
10175
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Add items to the order to get started." })
10176
+ ] }) : matches.length > 0 ? matches == null ? void 0 : matches.map((item) => /* @__PURE__ */ jsx(
10177
+ Item,
10178
+ {
10179
+ item,
10180
+ preview,
10181
+ currencyCode
10182
+ },
10183
+ item.id
10184
+ )) : /* @__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: [
10185
+ /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: "No items found" }),
10186
+ /* @__PURE__ */ jsxs(Text, { size: "small", className: "text-ui-fg-subtle", children: [
10187
+ 'No items found for "',
10188
+ query2,
10189
+ '".'
10190
+ ] })
10191
+ ] }) })
10192
+ ] })
10193
+ ] }),
10194
+ /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
10195
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-[1fr_0.5fr_0.5fr] gap-3", children: [
10196
+ /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: "Subtotal" }) }),
10197
+ /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsxs(
10198
+ Text,
10199
+ {
10200
+ size: "small",
10201
+ leading: "compact",
10202
+ className: "text-ui-fg-subtle",
10203
+ children: [
10204
+ itemCount,
10205
+ " ",
10206
+ itemCount === 1 ? "item" : "items"
10207
+ ]
10208
+ }
10209
+ ) }),
10210
+ /* @__PURE__ */ jsx("div", { className: "text-right", children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: getStylizedAmount(preview.item_subtotal, currencyCode) }) })
10211
+ ] })
10212
+ ] }) }),
10213
+ modalContent && (modalContent === "add-items" ? /* @__PURE__ */ jsx(ExistingItemsForm, { orderId: preview.id, items: preview.items }) : modalContent === "add-custom-item" ? /* @__PURE__ */ jsx(
10214
+ CustomItemForm,
10215
+ {
10216
+ orderId: preview.id,
10217
+ currencyCode
10218
+ }
10219
+ ) : null)
10220
+ ]
10221
+ }
10222
+ ) }),
10223
+ /* @__PURE__ */ jsx(RouteFocusModal.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
10224
+ /* @__PURE__ */ jsx(RouteFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
10225
+ /* @__PURE__ */ jsx(
10226
+ Button,
10435
10227
  {
10436
- "animate-pulse": isLoading
10228
+ size: "small",
10229
+ type: "button",
10230
+ onClick: onSubmit,
10231
+ isLoading: isSubmitting,
10232
+ children: "Save"
10233
+ }
10234
+ )
10235
+ ] }) })
10236
+ ] });
10237
+ };
10238
+ const Item = ({ item, preview, currencyCode }) => {
10239
+ if (item.variant_id) {
10240
+ return /* @__PURE__ */ jsx(VariantItem, { item, preview, currencyCode });
10241
+ }
10242
+ return /* @__PURE__ */ jsx(CustomItem, { item, preview, currencyCode });
10243
+ };
10244
+ const VariantItem = ({ item, preview, currencyCode }) => {
10245
+ const [editing, setEditing] = useState(false);
10246
+ const form = useForm({
10247
+ defaultValues: {
10248
+ quantity: item.quantity,
10249
+ unit_price: item.unit_price
10250
+ },
10251
+ resolver: zodResolver(variantItemSchema)
10252
+ });
10253
+ const actionId = useMemo(() => {
10254
+ var _a, _b;
10255
+ return (_b = (_a = item.actions) == null ? void 0 : _a.find((a) => a.action === "ITEM_ADD")) == null ? void 0 : _b.id;
10256
+ }, [item]);
10257
+ const { mutateAsync: updateActionItem, isPending: isUpdatingActionItem } = useDraftOrderUpdateActionItem(preview.id);
10258
+ const { mutateAsync: updateOriginalItem, isPending: isUpdatingOriginalItem } = useDraftOrderUpdateItem(preview.id);
10259
+ const isPending = isUpdatingActionItem || isUpdatingOriginalItem;
10260
+ const onSubmit = form.handleSubmit(async (data) => {
10261
+ if (convertNumber(data.unit_price) === item.unit_price && data.quantity === item.quantity) {
10262
+ setEditing(false);
10263
+ return;
10264
+ }
10265
+ if (!actionId) {
10266
+ await updateOriginalItem(
10267
+ {
10268
+ item_id: item.id,
10269
+ quantity: data.quantity,
10270
+ unit_price: convertNumber(data.unit_price)
10271
+ },
10272
+ {
10273
+ onSuccess: () => {
10274
+ setEditing(false);
10275
+ },
10276
+ onError: (e) => {
10277
+ toast.error(e.message);
10278
+ }
10279
+ }
10280
+ );
10281
+ return;
10282
+ }
10283
+ await updateActionItem(
10284
+ {
10285
+ action_id: actionId,
10286
+ quantity: data.quantity,
10287
+ unit_price: convertNumber(data.unit_price)
10288
+ },
10289
+ {
10290
+ onSuccess: () => {
10291
+ setEditing(false);
10292
+ },
10293
+ onError: (e) => {
10294
+ toast.error(e.message);
10295
+ }
10296
+ }
10297
+ );
10298
+ });
10299
+ 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: [
10300
+ /* @__PURE__ */ jsxs("div", { className: "flex w-full items-center gap-x-3", children: [
10301
+ /* @__PURE__ */ jsx(
10302
+ Thumbnail,
10303
+ {
10304
+ thumbnail: item.thumbnail,
10305
+ alt: item.product_title ?? void 0
10437
10306
  }
10438
10307
  ),
10439
- children: [
10440
- /* @__PURE__ */ jsxs("div", { children: [
10441
- /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: promotion.code }),
10442
- /* @__PURE__ */ jsxs("div", { className: "text-ui-fg-subtle flex items-center gap-1.5", children: [
10443
- displayValue && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
10444
- /* @__PURE__ */ jsx(Text, { size: "small", leading: "compact", children: displayValue }),
10445
- /* @__PURE__ */ jsx(Text, { size: "small", leading: "compact", children: "·" })
10446
- ] }),
10447
- /* @__PURE__ */ jsx(Text, { size: "small", leading: "compact", className: "capitalize", children: (_a = promotion.application_method) == null ? void 0 : _a.allocation })
10448
- ] })
10308
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
10309
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-1", children: [
10310
+ /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: item.product_title }),
10311
+ /* @__PURE__ */ jsxs(
10312
+ Text,
10313
+ {
10314
+ size: "small",
10315
+ leading: "compact",
10316
+ className: "text-ui-fg-subtle",
10317
+ children: [
10318
+ "(",
10319
+ item.variant_title,
10320
+ ")"
10321
+ ]
10322
+ }
10323
+ )
10449
10324
  ] }),
10450
10325
  /* @__PURE__ */ jsx(
10451
- IconButton,
10326
+ Text,
10452
10327
  {
10453
10328
  size: "small",
10454
- type: "button",
10455
- variant: "transparent",
10456
- onClick: onRemove,
10457
- isLoading: isPending || isLoading,
10458
- children: /* @__PURE__ */ jsx(XMark, {})
10329
+ leading: "compact",
10330
+ className: "text-ui-fg-subtle",
10331
+ children: item.variant_sku
10459
10332
  }
10460
10333
  )
10461
- ]
10462
- },
10463
- promotion.id
10464
- );
10465
- };
10466
- function getDisplayValue(promotion) {
10467
- var _a, _b, _c, _d;
10468
- const value = (_a = promotion.application_method) == null ? void 0 : _a.value;
10469
- if (!value) {
10470
- return null;
10471
- }
10472
- if (((_b = promotion.application_method) == null ? void 0 : _b.type) === "fixed") {
10473
- const currency = (_c = promotion.application_method) == null ? void 0 : _c.currency_code;
10474
- if (!currency) {
10475
- return null;
10476
- }
10477
- return getLocaleAmount(value, currency);
10478
- } else if (((_d = promotion.application_method) == null ? void 0 : _d.type) === "percentage") {
10479
- return formatPercentage(value);
10480
- }
10481
- return null;
10482
- }
10483
- const formatter = new Intl.NumberFormat([], {
10484
- style: "percent",
10485
- minimumFractionDigits: 2
10486
- });
10487
- const formatPercentage = (value, isPercentageValue = false) => {
10488
- let val = value || 0;
10489
- if (!isPercentageValue) {
10490
- val = val / 100;
10491
- }
10492
- return formatter.format(val);
10493
- };
10494
- function getPromotionIds(items, shippingMethods) {
10495
- const promotionIds = /* @__PURE__ */ new Set();
10496
- for (const item of items) {
10497
- if (item.adjustments) {
10498
- for (const adjustment of item.adjustments) {
10499
- if (adjustment.promotion_id) {
10500
- promotionIds.add(adjustment.promotion_id);
10334
+ ] })
10335
+ ] }),
10336
+ editing ? /* @__PURE__ */ jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsx(
10337
+ Form$2.Field,
10338
+ {
10339
+ control: form.control,
10340
+ name: "quantity",
10341
+ render: ({ field }) => {
10342
+ return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(NumberInput, { ...field }) }) });
10501
10343
  }
10502
10344
  }
10503
- }
10504
- }
10505
- for (const shippingMethod of shippingMethods) {
10506
- if (shippingMethod.adjustments) {
10507
- for (const adjustment of shippingMethod.adjustments) {
10508
- if (adjustment.promotion_id) {
10509
- promotionIds.add(adjustment.promotion_id);
10345
+ ) }) : /* @__PURE__ */ jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: item.quantity }) }),
10346
+ editing ? /* @__PURE__ */ jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsx(
10347
+ Form$2.Field,
10348
+ {
10349
+ control: form.control,
10350
+ name: "unit_price",
10351
+ render: ({ field: { onChange, ...field } }) => {
10352
+ return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
10353
+ CurrencyInput,
10354
+ {
10355
+ ...field,
10356
+ symbol: getNativeSymbol(currencyCode),
10357
+ code: currencyCode,
10358
+ onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value)
10359
+ }
10360
+ ) }) });
10510
10361
  }
10511
10362
  }
10512
- }
10513
- }
10514
- return Array.from(promotionIds);
10515
- }
10516
- const NumberInput = forwardRef(
10517
- ({
10518
- value,
10519
- onChange,
10520
- size = "base",
10521
- min = 0,
10522
- max = 100,
10523
- step = 1,
10524
- className,
10525
- disabled,
10526
- ...props
10527
- }, ref) => {
10528
- const handleChange = (event) => {
10529
- const newValue = event.target.value === "" ? min : Number(event.target.value);
10530
- if (!isNaN(newValue) && (max === void 0 || newValue <= max) && (min === void 0 || newValue >= min)) {
10531
- onChange(newValue);
10363
+ ) }) : /* @__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) }) }),
10364
+ /* @__PURE__ */ jsx(
10365
+ IconButton,
10366
+ {
10367
+ type: "button",
10368
+ size: "small",
10369
+ onClick: editing ? onSubmit : () => {
10370
+ setEditing(true);
10371
+ },
10372
+ disabled: isPending,
10373
+ children: editing ? /* @__PURE__ */ jsx(Check, {}) : /* @__PURE__ */ jsx(PencilSquare, {})
10532
10374
  }
10533
- };
10534
- const handleIncrement = () => {
10535
- const newValue = value + step;
10536
- if (max === void 0 || newValue <= max) {
10537
- onChange(newValue);
10375
+ )
10376
+ ] }) }) });
10377
+ };
10378
+ const variantItemSchema = objectType({
10379
+ quantity: numberType(),
10380
+ unit_price: unionType([numberType(), stringType()])
10381
+ });
10382
+ const CustomItem = ({ item, preview, currencyCode }) => {
10383
+ const [editing, setEditing] = useState(false);
10384
+ const { quantity, unit_price, title } = item;
10385
+ const form = useForm({
10386
+ defaultValues: {
10387
+ title,
10388
+ quantity,
10389
+ unit_price
10390
+ },
10391
+ resolver: zodResolver(customItemSchema)
10392
+ });
10393
+ useEffect(() => {
10394
+ form.reset({
10395
+ title,
10396
+ quantity,
10397
+ unit_price
10398
+ });
10399
+ }, [form, title, quantity, unit_price]);
10400
+ const actionId = useMemo(() => {
10401
+ var _a, _b;
10402
+ return (_b = (_a = item.actions) == null ? void 0 : _a.find((a) => a.action === "ITEM_ADD")) == null ? void 0 : _b.id;
10403
+ }, [item]);
10404
+ const { mutateAsync: updateActionItem, isPending: isUpdatingActionItem } = useDraftOrderUpdateActionItem(preview.id);
10405
+ const { mutateAsync: removeActionItem, isPending: isRemovingActionItem } = useDraftOrderRemoveActionItem(preview.id);
10406
+ const { mutateAsync: updateOriginalItem, isPending: isUpdatingOriginalItem } = useDraftOrderUpdateItem(preview.id);
10407
+ const isPending = isUpdatingActionItem || isUpdatingOriginalItem;
10408
+ const onSubmit = form.handleSubmit(async (data) => {
10409
+ if (convertNumber(data.unit_price) === item.unit_price && data.quantity === item.quantity && data.title === item.title) {
10410
+ setEditing(false);
10411
+ return;
10412
+ }
10413
+ if (!actionId) {
10414
+ await updateOriginalItem(
10415
+ {
10416
+ item_id: item.id,
10417
+ quantity: data.quantity,
10418
+ unit_price: convertNumber(data.unit_price)
10419
+ },
10420
+ {
10421
+ onSuccess: () => {
10422
+ setEditing(false);
10423
+ },
10424
+ onError: (e) => {
10425
+ toast.error(e.message);
10426
+ }
10427
+ }
10428
+ );
10429
+ return;
10430
+ }
10431
+ if (data.quantity === 0) {
10432
+ await removeActionItem(actionId, {
10433
+ onSuccess: () => {
10434
+ setEditing(false);
10435
+ },
10436
+ onError: (e) => {
10437
+ toast.error(e.message);
10438
+ }
10439
+ });
10440
+ return;
10441
+ }
10442
+ await updateActionItem(
10443
+ {
10444
+ action_id: actionId,
10445
+ quantity: data.quantity,
10446
+ unit_price: convertNumber(data.unit_price)
10447
+ },
10448
+ {
10449
+ onSuccess: () => {
10450
+ setEditing(false);
10451
+ },
10452
+ onError: (e) => {
10453
+ toast.error(e.message);
10454
+ }
10538
10455
  }
10539
- };
10540
- const handleDecrement = () => {
10541
- const newValue = value - step;
10542
- if (min === void 0 || newValue >= min) {
10543
- onChange(newValue);
10456
+ );
10457
+ });
10458
+ 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: [
10459
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-3", children: [
10460
+ /* @__PURE__ */ jsx(
10461
+ Thumbnail,
10462
+ {
10463
+ thumbnail: item.thumbnail,
10464
+ alt: item.title ?? void 0
10465
+ }
10466
+ ),
10467
+ editing ? /* @__PURE__ */ jsx(
10468
+ Form$2.Field,
10469
+ {
10470
+ control: form.control,
10471
+ name: "title",
10472
+ render: ({ field }) => {
10473
+ return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }) });
10474
+ }
10475
+ }
10476
+ ) : /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: item.title })
10477
+ ] }),
10478
+ editing ? /* @__PURE__ */ jsx(
10479
+ Form$2.Field,
10480
+ {
10481
+ control: form.control,
10482
+ name: "quantity",
10483
+ render: ({ field }) => {
10484
+ return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(NumberInput, { ...field }) }) });
10485
+ }
10544
10486
  }
10545
- };
10546
- return /* @__PURE__ */ jsxs(
10547
- "div",
10487
+ ) : /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: item.quantity }),
10488
+ editing ? /* @__PURE__ */ jsx(
10489
+ Form$2.Field,
10548
10490
  {
10549
- className: clx(
10550
- "inline-flex rounded-md bg-ui-bg-field shadow-borders-base overflow-hidden divide-x transition-fg",
10551
- "[&:has(input:focus)]:shadow-borders-interactive-with-active",
10552
- {
10553
- "h-7": size === "small",
10554
- "h-8": size === "base"
10555
- },
10556
- className
10557
- ),
10558
- children: [
10559
- /* @__PURE__ */ jsx(
10560
- "input",
10491
+ control: form.control,
10492
+ name: "unit_price",
10493
+ render: ({ field: { onChange, ...field } }) => {
10494
+ return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
10495
+ CurrencyInput,
10561
10496
  {
10562
- ref,
10563
- type: "number",
10564
- value,
10565
- onChange: handleChange,
10566
- min,
10567
- max,
10568
- step,
10569
- className: clx(
10570
- "flex-1 px-2 py-1 bg-transparent txt-compact-small text-ui-fg-base outline-none [appearance:textfield]",
10571
- "[&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none",
10572
- "placeholder:text-ui-fg-muted"
10573
- ),
10574
- ...props
10497
+ ...field,
10498
+ symbol: getNativeSymbol(currencyCode),
10499
+ code: currencyCode,
10500
+ onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value)
10575
10501
  }
10576
- ),
10577
- /* @__PURE__ */ jsxs(
10578
- "button",
10579
- {
10580
- className: clx(
10581
- "flex items-center justify-center outline-none transition-fg",
10582
- "disabled:cursor-not-allowed disabled:text-ui-fg-muted",
10583
- "focus:bg-ui-bg-field-component-hover",
10584
- "hover:bg-ui-bg-field-component-hover",
10585
- {
10586
- "size-7": size === "small",
10587
- "size-8": size === "base"
10588
- }
10589
- ),
10590
- type: "button",
10591
- onClick: handleDecrement,
10592
- disabled: min !== void 0 && value <= min || disabled,
10593
- children: [
10594
- /* @__PURE__ */ jsx(Minus, {}),
10595
- /* @__PURE__ */ jsx("span", { className: "sr-only", children: `Decrease by ${step}` })
10596
- ]
10597
- }
10598
- ),
10599
- /* @__PURE__ */ jsxs(
10600
- "button",
10601
- {
10602
- className: clx(
10603
- "flex items-center justify-center outline-none transition-fg",
10604
- "disabled:cursor-not-allowed disabled:text-ui-fg-muted",
10605
- "focus:bg-ui-bg-field-hover",
10606
- "hover:bg-ui-bg-field-hover",
10607
- {
10608
- "size-7": size === "small",
10609
- "size-8": size === "base"
10610
- }
10611
- ),
10612
- type: "button",
10613
- onClick: handleIncrement,
10614
- disabled: max !== void 0 && value >= max || disabled,
10615
- children: [
10616
- /* @__PURE__ */ jsx(Plus, {}),
10617
- /* @__PURE__ */ jsx("span", { className: "sr-only", children: `Increase by ${step}` })
10618
- ]
10619
- }
10620
- )
10621
- ]
10502
+ ) }) });
10503
+ }
10622
10504
  }
10623
- );
10624
- }
10625
- );
10626
- const PRODUCT_VARIANTS_QUERY_KEY = "product-variants";
10627
- const productVariantsQueryKeys = {
10628
- list: (query2) => [
10629
- PRODUCT_VARIANTS_QUERY_KEY,
10630
- query2 ? query2 : void 0
10631
- ]
10505
+ ) : /* @__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) }) }),
10506
+ /* @__PURE__ */ jsx(
10507
+ IconButton,
10508
+ {
10509
+ type: "button",
10510
+ size: "small",
10511
+ onClick: editing ? onSubmit : () => {
10512
+ setEditing(true);
10513
+ },
10514
+ disabled: isPending,
10515
+ children: editing ? /* @__PURE__ */ jsx(Check, {}) : /* @__PURE__ */ jsx(PencilSquare, {})
10516
+ }
10517
+ )
10518
+ ] }) }) });
10632
10519
  };
10633
- const useProductVariants = (query2, options) => {
10634
- const { data, ...rest } = useQuery({
10635
- queryKey: productVariantsQueryKeys.list(query2),
10636
- queryFn: async () => await sdk.admin.productVariant.list(query2),
10637
- ...options
10638
- });
10639
- return { ...data, ...rest };
10520
+ const StackedModalTrigger$1 = ({
10521
+ type,
10522
+ setModalContent
10523
+ }) => {
10524
+ const { setIsOpen } = useStackedModal();
10525
+ const onClick = useCallback(() => {
10526
+ setModalContent(type);
10527
+ setIsOpen(STACKED_MODAL_ID, true);
10528
+ }, [setModalContent, setIsOpen, type]);
10529
+ return /* @__PURE__ */ jsx(StackedFocusModal.Trigger, { asChild: true, children: /* @__PURE__ */ jsx(DropdownMenu.Item, { onClick, children: type === "add-items" ? "Add items" : "Add custom item" }) });
10640
10530
  };
10641
- function convertNumber(value) {
10642
- return typeof value === "string" ? Number(value.replace(",", ".")) : value;
10643
- }
10644
- const STACKED_MODAL_ID = "items_stacked_modal";
10645
- const Items = () => {
10646
- const { id } = useParams();
10647
- const {
10648
- order: preview,
10649
- isPending: isPreviewPending,
10650
- isError: isPreviewError,
10651
- error: previewError
10652
- } = useOrderPreview(id, void 0, {
10653
- placeholderData: keepPreviousData
10654
- });
10655
- useInitiateOrderEdit({ preview });
10656
- const { draft_order, isPending, isError, error } = useDraftOrder(
10657
- id,
10531
+ const VARIANT_PREFIX = "items";
10532
+ const LIMIT = 50;
10533
+ const ExistingItemsForm = ({ orderId, items }) => {
10534
+ const { setIsOpen } = useStackedModal();
10535
+ const [rowSelection, setRowSelection] = useState(
10536
+ items.reduce((acc, item) => {
10537
+ acc[item.variant_id] = true;
10538
+ return acc;
10539
+ }, {})
10540
+ );
10541
+ useEffect(() => {
10542
+ setRowSelection(
10543
+ items.reduce((acc, item) => {
10544
+ if (item.variant_id) {
10545
+ acc[item.variant_id] = true;
10546
+ }
10547
+ return acc;
10548
+ }, {})
10549
+ );
10550
+ }, [items]);
10551
+ const { q, order, offset } = useQueryParams(
10552
+ ["q", "order", "offset"],
10553
+ VARIANT_PREFIX
10554
+ );
10555
+ const { variants, count, isPending, isError, error } = useProductVariants(
10658
10556
  {
10659
- fields: "currency_code"
10557
+ q,
10558
+ order,
10559
+ offset: offset ? parseInt(offset) : void 0,
10560
+ limit: LIMIT
10660
10561
  },
10661
10562
  {
10662
- enabled: !!id
10563
+ placeholderData: keepPreviousData
10663
10564
  }
10664
10565
  );
10665
- const { onCancel } = useCancelOrderEdit({ preview });
10666
- if (isError) {
10667
- throw error;
10668
- }
10669
- if (isPreviewError) {
10670
- throw previewError;
10671
- }
10672
- const ready = !!preview && !isPreviewPending && !!draft_order && !isPending;
10673
- return /* @__PURE__ */ jsx(RouteFocusModal, { onClose: onCancel, children: ready ? /* @__PURE__ */ jsx(ItemsForm, { preview, currencyCode: draft_order.currency_code }) : /* @__PURE__ */ jsxs("div", { children: [
10674
- /* @__PURE__ */ jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Edit Items" }) }),
10675
- /* @__PURE__ */ jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Loading data for the draft order, please wait..." }) })
10676
- ] }) });
10677
- };
10678
- const ItemsForm = ({ preview, currencyCode }) => {
10679
- var _a;
10680
- const [isSubmitting, setIsSubmitting] = useState(false);
10681
- const [modalContent, setModalContent] = useState(
10682
- null
10683
- );
10684
- const { handleSuccess } = useRouteModal();
10685
- const { searchValue, onSearchValueChange, query: query2 } = useDebouncedSearch();
10686
- const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
10687
- const { mutateAsync: requestOrderEdit } = useDraftOrderRequestEdit(preview.id);
10688
- const itemCount = ((_a = preview.items) == null ? void 0 : _a.reduce((acc, item) => acc + item.quantity, 0)) || 0;
10689
- const matches = useMemo(() => {
10690
- return matchSorter(preview.items, query2, {
10691
- keys: ["product_title", "variant_title", "variant_sku", "title"]
10692
- });
10693
- }, [preview.items, query2]);
10566
+ const columns = useColumns();
10567
+ const { mutateAsync } = useDraftOrderAddItems(orderId);
10694
10568
  const onSubmit = async () => {
10695
- setIsSubmitting(true);
10696
- let requestSucceeded = false;
10697
- await requestOrderEdit(void 0, {
10698
- onError: (e) => {
10699
- toast.error(`Failed to request order edit: ${e.message}`);
10700
- },
10701
- onSuccess: () => {
10702
- requestSucceeded = true;
10703
- }
10704
- });
10705
- if (!requestSucceeded) {
10706
- setIsSubmitting(false);
10707
- return;
10708
- }
10709
- await confirmOrderEdit(void 0, {
10710
- onError: (e) => {
10711
- toast.error(`Failed to confirm order edit: ${e.message}`);
10712
- },
10713
- onSuccess: () => {
10714
- handleSuccess();
10569
+ const ids = Object.keys(rowSelection).filter(
10570
+ (id) => !items.find((i) => i.variant_id === id)
10571
+ );
10572
+ await mutateAsync(
10573
+ {
10574
+ items: ids.map((id) => ({
10575
+ variant_id: id,
10576
+ quantity: 1
10577
+ }))
10715
10578
  },
10716
- onSettled: () => {
10717
- setIsSubmitting(false);
10579
+ {
10580
+ onSuccess: () => {
10581
+ setRowSelection({});
10582
+ setIsOpen(STACKED_MODAL_ID, false);
10583
+ },
10584
+ onError: (e) => {
10585
+ toast.error(e.message);
10586
+ }
10718
10587
  }
10719
- });
10588
+ );
10720
10589
  };
10721
- const onKeyDown = useCallback(
10722
- (e) => {
10723
- if (e.key === "Enter" && (e.ctrlKey || e.metaKey)) {
10724
- if (modalContent || isSubmitting) {
10725
- return;
10590
+ if (isError) {
10591
+ throw error;
10592
+ }
10593
+ return /* @__PURE__ */ jsxs(
10594
+ StackedFocusModal.Content,
10595
+ {
10596
+ onOpenAutoFocus: (e) => {
10597
+ e.preventDefault();
10598
+ const searchInput = document.querySelector(
10599
+ "[data-modal-id='modal-search-input']"
10600
+ );
10601
+ if (searchInput) {
10602
+ searchInput.focus();
10726
10603
  }
10727
- onSubmit();
10728
- }
10729
- },
10730
- [modalContent, isSubmitting, onSubmit]
10731
- );
10732
- useEffect(() => {
10733
- document.addEventListener("keydown", onKeyDown);
10734
- return () => {
10735
- document.removeEventListener("keydown", onKeyDown);
10736
- };
10737
- }, [onKeyDown]);
10738
- return /* @__PURE__ */ jsxs("div", { className: "flex h-full flex-col overflow-hidden", children: [
10739
- /* @__PURE__ */ jsx(RouteFocusModal.Header, {}),
10740
- /* @__PURE__ */ jsx(RouteFocusModal.Body, { className: "flex flex-1 flex-col overflow-hidden", children: /* @__PURE__ */ jsxs(
10741
- StackedFocusModal,
10742
- {
10743
- id: STACKED_MODAL_ID,
10744
- onOpenChangeCallback: (open) => {
10745
- if (!open) {
10746
- setModalContent(null);
10747
- }
10748
- },
10749
- children: [
10750
- /* @__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: [
10751
- /* @__PURE__ */ jsxs("div", { children: [
10752
- /* @__PURE__ */ jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Items" }) }),
10753
- /* @__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" }) })
10754
- ] }),
10755
- /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
10756
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-y-6", children: [
10757
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 items-center gap-3", children: [
10758
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
10759
- /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: "Items" }),
10760
- /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Choose items from the product catalog." })
10761
- ] }),
10762
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
10763
- /* @__PURE__ */ jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsx(
10764
- Input,
10765
- {
10766
- type: "search",
10767
- placeholder: "Search items",
10768
- value: searchValue,
10769
- onChange: (e) => onSearchValueChange(e.target.value)
10770
- }
10771
- ) }),
10772
- /* @__PURE__ */ jsxs(DropdownMenu, { children: [
10773
- /* @__PURE__ */ jsx(DropdownMenu.Trigger, { asChild: true, children: /* @__PURE__ */ jsx(IconButton, { type: "button", children: /* @__PURE__ */ jsx(Plus, {}) }) }),
10774
- /* @__PURE__ */ jsxs(DropdownMenu.Content, { children: [
10775
- /* @__PURE__ */ jsx(
10776
- StackedModalTrigger$1,
10777
- {
10778
- type: "add-items",
10779
- setModalContent
10780
- }
10781
- ),
10782
- /* @__PURE__ */ jsx(
10783
- StackedModalTrigger$1,
10784
- {
10785
- type: "add-custom-item",
10786
- setModalContent
10787
- }
10788
- )
10789
- ] })
10790
- ] })
10791
- ] })
10792
- ] }),
10793
- /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-subtle shadow-elevation-card-rest rounded-xl", children: [
10794
- /* @__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: [
10795
- /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: "Item" }) }),
10796
- /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: "Quantity" }) }),
10797
- /* @__PURE__ */ jsx("div", { className: "text-right", children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: "Price" }) }),
10798
- /* @__PURE__ */ jsx("div", {})
10799
- ] }) }),
10800
- /* @__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: [
10801
- /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: "There are no items in this order" }),
10802
- /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Add items to the order to get started." })
10803
- ] }) : matches.length > 0 ? matches == null ? void 0 : matches.map((item) => /* @__PURE__ */ jsx(
10804
- Item,
10805
- {
10806
- item,
10807
- preview,
10808
- currencyCode
10809
- },
10810
- item.id
10811
- )) : /* @__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: [
10812
- /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: "No items found" }),
10813
- /* @__PURE__ */ jsxs(Text, { size: "small", className: "text-ui-fg-subtle", children: [
10814
- 'No items found for "',
10815
- query2,
10816
- '".'
10817
- ] })
10818
- ] }) })
10819
- ] })
10820
- ] }),
10821
- /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
10822
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-[1fr_0.5fr_0.5fr] gap-3", children: [
10823
- /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: "Subtotal" }) }),
10824
- /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsxs(
10825
- Text,
10826
- {
10827
- size: "small",
10828
- leading: "compact",
10829
- className: "text-ui-fg-subtle",
10830
- children: [
10831
- itemCount,
10832
- " ",
10833
- itemCount === 1 ? "item" : "items"
10834
- ]
10835
- }
10836
- ) }),
10837
- /* @__PURE__ */ jsx("div", { className: "text-right", children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: getStylizedAmount(preview.item_subtotal, currencyCode) }) })
10838
- ] })
10839
- ] }) }),
10840
- modalContent && (modalContent === "add-items" ? /* @__PURE__ */ jsx(ExistingItemsForm, { orderId: preview.id, items: preview.items }) : modalContent === "add-custom-item" ? /* @__PURE__ */ jsx(
10841
- CustomItemForm,
10604
+ },
10605
+ children: [
10606
+ /* @__PURE__ */ jsxs(StackedFocusModal.Header, { children: [
10607
+ /* @__PURE__ */ jsx(StackedFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Product Variants" }) }),
10608
+ /* @__PURE__ */ jsx(StackedFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Choose product variants to add to the order." }) })
10609
+ ] }),
10610
+ /* @__PURE__ */ jsx(StackedFocusModal.Body, { className: "flex-1 overflow-hidden", children: /* @__PURE__ */ jsx(
10611
+ DataTable,
10612
+ {
10613
+ data: variants,
10614
+ columns,
10615
+ isLoading: isPending,
10616
+ getRowId: (row) => row.id,
10617
+ rowCount: count,
10618
+ prefix: VARIANT_PREFIX,
10619
+ layout: "fill",
10620
+ rowSelection: {
10621
+ state: rowSelection,
10622
+ onRowSelectionChange: setRowSelection,
10623
+ enableRowSelection: (row) => {
10624
+ return !items.find((i) => i.variant_id === row.original.id);
10625
+ }
10626
+ },
10627
+ autoFocusSearch: true
10628
+ }
10629
+ ) }),
10630
+ /* @__PURE__ */ jsx(StackedFocusModal.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
10631
+ /* @__PURE__ */ jsx(StackedFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
10632
+ /* @__PURE__ */ jsx(Button, { size: "small", type: "button", onClick: onSubmit, children: "Update items" })
10633
+ ] }) })
10634
+ ]
10635
+ }
10636
+ );
10637
+ };
10638
+ const columnHelper = createDataTableColumnHelper();
10639
+ const useColumns = () => {
10640
+ return useMemo(() => {
10641
+ return [
10642
+ columnHelper.select(),
10643
+ columnHelper.accessor("product.title", {
10644
+ header: "Product",
10645
+ cell: ({ row }) => {
10646
+ var _a, _b, _c;
10647
+ return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-2", children: [
10648
+ /* @__PURE__ */ jsx(
10649
+ Thumbnail,
10650
+ {
10651
+ thumbnail: (_a = row.original.product) == null ? void 0 : _a.thumbnail,
10652
+ alt: (_b = row.original.product) == null ? void 0 : _b.title
10653
+ }
10654
+ ),
10655
+ /* @__PURE__ */ jsx("span", { children: (_c = row.original.product) == null ? void 0 : _c.title })
10656
+ ] });
10657
+ },
10658
+ enableSorting: true
10659
+ }),
10660
+ columnHelper.accessor("title", {
10661
+ header: "Variant",
10662
+ enableSorting: true
10663
+ }),
10664
+ columnHelper.accessor("sku", {
10665
+ header: "SKU",
10666
+ cell: ({ getValue }) => {
10667
+ return getValue() ?? "-";
10668
+ },
10669
+ enableSorting: true
10670
+ }),
10671
+ columnHelper.accessor("updated_at", {
10672
+ header: "Updated",
10673
+ cell: ({ getValue }) => {
10674
+ return /* @__PURE__ */ jsx(
10675
+ Tooltip,
10842
10676
  {
10843
- orderId: preview.id,
10844
- currencyCode
10677
+ content: getFullDate({ date: getValue(), includeTime: true }),
10678
+ children: /* @__PURE__ */ jsx("span", { children: getFullDate({ date: getValue() }) })
10845
10679
  }
10846
- ) : null)
10847
- ]
10848
- }
10849
- ) }),
10850
- /* @__PURE__ */ jsx(RouteFocusModal.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
10851
- /* @__PURE__ */ jsx(RouteFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
10852
- /* @__PURE__ */ jsx(
10853
- Button,
10854
- {
10855
- size: "small",
10856
- type: "button",
10857
- onClick: onSubmit,
10858
- isLoading: isSubmitting,
10859
- children: "Save"
10860
- }
10861
- )
10862
- ] }) })
10863
- ] });
10864
- };
10865
- const Item = ({ item, preview, currencyCode }) => {
10866
- if (item.variant_id) {
10867
- return /* @__PURE__ */ jsx(VariantItem, { item, preview, currencyCode });
10868
- }
10869
- return /* @__PURE__ */ jsx(CustomItem, { item, preview, currencyCode });
10680
+ );
10681
+ },
10682
+ enableSorting: true,
10683
+ sortAscLabel: "Oldest first",
10684
+ sortDescLabel: "Newest first"
10685
+ }),
10686
+ columnHelper.accessor("created_at", {
10687
+ header: "Created",
10688
+ cell: ({ getValue }) => {
10689
+ return /* @__PURE__ */ jsx(
10690
+ Tooltip,
10691
+ {
10692
+ content: getFullDate({ date: getValue(), includeTime: true }),
10693
+ children: /* @__PURE__ */ jsx("span", { children: getFullDate({ date: getValue() }) })
10694
+ }
10695
+ );
10696
+ },
10697
+ enableSorting: true,
10698
+ sortAscLabel: "Oldest first",
10699
+ sortDescLabel: "Newest first"
10700
+ })
10701
+ ];
10702
+ }, []);
10870
10703
  };
10871
- const VariantItem = ({ item, preview, currencyCode }) => {
10872
- const [editing, setEditing] = useState(false);
10704
+ const CustomItemForm = ({ orderId, currencyCode }) => {
10705
+ const { setIsOpen } = useStackedModal();
10706
+ const { mutateAsync: addItems } = useDraftOrderAddItems(orderId);
10873
10707
  const form = useForm({
10874
10708
  defaultValues: {
10875
- quantity: item.quantity,
10876
- unit_price: item.unit_price
10709
+ title: "",
10710
+ quantity: 1,
10711
+ unit_price: ""
10877
10712
  },
10878
- resolver: zodResolver(variantItemSchema)
10713
+ resolver: zodResolver(customItemSchema)
10879
10714
  });
10880
- const actionId = useMemo(() => {
10881
- var _a, _b;
10882
- return (_b = (_a = item.actions) == null ? void 0 : _a.find((a) => a.action === "ITEM_ADD")) == null ? void 0 : _b.id;
10883
- }, [item]);
10884
- const { mutateAsync: updateActionItem, isPending: isUpdatingActionItem } = useDraftOrderUpdateActionItem(preview.id);
10885
- const { mutateAsync: updateOriginalItem, isPending: isUpdatingOriginalItem } = useDraftOrderUpdateItem(preview.id);
10886
- const isPending = isUpdatingActionItem || isUpdatingOriginalItem;
10887
10715
  const onSubmit = form.handleSubmit(async (data) => {
10888
- if (convertNumber(data.unit_price) === item.unit_price && data.quantity === item.quantity) {
10889
- setEditing(false);
10890
- return;
10891
- }
10892
- if (!actionId) {
10893
- await updateOriginalItem(
10894
- {
10895
- item_id: item.id,
10896
- quantity: data.quantity,
10897
- unit_price: convertNumber(data.unit_price)
10898
- },
10899
- {
10900
- onSuccess: () => {
10901
- setEditing(false);
10902
- },
10903
- onError: (e) => {
10904
- toast.error(e.message);
10905
- }
10906
- }
10907
- );
10908
- return;
10909
- }
10910
- await updateActionItem(
10911
- {
10912
- action_id: actionId,
10913
- quantity: data.quantity,
10914
- unit_price: convertNumber(data.unit_price)
10915
- },
10716
+ await addItems(
10916
10717
  {
10917
- onSuccess: () => {
10918
- setEditing(false);
10718
+ items: [
10719
+ {
10720
+ title: data.title,
10721
+ quantity: data.quantity,
10722
+ unit_price: convertNumber(data.unit_price)
10723
+ }
10724
+ ]
10725
+ },
10726
+ {
10727
+ onSuccess: () => {
10728
+ setIsOpen(STACKED_MODAL_ID, false);
10919
10729
  },
10920
10730
  onError: (e) => {
10921
10731
  toast.error(e.message);
@@ -10923,524 +10733,714 @@ const VariantItem = ({ item, preview, currencyCode }) => {
10923
10733
  }
10924
10734
  );
10925
10735
  });
10926
- 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: [
10927
- /* @__PURE__ */ jsxs("div", { className: "flex w-full items-center gap-x-3", children: [
10736
+ return /* @__PURE__ */ jsx(Form$2, { ...form, children: /* @__PURE__ */ jsx(KeyboundForm, { onSubmit, children: /* @__PURE__ */ jsxs(StackedFocusModal.Content, { children: [
10737
+ /* @__PURE__ */ jsx(StackedFocusModal.Header, {}),
10738
+ /* @__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: [
10739
+ /* @__PURE__ */ jsxs("div", { children: [
10740
+ /* @__PURE__ */ jsx(StackedFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Add custom item" }) }),
10741
+ /* @__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." }) })
10742
+ ] }),
10743
+ /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
10928
10744
  /* @__PURE__ */ jsx(
10929
- Thumbnail,
10745
+ Form$2.Field,
10930
10746
  {
10931
- thumbnail: item.thumbnail,
10932
- alt: item.product_title ?? void 0
10747
+ control: form.control,
10748
+ name: "title",
10749
+ render: ({ field }) => /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
10750
+ /* @__PURE__ */ jsxs("div", { children: [
10751
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Title" }),
10752
+ /* @__PURE__ */ jsx(Form$2.Hint, { children: "Enter the title of the item" })
10753
+ ] }),
10754
+ /* @__PURE__ */ jsxs("div", { children: [
10755
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
10756
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
10757
+ ] })
10758
+ ] }) })
10933
10759
  }
10934
10760
  ),
10935
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
10936
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-1", children: [
10937
- /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: item.product_title }),
10938
- /* @__PURE__ */ jsxs(
10939
- Text,
10940
- {
10941
- size: "small",
10942
- leading: "compact",
10943
- className: "text-ui-fg-subtle",
10944
- children: [
10945
- "(",
10946
- item.variant_title,
10947
- ")"
10948
- ]
10949
- }
10950
- )
10951
- ] }),
10952
- /* @__PURE__ */ jsx(
10953
- Text,
10954
- {
10955
- size: "small",
10956
- leading: "compact",
10957
- className: "text-ui-fg-subtle",
10958
- children: item.variant_sku
10959
- }
10960
- )
10961
- ] })
10962
- ] }),
10963
- editing ? /* @__PURE__ */ jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsx(
10964
- Form$2.Field,
10965
- {
10966
- control: form.control,
10967
- name: "quantity",
10968
- render: ({ field }) => {
10969
- return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(NumberInput, { ...field }) }) });
10761
+ /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
10762
+ /* @__PURE__ */ jsx(
10763
+ Form$2.Field,
10764
+ {
10765
+ control: form.control,
10766
+ name: "unit_price",
10767
+ render: ({ field: { onChange, ...field } }) => /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
10768
+ /* @__PURE__ */ jsxs("div", { children: [
10769
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Unit price" }),
10770
+ /* @__PURE__ */ jsx(Form$2.Hint, { children: "Enter the unit price of the item" })
10771
+ ] }),
10772
+ /* @__PURE__ */ jsxs("div", { children: [
10773
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
10774
+ CurrencyInput,
10775
+ {
10776
+ symbol: getNativeSymbol(currencyCode),
10777
+ code: currencyCode,
10778
+ onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value),
10779
+ ...field
10780
+ }
10781
+ ) }),
10782
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
10783
+ ] })
10784
+ ] }) })
10970
10785
  }
10971
- }
10972
- ) }) : /* @__PURE__ */ jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: item.quantity }) }),
10973
- editing ? /* @__PURE__ */ jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsx(
10974
- Form$2.Field,
10975
- {
10976
- control: form.control,
10977
- name: "unit_price",
10978
- render: ({ field: { onChange, ...field } }) => {
10979
- return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
10980
- CurrencyInput,
10981
- {
10982
- ...field,
10983
- symbol: getNativeSymbol(currencyCode),
10984
- code: currencyCode,
10985
- onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value)
10986
- }
10987
- ) }) });
10786
+ ),
10787
+ /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
10788
+ /* @__PURE__ */ jsx(
10789
+ Form$2.Field,
10790
+ {
10791
+ control: form.control,
10792
+ name: "quantity",
10793
+ render: ({ field }) => /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
10794
+ /* @__PURE__ */ jsxs("div", { children: [
10795
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Quantity" }),
10796
+ /* @__PURE__ */ jsx(Form$2.Hint, { children: "Enter the quantity of the item" })
10797
+ ] }),
10798
+ /* @__PURE__ */ jsxs("div", { className: "w-full flex-1", children: [
10799
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsx(NumberInput, { ...field, className: "w-full" }) }) }),
10800
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
10801
+ ] })
10802
+ ] }) })
10988
10803
  }
10989
- }
10990
- ) }) : /* @__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) }) }),
10991
- /* @__PURE__ */ jsx(
10992
- IconButton,
10993
- {
10994
- type: "button",
10995
- size: "small",
10996
- onClick: editing ? onSubmit : () => {
10997
- setEditing(true);
10998
- },
10999
- disabled: isPending,
11000
- children: editing ? /* @__PURE__ */ jsx(Check, {}) : /* @__PURE__ */ jsx(PencilSquare, {})
11001
- }
11002
- )
10804
+ )
10805
+ ] }) }) }),
10806
+ /* @__PURE__ */ jsx(StackedFocusModal.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
10807
+ /* @__PURE__ */ jsx(StackedFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
10808
+ /* @__PURE__ */ jsx(Button, { size: "small", type: "button", onClick: onSubmit, children: "Add item" })
10809
+ ] }) })
11003
10810
  ] }) }) });
11004
10811
  };
11005
- const variantItemSchema = objectType({
10812
+ const customItemSchema = objectType({
10813
+ title: stringType().min(1),
11006
10814
  quantity: numberType(),
11007
10815
  unit_price: unionType([numberType(), stringType()])
11008
10816
  });
11009
- const CustomItem = ({ item, preview, currencyCode }) => {
11010
- const [editing, setEditing] = useState(false);
11011
- const { quantity, unit_price, title } = item;
10817
+ const InlineTip = forwardRef(
10818
+ ({ variant = "tip", label, className, children, ...props }, ref) => {
10819
+ const labelValue = label || (variant === "warning" ? "Warning" : "Tip");
10820
+ return /* @__PURE__ */ jsxs(
10821
+ "div",
10822
+ {
10823
+ ref,
10824
+ className: clx(
10825
+ "bg-ui-bg-component txt-small text-ui-fg-subtle grid grid-cols-[4px_1fr] items-start gap-3 rounded-lg border p-3",
10826
+ className
10827
+ ),
10828
+ ...props,
10829
+ children: [
10830
+ /* @__PURE__ */ jsx(
10831
+ "div",
10832
+ {
10833
+ role: "presentation",
10834
+ className: clx("w-4px bg-ui-tag-neutral-icon h-full rounded-full", {
10835
+ "bg-ui-tag-orange-icon": variant === "warning"
10836
+ })
10837
+ }
10838
+ ),
10839
+ /* @__PURE__ */ jsxs("div", { className: "text-pretty", children: [
10840
+ /* @__PURE__ */ jsxs("strong", { className: "txt-small-plus text-ui-fg-base", children: [
10841
+ labelValue,
10842
+ ":"
10843
+ ] }),
10844
+ " ",
10845
+ children
10846
+ ] })
10847
+ ]
10848
+ }
10849
+ );
10850
+ }
10851
+ );
10852
+ InlineTip.displayName = "InlineTip";
10853
+ const MetadataFieldSchema = objectType({
10854
+ key: stringType(),
10855
+ disabled: booleanType().optional(),
10856
+ value: anyType()
10857
+ });
10858
+ const MetadataSchema = objectType({
10859
+ metadata: arrayType(MetadataFieldSchema)
10860
+ });
10861
+ const Metadata = () => {
10862
+ const { id } = useParams();
10863
+ const { order, isPending, isError, error } = useOrder(id, {
10864
+ fields: "metadata"
10865
+ });
10866
+ if (isError) {
10867
+ throw error;
10868
+ }
10869
+ const isReady = !isPending && !!order;
10870
+ return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
10871
+ /* @__PURE__ */ jsxs(RouteDrawer.Header, { children: [
10872
+ /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Metadata" }) }),
10873
+ /* @__PURE__ */ jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Add metadata to the draft order." }) })
10874
+ ] }),
10875
+ !isReady ? /* @__PURE__ */ jsx(PlaceholderInner, {}) : /* @__PURE__ */ jsx(MetadataForm, { orderId: id, metadata: order == null ? void 0 : order.metadata })
10876
+ ] });
10877
+ };
10878
+ const METADATA_KEY_LABEL_ID = "metadata-form-key-label";
10879
+ const METADATA_VALUE_LABEL_ID = "metadata-form-value-label";
10880
+ const MetadataForm = ({ orderId, metadata }) => {
10881
+ const { handleSuccess } = useRouteModal();
10882
+ const hasUneditableRows = getHasUneditableRows(metadata);
10883
+ const { mutateAsync, isPending } = useUpdateDraftOrder(orderId);
11012
10884
  const form = useForm({
11013
10885
  defaultValues: {
11014
- title,
11015
- quantity,
11016
- unit_price
10886
+ metadata: getDefaultValues(metadata)
11017
10887
  },
11018
- resolver: zodResolver(customItemSchema)
10888
+ resolver: zodResolver(MetadataSchema)
11019
10889
  });
11020
- useEffect(() => {
11021
- form.reset({
11022
- title,
11023
- quantity,
11024
- unit_price
11025
- });
11026
- }, [form, title, quantity, unit_price]);
11027
- const actionId = useMemo(() => {
11028
- var _a, _b;
11029
- return (_b = (_a = item.actions) == null ? void 0 : _a.find((a) => a.action === "ITEM_ADD")) == null ? void 0 : _b.id;
11030
- }, [item]);
11031
- const { mutateAsync: updateActionItem, isPending: isUpdatingActionItem } = useDraftOrderUpdateActionItem(preview.id);
11032
- const { mutateAsync: removeActionItem, isPending: isRemovingActionItem } = useDraftOrderRemoveActionItem(preview.id);
11033
- const { mutateAsync: updateOriginalItem, isPending: isUpdatingOriginalItem } = useDraftOrderUpdateItem(preview.id);
11034
- const isPending = isUpdatingActionItem || isUpdatingOriginalItem;
11035
- const onSubmit = form.handleSubmit(async (data) => {
11036
- if (convertNumber(data.unit_price) === item.unit_price && data.quantity === item.quantity && data.title === item.title) {
11037
- setEditing(false);
11038
- return;
11039
- }
11040
- if (!actionId) {
11041
- await updateOriginalItem(
11042
- {
11043
- item_id: item.id,
11044
- quantity: data.quantity,
11045
- unit_price: convertNumber(data.unit_price)
11046
- },
11047
- {
11048
- onSuccess: () => {
11049
- setEditing(false);
11050
- },
11051
- onError: (e) => {
11052
- toast.error(e.message);
11053
- }
11054
- }
11055
- );
11056
- return;
11057
- }
11058
- if (data.quantity === 0) {
11059
- await removeActionItem(actionId, {
11060
- onSuccess: () => {
11061
- setEditing(false);
11062
- },
11063
- onError: (e) => {
11064
- toast.error(e.message);
11065
- }
11066
- });
11067
- return;
11068
- }
11069
- await updateActionItem(
10890
+ const handleSubmit = form.handleSubmit(async (data) => {
10891
+ const parsedData = parseValues(data);
10892
+ await mutateAsync(
11070
10893
  {
11071
- action_id: actionId,
11072
- quantity: data.quantity,
11073
- unit_price: convertNumber(data.unit_price)
10894
+ metadata: parsedData
11074
10895
  },
11075
10896
  {
11076
10897
  onSuccess: () => {
11077
- setEditing(false);
10898
+ toast.success("Metadata updated");
10899
+ handleSuccess();
11078
10900
  },
11079
- onError: (e) => {
11080
- toast.error(e.message);
10901
+ onError: (error) => {
10902
+ toast.error(error.message);
11081
10903
  }
11082
10904
  }
11083
10905
  );
11084
10906
  });
11085
- 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: [
11086
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-3", children: [
11087
- /* @__PURE__ */ jsx(
11088
- Thumbnail,
11089
- {
11090
- thumbnail: item.thumbnail,
11091
- alt: item.title ?? void 0
11092
- }
11093
- ),
11094
- editing ? /* @__PURE__ */ jsx(
11095
- Form$2.Field,
11096
- {
11097
- control: form.control,
11098
- name: "title",
11099
- render: ({ field }) => {
11100
- return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }) });
11101
- }
11102
- }
11103
- ) : /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: item.title })
11104
- ] }),
11105
- editing ? /* @__PURE__ */ jsx(
11106
- Form$2.Field,
11107
- {
11108
- control: form.control,
11109
- name: "quantity",
11110
- render: ({ field }) => {
11111
- return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(NumberInput, { ...field }) }) });
11112
- }
11113
- }
11114
- ) : /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: item.quantity }),
11115
- editing ? /* @__PURE__ */ jsx(
11116
- Form$2.Field,
11117
- {
11118
- control: form.control,
11119
- name: "unit_price",
11120
- render: ({ field: { onChange, ...field } }) => {
11121
- return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
11122
- CurrencyInput,
11123
- {
11124
- ...field,
11125
- symbol: getNativeSymbol(currencyCode),
11126
- code: currencyCode,
11127
- onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value)
11128
- }
11129
- ) }) });
11130
- }
11131
- }
11132
- ) : /* @__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) }) }),
11133
- /* @__PURE__ */ jsx(
11134
- IconButton,
11135
- {
11136
- type: "button",
11137
- size: "small",
11138
- onClick: editing ? onSubmit : () => {
11139
- setEditing(true);
11140
- },
11141
- disabled: isPending,
11142
- children: editing ? /* @__PURE__ */ jsx(Check, {}) : /* @__PURE__ */ jsx(PencilSquare, {})
11143
- }
11144
- )
11145
- ] }) }) });
11146
- };
11147
- const StackedModalTrigger$1 = ({
11148
- type,
11149
- setModalContent
11150
- }) => {
11151
- const { setIsOpen } = useStackedModal();
11152
- const onClick = useCallback(() => {
11153
- setModalContent(type);
11154
- setIsOpen(STACKED_MODAL_ID, true);
11155
- }, [setModalContent, setIsOpen, type]);
11156
- return /* @__PURE__ */ jsx(StackedFocusModal.Trigger, { asChild: true, children: /* @__PURE__ */ jsx(DropdownMenu.Item, { onClick, children: type === "add-items" ? "Add items" : "Add custom item" }) });
11157
- };
11158
- const VARIANT_PREFIX = "items";
11159
- const LIMIT = 50;
11160
- const ExistingItemsForm = ({ orderId, items }) => {
11161
- const { setIsOpen } = useStackedModal();
11162
- const [rowSelection, setRowSelection] = useState(
11163
- items.reduce((acc, item) => {
11164
- acc[item.variant_id] = true;
11165
- return acc;
11166
- }, {})
11167
- );
11168
- useEffect(() => {
11169
- setRowSelection(
11170
- items.reduce((acc, item) => {
11171
- if (item.variant_id) {
11172
- acc[item.variant_id] = true;
11173
- }
11174
- return acc;
11175
- }, {})
11176
- );
11177
- }, [items]);
11178
- const { q, order, offset } = useQueryParams(
11179
- ["q", "order", "offset"],
11180
- VARIANT_PREFIX
11181
- );
11182
- const { variants, count, isPending, isError, error } = useProductVariants(
10907
+ const { fields, insert, remove } = useFieldArray({
10908
+ control: form.control,
10909
+ name: "metadata"
10910
+ });
10911
+ function deleteRow(index) {
10912
+ remove(index);
10913
+ if (fields.length === 1) {
10914
+ insert(0, {
10915
+ key: "",
10916
+ value: "",
10917
+ disabled: false
10918
+ });
10919
+ }
10920
+ }
10921
+ function insertRow(index, position) {
10922
+ insert(index + (position === "above" ? 0 : 1), {
10923
+ key: "",
10924
+ value: "",
10925
+ disabled: false
10926
+ });
10927
+ }
10928
+ return /* @__PURE__ */ jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxs(
10929
+ KeyboundForm,
11183
10930
  {
11184
- q,
11185
- order,
11186
- offset: offset ? parseInt(offset) : void 0,
11187
- limit: LIMIT
11188
- },
10931
+ onSubmit: handleSubmit,
10932
+ className: "flex flex-1 flex-col overflow-hidden",
10933
+ children: [
10934
+ /* @__PURE__ */ jsxs(RouteDrawer.Body, { className: "flex flex-1 flex-col gap-y-8 overflow-y-auto", children: [
10935
+ /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest grid grid-cols-1 divide-y rounded-lg", children: [
10936
+ /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-subtle grid grid-cols-2 divide-x rounded-t-lg", children: [
10937
+ /* @__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" }) }),
10938
+ /* @__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" }) })
10939
+ ] }),
10940
+ fields.map((field, index) => {
10941
+ const isDisabled = field.disabled || false;
10942
+ let placeholder = "-";
10943
+ if (typeof field.value === "object") {
10944
+ placeholder = "{ ... }";
10945
+ }
10946
+ if (Array.isArray(field.value)) {
10947
+ placeholder = "[ ... ]";
10948
+ }
10949
+ return /* @__PURE__ */ jsx(
10950
+ ConditionalTooltip,
10951
+ {
10952
+ showTooltip: isDisabled,
10953
+ content: "This row is disabled because it contains non-primitive data.",
10954
+ children: /* @__PURE__ */ jsxs("div", { className: "group/table relative", children: [
10955
+ /* @__PURE__ */ jsxs(
10956
+ "div",
10957
+ {
10958
+ className: clx("grid grid-cols-2 divide-x", {
10959
+ "overflow-hidden rounded-b-lg": index === fields.length - 1
10960
+ }),
10961
+ children: [
10962
+ /* @__PURE__ */ jsx(
10963
+ Form$2.Field,
10964
+ {
10965
+ control: form.control,
10966
+ name: `metadata.${index}.key`,
10967
+ render: ({ field: field2 }) => {
10968
+ return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
10969
+ GridInput,
10970
+ {
10971
+ "aria-labelledby": METADATA_KEY_LABEL_ID,
10972
+ ...field2,
10973
+ disabled: isDisabled,
10974
+ placeholder: "Key"
10975
+ }
10976
+ ) }) });
10977
+ }
10978
+ }
10979
+ ),
10980
+ /* @__PURE__ */ jsx(
10981
+ Form$2.Field,
10982
+ {
10983
+ control: form.control,
10984
+ name: `metadata.${index}.value`,
10985
+ render: ({ field: { value, ...field2 } }) => {
10986
+ return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
10987
+ GridInput,
10988
+ {
10989
+ "aria-labelledby": METADATA_VALUE_LABEL_ID,
10990
+ ...field2,
10991
+ value: isDisabled ? placeholder : value,
10992
+ disabled: isDisabled,
10993
+ placeholder: "Value"
10994
+ }
10995
+ ) }) });
10996
+ }
10997
+ }
10998
+ )
10999
+ ]
11000
+ }
11001
+ ),
11002
+ /* @__PURE__ */ jsxs(DropdownMenu, { children: [
11003
+ /* @__PURE__ */ jsx(
11004
+ DropdownMenu.Trigger,
11005
+ {
11006
+ className: clx(
11007
+ "invisible absolute inset-y-0 -right-2.5 my-auto group-hover/table:visible data-[state='open']:visible",
11008
+ {
11009
+ hidden: isDisabled
11010
+ }
11011
+ ),
11012
+ disabled: isDisabled,
11013
+ asChild: true,
11014
+ children: /* @__PURE__ */ jsx(IconButton, { size: "2xsmall", children: /* @__PURE__ */ jsx(EllipsisVertical, {}) })
11015
+ }
11016
+ ),
11017
+ /* @__PURE__ */ jsxs(DropdownMenu.Content, { children: [
11018
+ /* @__PURE__ */ jsxs(
11019
+ DropdownMenu.Item,
11020
+ {
11021
+ className: "gap-x-2",
11022
+ onClick: () => insertRow(index, "above"),
11023
+ children: [
11024
+ /* @__PURE__ */ jsx(ArrowUpMini, { className: "text-ui-fg-subtle" }),
11025
+ "Insert row above"
11026
+ ]
11027
+ }
11028
+ ),
11029
+ /* @__PURE__ */ jsxs(
11030
+ DropdownMenu.Item,
11031
+ {
11032
+ className: "gap-x-2",
11033
+ onClick: () => insertRow(index, "below"),
11034
+ children: [
11035
+ /* @__PURE__ */ jsx(ArrowDownMini, { className: "text-ui-fg-subtle" }),
11036
+ "Insert row below"
11037
+ ]
11038
+ }
11039
+ ),
11040
+ /* @__PURE__ */ jsx(DropdownMenu.Separator, {}),
11041
+ /* @__PURE__ */ jsxs(
11042
+ DropdownMenu.Item,
11043
+ {
11044
+ className: "gap-x-2",
11045
+ onClick: () => deleteRow(index),
11046
+ children: [
11047
+ /* @__PURE__ */ jsx(Trash, { className: "text-ui-fg-subtle" }),
11048
+ "Delete row"
11049
+ ]
11050
+ }
11051
+ )
11052
+ ] })
11053
+ ] })
11054
+ ] })
11055
+ },
11056
+ field.id
11057
+ );
11058
+ })
11059
+ ] }),
11060
+ 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." })
11061
+ ] }),
11062
+ /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
11063
+ /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
11064
+ /* @__PURE__ */ jsx(Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
11065
+ ] }) })
11066
+ ]
11067
+ }
11068
+ ) });
11069
+ };
11070
+ const GridInput = forwardRef(({ className, ...props }, ref) => {
11071
+ return /* @__PURE__ */ jsx(
11072
+ "input",
11189
11073
  {
11190
- placeholderData: keepPreviousData
11074
+ ref,
11075
+ ...props,
11076
+ autoComplete: "off",
11077
+ className: clx(
11078
+ "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",
11079
+ className
11080
+ )
11191
11081
  }
11192
11082
  );
11193
- const columns = useColumns();
11194
- const { mutateAsync } = useDraftOrderAddItems(orderId);
11195
- const onSubmit = async () => {
11196
- const ids = Object.keys(rowSelection).filter(
11197
- (id) => !items.find((i) => i.variant_id === id)
11198
- );
11199
- await mutateAsync(
11200
- {
11201
- items: ids.map((id) => ({
11202
- variant_id: id,
11203
- quantity: 1
11204
- }))
11205
- },
11083
+ });
11084
+ GridInput.displayName = "MetadataForm.GridInput";
11085
+ const PlaceholderInner = () => {
11086
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-1 flex-col overflow-hidden", children: [
11087
+ /* @__PURE__ */ jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsx(Skeleton, { className: "h-[148ox] w-full rounded-lg" }) }),
11088
+ /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
11089
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-7 w-12 rounded-md" }),
11090
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-7 w-12 rounded-md" })
11091
+ ] }) })
11092
+ ] });
11093
+ };
11094
+ const EDITABLE_TYPES = ["string", "number", "boolean"];
11095
+ function getDefaultValues(metadata) {
11096
+ if (!metadata || !Object.keys(metadata).length) {
11097
+ return [
11206
11098
  {
11207
- onSuccess: () => {
11208
- setRowSelection({});
11209
- setIsOpen(STACKED_MODAL_ID, false);
11210
- },
11211
- onError: (e) => {
11212
- toast.error(e.message);
11213
- }
11099
+ key: "",
11100
+ value: "",
11101
+ disabled: false
11214
11102
  }
11215
- );
11216
- };
11217
- if (isError) {
11218
- throw error;
11103
+ ];
11219
11104
  }
11220
- return /* @__PURE__ */ jsxs(
11221
- StackedFocusModal.Content,
11222
- {
11223
- onOpenAutoFocus: (e) => {
11224
- e.preventDefault();
11225
- const searchInput = document.querySelector(
11226
- "[data-modal-id='modal-search-input']"
11227
- );
11228
- if (searchInput) {
11229
- searchInput.focus();
11230
- }
11231
- },
11232
- children: [
11233
- /* @__PURE__ */ jsxs(StackedFocusModal.Header, { children: [
11234
- /* @__PURE__ */ jsx(StackedFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Product Variants" }) }),
11235
- /* @__PURE__ */ jsx(StackedFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Choose product variants to add to the order." }) })
11236
- ] }),
11237
- /* @__PURE__ */ jsx(StackedFocusModal.Body, { className: "flex-1 overflow-hidden", children: /* @__PURE__ */ jsx(
11238
- DataTable,
11239
- {
11240
- data: variants,
11241
- columns,
11242
- isLoading: isPending,
11243
- getRowId: (row) => row.id,
11244
- rowCount: count,
11245
- prefix: VARIANT_PREFIX,
11246
- layout: "fill",
11247
- rowSelection: {
11248
- state: rowSelection,
11249
- onRowSelectionChange: setRowSelection,
11250
- enableRowSelection: (row) => {
11251
- return !items.find((i) => i.variant_id === row.original.id);
11252
- }
11253
- },
11254
- autoFocusSearch: true
11255
- }
11256
- ) }),
11257
- /* @__PURE__ */ jsx(StackedFocusModal.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
11258
- /* @__PURE__ */ jsx(StackedFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
11259
- /* @__PURE__ */ jsx(Button, { size: "small", type: "button", onClick: onSubmit, children: "Update items" })
11260
- ] }) })
11261
- ]
11105
+ return Object.entries(metadata).map(([key, value]) => {
11106
+ if (!EDITABLE_TYPES.includes(typeof value)) {
11107
+ return {
11108
+ key,
11109
+ value,
11110
+ disabled: true
11111
+ };
11112
+ }
11113
+ let stringValue = value;
11114
+ if (typeof value !== "string") {
11115
+ stringValue = JSON.stringify(value);
11116
+ }
11117
+ return {
11118
+ key,
11119
+ value: stringValue,
11120
+ original_key: key
11121
+ };
11122
+ });
11123
+ }
11124
+ function parseValues(values) {
11125
+ const metadata = values.metadata;
11126
+ const isEmpty = !metadata.length || metadata.length === 1 && !metadata[0].key && !metadata[0].value;
11127
+ if (isEmpty) {
11128
+ return null;
11129
+ }
11130
+ const update = {};
11131
+ metadata.forEach((field) => {
11132
+ let key = field.key;
11133
+ let value = field.value;
11134
+ const disabled = field.disabled;
11135
+ if (!key || !value) {
11136
+ return;
11137
+ }
11138
+ if (disabled) {
11139
+ update[key] = value;
11140
+ return;
11141
+ }
11142
+ key = key.trim();
11143
+ value = value.trim();
11144
+ if (value === "true") {
11145
+ update[key] = true;
11146
+ } else if (value === "false") {
11147
+ update[key] = false;
11148
+ } else {
11149
+ const parsedNumber = parseFloat(value);
11150
+ if (!isNaN(parsedNumber)) {
11151
+ update[key] = parsedNumber;
11152
+ } else {
11153
+ update[key] = value;
11154
+ }
11262
11155
  }
11156
+ });
11157
+ return update;
11158
+ }
11159
+ function getHasUneditableRows(metadata) {
11160
+ if (!metadata) {
11161
+ return false;
11162
+ }
11163
+ return Object.values(metadata).some(
11164
+ (value) => !EDITABLE_TYPES.includes(typeof value)
11263
11165
  );
11166
+ }
11167
+ const PROMOTION_QUERY_KEY = "promotions";
11168
+ const promotionsQueryKeys = {
11169
+ list: (query2) => [
11170
+ PROMOTION_QUERY_KEY,
11171
+ query2 ? query2 : void 0
11172
+ ],
11173
+ detail: (id, query2) => [
11174
+ PROMOTION_QUERY_KEY,
11175
+ id,
11176
+ query2 ? query2 : void 0
11177
+ ]
11264
11178
  };
11265
- const columnHelper = createDataTableColumnHelper();
11266
- const useColumns = () => {
11267
- return useMemo(() => {
11268
- return [
11269
- columnHelper.select(),
11270
- columnHelper.accessor("product.title", {
11271
- header: "Product",
11272
- cell: ({ row }) => {
11273
- var _a, _b, _c;
11274
- return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-2", children: [
11275
- /* @__PURE__ */ jsx(
11276
- Thumbnail,
11277
- {
11278
- thumbnail: (_a = row.original.product) == null ? void 0 : _a.thumbnail,
11279
- alt: (_b = row.original.product) == null ? void 0 : _b.title
11280
- }
11281
- ),
11282
- /* @__PURE__ */ jsx("span", { children: (_c = row.original.product) == null ? void 0 : _c.title })
11283
- ] });
11284
- },
11285
- enableSorting: true
11286
- }),
11287
- columnHelper.accessor("title", {
11288
- header: "Variant",
11289
- enableSorting: true
11290
- }),
11291
- columnHelper.accessor("sku", {
11292
- header: "SKU",
11293
- cell: ({ getValue }) => {
11294
- return getValue() ?? "-";
11295
- },
11296
- enableSorting: true
11297
- }),
11298
- columnHelper.accessor("updated_at", {
11299
- header: "Updated",
11300
- cell: ({ getValue }) => {
11301
- return /* @__PURE__ */ jsx(
11302
- Tooltip,
11303
- {
11304
- content: getFullDate({ date: getValue(), includeTime: true }),
11305
- children: /* @__PURE__ */ jsx("span", { children: getFullDate({ date: getValue() }) })
11306
- }
11307
- );
11308
- },
11309
- enableSorting: true,
11310
- sortAscLabel: "Oldest first",
11311
- sortDescLabel: "Newest first"
11312
- }),
11313
- columnHelper.accessor("created_at", {
11314
- header: "Created",
11315
- cell: ({ getValue }) => {
11316
- return /* @__PURE__ */ jsx(
11317
- Tooltip,
11318
- {
11319
- content: getFullDate({ date: getValue(), includeTime: true }),
11320
- children: /* @__PURE__ */ jsx("span", { children: getFullDate({ date: getValue() }) })
11321
- }
11322
- );
11323
- },
11324
- enableSorting: true,
11325
- sortAscLabel: "Oldest first",
11326
- sortDescLabel: "Newest first"
11327
- })
11328
- ];
11329
- }, []);
11179
+ const usePromotions = (query2, options) => {
11180
+ const { data, ...rest } = useQuery({
11181
+ queryKey: promotionsQueryKeys.list(query2),
11182
+ queryFn: async () => sdk.admin.promotion.list(query2),
11183
+ ...options
11184
+ });
11185
+ return { ...data, ...rest };
11186
+ };
11187
+ const Promotions = () => {
11188
+ const { id } = useParams();
11189
+ const {
11190
+ order: preview,
11191
+ isError: isPreviewError,
11192
+ error: previewError
11193
+ } = useOrderPreview(id, void 0);
11194
+ useInitiateOrderEdit({ preview });
11195
+ const { onCancel } = useCancelOrderEdit({ preview });
11196
+ if (isPreviewError) {
11197
+ throw previewError;
11198
+ }
11199
+ const isReady = !!preview;
11200
+ return /* @__PURE__ */ jsxs(RouteDrawer, { onClose: onCancel, children: [
11201
+ /* @__PURE__ */ jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Promotions" }) }) }),
11202
+ isReady && /* @__PURE__ */ jsx(PromotionForm, { preview })
11203
+ ] });
11330
11204
  };
11331
- const CustomItemForm = ({ orderId, currencyCode }) => {
11332
- const { setIsOpen } = useStackedModal();
11333
- const { mutateAsync: addItems } = useDraftOrderAddItems(orderId);
11334
- const form = useForm({
11335
- defaultValues: {
11336
- title: "",
11337
- quantity: 1,
11338
- unit_price: ""
11205
+ const PromotionForm = ({ preview }) => {
11206
+ const { items, shipping_methods } = preview;
11207
+ const [isSubmitting, setIsSubmitting] = useState(false);
11208
+ const [comboboxValue, setComboboxValue] = useState("");
11209
+ const { handleSuccess } = useRouteModal();
11210
+ const { mutateAsync: addPromotions, isPending: isAddingPromotions } = useDraftOrderAddPromotions(preview.id);
11211
+ const promoIds = getPromotionIds(items, shipping_methods);
11212
+ const { promotions, isPending, isError, error } = usePromotions(
11213
+ {
11214
+ id: promoIds
11339
11215
  },
11340
- resolver: zodResolver(customItemSchema)
11216
+ {
11217
+ enabled: !!promoIds.length
11218
+ }
11219
+ );
11220
+ const comboboxData = useComboboxData({
11221
+ queryKey: ["promotions", "combobox", promoIds],
11222
+ queryFn: async (params) => {
11223
+ return await sdk.admin.promotion.list({
11224
+ ...params,
11225
+ id: {
11226
+ $nin: promoIds
11227
+ }
11228
+ });
11229
+ },
11230
+ getOptions: (data) => {
11231
+ return data.promotions.map((promotion) => ({
11232
+ label: promotion.code,
11233
+ value: promotion.code
11234
+ }));
11235
+ }
11341
11236
  });
11342
- const onSubmit = form.handleSubmit(async (data) => {
11343
- await addItems(
11237
+ const add = async (value) => {
11238
+ if (!value) {
11239
+ return;
11240
+ }
11241
+ addPromotions(
11344
11242
  {
11345
- items: [
11346
- {
11347
- title: data.title,
11348
- quantity: data.quantity,
11349
- unit_price: convertNumber(data.unit_price)
11350
- }
11351
- ]
11243
+ promo_codes: [value]
11352
11244
  },
11353
11245
  {
11354
- onSuccess: () => {
11355
- setIsOpen(STACKED_MODAL_ID, false);
11356
- },
11357
11246
  onError: (e) => {
11358
11247
  toast.error(e.message);
11248
+ comboboxData.onSearchValueChange("");
11249
+ setComboboxValue("");
11250
+ },
11251
+ onSuccess: () => {
11252
+ comboboxData.onSearchValueChange("");
11253
+ setComboboxValue("");
11359
11254
  }
11360
11255
  }
11361
11256
  );
11362
- });
11363
- return /* @__PURE__ */ jsx(Form$2, { ...form, children: /* @__PURE__ */ jsx(KeyboundForm, { onSubmit, children: /* @__PURE__ */ jsxs(StackedFocusModal.Content, { children: [
11364
- /* @__PURE__ */ jsx(StackedFocusModal.Header, {}),
11365
- /* @__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: [
11366
- /* @__PURE__ */ jsxs("div", { children: [
11367
- /* @__PURE__ */ jsx(StackedFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Add custom item" }) }),
11368
- /* @__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." }) })
11257
+ };
11258
+ const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
11259
+ const { mutateAsync: requestOrderEdit } = useOrderEditRequest(preview.id);
11260
+ const onSubmit = async () => {
11261
+ setIsSubmitting(true);
11262
+ let requestSucceeded = false;
11263
+ await requestOrderEdit(void 0, {
11264
+ onError: (e) => {
11265
+ toast.error(e.message);
11266
+ },
11267
+ onSuccess: () => {
11268
+ requestSucceeded = true;
11269
+ }
11270
+ });
11271
+ if (!requestSucceeded) {
11272
+ setIsSubmitting(false);
11273
+ return;
11274
+ }
11275
+ await confirmOrderEdit(void 0, {
11276
+ onError: (e) => {
11277
+ toast.error(e.message);
11278
+ },
11279
+ onSuccess: () => {
11280
+ handleSuccess();
11281
+ },
11282
+ onSettled: () => {
11283
+ setIsSubmitting(false);
11284
+ }
11285
+ });
11286
+ };
11287
+ if (isError) {
11288
+ throw error;
11289
+ }
11290
+ return /* @__PURE__ */ jsxs(KeyboundForm, { className: "flex flex-1 flex-col", onSubmit, children: [
11291
+ /* @__PURE__ */ jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-4", children: [
11292
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3", children: [
11293
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
11294
+ /* @__PURE__ */ jsx(Label$1, { size: "small", weight: "plus", htmlFor: "promotion-combobox", children: "Apply promotions" }),
11295
+ /* @__PURE__ */ jsx(Hint$1, { id: "promotion-combobox-hint", children: "Manage promotions that should be applied to the order." })
11296
+ ] }),
11297
+ /* @__PURE__ */ jsx(
11298
+ Combobox,
11299
+ {
11300
+ id: "promotion-combobox",
11301
+ "aria-describedby": "promotion-combobox-hint",
11302
+ isFetchingNextPage: comboboxData.isFetchingNextPage,
11303
+ fetchNextPage: comboboxData.fetchNextPage,
11304
+ options: comboboxData.options,
11305
+ onSearchValueChange: comboboxData.onSearchValueChange,
11306
+ searchValue: comboboxData.searchValue,
11307
+ disabled: comboboxData.disabled || isAddingPromotions,
11308
+ onChange: add,
11309
+ value: comboboxValue
11310
+ }
11311
+ )
11369
11312
  ] }),
11370
11313
  /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
11314
+ /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-2", children: promotions == null ? void 0 : promotions.map((promotion) => /* @__PURE__ */ jsx(
11315
+ PromotionItem,
11316
+ {
11317
+ promotion,
11318
+ orderId: preview.id,
11319
+ isLoading: isPending
11320
+ },
11321
+ promotion.id
11322
+ )) })
11323
+ ] }) }),
11324
+ /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
11325
+ /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
11371
11326
  /* @__PURE__ */ jsx(
11372
- Form$2.Field,
11327
+ Button,
11373
11328
  {
11374
- control: form.control,
11375
- name: "title",
11376
- render: ({ field }) => /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
11377
- /* @__PURE__ */ jsxs("div", { children: [
11378
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Title" }),
11379
- /* @__PURE__ */ jsx(Form$2.Hint, { children: "Enter the title of the item" })
11380
- ] }),
11381
- /* @__PURE__ */ jsxs("div", { children: [
11382
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
11383
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11384
- ] })
11385
- ] }) })
11329
+ size: "small",
11330
+ type: "submit",
11331
+ isLoading: isSubmitting || isAddingPromotions,
11332
+ children: "Save"
11386
11333
  }
11387
- ),
11388
- /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
11389
- /* @__PURE__ */ jsx(
11390
- Form$2.Field,
11334
+ )
11335
+ ] }) })
11336
+ ] });
11337
+ };
11338
+ const PromotionItem = ({
11339
+ promotion,
11340
+ orderId,
11341
+ isLoading
11342
+ }) => {
11343
+ var _a;
11344
+ const { mutateAsync: removePromotions, isPending } = useDraftOrderRemovePromotions(orderId);
11345
+ const onRemove = async () => {
11346
+ removePromotions(
11347
+ {
11348
+ promo_codes: [promotion.code]
11349
+ },
11350
+ {
11351
+ onError: (e) => {
11352
+ toast.error(e.message);
11353
+ }
11354
+ }
11355
+ );
11356
+ };
11357
+ const displayValue = getDisplayValue(promotion);
11358
+ return /* @__PURE__ */ jsxs(
11359
+ "div",
11360
+ {
11361
+ className: clx(
11362
+ "bg-ui-bg-component shadow-elevation-card-rest flex items-center justify-between rounded-lg px-3 py-2",
11391
11363
  {
11392
- control: form.control,
11393
- name: "unit_price",
11394
- render: ({ field: { onChange, ...field } }) => /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
11395
- /* @__PURE__ */ jsxs("div", { children: [
11396
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Unit price" }),
11397
- /* @__PURE__ */ jsx(Form$2.Hint, { children: "Enter the unit price of the item" })
11398
- ] }),
11399
- /* @__PURE__ */ jsxs("div", { children: [
11400
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
11401
- CurrencyInput,
11402
- {
11403
- symbol: getNativeSymbol(currencyCode),
11404
- code: currencyCode,
11405
- onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value),
11406
- ...field
11407
- }
11408
- ) }),
11409
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11410
- ] })
11411
- ] }) })
11364
+ "animate-pulse": isLoading
11412
11365
  }
11413
11366
  ),
11414
- /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
11415
- /* @__PURE__ */ jsx(
11416
- Form$2.Field,
11417
- {
11418
- control: form.control,
11419
- name: "quantity",
11420
- render: ({ field }) => /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
11421
- /* @__PURE__ */ jsxs("div", { children: [
11422
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Quantity" }),
11423
- /* @__PURE__ */ jsx(Form$2.Hint, { children: "Enter the quantity of the item" })
11367
+ children: [
11368
+ /* @__PURE__ */ jsxs("div", { children: [
11369
+ /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: promotion.code }),
11370
+ /* @__PURE__ */ jsxs("div", { className: "text-ui-fg-subtle flex items-center gap-1.5", children: [
11371
+ displayValue && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
11372
+ /* @__PURE__ */ jsx(Text, { size: "small", leading: "compact", children: displayValue }),
11373
+ /* @__PURE__ */ jsx(Text, { size: "small", leading: "compact", children: "·" })
11424
11374
  ] }),
11425
- /* @__PURE__ */ jsxs("div", { className: "w-full flex-1", children: [
11426
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsx(NumberInput, { ...field, className: "w-full" }) }) }),
11427
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11428
- ] })
11429
- ] }) })
11430
- }
11431
- )
11432
- ] }) }) }),
11433
- /* @__PURE__ */ jsx(StackedFocusModal.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
11434
- /* @__PURE__ */ jsx(StackedFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
11435
- /* @__PURE__ */ jsx(Button, { size: "small", type: "button", onClick: onSubmit, children: "Add item" })
11436
- ] }) })
11437
- ] }) }) });
11375
+ /* @__PURE__ */ jsx(Text, { size: "small", leading: "compact", className: "capitalize", children: (_a = promotion.application_method) == null ? void 0 : _a.allocation })
11376
+ ] })
11377
+ ] }),
11378
+ /* @__PURE__ */ jsx(
11379
+ IconButton,
11380
+ {
11381
+ size: "small",
11382
+ type: "button",
11383
+ variant: "transparent",
11384
+ onClick: onRemove,
11385
+ isLoading: isPending || isLoading,
11386
+ children: /* @__PURE__ */ jsx(XMark, {})
11387
+ }
11388
+ )
11389
+ ]
11390
+ },
11391
+ promotion.id
11392
+ );
11438
11393
  };
11439
- const customItemSchema = objectType({
11440
- title: stringType().min(1),
11441
- quantity: numberType(),
11442
- unit_price: unionType([numberType(), stringType()])
11394
+ function getDisplayValue(promotion) {
11395
+ var _a, _b, _c, _d;
11396
+ const value = (_a = promotion.application_method) == null ? void 0 : _a.value;
11397
+ if (!value) {
11398
+ return null;
11399
+ }
11400
+ if (((_b = promotion.application_method) == null ? void 0 : _b.type) === "fixed") {
11401
+ const currency = (_c = promotion.application_method) == null ? void 0 : _c.currency_code;
11402
+ if (!currency) {
11403
+ return null;
11404
+ }
11405
+ return getLocaleAmount(value, currency);
11406
+ } else if (((_d = promotion.application_method) == null ? void 0 : _d.type) === "percentage") {
11407
+ return formatPercentage(value);
11408
+ }
11409
+ return null;
11410
+ }
11411
+ const formatter = new Intl.NumberFormat([], {
11412
+ style: "percent",
11413
+ minimumFractionDigits: 2
11443
11414
  });
11415
+ const formatPercentage = (value, isPercentageValue = false) => {
11416
+ let val = value || 0;
11417
+ if (!isPercentageValue) {
11418
+ val = val / 100;
11419
+ }
11420
+ return formatter.format(val);
11421
+ };
11422
+ function getPromotionIds(items, shippingMethods) {
11423
+ const promotionIds = /* @__PURE__ */ new Set();
11424
+ for (const item of items) {
11425
+ if (item.adjustments) {
11426
+ for (const adjustment of item.adjustments) {
11427
+ if (adjustment.promotion_id) {
11428
+ promotionIds.add(adjustment.promotion_id);
11429
+ }
11430
+ }
11431
+ }
11432
+ }
11433
+ for (const shippingMethod of shippingMethods) {
11434
+ if (shippingMethod.adjustments) {
11435
+ for (const adjustment of shippingMethod.adjustments) {
11436
+ if (adjustment.promotion_id) {
11437
+ promotionIds.add(adjustment.promotion_id);
11438
+ }
11439
+ }
11440
+ }
11441
+ }
11442
+ return Array.from(promotionIds);
11443
+ }
11444
11444
  const SalesChannel = () => {
11445
11445
  const { id } = useParams();
11446
11446
  const { draft_order, isPending, isError, error } = useDraftOrder(
@@ -12337,226 +12337,23 @@ const CustomAmountField = ({
12337
12337
  render: ({ field: { onChange, ...field } }) => {
12338
12338
  return /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
12339
12339
  /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
12340
- /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Custom amount" }),
12341
- /* @__PURE__ */ jsx(Form$2.Hint, { children: "Set a custom amount for the shipping option." })
12342
- ] }),
12343
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
12344
- CurrencyInput,
12345
- {
12346
- ...field,
12347
- onValueChange: (value) => onChange(value),
12348
- symbol: getNativeSymbol(currencyCode),
12349
- code: currencyCode
12350
- }
12351
- ) })
12352
- ] });
12353
- }
12354
- }
12355
- );
12356
- };
12357
- const ShippingAddress = () => {
12358
- const { id } = useParams();
12359
- const { order, isPending, isError, error } = useOrder(id, {
12360
- fields: "+shipping_address"
12361
- });
12362
- if (isError) {
12363
- throw error;
12364
- }
12365
- const isReady = !isPending && !!order;
12366
- return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
12367
- /* @__PURE__ */ jsxs(RouteDrawer.Header, { children: [
12368
- /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Shipping Address" }) }),
12369
- /* @__PURE__ */ jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Edit the shipping address for the draft order" }) })
12370
- ] }),
12371
- isReady && /* @__PURE__ */ jsx(ShippingAddressForm, { order })
12372
- ] });
12373
- };
12374
- const ShippingAddressForm = ({ order }) => {
12375
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
12376
- const form = useForm({
12377
- defaultValues: {
12378
- first_name: ((_a = order.shipping_address) == null ? void 0 : _a.first_name) ?? "",
12379
- last_name: ((_b = order.shipping_address) == null ? void 0 : _b.last_name) ?? "",
12380
- company: ((_c = order.shipping_address) == null ? void 0 : _c.company) ?? "",
12381
- address_1: ((_d = order.shipping_address) == null ? void 0 : _d.address_1) ?? "",
12382
- address_2: ((_e = order.shipping_address) == null ? void 0 : _e.address_2) ?? "",
12383
- city: ((_f = order.shipping_address) == null ? void 0 : _f.city) ?? "",
12384
- province: ((_g = order.shipping_address) == null ? void 0 : _g.province) ?? "",
12385
- country_code: ((_h = order.shipping_address) == null ? void 0 : _h.country_code) ?? "",
12386
- postal_code: ((_i = order.shipping_address) == null ? void 0 : _i.postal_code) ?? "",
12387
- phone: ((_j = order.shipping_address) == null ? void 0 : _j.phone) ?? ""
12388
- },
12389
- resolver: zodResolver(schema$1)
12390
- });
12391
- const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
12392
- const { handleSuccess } = useRouteModal();
12393
- const onSubmit = form.handleSubmit(async (data) => {
12394
- await mutateAsync(
12395
- {
12396
- shipping_address: {
12397
- first_name: data.first_name,
12398
- last_name: data.last_name,
12399
- company: data.company,
12400
- address_1: data.address_1,
12401
- address_2: data.address_2,
12402
- city: data.city,
12403
- province: data.province,
12404
- country_code: data.country_code,
12405
- postal_code: data.postal_code,
12406
- phone: data.phone
12407
- }
12408
- },
12409
- {
12410
- onSuccess: () => {
12411
- handleSuccess();
12412
- },
12413
- onError: (error) => {
12414
- toast.error(error.message);
12415
- }
12416
- }
12417
- );
12418
- });
12419
- return /* @__PURE__ */ jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxs(
12420
- KeyboundForm,
12421
- {
12422
- className: "flex flex-1 flex-col overflow-hidden",
12423
- onSubmit,
12424
- children: [
12425
- /* @__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: [
12426
- /* @__PURE__ */ jsx(
12427
- Form$2.Field,
12428
- {
12429
- control: form.control,
12430
- name: "country_code",
12431
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12432
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Country" }),
12433
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(CountrySelect, { ...field }) }),
12434
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12435
- ] })
12436
- }
12437
- ),
12438
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
12439
- /* @__PURE__ */ jsx(
12440
- Form$2.Field,
12441
- {
12442
- control: form.control,
12443
- name: "first_name",
12444
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12445
- /* @__PURE__ */ jsx(Form$2.Label, { children: "First name" }),
12446
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12447
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12448
- ] })
12449
- }
12450
- ),
12451
- /* @__PURE__ */ jsx(
12452
- Form$2.Field,
12453
- {
12454
- control: form.control,
12455
- name: "last_name",
12456
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12457
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Last name" }),
12458
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12459
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12460
- ] })
12461
- }
12462
- )
12463
- ] }),
12464
- /* @__PURE__ */ jsx(
12465
- Form$2.Field,
12466
- {
12467
- control: form.control,
12468
- name: "company",
12469
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12470
- /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Company" }),
12471
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12472
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12473
- ] })
12474
- }
12475
- ),
12476
- /* @__PURE__ */ jsx(
12477
- Form$2.Field,
12478
- {
12479
- control: form.control,
12480
- name: "address_1",
12481
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12482
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Address" }),
12483
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12484
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12485
- ] })
12486
- }
12487
- ),
12488
- /* @__PURE__ */ jsx(
12489
- Form$2.Field,
12490
- {
12491
- control: form.control,
12492
- name: "address_2",
12493
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12494
- /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Apartment, suite, etc." }),
12495
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12496
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12497
- ] })
12498
- }
12499
- ),
12500
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
12501
- /* @__PURE__ */ jsx(
12502
- Form$2.Field,
12503
- {
12504
- control: form.control,
12505
- name: "postal_code",
12506
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12507
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Postal code" }),
12508
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12509
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12510
- ] })
12511
- }
12512
- ),
12513
- /* @__PURE__ */ jsx(
12514
- Form$2.Field,
12515
- {
12516
- control: form.control,
12517
- name: "city",
12518
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12519
- /* @__PURE__ */ jsx(Form$2.Label, { children: "City" }),
12520
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12521
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12522
- ] })
12523
- }
12524
- )
12525
- ] }),
12526
- /* @__PURE__ */ jsx(
12527
- Form$2.Field,
12528
- {
12529
- control: form.control,
12530
- name: "province",
12531
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12532
- /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Province / State" }),
12533
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12534
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12535
- ] })
12536
- }
12537
- ),
12538
- /* @__PURE__ */ jsx(
12539
- Form$2.Field,
12340
+ /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Custom amount" }),
12341
+ /* @__PURE__ */ jsx(Form$2.Hint, { children: "Set a custom amount for the shipping option." })
12342
+ ] }),
12343
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
12344
+ CurrencyInput,
12540
12345
  {
12541
- control: form.control,
12542
- name: "phone",
12543
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12544
- /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Phone" }),
12545
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12546
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12547
- ] })
12346
+ ...field,
12347
+ onValueChange: (value) => onChange(value),
12348
+ symbol: getNativeSymbol(currencyCode),
12349
+ code: currencyCode
12548
12350
  }
12549
- )
12550
- ] }) }),
12551
- /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
12552
- /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
12553
- /* @__PURE__ */ jsx(Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
12554
- ] }) })
12555
- ]
12351
+ ) })
12352
+ ] });
12353
+ }
12556
12354
  }
12557
- ) });
12355
+ );
12558
12356
  };
12559
- const schema$1 = addressSchema;
12560
12357
  const TransferOwnership = () => {
12561
12358
  const { id } = useParams();
12562
12359
  const { draft_order, isPending, isError, error } = useDraftOrder(id, {
@@ -12580,7 +12377,7 @@ const TransferOwnershipForm = ({ order }) => {
12580
12377
  defaultValues: {
12581
12378
  customer_id: order.customer_id || ""
12582
12379
  },
12583
- resolver: zodResolver(schema)
12380
+ resolver: zodResolver(schema$1)
12584
12381
  });
12585
12382
  const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
12586
12383
  const { handleSuccess } = useRouteModal();
@@ -13030,9 +12827,212 @@ const Illustration = () => {
13030
12827
  }
13031
12828
  );
13032
12829
  };
13033
- const schema = objectType({
12830
+ const schema$1 = objectType({
13034
12831
  customer_id: stringType().min(1)
13035
12832
  });
12833
+ const ShippingAddress = () => {
12834
+ const { id } = useParams();
12835
+ const { order, isPending, isError, error } = useOrder(id, {
12836
+ fields: "+shipping_address"
12837
+ });
12838
+ if (isError) {
12839
+ throw error;
12840
+ }
12841
+ const isReady = !isPending && !!order;
12842
+ return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
12843
+ /* @__PURE__ */ jsxs(RouteDrawer.Header, { children: [
12844
+ /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Shipping Address" }) }),
12845
+ /* @__PURE__ */ jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Edit the shipping address for the draft order" }) })
12846
+ ] }),
12847
+ isReady && /* @__PURE__ */ jsx(ShippingAddressForm, { order })
12848
+ ] });
12849
+ };
12850
+ const ShippingAddressForm = ({ order }) => {
12851
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
12852
+ const form = useForm({
12853
+ defaultValues: {
12854
+ first_name: ((_a = order.shipping_address) == null ? void 0 : _a.first_name) ?? "",
12855
+ last_name: ((_b = order.shipping_address) == null ? void 0 : _b.last_name) ?? "",
12856
+ company: ((_c = order.shipping_address) == null ? void 0 : _c.company) ?? "",
12857
+ address_1: ((_d = order.shipping_address) == null ? void 0 : _d.address_1) ?? "",
12858
+ address_2: ((_e = order.shipping_address) == null ? void 0 : _e.address_2) ?? "",
12859
+ city: ((_f = order.shipping_address) == null ? void 0 : _f.city) ?? "",
12860
+ province: ((_g = order.shipping_address) == null ? void 0 : _g.province) ?? "",
12861
+ country_code: ((_h = order.shipping_address) == null ? void 0 : _h.country_code) ?? "",
12862
+ postal_code: ((_i = order.shipping_address) == null ? void 0 : _i.postal_code) ?? "",
12863
+ phone: ((_j = order.shipping_address) == null ? void 0 : _j.phone) ?? ""
12864
+ },
12865
+ resolver: zodResolver(schema)
12866
+ });
12867
+ const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
12868
+ const { handleSuccess } = useRouteModal();
12869
+ const onSubmit = form.handleSubmit(async (data) => {
12870
+ await mutateAsync(
12871
+ {
12872
+ shipping_address: {
12873
+ first_name: data.first_name,
12874
+ last_name: data.last_name,
12875
+ company: data.company,
12876
+ address_1: data.address_1,
12877
+ address_2: data.address_2,
12878
+ city: data.city,
12879
+ province: data.province,
12880
+ country_code: data.country_code,
12881
+ postal_code: data.postal_code,
12882
+ phone: data.phone
12883
+ }
12884
+ },
12885
+ {
12886
+ onSuccess: () => {
12887
+ handleSuccess();
12888
+ },
12889
+ onError: (error) => {
12890
+ toast.error(error.message);
12891
+ }
12892
+ }
12893
+ );
12894
+ });
12895
+ return /* @__PURE__ */ jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxs(
12896
+ KeyboundForm,
12897
+ {
12898
+ className: "flex flex-1 flex-col overflow-hidden",
12899
+ onSubmit,
12900
+ children: [
12901
+ /* @__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: [
12902
+ /* @__PURE__ */ jsx(
12903
+ Form$2.Field,
12904
+ {
12905
+ control: form.control,
12906
+ name: "country_code",
12907
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12908
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Country" }),
12909
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(CountrySelect, { ...field }) }),
12910
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12911
+ ] })
12912
+ }
12913
+ ),
12914
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
12915
+ /* @__PURE__ */ jsx(
12916
+ Form$2.Field,
12917
+ {
12918
+ control: form.control,
12919
+ name: "first_name",
12920
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12921
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "First name" }),
12922
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12923
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12924
+ ] })
12925
+ }
12926
+ ),
12927
+ /* @__PURE__ */ jsx(
12928
+ Form$2.Field,
12929
+ {
12930
+ control: form.control,
12931
+ name: "last_name",
12932
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12933
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Last name" }),
12934
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12935
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12936
+ ] })
12937
+ }
12938
+ )
12939
+ ] }),
12940
+ /* @__PURE__ */ jsx(
12941
+ Form$2.Field,
12942
+ {
12943
+ control: form.control,
12944
+ name: "company",
12945
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12946
+ /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Company" }),
12947
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12948
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12949
+ ] })
12950
+ }
12951
+ ),
12952
+ /* @__PURE__ */ jsx(
12953
+ Form$2.Field,
12954
+ {
12955
+ control: form.control,
12956
+ name: "address_1",
12957
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12958
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Address" }),
12959
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12960
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12961
+ ] })
12962
+ }
12963
+ ),
12964
+ /* @__PURE__ */ jsx(
12965
+ Form$2.Field,
12966
+ {
12967
+ control: form.control,
12968
+ name: "address_2",
12969
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12970
+ /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Apartment, suite, etc." }),
12971
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12972
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12973
+ ] })
12974
+ }
12975
+ ),
12976
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
12977
+ /* @__PURE__ */ jsx(
12978
+ Form$2.Field,
12979
+ {
12980
+ control: form.control,
12981
+ name: "postal_code",
12982
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12983
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Postal code" }),
12984
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12985
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12986
+ ] })
12987
+ }
12988
+ ),
12989
+ /* @__PURE__ */ jsx(
12990
+ Form$2.Field,
12991
+ {
12992
+ control: form.control,
12993
+ name: "city",
12994
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12995
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "City" }),
12996
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12997
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12998
+ ] })
12999
+ }
13000
+ )
13001
+ ] }),
13002
+ /* @__PURE__ */ jsx(
13003
+ Form$2.Field,
13004
+ {
13005
+ control: form.control,
13006
+ name: "province",
13007
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
13008
+ /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Province / State" }),
13009
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
13010
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
13011
+ ] })
13012
+ }
13013
+ ),
13014
+ /* @__PURE__ */ jsx(
13015
+ Form$2.Field,
13016
+ {
13017
+ control: form.control,
13018
+ name: "phone",
13019
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
13020
+ /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Phone" }),
13021
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
13022
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
13023
+ ] })
13024
+ }
13025
+ )
13026
+ ] }) }),
13027
+ /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
13028
+ /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
13029
+ /* @__PURE__ */ jsx(Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
13030
+ ] }) })
13031
+ ]
13032
+ }
13033
+ ) });
13034
+ };
13035
+ const schema = addressSchema;
13036
13036
  const widgetModule = { widgets: [] };
13037
13037
  const routeModule = {
13038
13038
  routes: [
@@ -13053,18 +13053,22 @@ const routeModule = {
13053
13053
  handle,
13054
13054
  loader,
13055
13055
  children: [
13056
- {
13057
- Component: BillingAddress,
13058
- path: "/draft-orders/:id/billing-address"
13059
- },
13060
13056
  {
13061
13057
  Component: CustomItems,
13062
13058
  path: "/draft-orders/:id/custom-items"
13063
13059
  },
13060
+ {
13061
+ Component: BillingAddress,
13062
+ path: "/draft-orders/:id/billing-address"
13063
+ },
13064
13064
  {
13065
13065
  Component: Email,
13066
13066
  path: "/draft-orders/:id/email"
13067
13067
  },
13068
+ {
13069
+ Component: Items,
13070
+ path: "/draft-orders/:id/items"
13071
+ },
13068
13072
  {
13069
13073
  Component: Metadata,
13070
13074
  path: "/draft-orders/:id/metadata"
@@ -13073,10 +13077,6 @@ const routeModule = {
13073
13077
  Component: Promotions,
13074
13078
  path: "/draft-orders/:id/promotions"
13075
13079
  },
13076
- {
13077
- Component: Items,
13078
- path: "/draft-orders/:id/items"
13079
- },
13080
13080
  {
13081
13081
  Component: SalesChannel,
13082
13082
  path: "/draft-orders/:id/sales-channel"
@@ -13085,13 +13085,13 @@ const routeModule = {
13085
13085
  Component: Shipping,
13086
13086
  path: "/draft-orders/:id/shipping"
13087
13087
  },
13088
- {
13089
- Component: ShippingAddress,
13090
- path: "/draft-orders/:id/shipping-address"
13091
- },
13092
13088
  {
13093
13089
  Component: TransferOwnership,
13094
13090
  path: "/draft-orders/:id/transfer-ownership"
13091
+ },
13092
+ {
13093
+ Component: ShippingAddress,
13094
+ path: "/draft-orders/:id/shipping-address"
13095
13095
  }
13096
13096
  ]
13097
13097
  }