@medusajs/draft-order 2.11.1-snapshot-20251021080449 → 2.11.1-snapshot-20251021090705

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