@medusajs/draft-order 2.10.4-snapshot-20250918173105 → 2.10.4-snapshot-20250922090257

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