@medusajs/draft-order 2.11.0-preview-20251020120209 → 2.11.0-preview-20251020141229

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,27 +9565,6 @@ const ID = () => {
9565
9565
  /* @__PURE__ */ jsx(Outlet, {})
9566
9566
  ] });
9567
9567
  };
9568
- const CustomItems = () => {
9569
- return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
9570
- /* @__PURE__ */ jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Custom Items" }) }) }),
9571
- /* @__PURE__ */ jsx(CustomItemsForm, {})
9572
- ] });
9573
- };
9574
- const CustomItemsForm = () => {
9575
- const form = useForm({
9576
- resolver: zodResolver(schema$5)
9577
- });
9578
- return /* @__PURE__ */ jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxs(KeyboundForm, { className: "flex flex-1 flex-col", children: [
9579
- /* @__PURE__ */ jsx(RouteDrawer.Body, {}),
9580
- /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
9581
- /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
9582
- /* @__PURE__ */ jsx(Button, { size: "small", type: "submit", children: "Save" })
9583
- ] }) })
9584
- ] }) });
9585
- };
9586
- const schema$5 = objectType({
9587
- email: stringType().email()
9588
- });
9589
9568
  const Email = () => {
9590
9569
  const { id } = useParams();
9591
9570
  const { order, isPending, isError, error } = useOrder(id, {
@@ -9608,7 +9587,7 @@ const EmailForm = ({ order }) => {
9608
9587
  defaultValues: {
9609
9588
  email: order.email ?? ""
9610
9589
  },
9611
- resolver: zodResolver(schema$4)
9590
+ resolver: zodResolver(schema$5)
9612
9591
  });
9613
9592
  const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
9614
9593
  const { handleSuccess } = useRouteModal();
@@ -9651,895 +9630,1019 @@ const EmailForm = ({ order }) => {
9651
9630
  }
9652
9631
  ) });
9653
9632
  };
9633
+ const schema$5 = objectType({
9634
+ email: stringType().email()
9635
+ });
9636
+ const CustomItems = () => {
9637
+ return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
9638
+ /* @__PURE__ */ jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Custom Items" }) }) }),
9639
+ /* @__PURE__ */ jsx(CustomItemsForm, {})
9640
+ ] });
9641
+ };
9642
+ const CustomItemsForm = () => {
9643
+ const form = useForm({
9644
+ resolver: zodResolver(schema$4)
9645
+ });
9646
+ return /* @__PURE__ */ jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxs(KeyboundForm, { className: "flex flex-1 flex-col", children: [
9647
+ /* @__PURE__ */ jsx(RouteDrawer.Body, {}),
9648
+ /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
9649
+ /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
9650
+ /* @__PURE__ */ jsx(Button, { size: "small", type: "submit", children: "Save" })
9651
+ ] }) })
9652
+ ] }) });
9653
+ };
9654
9654
  const schema$4 = objectType({
9655
9655
  email: stringType().email()
9656
9656
  });
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
- };
9687
- return /* @__PURE__ */ jsxs(
9688
- "div",
9657
+ const BillingAddress = () => {
9658
+ const { id } = useParams();
9659
+ const { order, isPending, isError, error } = useOrder(id, {
9660
+ fields: "+billing_address"
9661
+ });
9662
+ if (isError) {
9663
+ throw error;
9664
+ }
9665
+ const isReady = !isPending && !!order;
9666
+ return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
9667
+ /* @__PURE__ */ jsxs(RouteDrawer.Header, { children: [
9668
+ /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Billing Address" }) }),
9669
+ /* @__PURE__ */ jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Edit the billing address for the draft order" }) })
9670
+ ] }),
9671
+ isReady && /* @__PURE__ */ jsx(BillingAddressForm, { order })
9672
+ ] });
9673
+ };
9674
+ const BillingAddressForm = ({ order }) => {
9675
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
9676
+ const form = useForm({
9677
+ defaultValues: {
9678
+ first_name: ((_a = order.billing_address) == null ? void 0 : _a.first_name) ?? "",
9679
+ last_name: ((_b = order.billing_address) == null ? void 0 : _b.last_name) ?? "",
9680
+ company: ((_c = order.billing_address) == null ? void 0 : _c.company) ?? "",
9681
+ address_1: ((_d = order.billing_address) == null ? void 0 : _d.address_1) ?? "",
9682
+ address_2: ((_e = order.billing_address) == null ? void 0 : _e.address_2) ?? "",
9683
+ city: ((_f = order.billing_address) == null ? void 0 : _f.city) ?? "",
9684
+ province: ((_g = order.billing_address) == null ? void 0 : _g.province) ?? "",
9685
+ country_code: ((_h = order.billing_address) == null ? void 0 : _h.country_code) ?? "",
9686
+ postal_code: ((_i = order.billing_address) == null ? void 0 : _i.postal_code) ?? "",
9687
+ phone: ((_j = order.billing_address) == null ? void 0 : _j.phone) ?? ""
9688
+ },
9689
+ resolver: zodResolver(schema$3)
9690
+ });
9691
+ const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
9692
+ const { handleSuccess } = useRouteModal();
9693
+ const onSubmit = form.handleSubmit(async (data) => {
9694
+ await mutateAsync(
9695
+ { billing_address: data },
9689
9696
  {
9690
- 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
- },
9697
- className
9698
- ),
9699
- children: [
9697
+ onSuccess: () => {
9698
+ handleSuccess();
9699
+ },
9700
+ onError: (error) => {
9701
+ toast.error(error.message);
9702
+ }
9703
+ }
9704
+ );
9705
+ });
9706
+ return /* @__PURE__ */ jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxs(
9707
+ KeyboundForm,
9708
+ {
9709
+ className: "flex flex-1 flex-col overflow-hidden",
9710
+ onSubmit,
9711
+ children: [
9712
+ /* @__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: [
9700
9713
  /* @__PURE__ */ jsx(
9701
- "input",
9714
+ Form$2.Field,
9702
9715
  {
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
+ control: form.control,
9717
+ name: "country_code",
9718
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
9719
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Country" }),
9720
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(CountrySelect, { ...field }) }),
9721
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
9722
+ ] })
9716
9723
  }
9717
9724
  ),
9718
- /* @__PURE__ */ jsxs(
9719
- "button",
9725
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
9726
+ /* @__PURE__ */ jsx(
9727
+ Form$2.Field,
9728
+ {
9729
+ control: form.control,
9730
+ name: "first_name",
9731
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
9732
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "First name" }),
9733
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
9734
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
9735
+ ] })
9736
+ }
9737
+ ),
9738
+ /* @__PURE__ */ jsx(
9739
+ Form$2.Field,
9740
+ {
9741
+ control: form.control,
9742
+ name: "last_name",
9743
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
9744
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Last name" }),
9745
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
9746
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
9747
+ ] })
9748
+ }
9749
+ )
9750
+ ] }),
9751
+ /* @__PURE__ */ jsx(
9752
+ Form$2.Field,
9720
9753
  {
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
- ]
9754
+ control: form.control,
9755
+ name: "company",
9756
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
9757
+ /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Company" }),
9758
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
9759
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
9760
+ ] })
9738
9761
  }
9739
9762
  ),
9740
- /* @__PURE__ */ jsxs(
9741
- "button",
9763
+ /* @__PURE__ */ jsx(
9764
+ Form$2.Field,
9742
9765
  {
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
- ]
9766
+ control: form.control,
9767
+ name: "address_1",
9768
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
9769
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Address" }),
9770
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
9771
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
9772
+ ] })
9760
9773
  }
9761
- )
9762
- ]
9763
- }
9764
- );
9765
- }
9766
- );
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;
9774
+ ),
9775
+ /* @__PURE__ */ jsx(
9776
+ Form$2.Field,
9777
+ {
9778
+ control: form.control,
9779
+ name: "address_2",
9780
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
9781
+ /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Apartment, suite, etc." }),
9782
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
9783
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
9784
+ ] })
9785
+ }
9786
+ ),
9787
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
9788
+ /* @__PURE__ */ jsx(
9789
+ Form$2.Field,
9790
+ {
9791
+ control: form.control,
9792
+ name: "postal_code",
9793
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
9794
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Postal code" }),
9795
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
9796
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
9797
+ ] })
9798
+ }
9799
+ ),
9800
+ /* @__PURE__ */ jsx(
9801
+ Form$2.Field,
9802
+ {
9803
+ control: form.control,
9804
+ name: "city",
9805
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
9806
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "City" }),
9807
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
9808
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
9809
+ ] })
9810
+ }
9811
+ )
9812
+ ] }),
9813
+ /* @__PURE__ */ jsx(
9814
+ Form$2.Field,
9815
+ {
9816
+ control: form.control,
9817
+ name: "province",
9818
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
9819
+ /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Province / State" }),
9820
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
9821
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
9822
+ ] })
9823
+ }
9824
+ ),
9825
+ /* @__PURE__ */ jsx(
9826
+ Form$2.Field,
9827
+ {
9828
+ control: form.control,
9829
+ name: "phone",
9830
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
9831
+ /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Phone" }),
9832
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
9833
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
9834
+ ] })
9835
+ }
9836
+ )
9837
+ ] }) }),
9838
+ /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
9839
+ /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
9840
+ /* @__PURE__ */ jsx(Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
9841
+ ] }) })
9842
+ ]
9787
9843
  }
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 };
9844
+ ) });
9800
9845
  };
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;
9846
+ const schema$3 = addressSchema;
9847
+ const InlineTip = forwardRef(
9848
+ ({ variant = "tip", label, className, children, ...props }, ref) => {
9849
+ const labelValue = label || (variant === "warning" ? "Warning" : "Tip");
9850
+ return /* @__PURE__ */ jsxs(
9851
+ "div",
9852
+ {
9853
+ ref,
9854
+ className: clx(
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",
9856
+ className
9857
+ ),
9858
+ ...props,
9859
+ children: [
9860
+ /* @__PURE__ */ jsx(
9861
+ "div",
9862
+ {
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
+ })
9867
+ }
9868
+ ),
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
+ ] })
9877
+ ]
9814
9878
  }
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 = () => {
9879
+ );
9880
+ }
9881
+ );
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
- )
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
+ ] })
9976
10083
  ] })
9977
10084
  ] })
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
- }
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." })
10091
+ ] }),
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" })
10095
+ ] }) })
10096
+ ]
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
10048
10110
  )
10111
+ }
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" })
10049
10121
  ] }) })
10050
10122
  ] });
10051
10123
  };
10052
- const Item = ({ item, preview, currencyCode }) => {
10053
- if (item.variant_id) {
10054
- return /* @__PURE__ */ jsx(VariantItem, { item, preview, currencyCode });
10124
+ const EDITABLE_TYPES = ["string", "number", "boolean"];
10125
+ function getDefaultValues(metadata) {
10126
+ if (!metadata || !Object.keys(metadata).length) {
10127
+ return [
10128
+ {
10129
+ key: "",
10130
+ value: "",
10131
+ disabled: false
10132
+ }
10133
+ ];
10055
10134
  }
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)
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
+ };
10066
10152
  });
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);
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) {
10077
10166
  return;
10078
10167
  }
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
- );
10168
+ if (disabled) {
10169
+ update[key] = value;
10095
10170
  return;
10096
10171
  }
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
- }
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;
10110
10184
  }
10111
- );
10185
+ }
10112
10186
  });
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
- }
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 NumberInput = forwardRef(
10198
+ ({
10199
+ value,
10200
+ onChange,
10201
+ size = "base",
10202
+ min = 0,
10203
+ max = 100,
10204
+ step = 1,
10205
+ className,
10206
+ disabled,
10207
+ ...props
10208
+ }, ref) => {
10209
+ const handleChange = (event) => {
10210
+ const newValue = event.target.value === "" ? min : Number(event.target.value);
10211
+ if (!isNaN(newValue) && (max === void 0 || newValue <= max) && (min === void 0 || newValue >= min)) {
10212
+ onChange(newValue);
10158
10213
  }
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
- }
10214
+ };
10215
+ const handleIncrement = () => {
10216
+ const newValue = value + step;
10217
+ if (max === void 0 || newValue <= max) {
10218
+ onChange(newValue);
10176
10219
  }
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,
10220
+ };
10221
+ const handleDecrement = () => {
10222
+ const newValue = value - step;
10223
+ if (min === void 0 || newValue >= min) {
10224
+ onChange(newValue);
10225
+ }
10226
+ };
10227
+ return /* @__PURE__ */ jsxs(
10228
+ "div",
10180
10229
  {
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, {})
10230
+ className: clx(
10231
+ "inline-flex rounded-md bg-ui-bg-field shadow-borders-base overflow-hidden divide-x transition-fg",
10232
+ "[&:has(input:focus)]:shadow-borders-interactive-with-active",
10233
+ {
10234
+ "h-7": size === "small",
10235
+ "h-8": size === "base"
10236
+ },
10237
+ className
10238
+ ),
10239
+ children: [
10240
+ /* @__PURE__ */ jsx(
10241
+ "input",
10242
+ {
10243
+ ref,
10244
+ type: "number",
10245
+ value,
10246
+ onChange: handleChange,
10247
+ min,
10248
+ max,
10249
+ step,
10250
+ className: clx(
10251
+ "flex-1 px-2 py-1 bg-transparent txt-compact-small text-ui-fg-base outline-none [appearance:textfield]",
10252
+ "[&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none",
10253
+ "placeholder:text-ui-fg-muted"
10254
+ ),
10255
+ ...props
10256
+ }
10257
+ ),
10258
+ /* @__PURE__ */ jsxs(
10259
+ "button",
10260
+ {
10261
+ className: clx(
10262
+ "flex items-center justify-center outline-none transition-fg",
10263
+ "disabled:cursor-not-allowed disabled:text-ui-fg-muted",
10264
+ "focus:bg-ui-bg-field-component-hover",
10265
+ "hover:bg-ui-bg-field-component-hover",
10266
+ {
10267
+ "size-7": size === "small",
10268
+ "size-8": size === "base"
10269
+ }
10270
+ ),
10271
+ type: "button",
10272
+ onClick: handleDecrement,
10273
+ disabled: min !== void 0 && value <= min || disabled,
10274
+ children: [
10275
+ /* @__PURE__ */ jsx(Minus, {}),
10276
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: `Decrease by ${step}` })
10277
+ ]
10278
+ }
10279
+ ),
10280
+ /* @__PURE__ */ jsxs(
10281
+ "button",
10282
+ {
10283
+ className: clx(
10284
+ "flex items-center justify-center outline-none transition-fg",
10285
+ "disabled:cursor-not-allowed disabled:text-ui-fg-muted",
10286
+ "focus:bg-ui-bg-field-hover",
10287
+ "hover:bg-ui-bg-field-hover",
10288
+ {
10289
+ "size-7": size === "small",
10290
+ "size-8": size === "base"
10291
+ }
10292
+ ),
10293
+ type: "button",
10294
+ onClick: handleIncrement,
10295
+ disabled: max !== void 0 && value >= max || disabled,
10296
+ children: [
10297
+ /* @__PURE__ */ jsx(Plus, {}),
10298
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: `Increase by ${step}` })
10299
+ ]
10300
+ }
10301
+ )
10302
+ ]
10188
10303
  }
10189
- )
10190
- ] }) }) });
10304
+ );
10305
+ }
10306
+ );
10307
+ const PRODUCT_VARIANTS_QUERY_KEY = "product-variants";
10308
+ const productVariantsQueryKeys = {
10309
+ list: (query2) => [
10310
+ PRODUCT_VARIANTS_QUERY_KEY,
10311
+ query2 ? query2 : void 0
10312
+ ]
10191
10313
  };
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)
10314
+ const useProductVariants = (query2, options) => {
10315
+ const { data, ...rest } = useQuery({
10316
+ queryKey: productVariantsQueryKeys.list(query2),
10317
+ queryFn: async () => await sdk.admin.productVariant.list(query2),
10318
+ ...options
10206
10319
  });
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;
10320
+ return { ...data, ...rest };
10321
+ };
10322
+ const useCancelOrderEdit = ({ preview }) => {
10323
+ const { mutateAsync: cancelOrderEdit } = useDraftOrderCancelEdit(preview == null ? void 0 : preview.id);
10324
+ const onCancel = useCallback(async () => {
10325
+ if (!preview) {
10326
+ return true;
10244
10327
  }
10245
- if (data.quantity === 0) {
10246
- await removeActionItem(actionId, {
10247
- onSuccess: () => {
10248
- setEditing(false);
10249
- },
10328
+ let res = false;
10329
+ await cancelOrderEdit(void 0, {
10330
+ onError: (e) => {
10331
+ toast.error(e.message);
10332
+ },
10333
+ onSuccess: () => {
10334
+ res = true;
10335
+ }
10336
+ });
10337
+ return res;
10338
+ }, [preview, cancelOrderEdit]);
10339
+ return { onCancel };
10340
+ };
10341
+ let IS_REQUEST_RUNNING = false;
10342
+ const useInitiateOrderEdit = ({
10343
+ preview
10344
+ }) => {
10345
+ const navigate = useNavigate();
10346
+ const { mutateAsync } = useDraftOrderBeginEdit(preview == null ? void 0 : preview.id);
10347
+ useEffect(() => {
10348
+ async function run() {
10349
+ if (IS_REQUEST_RUNNING || !preview) {
10350
+ return;
10351
+ }
10352
+ if (preview.order_change) {
10353
+ return;
10354
+ }
10355
+ IS_REQUEST_RUNNING = true;
10356
+ await mutateAsync(void 0, {
10250
10357
  onError: (e) => {
10251
10358
  toast.error(e.message);
10359
+ navigate(`/draft-orders/${preview.id}`, { replace: true });
10360
+ return;
10252
10361
  }
10253
10362
  });
10254
- return;
10363
+ IS_REQUEST_RUNNING = false;
10255
10364
  }
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
- );
10365
+ run();
10366
+ }, [preview, navigate, mutateAsync]);
10367
+ };
10368
+ function convertNumber(value) {
10369
+ return typeof value === "string" ? Number(value.replace(",", ".")) : value;
10370
+ }
10371
+ const STACKED_MODAL_ID = "items_stacked_modal";
10372
+ const Items = () => {
10373
+ const { id } = useParams();
10374
+ const {
10375
+ order: preview,
10376
+ isPending: isPreviewPending,
10377
+ isError: isPreviewError,
10378
+ error: previewError
10379
+ } = useOrderPreview(id, void 0, {
10380
+ placeholderData: keepPreviousData
10271
10381
  });
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(
10382
+ useInitiateOrderEdit({ preview });
10383
+ const { draft_order, isPending, isError, error } = useDraftOrder(
10384
+ id,
10370
10385
  {
10371
- q,
10372
- order,
10373
- offset: offset ? parseInt(offset) : void 0,
10374
- limit: LIMIT
10386
+ fields: "currency_code"
10375
10387
  },
10376
10388
  {
10377
- placeholderData: keepPreviousData
10389
+ enabled: !!id
10378
10390
  }
10379
10391
  );
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
- };
10392
+ const { onCancel } = useCancelOrderEdit({ preview });
10404
10393
  if (isError) {
10405
10394
  throw error;
10406
10395
  }
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
- }
10396
+ if (isPreviewError) {
10397
+ throw previewError;
10398
+ }
10399
+ const ready = !!preview && !isPreviewPending && !!draft_order && !isPending;
10400
+ return /* @__PURE__ */ jsx(RouteFocusModal, { onClose: onCancel, children: ready ? /* @__PURE__ */ jsx(ItemsForm, { preview, currencyCode: draft_order.currency_code }) : /* @__PURE__ */ jsxs("div", { children: [
10401
+ /* @__PURE__ */ jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Edit Items" }) }),
10402
+ /* @__PURE__ */ jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Loading data for the draft order, please wait..." }) })
10403
+ ] }) });
10404
+ };
10405
+ const ItemsForm = ({ preview, currencyCode }) => {
10406
+ var _a;
10407
+ const [isSubmitting, setIsSubmitting] = useState(false);
10408
+ const [modalContent, setModalContent] = useState(
10409
+ null
10410
+ );
10411
+ const { handleSuccess } = useRouteModal();
10412
+ const { searchValue, onSearchValueChange, query: query2 } = useDebouncedSearch();
10413
+ const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
10414
+ const { mutateAsync: requestOrderEdit } = useDraftOrderRequestEdit(preview.id);
10415
+ const itemCount = ((_a = preview.items) == null ? void 0 : _a.reduce((acc, item) => acc + item.quantity, 0)) || 0;
10416
+ const matches = useMemo(() => {
10417
+ return matchSorter(preview.items, query2, {
10418
+ keys: ["product_title", "variant_title", "variant_sku", "title"]
10419
+ });
10420
+ }, [preview.items, query2]);
10421
+ const onSubmit = async () => {
10422
+ setIsSubmitting(true);
10423
+ let requestSucceeded = false;
10424
+ await requestOrderEdit(void 0, {
10425
+ onError: (e) => {
10426
+ toast.error(`Failed to request order edit: ${e.message}`);
10418
10427
  },
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." }) })
10423
- ] }),
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" })
10447
- ] }) })
10448
- ]
10428
+ onSuccess: () => {
10429
+ requestSucceeded = true;
10430
+ }
10431
+ });
10432
+ if (!requestSucceeded) {
10433
+ setIsSubmitting(false);
10434
+ return;
10449
10435
  }
10436
+ await confirmOrderEdit(void 0, {
10437
+ onError: (e) => {
10438
+ toast.error(`Failed to confirm order edit: ${e.message}`);
10439
+ },
10440
+ onSuccess: () => {
10441
+ handleSuccess();
10442
+ },
10443
+ onSettled: () => {
10444
+ setIsSubmitting(false);
10445
+ }
10446
+ });
10447
+ };
10448
+ const onKeyDown = useCallback(
10449
+ (e) => {
10450
+ if (e.key === "Enter" && (e.ctrlKey || e.metaKey)) {
10451
+ if (modalContent || isSubmitting) {
10452
+ return;
10453
+ }
10454
+ onSubmit();
10455
+ }
10456
+ },
10457
+ [modalContent, isSubmitting, onSubmit]
10450
10458
  );
10451
- };
10452
- const columnHelper = createDataTableColumnHelper();
10453
- const useColumns = () => {
10454
- return useMemo(() => {
10455
- 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
- );
10459
+ useEffect(() => {
10460
+ document.addEventListener("keydown", onKeyDown);
10461
+ return () => {
10462
+ document.removeEventListener("keydown", onKeyDown);
10463
+ };
10464
+ }, [onKeyDown]);
10465
+ return /* @__PURE__ */ jsxs("div", { className: "flex h-full flex-col overflow-hidden", children: [
10466
+ /* @__PURE__ */ jsx(RouteFocusModal.Header, {}),
10467
+ /* @__PURE__ */ jsx(RouteFocusModal.Body, { className: "flex flex-1 flex-col overflow-hidden", children: /* @__PURE__ */ jsxs(
10468
+ StackedFocusModal,
10469
+ {
10470
+ id: STACKED_MODAL_ID,
10471
+ onOpenChangeCallback: (open) => {
10472
+ if (!open) {
10473
+ setModalContent(null);
10474
+ }
10495
10475
  },
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,
10476
+ children: [
10477
+ /* @__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: [
10478
+ /* @__PURE__ */ jsxs("div", { children: [
10479
+ /* @__PURE__ */ jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Items" }) }),
10480
+ /* @__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" }) })
10481
+ ] }),
10482
+ /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
10483
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-y-6", children: [
10484
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 items-center gap-3", children: [
10485
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
10486
+ /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: "Items" }),
10487
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Choose items from the product catalog." })
10488
+ ] }),
10489
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
10490
+ /* @__PURE__ */ jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsx(
10491
+ Input,
10492
+ {
10493
+ type: "search",
10494
+ placeholder: "Search items",
10495
+ value: searchValue,
10496
+ onChange: (e) => onSearchValueChange(e.target.value)
10497
+ }
10498
+ ) }),
10499
+ /* @__PURE__ */ jsxs(DropdownMenu, { children: [
10500
+ /* @__PURE__ */ jsx(DropdownMenu.Trigger, { asChild: true, children: /* @__PURE__ */ jsx(IconButton, { type: "button", children: /* @__PURE__ */ jsx(Plus, {}) }) }),
10501
+ /* @__PURE__ */ jsxs(DropdownMenu.Content, { children: [
10502
+ /* @__PURE__ */ jsx(
10503
+ StackedModalTrigger$1,
10504
+ {
10505
+ type: "add-items",
10506
+ setModalContent
10507
+ }
10508
+ ),
10509
+ /* @__PURE__ */ jsx(
10510
+ StackedModalTrigger$1,
10511
+ {
10512
+ type: "add-custom-item",
10513
+ setModalContent
10514
+ }
10515
+ )
10516
+ ] })
10517
+ ] })
10518
+ ] })
10519
+ ] }),
10520
+ /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-subtle shadow-elevation-card-rest rounded-xl", children: [
10521
+ /* @__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: [
10522
+ /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: "Item" }) }),
10523
+ /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: "Quantity" }) }),
10524
+ /* @__PURE__ */ jsx("div", { className: "text-right", children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: "Price" }) }),
10525
+ /* @__PURE__ */ jsx("div", {})
10526
+ ] }) }),
10527
+ /* @__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: [
10528
+ /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: "There are no items in this order" }),
10529
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Add items to the order to get started." })
10530
+ ] }) : matches.length > 0 ? matches == null ? void 0 : matches.map((item) => /* @__PURE__ */ jsx(
10531
+ Item,
10532
+ {
10533
+ item,
10534
+ preview,
10535
+ currencyCode
10536
+ },
10537
+ item.id
10538
+ )) : /* @__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: [
10539
+ /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: "No items found" }),
10540
+ /* @__PURE__ */ jsxs(Text, { size: "small", className: "text-ui-fg-subtle", children: [
10541
+ 'No items found for "',
10542
+ query2,
10543
+ '".'
10544
+ ] })
10545
+ ] }) })
10546
+ ] })
10547
+ ] }),
10548
+ /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
10549
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-[1fr_0.5fr_0.5fr] gap-3", children: [
10550
+ /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: "Subtotal" }) }),
10551
+ /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsxs(
10552
+ Text,
10553
+ {
10554
+ size: "small",
10555
+ leading: "compact",
10556
+ className: "text-ui-fg-subtle",
10557
+ children: [
10558
+ itemCount,
10559
+ " ",
10560
+ itemCount === 1 ? "item" : "items"
10561
+ ]
10562
+ }
10563
+ ) }),
10564
+ /* @__PURE__ */ jsx("div", { className: "text-right", children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: getStylizedAmount(preview.item_subtotal, currencyCode) }) })
10565
+ ] })
10566
+ ] }) }),
10567
+ modalContent && (modalContent === "add-items" ? /* @__PURE__ */ jsx(ExistingItemsForm, { orderId: preview.id, items: preview.items }) : modalContent === "add-custom-item" ? /* @__PURE__ */ jsx(
10568
+ CustomItemForm,
10505
10569
  {
10506
- content: getFullDate({ date: getValue(), includeTime: true }),
10507
- children: /* @__PURE__ */ jsx("span", { children: getFullDate({ date: getValue() }) })
10570
+ orderId: preview.id,
10571
+ currencyCode
10508
10572
  }
10509
- );
10510
- },
10511
- enableSorting: true,
10512
- sortAscLabel: "Oldest first",
10513
- sortDescLabel: "Newest first"
10514
- })
10515
- ];
10516
- }, []);
10573
+ ) : null)
10574
+ ]
10575
+ }
10576
+ ) }),
10577
+ /* @__PURE__ */ jsx(RouteFocusModal.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
10578
+ /* @__PURE__ */ jsx(RouteFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
10579
+ /* @__PURE__ */ jsx(
10580
+ Button,
10581
+ {
10582
+ size: "small",
10583
+ type: "button",
10584
+ onClick: onSubmit,
10585
+ isLoading: isSubmitting,
10586
+ children: "Save"
10587
+ }
10588
+ )
10589
+ ] }) })
10590
+ ] });
10517
10591
  };
10518
- const CustomItemForm = ({ orderId, currencyCode }) => {
10519
- const { setIsOpen } = useStackedModal();
10520
- const { mutateAsync: addItems } = useDraftOrderAddItems(orderId);
10592
+ const Item = ({ item, preview, currencyCode }) => {
10593
+ if (item.variant_id) {
10594
+ return /* @__PURE__ */ jsx(VariantItem, { item, preview, currencyCode });
10595
+ }
10596
+ return /* @__PURE__ */ jsx(CustomItem, { item, preview, currencyCode });
10597
+ };
10598
+ const VariantItem = ({ item, preview, currencyCode }) => {
10599
+ const [editing, setEditing] = useState(false);
10521
10600
  const form = useForm({
10522
10601
  defaultValues: {
10523
- title: "",
10524
- quantity: 1,
10525
- unit_price: ""
10602
+ quantity: item.quantity,
10603
+ unit_price: item.unit_price
10526
10604
  },
10527
- resolver: zodResolver(customItemSchema)
10605
+ resolver: zodResolver(variantItemSchema)
10528
10606
  });
10607
+ const actionId = useMemo(() => {
10608
+ var _a, _b;
10609
+ return (_b = (_a = item.actions) == null ? void 0 : _a.find((a) => a.action === "ITEM_ADD")) == null ? void 0 : _b.id;
10610
+ }, [item]);
10611
+ const { mutateAsync: updateActionItem, isPending: isUpdatingActionItem } = useDraftOrderUpdateActionItem(preview.id);
10612
+ const { mutateAsync: updateOriginalItem, isPending: isUpdatingOriginalItem } = useDraftOrderUpdateItem(preview.id);
10613
+ const isPending = isUpdatingActionItem || isUpdatingOriginalItem;
10529
10614
  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)
10615
+ if (convertNumber(data.unit_price) === item.unit_price && data.quantity === item.quantity) {
10616
+ setEditing(false);
10617
+ return;
10618
+ }
10619
+ if (!actionId) {
10620
+ await updateOriginalItem(
10621
+ {
10622
+ item_id: item.id,
10623
+ quantity: data.quantity,
10624
+ unit_price: convertNumber(data.unit_price)
10625
+ },
10626
+ {
10627
+ onSuccess: () => {
10628
+ setEditing(false);
10629
+ },
10630
+ onError: (e) => {
10631
+ toast.error(e.message);
10537
10632
  }
10538
- ]
10633
+ }
10634
+ );
10635
+ return;
10636
+ }
10637
+ await updateActionItem(
10638
+ {
10639
+ action_id: actionId,
10640
+ quantity: data.quantity,
10641
+ unit_price: convertNumber(data.unit_price)
10539
10642
  },
10540
10643
  {
10541
10644
  onSuccess: () => {
10542
- setIsOpen(STACKED_MODAL_ID, false);
10645
+ setEditing(false);
10543
10646
  },
10544
10647
  onError: (e) => {
10545
10648
  toast.error(e.message);
@@ -10547,754 +10650,578 @@ const CustomItemForm = ({ orderId, currencyCode }) => {
10547
10650
  }
10548
10651
  );
10549
10652
  });
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" }),
10653
+ 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: [
10654
+ /* @__PURE__ */ jsxs("div", { className: "flex w-full items-center gap-x-3", children: [
10558
10655
  /* @__PURE__ */ jsx(
10559
- Form$2.Field,
10656
+ Thumbnail,
10560
10657
  {
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
- ] }) })
10658
+ thumbnail: item.thumbnail,
10659
+ alt: item.product_title ?? void 0
10573
10660
  }
10574
10661
  ),
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
- ] }) })
10662
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
10663
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-1", children: [
10664
+ /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: item.product_title }),
10665
+ /* @__PURE__ */ jsxs(
10666
+ Text,
10667
+ {
10668
+ size: "small",
10669
+ leading: "compact",
10670
+ className: "text-ui-fg-subtle",
10671
+ children: [
10672
+ "(",
10673
+ item.variant_title,
10674
+ ")"
10675
+ ]
10676
+ }
10677
+ )
10678
+ ] }),
10679
+ /* @__PURE__ */ jsx(
10680
+ Text,
10681
+ {
10682
+ size: "small",
10683
+ leading: "compact",
10684
+ className: "text-ui-fg-subtle",
10685
+ children: item.variant_sku
10686
+ }
10687
+ )
10688
+ ] })
10689
+ ] }),
10690
+ editing ? /* @__PURE__ */ jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsx(
10691
+ Form$2.Field,
10692
+ {
10693
+ control: form.control,
10694
+ name: "quantity",
10695
+ render: ({ field }) => {
10696
+ return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(NumberInput, { ...field }) }) });
10599
10697
  }
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
- ] }) })
10698
+ }
10699
+ ) }) : /* @__PURE__ */ jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: item.quantity }) }),
10700
+ editing ? /* @__PURE__ */ jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsx(
10701
+ Form$2.Field,
10702
+ {
10703
+ control: form.control,
10704
+ name: "unit_price",
10705
+ render: ({ field: { onChange, ...field } }) => {
10706
+ return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
10707
+ CurrencyInput,
10708
+ {
10709
+ ...field,
10710
+ symbol: getNativeSymbol(currencyCode),
10711
+ code: currencyCode,
10712
+ onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value)
10713
+ }
10714
+ ) }) });
10617
10715
  }
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
- ] }) })
10716
+ }
10717
+ ) }) : /* @__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) }) }),
10718
+ /* @__PURE__ */ jsx(
10719
+ IconButton,
10720
+ {
10721
+ type: "button",
10722
+ size: "small",
10723
+ onClick: editing ? onSubmit : () => {
10724
+ setEditing(true);
10725
+ },
10726
+ disabled: isPending,
10727
+ children: editing ? /* @__PURE__ */ jsx(Check, {}) : /* @__PURE__ */ jsx(PencilSquare, {})
10728
+ }
10729
+ )
10624
10730
  ] }) }) });
10625
10731
  };
10626
- const customItemSchema = objectType({
10627
- title: stringType().min(1),
10732
+ const variantItemSchema = objectType({
10628
10733
  quantity: numberType(),
10629
10734
  unit_price: unionType([numberType(), stringType()])
10630
10735
  });
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 = () => {
10676
- const { id } = useParams();
10677
- const { order, isPending, isError, error } = useOrder(id, {
10678
- fields: "metadata"
10679
- });
10680
- if (isError) {
10681
- throw error;
10682
- }
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 })
10690
- ] });
10691
- };
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 }) => {
10695
- const { handleSuccess } = useRouteModal();
10696
- const hasUneditableRows = getHasUneditableRows(metadata);
10697
- const { mutateAsync, isPending } = useUpdateDraftOrder(orderId);
10736
+ const CustomItem = ({ item, preview, currencyCode }) => {
10737
+ const [editing, setEditing] = useState(false);
10738
+ const { quantity, unit_price, title } = item;
10698
10739
  const form = useForm({
10699
10740
  defaultValues: {
10700
- metadata: getDefaultValues(metadata)
10741
+ title,
10742
+ quantity,
10743
+ unit_price
10701
10744
  },
10702
- resolver: zodResolver(MetadataSchema)
10703
- });
10704
- const handleSubmit = form.handleSubmit(async (data) => {
10705
- const parsedData = parseValues(data);
10706
- await mutateAsync(
10707
- {
10708
- metadata: parsedData
10709
- },
10710
- {
10711
- onSuccess: () => {
10712
- toast.success("Metadata updated");
10713
- handleSuccess();
10714
- },
10715
- onError: (error) => {
10716
- toast.error(error.message);
10717
- }
10718
- }
10719
- );
10720
- });
10721
- const { fields, insert, remove } = useFieldArray({
10722
- control: form.control,
10723
- name: "metadata"
10745
+ resolver: zodResolver(customItemSchema)
10724
10746
  });
10725
- function deleteRow(index) {
10726
- remove(index);
10727
- if (fields.length === 1) {
10728
- insert(0, {
10729
- key: "",
10730
- value: "",
10731
- disabled: false
10732
- });
10733
- }
10734
- }
10735
- function insertRow(index, position) {
10736
- insert(index + (position === "above" ? 0 : 1), {
10737
- key: "",
10738
- value: "",
10739
- disabled: false
10747
+ useEffect(() => {
10748
+ form.reset({
10749
+ title,
10750
+ quantity,
10751
+ unit_price
10740
10752
  });
10741
- }
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." })
10875
- ] }),
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" })
10905
- ] }) })
10906
- ] });
10907
- };
10908
- const EDITABLE_TYPES = ["string", "number", "boolean"];
10909
- function getDefaultValues(metadata) {
10910
- if (!metadata || !Object.keys(metadata).length) {
10911
- return [
10912
- {
10913
- key: "",
10914
- value: "",
10915
- disabled: false
10916
- }
10917
- ];
10918
- }
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);
10753
+ }, [form, title, quantity, unit_price]);
10754
+ const actionId = useMemo(() => {
10755
+ var _a, _b;
10756
+ return (_b = (_a = item.actions) == null ? void 0 : _a.find((a) => a.action === "ITEM_ADD")) == null ? void 0 : _b.id;
10757
+ }, [item]);
10758
+ const { mutateAsync: updateActionItem, isPending: isUpdatingActionItem } = useDraftOrderUpdateActionItem(preview.id);
10759
+ const { mutateAsync: removeActionItem, isPending: isRemovingActionItem } = useDraftOrderRemoveActionItem(preview.id);
10760
+ const { mutateAsync: updateOriginalItem, isPending: isUpdatingOriginalItem } = useDraftOrderUpdateItem(preview.id);
10761
+ const isPending = isUpdatingActionItem || isUpdatingOriginalItem;
10762
+ const onSubmit = form.handleSubmit(async (data) => {
10763
+ if (convertNumber(data.unit_price) === item.unit_price && data.quantity === item.quantity && data.title === item.title) {
10764
+ setEditing(false);
10765
+ return;
10930
10766
  }
10931
- return {
10932
- key,
10933
- value: stringValue,
10934
- original_key: key
10935
- };
10936
- });
10937
- }
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;
10943
- }
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) {
10767
+ if (!actionId) {
10768
+ await updateOriginalItem(
10769
+ {
10770
+ item_id: item.id,
10771
+ quantity: data.quantity,
10772
+ unit_price: convertNumber(data.unit_price)
10773
+ },
10774
+ {
10775
+ onSuccess: () => {
10776
+ setEditing(false);
10777
+ },
10778
+ onError: (e) => {
10779
+ toast.error(e.message);
10780
+ }
10781
+ }
10782
+ );
10950
10783
  return;
10951
10784
  }
10952
- if (disabled) {
10953
- update[key] = value;
10785
+ if (data.quantity === 0) {
10786
+ await removeActionItem(actionId, {
10787
+ onSuccess: () => {
10788
+ setEditing(false);
10789
+ },
10790
+ onError: (e) => {
10791
+ toast.error(e.message);
10792
+ }
10793
+ });
10954
10794
  return;
10955
10795
  }
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;
10796
+ await updateActionItem(
10797
+ {
10798
+ action_id: actionId,
10799
+ quantity: data.quantity,
10800
+ unit_price: convertNumber(data.unit_price)
10801
+ },
10802
+ {
10803
+ onSuccess: () => {
10804
+ setEditing(false);
10805
+ },
10806
+ onError: (e) => {
10807
+ toast.error(e.message);
10808
+ }
10968
10809
  }
10969
- }
10970
- });
10971
- return update;
10972
- }
10973
- function getHasUneditableRows(metadata) {
10974
- if (!metadata) {
10975
- return false;
10976
- }
10977
- return Object.values(metadata).some(
10978
- (value) => !EDITABLE_TYPES.includes(typeof value)
10979
- );
10980
- }
10981
- const PROMOTION_QUERY_KEY = "promotions";
10982
- const promotionsQueryKeys = {
10983
- list: (query2) => [
10984
- PROMOTION_QUERY_KEY,
10985
- query2 ? query2 : void 0
10986
- ],
10987
- detail: (id, query2) => [
10988
- PROMOTION_QUERY_KEY,
10989
- id,
10990
- query2 ? query2 : void 0
10991
- ]
10992
- };
10993
- const usePromotions = (query2, options) => {
10994
- const { data, ...rest } = useQuery({
10995
- queryKey: promotionsQueryKeys.list(query2),
10996
- queryFn: async () => sdk.admin.promotion.list(query2),
10997
- ...options
10810
+ );
10998
10811
  });
10999
- return { ...data, ...rest };
10812
+ 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: [
10813
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-3", children: [
10814
+ /* @__PURE__ */ jsx(
10815
+ Thumbnail,
10816
+ {
10817
+ thumbnail: item.thumbnail,
10818
+ alt: item.title ?? void 0
10819
+ }
10820
+ ),
10821
+ editing ? /* @__PURE__ */ jsx(
10822
+ Form$2.Field,
10823
+ {
10824
+ control: form.control,
10825
+ name: "title",
10826
+ render: ({ field }) => {
10827
+ return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }) });
10828
+ }
10829
+ }
10830
+ ) : /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: item.title })
10831
+ ] }),
10832
+ editing ? /* @__PURE__ */ jsx(
10833
+ Form$2.Field,
10834
+ {
10835
+ control: form.control,
10836
+ name: "quantity",
10837
+ render: ({ field }) => {
10838
+ return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(NumberInput, { ...field }) }) });
10839
+ }
10840
+ }
10841
+ ) : /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: item.quantity }),
10842
+ editing ? /* @__PURE__ */ jsx(
10843
+ Form$2.Field,
10844
+ {
10845
+ control: form.control,
10846
+ name: "unit_price",
10847
+ render: ({ field: { onChange, ...field } }) => {
10848
+ return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
10849
+ CurrencyInput,
10850
+ {
10851
+ ...field,
10852
+ symbol: getNativeSymbol(currencyCode),
10853
+ code: currencyCode,
10854
+ onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value)
10855
+ }
10856
+ ) }) });
10857
+ }
10858
+ }
10859
+ ) : /* @__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) }) }),
10860
+ /* @__PURE__ */ jsx(
10861
+ IconButton,
10862
+ {
10863
+ type: "button",
10864
+ size: "small",
10865
+ onClick: editing ? onSubmit : () => {
10866
+ setEditing(true);
10867
+ },
10868
+ disabled: isPending,
10869
+ children: editing ? /* @__PURE__ */ jsx(Check, {}) : /* @__PURE__ */ jsx(PencilSquare, {})
10870
+ }
10871
+ )
10872
+ ] }) }) });
11000
10873
  };
11001
- const Promotions = () => {
11002
- const { id } = useParams();
11003
- const {
11004
- order: preview,
11005
- isError: isPreviewError,
11006
- error: previewError
11007
- } = useOrderPreview(id, void 0);
11008
- useInitiateOrderEdit({ preview });
11009
- const { onCancel } = useCancelOrderEdit({ preview });
11010
- if (isPreviewError) {
11011
- throw previewError;
11012
- }
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 })
11017
- ] });
10874
+ const StackedModalTrigger$1 = ({
10875
+ type,
10876
+ setModalContent
10877
+ }) => {
10878
+ const { setIsOpen } = useStackedModal();
10879
+ const onClick = useCallback(() => {
10880
+ setModalContent(type);
10881
+ setIsOpen(STACKED_MODAL_ID, true);
10882
+ }, [setModalContent, setIsOpen, type]);
10883
+ return /* @__PURE__ */ jsx(StackedFocusModal.Trigger, { asChild: true, children: /* @__PURE__ */ jsx(DropdownMenu.Item, { onClick, children: type === "add-items" ? "Add items" : "Add custom item" }) });
11018
10884
  };
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
11029
- },
11030
- {
11031
- enabled: !!promoIds.length
11032
- }
10885
+ const VARIANT_PREFIX = "items";
10886
+ const LIMIT = 50;
10887
+ const ExistingItemsForm = ({ orderId, items }) => {
10888
+ const { setIsOpen } = useStackedModal();
10889
+ const [rowSelection, setRowSelection] = useState(
10890
+ items.reduce((acc, item) => {
10891
+ acc[item.variant_id] = true;
10892
+ return acc;
10893
+ }, {})
11033
10894
  );
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
10895
+ useEffect(() => {
10896
+ setRowSelection(
10897
+ items.reduce((acc, item) => {
10898
+ if (item.variant_id) {
10899
+ acc[item.variant_id] = true;
11041
10900
  }
11042
- });
10901
+ return acc;
10902
+ }, {})
10903
+ );
10904
+ }, [items]);
10905
+ const { q, order, offset } = useQueryParams(
10906
+ ["q", "order", "offset"],
10907
+ VARIANT_PREFIX
10908
+ );
10909
+ const { variants, count, isPending, isError, error } = useProductVariants(
10910
+ {
10911
+ q,
10912
+ order,
10913
+ offset: offset ? parseInt(offset) : void 0,
10914
+ limit: LIMIT
11043
10915
  },
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) {
11053
- return;
10916
+ {
10917
+ placeholderData: keepPreviousData
11054
10918
  }
11055
- addPromotions(
10919
+ );
10920
+ const columns = useColumns();
10921
+ const { mutateAsync } = useDraftOrderAddItems(orderId);
10922
+ const onSubmit = async () => {
10923
+ const ids = Object.keys(rowSelection).filter(
10924
+ (id) => !items.find((i) => i.variant_id === id)
10925
+ );
10926
+ await mutateAsync(
11056
10927
  {
11057
- promo_codes: [value]
10928
+ items: ids.map((id) => ({
10929
+ variant_id: id,
10930
+ quantity: 1
10931
+ }))
11058
10932
  },
11059
10933
  {
10934
+ onSuccess: () => {
10935
+ setRowSelection({});
10936
+ setIsOpen(STACKED_MODAL_ID, false);
10937
+ },
11060
10938
  onError: (e) => {
11061
10939
  toast.error(e.message);
11062
- comboboxData.onSearchValueChange("");
11063
- setComboboxValue("");
11064
- },
11065
- onSuccess: () => {
11066
- comboboxData.onSearchValueChange("");
11067
- setComboboxValue("");
11068
10940
  }
11069
10941
  }
11070
10942
  );
11071
10943
  };
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
10944
  if (isError) {
11102
10945
  throw error;
11103
10946
  }
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." })
10947
+ return /* @__PURE__ */ jsxs(
10948
+ StackedFocusModal.Content,
10949
+ {
10950
+ onOpenAutoFocus: (e) => {
10951
+ e.preventDefault();
10952
+ const searchInput = document.querySelector(
10953
+ "[data-modal-id='modal-search-input']"
10954
+ );
10955
+ if (searchInput) {
10956
+ searchInput.focus();
10957
+ }
10958
+ },
10959
+ children: [
10960
+ /* @__PURE__ */ jsxs(StackedFocusModal.Header, { children: [
10961
+ /* @__PURE__ */ jsx(StackedFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Product Variants" }) }),
10962
+ /* @__PURE__ */ jsx(StackedFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Choose product variants to add to the order." }) })
11110
10963
  ] }),
11111
- /* @__PURE__ */ jsx(
11112
- Combobox,
10964
+ /* @__PURE__ */ jsx(StackedFocusModal.Body, { className: "flex-1 overflow-hidden", children: /* @__PURE__ */ jsx(
10965
+ DataTable,
11113
10966
  {
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
10967
+ data: variants,
10968
+ columns,
10969
+ isLoading: isPending,
10970
+ getRowId: (row) => row.id,
10971
+ rowCount: count,
10972
+ prefix: VARIANT_PREFIX,
10973
+ layout: "fill",
10974
+ rowSelection: {
10975
+ state: rowSelection,
10976
+ onRowSelectionChange: setRowSelection,
10977
+ enableRowSelection: (row) => {
10978
+ return !items.find((i) => i.variant_id === row.original.id);
10979
+ }
10980
+ },
10981
+ autoFocusSearch: true
11124
10982
  }
11125
- )
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
10983
+ ) }),
10984
+ /* @__PURE__ */ jsx(StackedFocusModal.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
10985
+ /* @__PURE__ */ jsx(StackedFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
10986
+ /* @__PURE__ */ jsx(Button, { size: "small", type: "button", onClick: onSubmit, children: "Update items" })
10987
+ ] }) })
10988
+ ]
10989
+ }
10990
+ );
10991
+ };
10992
+ const columnHelper = createDataTableColumnHelper();
10993
+ const useColumns = () => {
10994
+ return useMemo(() => {
10995
+ return [
10996
+ columnHelper.select(),
10997
+ columnHelper.accessor("product.title", {
10998
+ header: "Product",
10999
+ cell: ({ row }) => {
11000
+ var _a, _b, _c;
11001
+ return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-2", children: [
11002
+ /* @__PURE__ */ jsx(
11003
+ Thumbnail,
11004
+ {
11005
+ thumbnail: (_a = row.original.product) == null ? void 0 : _a.thumbnail,
11006
+ alt: (_b = row.original.product) == null ? void 0 : _b.title
11007
+ }
11008
+ ),
11009
+ /* @__PURE__ */ jsx("span", { children: (_c = row.original.product) == null ? void 0 : _c.title })
11010
+ ] });
11134
11011
  },
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,
11142
- {
11143
- size: "small",
11144
- type: "submit",
11145
- isLoading: isSubmitting || isAddingPromotions,
11146
- children: "Save"
11147
- }
11148
- )
11149
- ] }) })
11150
- ] });
11012
+ enableSorting: true
11013
+ }),
11014
+ columnHelper.accessor("title", {
11015
+ header: "Variant",
11016
+ enableSorting: true
11017
+ }),
11018
+ columnHelper.accessor("sku", {
11019
+ header: "SKU",
11020
+ cell: ({ getValue }) => {
11021
+ return getValue() ?? "-";
11022
+ },
11023
+ enableSorting: true
11024
+ }),
11025
+ columnHelper.accessor("updated_at", {
11026
+ header: "Updated",
11027
+ cell: ({ getValue }) => {
11028
+ return /* @__PURE__ */ jsx(
11029
+ Tooltip,
11030
+ {
11031
+ content: getFullDate({ date: getValue(), includeTime: true }),
11032
+ children: /* @__PURE__ */ jsx("span", { children: getFullDate({ date: getValue() }) })
11033
+ }
11034
+ );
11035
+ },
11036
+ enableSorting: true,
11037
+ sortAscLabel: "Oldest first",
11038
+ sortDescLabel: "Newest first"
11039
+ }),
11040
+ columnHelper.accessor("created_at", {
11041
+ header: "Created",
11042
+ cell: ({ getValue }) => {
11043
+ return /* @__PURE__ */ jsx(
11044
+ Tooltip,
11045
+ {
11046
+ content: getFullDate({ date: getValue(), includeTime: true }),
11047
+ children: /* @__PURE__ */ jsx("span", { children: getFullDate({ date: getValue() }) })
11048
+ }
11049
+ );
11050
+ },
11051
+ enableSorting: true,
11052
+ sortAscLabel: "Oldest first",
11053
+ sortDescLabel: "Newest first"
11054
+ })
11055
+ ];
11056
+ }, []);
11151
11057
  };
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(
11058
+ const CustomItemForm = ({ orderId, currencyCode }) => {
11059
+ const { setIsOpen } = useStackedModal();
11060
+ const { mutateAsync: addItems } = useDraftOrderAddItems(orderId);
11061
+ const form = useForm({
11062
+ defaultValues: {
11063
+ title: "",
11064
+ quantity: 1,
11065
+ unit_price: ""
11066
+ },
11067
+ resolver: zodResolver(customItemSchema)
11068
+ });
11069
+ const onSubmit = form.handleSubmit(async (data) => {
11070
+ await addItems(
11161
11071
  {
11162
- promo_codes: [promotion.code]
11072
+ items: [
11073
+ {
11074
+ title: data.title,
11075
+ quantity: data.quantity,
11076
+ unit_price: convertNumber(data.unit_price)
11077
+ }
11078
+ ]
11163
11079
  },
11164
11080
  {
11081
+ onSuccess: () => {
11082
+ setIsOpen(STACKED_MODAL_ID, false);
11083
+ },
11165
11084
  onError: (e) => {
11166
11085
  toast.error(e.message);
11167
11086
  }
11168
- }
11169
- );
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",
11087
+ }
11088
+ );
11089
+ });
11090
+ return /* @__PURE__ */ jsx(Form$2, { ...form, children: /* @__PURE__ */ jsx(KeyboundForm, { onSubmit, children: /* @__PURE__ */ jsxs(StackedFocusModal.Content, { children: [
11091
+ /* @__PURE__ */ jsx(StackedFocusModal.Header, {}),
11092
+ /* @__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: [
11093
+ /* @__PURE__ */ jsxs("div", { children: [
11094
+ /* @__PURE__ */ jsx(StackedFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Add custom item" }) }),
11095
+ /* @__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." }) })
11096
+ ] }),
11097
+ /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
11098
+ /* @__PURE__ */ jsx(
11099
+ Form$2.Field,
11100
+ {
11101
+ control: form.control,
11102
+ name: "title",
11103
+ render: ({ field }) => /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
11104
+ /* @__PURE__ */ jsxs("div", { children: [
11105
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Title" }),
11106
+ /* @__PURE__ */ jsx(Form$2.Hint, { children: "Enter the title of the item" })
11107
+ ] }),
11108
+ /* @__PURE__ */ jsxs("div", { children: [
11109
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
11110
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11111
+ ] })
11112
+ ] }) })
11113
+ }
11114
+ ),
11115
+ /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
11116
+ /* @__PURE__ */ jsx(
11117
+ Form$2.Field,
11177
11118
  {
11178
- "animate-pulse": isLoading
11119
+ control: form.control,
11120
+ name: "unit_price",
11121
+ render: ({ field: { onChange, ...field } }) => /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
11122
+ /* @__PURE__ */ jsxs("div", { children: [
11123
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Unit price" }),
11124
+ /* @__PURE__ */ jsx(Form$2.Hint, { children: "Enter the unit price of the item" })
11125
+ ] }),
11126
+ /* @__PURE__ */ jsxs("div", { children: [
11127
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
11128
+ CurrencyInput,
11129
+ {
11130
+ symbol: getNativeSymbol(currencyCode),
11131
+ code: currencyCode,
11132
+ onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value),
11133
+ ...field
11134
+ }
11135
+ ) }),
11136
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11137
+ ] })
11138
+ ] }) })
11179
11139
  }
11180
11140
  ),
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: "·" })
11141
+ /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
11142
+ /* @__PURE__ */ jsx(
11143
+ Form$2.Field,
11144
+ {
11145
+ control: form.control,
11146
+ name: "quantity",
11147
+ render: ({ field }) => /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
11148
+ /* @__PURE__ */ jsxs("div", { children: [
11149
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Quantity" }),
11150
+ /* @__PURE__ */ jsx(Form$2.Hint, { children: "Enter the quantity of the item" })
11188
11151
  ] }),
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, {})
11201
- }
11202
- )
11203
- ]
11204
- },
11205
- promotion.id
11206
- );
11152
+ /* @__PURE__ */ jsxs("div", { className: "w-full flex-1", children: [
11153
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsx(NumberInput, { ...field, className: "w-full" }) }) }),
11154
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11155
+ ] })
11156
+ ] }) })
11157
+ }
11158
+ )
11159
+ ] }) }) }),
11160
+ /* @__PURE__ */ jsx(StackedFocusModal.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
11161
+ /* @__PURE__ */ jsx(StackedFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
11162
+ /* @__PURE__ */ jsx(Button, { size: "small", type: "button", onClick: onSubmit, children: "Add item" })
11163
+ ] }) })
11164
+ ] }) }) });
11207
11165
  };
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
11166
+ const customItemSchema = objectType({
11167
+ title: stringType().min(1),
11168
+ quantity: numberType(),
11169
+ unit_price: unionType([numberType(), stringType()])
11228
11170
  });
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);
11243
- }
11244
- }
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);
11252
- }
11253
- }
11254
- }
11255
- }
11256
- return Array.from(promotionIds);
11257
- }
11258
- const SalesChannel = () => {
11171
+ const ShippingAddress = () => {
11259
11172
  const { id } = useParams();
11260
- const { draft_order, isPending, isError, error } = useDraftOrder(
11261
- id,
11262
- {
11263
- fields: "+sales_channel_id"
11264
- },
11265
- {
11266
- enabled: !!id
11267
- }
11268
- );
11173
+ const { order, isPending, isError, error } = useOrder(id, {
11174
+ fields: "+shipping_address"
11175
+ });
11269
11176
  if (isError) {
11270
11177
  throw error;
11271
11178
  }
11272
- const ISrEADY = !!draft_order && !isPending;
11179
+ const isReady = !isPending && !!order;
11273
11180
  return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
11274
11181
  /* @__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" }) })
11182
+ /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Shipping Address" }) }),
11183
+ /* @__PURE__ */ jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Edit the shipping address for the draft order" }) })
11277
11184
  ] }),
11278
- ISrEADY && /* @__PURE__ */ jsx(SalesChannelForm, { order: draft_order })
11185
+ isReady && /* @__PURE__ */ jsx(ShippingAddressForm, { order })
11279
11186
  ] });
11280
11187
  };
11281
- const SalesChannelForm = ({ order }) => {
11188
+ const ShippingAddressForm = ({ order }) => {
11189
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
11282
11190
  const form = useForm({
11283
11191
  defaultValues: {
11284
- sales_channel_id: order.sales_channel_id || ""
11192
+ first_name: ((_a = order.shipping_address) == null ? void 0 : _a.first_name) ?? "",
11193
+ last_name: ((_b = order.shipping_address) == null ? void 0 : _b.last_name) ?? "",
11194
+ company: ((_c = order.shipping_address) == null ? void 0 : _c.company) ?? "",
11195
+ address_1: ((_d = order.shipping_address) == null ? void 0 : _d.address_1) ?? "",
11196
+ address_2: ((_e = order.shipping_address) == null ? void 0 : _e.address_2) ?? "",
11197
+ city: ((_f = order.shipping_address) == null ? void 0 : _f.city) ?? "",
11198
+ province: ((_g = order.shipping_address) == null ? void 0 : _g.province) ?? "",
11199
+ country_code: ((_h = order.shipping_address) == null ? void 0 : _h.country_code) ?? "",
11200
+ postal_code: ((_i = order.shipping_address) == null ? void 0 : _i.postal_code) ?? "",
11201
+ phone: ((_j = order.shipping_address) == null ? void 0 : _j.phone) ?? ""
11285
11202
  },
11286
- resolver: zodResolver(schema$3)
11203
+ resolver: zodResolver(schema$2)
11287
11204
  });
11288
11205
  const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
11289
11206
  const { handleSuccess } = useRouteModal();
11290
11207
  const onSubmit = form.handleSubmit(async (data) => {
11291
11208
  await mutateAsync(
11292
11209
  {
11293
- sales_channel_id: data.sales_channel_id
11210
+ shipping_address: {
11211
+ first_name: data.first_name,
11212
+ last_name: data.last_name,
11213
+ company: data.company,
11214
+ address_1: data.address_1,
11215
+ address_2: data.address_2,
11216
+ city: data.city,
11217
+ province: data.province,
11218
+ country_code: data.country_code,
11219
+ postal_code: data.postal_code,
11220
+ phone: data.phone
11221
+ }
11294
11222
  },
11295
11223
  {
11296
11224
  onSuccess: () => {
11297
- toast.success("Sales channel updated");
11298
11225
  handleSuccess();
11299
11226
  },
11300
11227
  onError: (error) => {
@@ -11309,7 +11236,132 @@ const SalesChannelForm = ({ order }) => {
11309
11236
  className: "flex flex-1 flex-col overflow-hidden",
11310
11237
  onSubmit,
11311
11238
  children: [
11312
- /* @__PURE__ */ jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsx(SalesChannelField, { control: form.control, order }) }),
11239
+ /* @__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: [
11240
+ /* @__PURE__ */ jsx(
11241
+ Form$2.Field,
11242
+ {
11243
+ control: form.control,
11244
+ name: "country_code",
11245
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
11246
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Country" }),
11247
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(CountrySelect, { ...field }) }),
11248
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11249
+ ] })
11250
+ }
11251
+ ),
11252
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
11253
+ /* @__PURE__ */ jsx(
11254
+ Form$2.Field,
11255
+ {
11256
+ control: form.control,
11257
+ name: "first_name",
11258
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
11259
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "First name" }),
11260
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
11261
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11262
+ ] })
11263
+ }
11264
+ ),
11265
+ /* @__PURE__ */ jsx(
11266
+ Form$2.Field,
11267
+ {
11268
+ control: form.control,
11269
+ name: "last_name",
11270
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
11271
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Last name" }),
11272
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
11273
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11274
+ ] })
11275
+ }
11276
+ )
11277
+ ] }),
11278
+ /* @__PURE__ */ jsx(
11279
+ Form$2.Field,
11280
+ {
11281
+ control: form.control,
11282
+ name: "company",
11283
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
11284
+ /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Company" }),
11285
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
11286
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11287
+ ] })
11288
+ }
11289
+ ),
11290
+ /* @__PURE__ */ jsx(
11291
+ Form$2.Field,
11292
+ {
11293
+ control: form.control,
11294
+ name: "address_1",
11295
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
11296
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Address" }),
11297
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
11298
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11299
+ ] })
11300
+ }
11301
+ ),
11302
+ /* @__PURE__ */ jsx(
11303
+ Form$2.Field,
11304
+ {
11305
+ control: form.control,
11306
+ name: "address_2",
11307
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
11308
+ /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Apartment, suite, etc." }),
11309
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
11310
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11311
+ ] })
11312
+ }
11313
+ ),
11314
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
11315
+ /* @__PURE__ */ jsx(
11316
+ Form$2.Field,
11317
+ {
11318
+ control: form.control,
11319
+ name: "postal_code",
11320
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
11321
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Postal code" }),
11322
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
11323
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11324
+ ] })
11325
+ }
11326
+ ),
11327
+ /* @__PURE__ */ jsx(
11328
+ Form$2.Field,
11329
+ {
11330
+ control: form.control,
11331
+ name: "city",
11332
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
11333
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "City" }),
11334
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
11335
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11336
+ ] })
11337
+ }
11338
+ )
11339
+ ] }),
11340
+ /* @__PURE__ */ jsx(
11341
+ Form$2.Field,
11342
+ {
11343
+ control: form.control,
11344
+ name: "province",
11345
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
11346
+ /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Province / State" }),
11347
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
11348
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11349
+ ] })
11350
+ }
11351
+ ),
11352
+ /* @__PURE__ */ jsx(
11353
+ Form$2.Field,
11354
+ {
11355
+ control: form.control,
11356
+ name: "phone",
11357
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
11358
+ /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Phone" }),
11359
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
11360
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11361
+ ] })
11362
+ }
11363
+ )
11364
+ ] }) }),
11313
11365
  /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
11314
11366
  /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
11315
11367
  /* @__PURE__ */ jsx(Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
@@ -11318,49 +11370,7 @@ const SalesChannelForm = ({ order }) => {
11318
11370
  }
11319
11371
  ) });
11320
11372
  };
11321
- const SalesChannelField = ({ control, order }) => {
11322
- const salesChannels = useComboboxData({
11323
- queryFn: async (params) => {
11324
- return await sdk.admin.salesChannel.list(params);
11325
- },
11326
- queryKey: ["sales-channels"],
11327
- getOptions: (data) => {
11328
- return data.sales_channels.map((salesChannel) => ({
11329
- label: salesChannel.name,
11330
- value: salesChannel.id
11331
- }));
11332
- },
11333
- defaultValue: order.sales_channel_id || void 0
11334
- });
11335
- return /* @__PURE__ */ jsx(
11336
- Form$2.Field,
11337
- {
11338
- control,
11339
- name: "sales_channel_id",
11340
- render: ({ field }) => {
11341
- return /* @__PURE__ */ jsxs(Form$2.Item, { children: [
11342
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Sales Channel" }),
11343
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
11344
- Combobox,
11345
- {
11346
- options: salesChannels.options,
11347
- fetchNextPage: salesChannels.fetchNextPage,
11348
- isFetchingNextPage: salesChannels.isFetchingNextPage,
11349
- searchValue: salesChannels.searchValue,
11350
- onSearchValueChange: salesChannels.onSearchValueChange,
11351
- placeholder: "Select sales channel",
11352
- ...field
11353
- }
11354
- ) }),
11355
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11356
- ] });
11357
- }
11358
- }
11359
- );
11360
- };
11361
- const schema$3 = objectType({
11362
- sales_channel_id: stringType().min(1)
11363
- });
11373
+ const schema$2 = addressSchema;
11364
11374
  const STACKED_FOCUS_MODAL_ID = "shipping-form";
11365
11375
  const Shipping = () => {
11366
11376
  var _a;
@@ -12079,298 +12089,478 @@ const ShippingOptionField = ({
12079
12089
  const shippingOptions = useComboboxData({
12080
12090
  queryKey: ["shipping_options", locationId, shippingProfileId],
12081
12091
  queryFn: async (params) => {
12082
- return await sdk.admin.shippingOption.list({
12083
- ...params,
12084
- stock_location_id: locationId,
12085
- shipping_profile_id: shippingProfileId
12086
- });
12092
+ return await sdk.admin.shippingOption.list({
12093
+ ...params,
12094
+ stock_location_id: locationId,
12095
+ shipping_profile_id: shippingProfileId
12096
+ });
12097
+ },
12098
+ getOptions: (data) => {
12099
+ return data.shipping_options.map((option) => {
12100
+ var _a2;
12101
+ if ((_a2 = option.rules) == null ? void 0 : _a2.find(
12102
+ (r) => r.attribute === "is_return" && r.value === "true"
12103
+ )) {
12104
+ return void 0;
12105
+ }
12106
+ return {
12107
+ label: option.name,
12108
+ value: option.id
12109
+ };
12110
+ }).filter(Boolean);
12111
+ },
12112
+ enabled: !!locationId && !!shippingProfileId,
12113
+ defaultValue: ((_a = preview.shipping_methods[0]) == null ? void 0 : _a.shipping_option_id) || void 0
12114
+ });
12115
+ const tooltipContent = !locationId && !shippingProfileId ? "Choose a location and shipping profile first." : !locationId ? "Choose a location first." : "Choose a shipping profile first.";
12116
+ return /* @__PURE__ */ jsx(
12117
+ Form$2.Field,
12118
+ {
12119
+ control,
12120
+ name: "shipping_option_id",
12121
+ render: ({ field }) => {
12122
+ return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
12123
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
12124
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Shipping option" }),
12125
+ /* @__PURE__ */ jsx(Form$2.Hint, { children: "Choose the shipping option to use." })
12126
+ ] }),
12127
+ /* @__PURE__ */ jsx(
12128
+ ConditionalTooltip,
12129
+ {
12130
+ content: tooltipContent,
12131
+ showTooltip: !locationId || !shippingProfileId,
12132
+ children: /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
12133
+ Combobox,
12134
+ {
12135
+ options: shippingOptions.options,
12136
+ fetchNextPage: shippingOptions.fetchNextPage,
12137
+ isFetchingNextPage: shippingOptions.isFetchingNextPage,
12138
+ searchValue: shippingOptions.searchValue,
12139
+ onSearchValueChange: shippingOptions.onSearchValueChange,
12140
+ placeholder: "Select shipping option",
12141
+ ...field,
12142
+ disabled: !locationId || !shippingProfileId
12143
+ }
12144
+ ) }) })
12145
+ }
12146
+ )
12147
+ ] }) });
12148
+ }
12149
+ }
12150
+ );
12151
+ };
12152
+ const CustomAmountField = ({
12153
+ control,
12154
+ currencyCode
12155
+ }) => {
12156
+ return /* @__PURE__ */ jsx(
12157
+ Form$2.Field,
12158
+ {
12159
+ control,
12160
+ name: "custom_amount",
12161
+ render: ({ field: { onChange, ...field } }) => {
12162
+ return /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
12163
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
12164
+ /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Custom amount" }),
12165
+ /* @__PURE__ */ jsx(Form$2.Hint, { children: "Set a custom amount for the shipping option." })
12166
+ ] }),
12167
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
12168
+ CurrencyInput,
12169
+ {
12170
+ ...field,
12171
+ onValueChange: (value) => onChange(value),
12172
+ symbol: getNativeSymbol(currencyCode),
12173
+ code: currencyCode
12174
+ }
12175
+ ) })
12176
+ ] });
12177
+ }
12178
+ }
12179
+ );
12180
+ };
12181
+ const SalesChannel = () => {
12182
+ const { id } = useParams();
12183
+ const { draft_order, isPending, isError, error } = useDraftOrder(
12184
+ id,
12185
+ {
12186
+ fields: "+sales_channel_id"
12187
+ },
12188
+ {
12189
+ enabled: !!id
12190
+ }
12191
+ );
12192
+ if (isError) {
12193
+ throw error;
12194
+ }
12195
+ const ISrEADY = !!draft_order && !isPending;
12196
+ return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
12197
+ /* @__PURE__ */ jsxs(RouteDrawer.Header, { children: [
12198
+ /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Sales Channel" }) }),
12199
+ /* @__PURE__ */ jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Update which sales channel the draft order is associated with" }) })
12200
+ ] }),
12201
+ ISrEADY && /* @__PURE__ */ jsx(SalesChannelForm, { order: draft_order })
12202
+ ] });
12203
+ };
12204
+ const SalesChannelForm = ({ order }) => {
12205
+ const form = useForm({
12206
+ defaultValues: {
12207
+ sales_channel_id: order.sales_channel_id || ""
12208
+ },
12209
+ resolver: zodResolver(schema$1)
12210
+ });
12211
+ const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
12212
+ const { handleSuccess } = useRouteModal();
12213
+ const onSubmit = form.handleSubmit(async (data) => {
12214
+ await mutateAsync(
12215
+ {
12216
+ sales_channel_id: data.sales_channel_id
12217
+ },
12218
+ {
12219
+ onSuccess: () => {
12220
+ toast.success("Sales channel updated");
12221
+ handleSuccess();
12222
+ },
12223
+ onError: (error) => {
12224
+ toast.error(error.message);
12225
+ }
12226
+ }
12227
+ );
12228
+ });
12229
+ return /* @__PURE__ */ jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxs(
12230
+ KeyboundForm,
12231
+ {
12232
+ className: "flex flex-1 flex-col overflow-hidden",
12233
+ onSubmit,
12234
+ children: [
12235
+ /* @__PURE__ */ jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsx(SalesChannelField, { control: form.control, order }) }),
12236
+ /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
12237
+ /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
12238
+ /* @__PURE__ */ jsx(Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
12239
+ ] }) })
12240
+ ]
12241
+ }
12242
+ ) });
12243
+ };
12244
+ const SalesChannelField = ({ control, order }) => {
12245
+ const salesChannels = useComboboxData({
12246
+ queryFn: async (params) => {
12247
+ return await sdk.admin.salesChannel.list(params);
12087
12248
  },
12249
+ queryKey: ["sales-channels"],
12088
12250
  getOptions: (data) => {
12089
- return data.shipping_options.map((option) => {
12090
- var _a2;
12091
- if ((_a2 = option.rules) == null ? void 0 : _a2.find(
12092
- (r) => r.attribute === "is_return" && r.value === "true"
12093
- )) {
12094
- return void 0;
12095
- }
12096
- return {
12097
- label: option.name,
12098
- value: option.id
12099
- };
12100
- }).filter(Boolean);
12251
+ return data.sales_channels.map((salesChannel) => ({
12252
+ label: salesChannel.name,
12253
+ value: salesChannel.id
12254
+ }));
12101
12255
  },
12102
- enabled: !!locationId && !!shippingProfileId,
12103
- defaultValue: ((_a = preview.shipping_methods[0]) == null ? void 0 : _a.shipping_option_id) || void 0
12256
+ defaultValue: order.sales_channel_id || void 0
12104
12257
  });
12105
- const tooltipContent = !locationId && !shippingProfileId ? "Choose a location and shipping profile first." : !locationId ? "Choose a location first." : "Choose a shipping profile first.";
12106
12258
  return /* @__PURE__ */ jsx(
12107
12259
  Form$2.Field,
12108
12260
  {
12109
12261
  control,
12110
- name: "shipping_option_id",
12262
+ name: "sales_channel_id",
12111
12263
  render: ({ field }) => {
12112
- return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
12113
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
12114
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Shipping option" }),
12115
- /* @__PURE__ */ jsx(Form$2.Hint, { children: "Choose the shipping option to use." })
12116
- ] }),
12117
- /* @__PURE__ */ jsx(
12118
- ConditionalTooltip,
12119
- {
12120
- content: tooltipContent,
12121
- showTooltip: !locationId || !shippingProfileId,
12122
- children: /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
12123
- Combobox,
12124
- {
12125
- options: shippingOptions.options,
12126
- fetchNextPage: shippingOptions.fetchNextPage,
12127
- isFetchingNextPage: shippingOptions.isFetchingNextPage,
12128
- searchValue: shippingOptions.searchValue,
12129
- onSearchValueChange: shippingOptions.onSearchValueChange,
12130
- placeholder: "Select shipping option",
12131
- ...field,
12132
- disabled: !locationId || !shippingProfileId
12133
- }
12134
- ) }) })
12135
- }
12136
- )
12137
- ] }) });
12138
- }
12139
- }
12140
- );
12141
- };
12142
- const CustomAmountField = ({
12143
- control,
12144
- currencyCode
12145
- }) => {
12146
- return /* @__PURE__ */ jsx(
12147
- Form$2.Field,
12148
- {
12149
- control,
12150
- name: "custom_amount",
12151
- render: ({ field: { onChange, ...field } }) => {
12152
- return /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
12153
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
12154
- /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Custom amount" }),
12155
- /* @__PURE__ */ jsx(Form$2.Hint, { children: "Set a custom amount for the shipping option." })
12156
- ] }),
12264
+ return /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12265
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Sales Channel" }),
12157
12266
  /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
12158
- CurrencyInput,
12267
+ Combobox,
12159
12268
  {
12160
- ...field,
12161
- onValueChange: (value) => onChange(value),
12162
- symbol: getNativeSymbol(currencyCode),
12163
- code: currencyCode
12269
+ options: salesChannels.options,
12270
+ fetchNextPage: salesChannels.fetchNextPage,
12271
+ isFetchingNextPage: salesChannels.isFetchingNextPage,
12272
+ searchValue: salesChannels.searchValue,
12273
+ onSearchValueChange: salesChannels.onSearchValueChange,
12274
+ placeholder: "Select sales channel",
12275
+ ...field
12164
12276
  }
12165
- ) })
12277
+ ) }),
12278
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12166
12279
  ] });
12167
12280
  }
12168
12281
  }
12169
12282
  );
12170
12283
  };
12171
- const ShippingAddress = () => {
12284
+ const schema$1 = objectType({
12285
+ sales_channel_id: stringType().min(1)
12286
+ });
12287
+ const PROMOTION_QUERY_KEY = "promotions";
12288
+ const promotionsQueryKeys = {
12289
+ list: (query2) => [
12290
+ PROMOTION_QUERY_KEY,
12291
+ query2 ? query2 : void 0
12292
+ ],
12293
+ detail: (id, query2) => [
12294
+ PROMOTION_QUERY_KEY,
12295
+ id,
12296
+ query2 ? query2 : void 0
12297
+ ]
12298
+ };
12299
+ const usePromotions = (query2, options) => {
12300
+ const { data, ...rest } = useQuery({
12301
+ queryKey: promotionsQueryKeys.list(query2),
12302
+ queryFn: async () => sdk.admin.promotion.list(query2),
12303
+ ...options
12304
+ });
12305
+ return { ...data, ...rest };
12306
+ };
12307
+ const Promotions = () => {
12172
12308
  const { id } = useParams();
12173
- const { order, isPending, isError, error } = useOrder(id, {
12174
- fields: "+shipping_address"
12309
+ const {
12310
+ order: preview,
12311
+ isError: isPreviewError,
12312
+ error: previewError
12313
+ } = useOrderPreview(id, void 0);
12314
+ useInitiateOrderEdit({ preview });
12315
+ const { onCancel } = useCancelOrderEdit({ preview });
12316
+ if (isPreviewError) {
12317
+ throw previewError;
12318
+ }
12319
+ const isReady = !!preview;
12320
+ return /* @__PURE__ */ jsxs(RouteDrawer, { onClose: onCancel, children: [
12321
+ /* @__PURE__ */ jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Promotions" }) }) }),
12322
+ isReady && /* @__PURE__ */ jsx(PromotionForm, { preview })
12323
+ ] });
12324
+ };
12325
+ const PromotionForm = ({ preview }) => {
12326
+ const { items, shipping_methods } = preview;
12327
+ const [isSubmitting, setIsSubmitting] = useState(false);
12328
+ const [comboboxValue, setComboboxValue] = useState("");
12329
+ const { handleSuccess } = useRouteModal();
12330
+ const { mutateAsync: addPromotions, isPending: isAddingPromotions } = useDraftOrderAddPromotions(preview.id);
12331
+ const promoIds = getPromotionIds(items, shipping_methods);
12332
+ const { promotions, isPending, isError, error } = usePromotions(
12333
+ {
12334
+ id: promoIds
12335
+ },
12336
+ {
12337
+ enabled: !!promoIds.length
12338
+ }
12339
+ );
12340
+ const comboboxData = useComboboxData({
12341
+ queryKey: ["promotions", "combobox", promoIds],
12342
+ queryFn: async (params) => {
12343
+ return await sdk.admin.promotion.list({
12344
+ ...params,
12345
+ id: {
12346
+ $nin: promoIds
12347
+ }
12348
+ });
12349
+ },
12350
+ getOptions: (data) => {
12351
+ return data.promotions.map((promotion) => ({
12352
+ label: promotion.code,
12353
+ value: promotion.code
12354
+ }));
12355
+ }
12175
12356
  });
12357
+ const add = async (value) => {
12358
+ if (!value) {
12359
+ return;
12360
+ }
12361
+ addPromotions(
12362
+ {
12363
+ promo_codes: [value]
12364
+ },
12365
+ {
12366
+ onError: (e) => {
12367
+ toast.error(e.message);
12368
+ comboboxData.onSearchValueChange("");
12369
+ setComboboxValue("");
12370
+ },
12371
+ onSuccess: () => {
12372
+ comboboxData.onSearchValueChange("");
12373
+ setComboboxValue("");
12374
+ }
12375
+ }
12376
+ );
12377
+ };
12378
+ const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
12379
+ const { mutateAsync: requestOrderEdit } = useOrderEditRequest(preview.id);
12380
+ const onSubmit = async () => {
12381
+ setIsSubmitting(true);
12382
+ let requestSucceeded = false;
12383
+ await requestOrderEdit(void 0, {
12384
+ onError: (e) => {
12385
+ toast.error(e.message);
12386
+ },
12387
+ onSuccess: () => {
12388
+ requestSucceeded = true;
12389
+ }
12390
+ });
12391
+ if (!requestSucceeded) {
12392
+ setIsSubmitting(false);
12393
+ return;
12394
+ }
12395
+ await confirmOrderEdit(void 0, {
12396
+ onError: (e) => {
12397
+ toast.error(e.message);
12398
+ },
12399
+ onSuccess: () => {
12400
+ handleSuccess();
12401
+ },
12402
+ onSettled: () => {
12403
+ setIsSubmitting(false);
12404
+ }
12405
+ });
12406
+ };
12176
12407
  if (isError) {
12177
12408
  throw error;
12178
12409
  }
12179
- const isReady = !isPending && !!order;
12180
- return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
12181
- /* @__PURE__ */ jsxs(RouteDrawer.Header, { children: [
12182
- /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Shipping Address" }) }),
12183
- /* @__PURE__ */ jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Edit the shipping address for the draft order" }) })
12184
- ] }),
12185
- isReady && /* @__PURE__ */ jsx(ShippingAddressForm, { order })
12410
+ return /* @__PURE__ */ jsxs(KeyboundForm, { className: "flex flex-1 flex-col", onSubmit, children: [
12411
+ /* @__PURE__ */ jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-4", children: [
12412
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3", children: [
12413
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
12414
+ /* @__PURE__ */ jsx(Label$1, { size: "small", weight: "plus", htmlFor: "promotion-combobox", children: "Apply promotions" }),
12415
+ /* @__PURE__ */ jsx(Hint$1, { id: "promotion-combobox-hint", children: "Manage promotions that should be applied to the order." })
12416
+ ] }),
12417
+ /* @__PURE__ */ jsx(
12418
+ Combobox,
12419
+ {
12420
+ id: "promotion-combobox",
12421
+ "aria-describedby": "promotion-combobox-hint",
12422
+ isFetchingNextPage: comboboxData.isFetchingNextPage,
12423
+ fetchNextPage: comboboxData.fetchNextPage,
12424
+ options: comboboxData.options,
12425
+ onSearchValueChange: comboboxData.onSearchValueChange,
12426
+ searchValue: comboboxData.searchValue,
12427
+ disabled: comboboxData.disabled || isAddingPromotions,
12428
+ onChange: add,
12429
+ value: comboboxValue
12430
+ }
12431
+ )
12432
+ ] }),
12433
+ /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
12434
+ /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-2", children: promotions == null ? void 0 : promotions.map((promotion) => /* @__PURE__ */ jsx(
12435
+ PromotionItem,
12436
+ {
12437
+ promotion,
12438
+ orderId: preview.id,
12439
+ isLoading: isPending
12440
+ },
12441
+ promotion.id
12442
+ )) })
12443
+ ] }) }),
12444
+ /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
12445
+ /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
12446
+ /* @__PURE__ */ jsx(
12447
+ Button,
12448
+ {
12449
+ size: "small",
12450
+ type: "submit",
12451
+ isLoading: isSubmitting || isAddingPromotions,
12452
+ children: "Save"
12453
+ }
12454
+ )
12455
+ ] }) })
12186
12456
  ] });
12187
12457
  };
12188
- const ShippingAddressForm = ({ order }) => {
12189
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
12190
- const form = useForm({
12191
- defaultValues: {
12192
- first_name: ((_a = order.shipping_address) == null ? void 0 : _a.first_name) ?? "",
12193
- last_name: ((_b = order.shipping_address) == null ? void 0 : _b.last_name) ?? "",
12194
- company: ((_c = order.shipping_address) == null ? void 0 : _c.company) ?? "",
12195
- address_1: ((_d = order.shipping_address) == null ? void 0 : _d.address_1) ?? "",
12196
- address_2: ((_e = order.shipping_address) == null ? void 0 : _e.address_2) ?? "",
12197
- city: ((_f = order.shipping_address) == null ? void 0 : _f.city) ?? "",
12198
- province: ((_g = order.shipping_address) == null ? void 0 : _g.province) ?? "",
12199
- country_code: ((_h = order.shipping_address) == null ? void 0 : _h.country_code) ?? "",
12200
- postal_code: ((_i = order.shipping_address) == null ? void 0 : _i.postal_code) ?? "",
12201
- phone: ((_j = order.shipping_address) == null ? void 0 : _j.phone) ?? ""
12202
- },
12203
- resolver: zodResolver(schema$2)
12204
- });
12205
- const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
12206
- const { handleSuccess } = useRouteModal();
12207
- const onSubmit = form.handleSubmit(async (data) => {
12208
- await mutateAsync(
12458
+ const PromotionItem = ({
12459
+ promotion,
12460
+ orderId,
12461
+ isLoading
12462
+ }) => {
12463
+ var _a;
12464
+ const { mutateAsync: removePromotions, isPending } = useDraftOrderRemovePromotions(orderId);
12465
+ const onRemove = async () => {
12466
+ removePromotions(
12209
12467
  {
12210
- shipping_address: {
12211
- first_name: data.first_name,
12212
- last_name: data.last_name,
12213
- company: data.company,
12214
- address_1: data.address_1,
12215
- address_2: data.address_2,
12216
- city: data.city,
12217
- province: data.province,
12218
- country_code: data.country_code,
12219
- postal_code: data.postal_code,
12220
- phone: data.phone
12221
- }
12468
+ promo_codes: [promotion.code]
12222
12469
  },
12223
12470
  {
12224
- onSuccess: () => {
12225
- handleSuccess();
12226
- },
12227
- onError: (error) => {
12228
- toast.error(error.message);
12471
+ onError: (e) => {
12472
+ toast.error(e.message);
12229
12473
  }
12230
12474
  }
12231
12475
  );
12232
- });
12233
- return /* @__PURE__ */ jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxs(
12234
- KeyboundForm,
12476
+ };
12477
+ const displayValue = getDisplayValue(promotion);
12478
+ return /* @__PURE__ */ jsxs(
12479
+ "div",
12235
12480
  {
12236
- className: "flex flex-1 flex-col overflow-hidden",
12237
- onSubmit,
12481
+ className: clx(
12482
+ "bg-ui-bg-component shadow-elevation-card-rest flex items-center justify-between rounded-lg px-3 py-2",
12483
+ {
12484
+ "animate-pulse": isLoading
12485
+ }
12486
+ ),
12238
12487
  children: [
12239
- /* @__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: [
12240
- /* @__PURE__ */ jsx(
12241
- Form$2.Field,
12242
- {
12243
- control: form.control,
12244
- name: "country_code",
12245
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12246
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Country" }),
12247
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(CountrySelect, { ...field }) }),
12248
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12249
- ] })
12250
- }
12251
- ),
12252
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
12253
- /* @__PURE__ */ jsx(
12254
- Form$2.Field,
12255
- {
12256
- control: form.control,
12257
- name: "first_name",
12258
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12259
- /* @__PURE__ */ jsx(Form$2.Label, { children: "First name" }),
12260
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12261
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12262
- ] })
12263
- }
12264
- ),
12265
- /* @__PURE__ */ jsx(
12266
- Form$2.Field,
12267
- {
12268
- control: form.control,
12269
- name: "last_name",
12270
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12271
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Last name" }),
12272
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12273
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12274
- ] })
12275
- }
12276
- )
12277
- ] }),
12278
- /* @__PURE__ */ jsx(
12279
- Form$2.Field,
12280
- {
12281
- control: form.control,
12282
- name: "company",
12283
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12284
- /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Company" }),
12285
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12286
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12287
- ] })
12288
- }
12289
- ),
12290
- /* @__PURE__ */ jsx(
12291
- Form$2.Field,
12292
- {
12293
- control: form.control,
12294
- name: "address_1",
12295
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12296
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Address" }),
12297
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12298
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12299
- ] })
12300
- }
12301
- ),
12302
- /* @__PURE__ */ jsx(
12303
- Form$2.Field,
12304
- {
12305
- control: form.control,
12306
- name: "address_2",
12307
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12308
- /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Apartment, suite, etc." }),
12309
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12310
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12311
- ] })
12312
- }
12313
- ),
12314
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
12315
- /* @__PURE__ */ jsx(
12316
- Form$2.Field,
12317
- {
12318
- control: form.control,
12319
- name: "postal_code",
12320
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12321
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Postal code" }),
12322
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12323
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12324
- ] })
12325
- }
12326
- ),
12327
- /* @__PURE__ */ jsx(
12328
- Form$2.Field,
12329
- {
12330
- control: form.control,
12331
- name: "city",
12332
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12333
- /* @__PURE__ */ jsx(Form$2.Label, { children: "City" }),
12334
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12335
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12336
- ] })
12337
- }
12338
- )
12339
- ] }),
12340
- /* @__PURE__ */ jsx(
12341
- Form$2.Field,
12342
- {
12343
- control: form.control,
12344
- name: "province",
12345
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12346
- /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Province / State" }),
12347
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12348
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12349
- ] })
12350
- }
12351
- ),
12352
- /* @__PURE__ */ jsx(
12353
- Form$2.Field,
12354
- {
12355
- control: form.control,
12356
- name: "phone",
12357
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12358
- /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Phone" }),
12359
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12360
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12361
- ] })
12362
- }
12363
- )
12364
- ] }) }),
12365
- /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
12366
- /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
12367
- /* @__PURE__ */ jsx(Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
12368
- ] }) })
12488
+ /* @__PURE__ */ jsxs("div", { children: [
12489
+ /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: promotion.code }),
12490
+ /* @__PURE__ */ jsxs("div", { className: "text-ui-fg-subtle flex items-center gap-1.5", children: [
12491
+ displayValue && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
12492
+ /* @__PURE__ */ jsx(Text, { size: "small", leading: "compact", children: displayValue }),
12493
+ /* @__PURE__ */ jsx(Text, { size: "small", leading: "compact", children: "·" })
12494
+ ] }),
12495
+ /* @__PURE__ */ jsx(Text, { size: "small", leading: "compact", className: "capitalize", children: (_a = promotion.application_method) == null ? void 0 : _a.allocation })
12496
+ ] })
12497
+ ] }),
12498
+ /* @__PURE__ */ jsx(
12499
+ IconButton,
12500
+ {
12501
+ size: "small",
12502
+ type: "button",
12503
+ variant: "transparent",
12504
+ onClick: onRemove,
12505
+ isLoading: isPending || isLoading,
12506
+ children: /* @__PURE__ */ jsx(XMark, {})
12507
+ }
12508
+ )
12369
12509
  ]
12510
+ },
12511
+ promotion.id
12512
+ );
12513
+ };
12514
+ function getDisplayValue(promotion) {
12515
+ var _a, _b, _c, _d;
12516
+ const value = (_a = promotion.application_method) == null ? void 0 : _a.value;
12517
+ if (!value) {
12518
+ return null;
12519
+ }
12520
+ if (((_b = promotion.application_method) == null ? void 0 : _b.type) === "fixed") {
12521
+ const currency = (_c = promotion.application_method) == null ? void 0 : _c.currency_code;
12522
+ if (!currency) {
12523
+ return null;
12370
12524
  }
12371
- ) });
12525
+ return getLocaleAmount(value, currency);
12526
+ } else if (((_d = promotion.application_method) == null ? void 0 : _d.type) === "percentage") {
12527
+ return formatPercentage(value);
12528
+ }
12529
+ return null;
12530
+ }
12531
+ const formatter = new Intl.NumberFormat([], {
12532
+ style: "percent",
12533
+ minimumFractionDigits: 2
12534
+ });
12535
+ const formatPercentage = (value, isPercentageValue = false) => {
12536
+ let val = value || 0;
12537
+ if (!isPercentageValue) {
12538
+ val = val / 100;
12539
+ }
12540
+ return formatter.format(val);
12372
12541
  };
12373
- const schema$2 = addressSchema;
12542
+ function getPromotionIds(items, shippingMethods) {
12543
+ const promotionIds = /* @__PURE__ */ new Set();
12544
+ for (const item of items) {
12545
+ if (item.adjustments) {
12546
+ for (const adjustment of item.adjustments) {
12547
+ if (adjustment.promotion_id) {
12548
+ promotionIds.add(adjustment.promotion_id);
12549
+ }
12550
+ }
12551
+ }
12552
+ }
12553
+ for (const shippingMethod of shippingMethods) {
12554
+ if (shippingMethod.adjustments) {
12555
+ for (const adjustment of shippingMethod.adjustments) {
12556
+ if (adjustment.promotion_id) {
12557
+ promotionIds.add(adjustment.promotion_id);
12558
+ }
12559
+ }
12560
+ }
12561
+ }
12562
+ return Array.from(promotionIds);
12563
+ }
12374
12564
  const TransferOwnership = () => {
12375
12565
  const { id } = useParams();
12376
12566
  const { draft_order, isPending, isError, error } = useDraftOrder(id, {
@@ -12394,7 +12584,7 @@ const TransferOwnershipForm = ({ order }) => {
12394
12584
  defaultValues: {
12395
12585
  customer_id: order.customer_id || ""
12396
12586
  },
12397
- resolver: zodResolver(schema$1)
12587
+ resolver: zodResolver(schema)
12398
12588
  });
12399
12589
  const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
12400
12590
  const { handleSuccess } = useRouteModal();
@@ -12844,199 +13034,9 @@ const Illustration = () => {
12844
13034
  }
12845
13035
  );
12846
13036
  };
12847
- const schema$1 = objectType({
13037
+ const schema = objectType({
12848
13038
  customer_id: stringType().min(1)
12849
13039
  });
12850
- const BillingAddress = () => {
12851
- const { id } = useParams();
12852
- const { order, isPending, isError, error } = useOrder(id, {
12853
- fields: "+billing_address"
12854
- });
12855
- if (isError) {
12856
- throw error;
12857
- }
12858
- const isReady = !isPending && !!order;
12859
- return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
12860
- /* @__PURE__ */ jsxs(RouteDrawer.Header, { children: [
12861
- /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Billing Address" }) }),
12862
- /* @__PURE__ */ jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Edit the billing address for the draft order" }) })
12863
- ] }),
12864
- isReady && /* @__PURE__ */ jsx(BillingAddressForm, { order })
12865
- ] });
12866
- };
12867
- const BillingAddressForm = ({ order }) => {
12868
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
12869
- const form = useForm({
12870
- defaultValues: {
12871
- first_name: ((_a = order.billing_address) == null ? void 0 : _a.first_name) ?? "",
12872
- last_name: ((_b = order.billing_address) == null ? void 0 : _b.last_name) ?? "",
12873
- company: ((_c = order.billing_address) == null ? void 0 : _c.company) ?? "",
12874
- address_1: ((_d = order.billing_address) == null ? void 0 : _d.address_1) ?? "",
12875
- address_2: ((_e = order.billing_address) == null ? void 0 : _e.address_2) ?? "",
12876
- city: ((_f = order.billing_address) == null ? void 0 : _f.city) ?? "",
12877
- province: ((_g = order.billing_address) == null ? void 0 : _g.province) ?? "",
12878
- country_code: ((_h = order.billing_address) == null ? void 0 : _h.country_code) ?? "",
12879
- postal_code: ((_i = order.billing_address) == null ? void 0 : _i.postal_code) ?? "",
12880
- phone: ((_j = order.billing_address) == null ? void 0 : _j.phone) ?? ""
12881
- },
12882
- resolver: zodResolver(schema)
12883
- });
12884
- const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
12885
- const { handleSuccess } = useRouteModal();
12886
- const onSubmit = form.handleSubmit(async (data) => {
12887
- await mutateAsync(
12888
- { billing_address: data },
12889
- {
12890
- onSuccess: () => {
12891
- handleSuccess();
12892
- },
12893
- onError: (error) => {
12894
- toast.error(error.message);
12895
- }
12896
- }
12897
- );
12898
- });
12899
- return /* @__PURE__ */ jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxs(
12900
- KeyboundForm,
12901
- {
12902
- className: "flex flex-1 flex-col overflow-hidden",
12903
- onSubmit,
12904
- 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
- ] }) }),
13031
- /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
13032
- /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
13033
- /* @__PURE__ */ jsx(Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
13034
- ] }) })
13035
- ]
13036
- }
13037
- ) });
13038
- };
13039
- const schema = addressSchema;
13040
13040
  const widgetModule = { widgets: [] };
13041
13041
  const routeModule = {
13042
13042
  routes: [
@@ -13057,45 +13057,45 @@ const routeModule = {
13057
13057
  handle,
13058
13058
  loader,
13059
13059
  children: [
13060
- {
13061
- Component: CustomItems,
13062
- path: "/draft-orders/:id/custom-items"
13063
- },
13064
13060
  {
13065
13061
  Component: Email,
13066
13062
  path: "/draft-orders/:id/email"
13067
13063
  },
13068
13064
  {
13069
- Component: Items,
13070
- path: "/draft-orders/:id/items"
13065
+ Component: CustomItems,
13066
+ path: "/draft-orders/:id/custom-items"
13067
+ },
13068
+ {
13069
+ Component: BillingAddress,
13070
+ path: "/draft-orders/:id/billing-address"
13071
13071
  },
13072
13072
  {
13073
13073
  Component: Metadata,
13074
13074
  path: "/draft-orders/:id/metadata"
13075
13075
  },
13076
13076
  {
13077
- Component: Promotions,
13078
- path: "/draft-orders/:id/promotions"
13077
+ Component: Items,
13078
+ path: "/draft-orders/:id/items"
13079
13079
  },
13080
13080
  {
13081
- Component: SalesChannel,
13082
- path: "/draft-orders/:id/sales-channel"
13081
+ Component: ShippingAddress,
13082
+ path: "/draft-orders/:id/shipping-address"
13083
13083
  },
13084
13084
  {
13085
13085
  Component: Shipping,
13086
13086
  path: "/draft-orders/:id/shipping"
13087
13087
  },
13088
13088
  {
13089
- Component: ShippingAddress,
13090
- path: "/draft-orders/:id/shipping-address"
13089
+ Component: SalesChannel,
13090
+ path: "/draft-orders/:id/sales-channel"
13091
13091
  },
13092
13092
  {
13093
- Component: TransferOwnership,
13094
- path: "/draft-orders/:id/transfer-ownership"
13093
+ Component: Promotions,
13094
+ path: "/draft-orders/:id/promotions"
13095
13095
  },
13096
13096
  {
13097
- Component: BillingAddress,
13098
- path: "/draft-orders/:id/billing-address"
13097
+ Component: TransferOwnership,
13098
+ path: "/draft-orders/:id/transfer-ownership"
13099
13099
  }
13100
13100
  ]
13101
13101
  }