@medusajs/draft-order 2.11.2-snapshot-20251026124930 → 2.11.2-snapshot-20251029122124

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