@medusajs/draft-order 2.10.4-snapshot-20251003114416 → 2.10.4-snapshot-20251003141424

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4,7 +4,7 @@ import { Tooltip, DropdownMenu, clx, IconButton, useDataTable, DataTable as Data
4
4
  import { useQuery, useQueryClient, useMutation, keepPreviousData, useInfiniteQuery } from "@tanstack/react-query";
5
5
  import React, { useState, useCallback, useMemo, Fragment, createContext, forwardRef, useId, useContext, useTransition, useRef, useImperativeHandle, useDeferredValue, useEffect, Suspense } from "react";
6
6
  import { useSearchParams, Link, useNavigate, Outlet, useBlocker, useLocation, useParams } from "react-router-dom";
7
- import { EllipsisHorizontal, XMark, InformationCircleSolid, XMarkMini, TrianglesMini, CheckMini, EllipseMiniSolid, PlusMini, ExclamationCircleSolid, ArrowPath, FlyingBox, CurrencyDollar, Envelope, Channels, Trash, ArrowUpRightOnBox, TriangleDownMini, Check, SquareTwoStack, Photo, TriangleRightMini, Shopping, Buildings, TruckFast, Plus, ReceiptPercent, Minus, PencilSquare, EllipsisVertical, ArrowUpMini, ArrowDownMini } from "@medusajs/icons";
7
+ import { EllipsisHorizontal, XMark, InformationCircleSolid, XMarkMini, TrianglesMini, CheckMini, EllipseMiniSolid, PlusMini, ExclamationCircleSolid, ArrowPath, FlyingBox, CurrencyDollar, Envelope, Channels, Trash, ArrowUpRightOnBox, TriangleDownMini, Check, SquareTwoStack, Photo, TriangleRightMini, Shopping, Buildings, TruckFast, Plus, ReceiptPercent, EllipsisVertical, ArrowUpMini, ArrowDownMini, Minus, PencilSquare } from "@medusajs/icons";
8
8
  import Medusa from "@medusajs/js-sdk";
9
9
  import { format, formatDistance, sub, subDays, subMonths } from "date-fns";
10
10
  import { enUS } from "date-fns/locale";
@@ -9567,10 +9567,31 @@ const ID = () => {
9567
9567
  /* @__PURE__ */ jsx(Outlet, {})
9568
9568
  ] });
9569
9569
  };
9570
- const BillingAddress = () => {
9570
+ const CustomItems = () => {
9571
+ return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
9572
+ /* @__PURE__ */ jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Custom Items" }) }) }),
9573
+ /* @__PURE__ */ jsx(CustomItemsForm, {})
9574
+ ] });
9575
+ };
9576
+ const CustomItemsForm = () => {
9577
+ const form = useForm({
9578
+ resolver: zodResolver(schema$5)
9579
+ });
9580
+ return /* @__PURE__ */ jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxs(KeyboundForm, { className: "flex flex-1 flex-col", children: [
9581
+ /* @__PURE__ */ jsx(RouteDrawer.Body, {}),
9582
+ /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
9583
+ /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
9584
+ /* @__PURE__ */ jsx(Button, { size: "small", type: "submit", children: "Save" })
9585
+ ] }) })
9586
+ ] }) });
9587
+ };
9588
+ const schema$5 = objectType({
9589
+ email: stringType().email()
9590
+ });
9591
+ const Email = () => {
9571
9592
  const { id } = useParams();
9572
9593
  const { order, isPending, isError, error } = useOrder(id, {
9573
- fields: "+billing_address"
9594
+ fields: "+email"
9574
9595
  });
9575
9596
  if (isError) {
9576
9597
  throw error;
@@ -9578,34 +9599,24 @@ const BillingAddress = () => {
9578
9599
  const isReady = !isPending && !!order;
9579
9600
  return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
9580
9601
  /* @__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" }) })
9602
+ /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Email" }) }),
9603
+ /* @__PURE__ */ jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Edit the email for the draft order" }) })
9583
9604
  ] }),
9584
- isReady && /* @__PURE__ */ jsx(BillingAddressForm, { order })
9605
+ isReady && /* @__PURE__ */ jsx(EmailForm, { order })
9585
9606
  ] });
9586
9607
  };
9587
- const BillingAddressForm = ({ order }) => {
9588
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
9608
+ const EmailForm = ({ order }) => {
9589
9609
  const form = useForm({
9590
9610
  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) ?? ""
9611
+ email: order.email ?? ""
9601
9612
  },
9602
- resolver: zodResolver(schema$5)
9613
+ resolver: zodResolver(schema$4)
9603
9614
  });
9604
9615
  const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
9605
9616
  const { handleSuccess } = useRouteModal();
9606
9617
  const onSubmit = form.handleSubmit(async (data) => {
9607
9618
  await mutateAsync(
9608
- { billing_address: data },
9619
+ { email: data.email },
9609
9620
  {
9610
9621
  onSuccess: () => {
9611
9622
  handleSuccess();
@@ -9622,132 +9633,18 @@ const BillingAddressForm = ({ order }) => {
9622
9633
  className: "flex flex-1 flex-col overflow-hidden",
9623
9634
  onSubmit,
9624
9635
  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
- ] }) }),
9636
+ /* @__PURE__ */ jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsx(
9637
+ Form$2.Field,
9638
+ {
9639
+ control: form.control,
9640
+ name: "email",
9641
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
9642
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Email" }),
9643
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
9644
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
9645
+ ] })
9646
+ }
9647
+ ) }),
9751
9648
  /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
9752
9649
  /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
9753
9650
  /* @__PURE__ */ jsx(Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
@@ -9756,698 +9653,1029 @@ const BillingAddressForm = ({ order }) => {
9756
9653
  }
9757
9654
  ) });
9758
9655
  };
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
9656
  const schema$4 = objectType({
9779
9657
  email: stringType().email()
9780
9658
  });
9781
- const NumberInput = forwardRef(
9782
- ({
9783
- value,
9784
- onChange,
9785
- size = "base",
9786
- min = 0,
9787
- max = 100,
9788
- step = 1,
9789
- className,
9790
- disabled,
9791
- ...props
9792
- }, ref) => {
9793
- const handleChange = (event) => {
9794
- const newValue = event.target.value === "" ? min : Number(event.target.value);
9795
- if (!isNaN(newValue) && (max === void 0 || newValue <= max) && (min === void 0 || newValue >= min)) {
9796
- onChange(newValue);
9797
- }
9798
- };
9799
- const handleIncrement = () => {
9800
- const newValue = value + step;
9801
- if (max === void 0 || newValue <= max) {
9802
- onChange(newValue);
9803
- }
9804
- };
9805
- const handleDecrement = () => {
9806
- const newValue = value - step;
9807
- if (min === void 0 || newValue >= min) {
9808
- onChange(newValue);
9809
- }
9810
- };
9659
+ const InlineTip = forwardRef(
9660
+ ({ variant = "tip", label, className, children, ...props }, ref) => {
9661
+ const labelValue = label || (variant === "warning" ? "Warning" : "Tip");
9811
9662
  return /* @__PURE__ */ jsxs(
9812
9663
  "div",
9813
9664
  {
9665
+ ref,
9814
9666
  className: clx(
9815
- "inline-flex rounded-md bg-ui-bg-field shadow-borders-base overflow-hidden divide-x transition-fg",
9816
- "[&:has(input:focus)]:shadow-borders-interactive-with-active",
9817
- {
9818
- "h-7": size === "small",
9819
- "h-8": size === "base"
9820
- },
9667
+ "bg-ui-bg-component txt-small text-ui-fg-subtle grid grid-cols-[4px_1fr] items-start gap-3 rounded-lg border p-3",
9821
9668
  className
9822
9669
  ),
9670
+ ...props,
9823
9671
  children: [
9824
9672
  /* @__PURE__ */ jsx(
9825
- "input",
9673
+ "div",
9826
9674
  {
9827
- ref,
9828
- type: "number",
9829
- value,
9830
- onChange: handleChange,
9831
- min,
9832
- max,
9833
- step,
9834
- className: clx(
9835
- "flex-1 px-2 py-1 bg-transparent txt-compact-small text-ui-fg-base outline-none [appearance:textfield]",
9836
- "[&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none",
9837
- "placeholder:text-ui-fg-muted"
9838
- ),
9839
- ...props
9840
- }
9841
- ),
9842
- /* @__PURE__ */ jsxs(
9843
- "button",
9844
- {
9845
- className: clx(
9846
- "flex items-center justify-center outline-none transition-fg",
9847
- "disabled:cursor-not-allowed disabled:text-ui-fg-muted",
9848
- "focus:bg-ui-bg-field-component-hover",
9849
- "hover:bg-ui-bg-field-component-hover",
9850
- {
9851
- "size-7": size === "small",
9852
- "size-8": size === "base"
9853
- }
9854
- ),
9855
- type: "button",
9856
- onClick: handleDecrement,
9857
- disabled: min !== void 0 && value <= min || disabled,
9858
- children: [
9859
- /* @__PURE__ */ jsx(Minus, {}),
9860
- /* @__PURE__ */ jsx("span", { className: "sr-only", children: `Decrease by ${step}` })
9861
- ]
9675
+ role: "presentation",
9676
+ className: clx("w-4px bg-ui-tag-neutral-icon h-full rounded-full", {
9677
+ "bg-ui-tag-orange-icon": variant === "warning"
9678
+ })
9862
9679
  }
9863
9680
  ),
9864
- /* @__PURE__ */ jsxs(
9865
- "button",
9866
- {
9867
- className: clx(
9868
- "flex items-center justify-center outline-none transition-fg",
9869
- "disabled:cursor-not-allowed disabled:text-ui-fg-muted",
9870
- "focus:bg-ui-bg-field-hover",
9871
- "hover:bg-ui-bg-field-hover",
9872
- {
9873
- "size-7": size === "small",
9874
- "size-8": size === "base"
9875
- }
9876
- ),
9877
- type: "button",
9878
- onClick: handleIncrement,
9879
- disabled: max !== void 0 && value >= max || disabled,
9880
- children: [
9881
- /* @__PURE__ */ jsx(Plus, {}),
9882
- /* @__PURE__ */ jsx("span", { className: "sr-only", children: `Increase by ${step}` })
9883
- ]
9884
- }
9885
- )
9681
+ /* @__PURE__ */ jsxs("div", { className: "text-pretty", children: [
9682
+ /* @__PURE__ */ jsxs("strong", { className: "txt-small-plus text-ui-fg-base", children: [
9683
+ labelValue,
9684
+ ":"
9685
+ ] }),
9686
+ " ",
9687
+ children
9688
+ ] })
9886
9689
  ]
9887
9690
  }
9888
9691
  );
9889
9692
  }
9890
9693
  );
9891
- const PRODUCT_VARIANTS_QUERY_KEY = "product-variants";
9892
- const productVariantsQueryKeys = {
9893
- list: (query2) => [
9894
- PRODUCT_VARIANTS_QUERY_KEY,
9895
- query2 ? query2 : void 0
9896
- ]
9897
- };
9898
- const useProductVariants = (query2, options) => {
9899
- const { data, ...rest } = useQuery({
9900
- queryKey: productVariantsQueryKeys.list(query2),
9901
- queryFn: async () => await sdk.admin.productVariant.list(query2),
9902
- ...options
9903
- });
9904
- return { ...data, ...rest };
9905
- };
9906
- const useCancelOrderEdit = ({ preview }) => {
9907
- const { mutateAsync: cancelOrderEdit } = useDraftOrderCancelEdit(preview == null ? void 0 : preview.id);
9908
- const onCancel = useCallback(async () => {
9909
- if (!preview) {
9910
- return true;
9911
- }
9912
- let res = false;
9913
- await cancelOrderEdit(void 0, {
9914
- onError: (e) => {
9915
- toast.error(e.message);
9916
- },
9917
- onSuccess: () => {
9918
- res = true;
9919
- }
9920
- });
9921
- return res;
9922
- }, [preview, cancelOrderEdit]);
9923
- return { onCancel };
9924
- };
9925
- let IS_REQUEST_RUNNING = false;
9926
- const useInitiateOrderEdit = ({
9927
- preview
9928
- }) => {
9929
- const navigate = useNavigate();
9930
- const { mutateAsync } = useDraftOrderBeginEdit(preview == null ? void 0 : preview.id);
9931
- useEffect(() => {
9932
- async function run() {
9933
- if (IS_REQUEST_RUNNING || !preview) {
9934
- return;
9935
- }
9936
- if (preview.order_change) {
9937
- return;
9938
- }
9939
- IS_REQUEST_RUNNING = true;
9940
- await mutateAsync(void 0, {
9941
- onError: (e) => {
9942
- toast.error(e.message);
9943
- navigate(`/draft-orders/${preview.id}`, { replace: true });
9944
- return;
9945
- }
9946
- });
9947
- IS_REQUEST_RUNNING = false;
9948
- }
9949
- run();
9950
- }, [preview, navigate, mutateAsync]);
9951
- };
9952
- function convertNumber(value) {
9953
- return typeof value === "string" ? Number(value.replace(",", ".")) : value;
9954
- }
9955
- const STACKED_MODAL_ID = "items_stacked_modal";
9956
- const Items = () => {
9694
+ InlineTip.displayName = "InlineTip";
9695
+ const MetadataFieldSchema = objectType({
9696
+ key: stringType(),
9697
+ disabled: booleanType().optional(),
9698
+ value: anyType()
9699
+ });
9700
+ const MetadataSchema = objectType({
9701
+ metadata: arrayType(MetadataFieldSchema)
9702
+ });
9703
+ const Metadata = () => {
9957
9704
  const { id } = useParams();
9958
- const {
9959
- order: preview,
9960
- isPending: isPreviewPending,
9961
- isError: isPreviewError,
9962
- error: previewError
9963
- } = useOrderPreview(id, void 0, {
9964
- placeholderData: keepPreviousData
9705
+ const { order, isPending, isError, error } = useOrder(id, {
9706
+ fields: "metadata"
9965
9707
  });
9966
- useInitiateOrderEdit({ preview });
9967
- const { draft_order, isPending, isError, error } = useDraftOrder(
9968
- id,
9969
- {
9970
- fields: "currency_code"
9971
- },
9972
- {
9973
- enabled: !!id
9974
- }
9975
- );
9976
- const { onCancel } = useCancelOrderEdit({ preview });
9977
9708
  if (isError) {
9978
9709
  throw error;
9979
9710
  }
9980
- if (isPreviewError) {
9981
- throw previewError;
9982
- }
9983
- const ready = !!preview && !isPreviewPending && !!draft_order && !isPending;
9984
- return /* @__PURE__ */ jsx(RouteFocusModal, { onClose: onCancel, children: ready ? /* @__PURE__ */ jsx(ItemsForm, { preview, currencyCode: draft_order.currency_code }) : /* @__PURE__ */ jsxs("div", { children: [
9985
- /* @__PURE__ */ jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Edit Items" }) }),
9986
- /* @__PURE__ */ jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Loading data for the draft order, please wait..." }) })
9987
- ] }) });
9711
+ const isReady = !isPending && !!order;
9712
+ return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
9713
+ /* @__PURE__ */ jsxs(RouteDrawer.Header, { children: [
9714
+ /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Metadata" }) }),
9715
+ /* @__PURE__ */ jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Add metadata to the draft order." }) })
9716
+ ] }),
9717
+ !isReady ? /* @__PURE__ */ jsx(PlaceholderInner, {}) : /* @__PURE__ */ jsx(MetadataForm, { orderId: id, metadata: order == null ? void 0 : order.metadata })
9718
+ ] });
9988
9719
  };
9989
- const ItemsForm = ({ preview, currencyCode }) => {
9990
- var _a;
9991
- const [isSubmitting, setIsSubmitting] = useState(false);
9992
- const [modalContent, setModalContent] = useState(
9993
- null
9994
- );
9720
+ const METADATA_KEY_LABEL_ID = "metadata-form-key-label";
9721
+ const METADATA_VALUE_LABEL_ID = "metadata-form-value-label";
9722
+ const MetadataForm = ({ orderId, metadata }) => {
9995
9723
  const { handleSuccess } = useRouteModal();
9996
- const { searchValue, onSearchValueChange, query: query2 } = useDebouncedSearch();
9997
- const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
9998
- const { mutateAsync: requestOrderEdit } = useDraftOrderRequestEdit(preview.id);
9999
- const itemCount = ((_a = preview.items) == null ? void 0 : _a.reduce((acc, item) => acc + item.quantity, 0)) || 0;
10000
- const matches = useMemo(() => {
10001
- return matchSorter(preview.items, query2, {
10002
- keys: ["product_title", "variant_title", "variant_sku", "title"]
10003
- });
10004
- }, [preview.items, query2]);
10005
- const onSubmit = async () => {
10006
- setIsSubmitting(true);
10007
- let requestSucceeded = false;
10008
- await requestOrderEdit(void 0, {
10009
- onError: (e) => {
10010
- toast.error(`Failed to request order edit: ${e.message}`);
9724
+ const hasUneditableRows = getHasUneditableRows(metadata);
9725
+ const { mutateAsync, isPending } = useUpdateDraftOrder(orderId);
9726
+ const form = useForm({
9727
+ defaultValues: {
9728
+ metadata: getDefaultValues(metadata)
9729
+ },
9730
+ resolver: zodResolver(MetadataSchema)
9731
+ });
9732
+ const handleSubmit = form.handleSubmit(async (data) => {
9733
+ const parsedData = parseValues(data);
9734
+ await mutateAsync(
9735
+ {
9736
+ metadata: parsedData
10011
9737
  },
10012
- onSuccess: () => {
10013
- requestSucceeded = true;
9738
+ {
9739
+ onSuccess: () => {
9740
+ toast.success("Metadata updated");
9741
+ handleSuccess();
9742
+ },
9743
+ onError: (error) => {
9744
+ toast.error(error.message);
9745
+ }
10014
9746
  }
10015
- });
10016
- if (!requestSucceeded) {
10017
- setIsSubmitting(false);
10018
- return;
9747
+ );
9748
+ });
9749
+ const { fields, insert, remove } = useFieldArray({
9750
+ control: form.control,
9751
+ name: "metadata"
9752
+ });
9753
+ function deleteRow(index) {
9754
+ remove(index);
9755
+ if (fields.length === 1) {
9756
+ insert(0, {
9757
+ key: "",
9758
+ value: "",
9759
+ disabled: false
9760
+ });
10019
9761
  }
10020
- await confirmOrderEdit(void 0, {
10021
- onError: (e) => {
10022
- toast.error(`Failed to confirm order edit: ${e.message}`);
10023
- },
10024
- onSuccess: () => {
10025
- handleSuccess();
10026
- },
10027
- onSettled: () => {
10028
- setIsSubmitting(false);
10029
- }
9762
+ }
9763
+ function insertRow(index, position) {
9764
+ insert(index + (position === "above" ? 0 : 1), {
9765
+ key: "",
9766
+ value: "",
9767
+ disabled: false
10030
9768
  });
10031
- };
10032
- const onKeyDown = useCallback(
10033
- (e) => {
10034
- if (e.key === "Enter" && (e.ctrlKey || e.metaKey)) {
10035
- if (modalContent || isSubmitting) {
10036
- return;
10037
- }
10038
- onSubmit();
10039
- }
10040
- },
10041
- [modalContent, isSubmitting, onSubmit]
10042
- );
10043
- useEffect(() => {
10044
- document.addEventListener("keydown", onKeyDown);
10045
- return () => {
10046
- document.removeEventListener("keydown", onKeyDown);
10047
- };
10048
- }, [onKeyDown]);
10049
- return /* @__PURE__ */ jsxs("div", { className: "flex h-full flex-col overflow-hidden", children: [
10050
- /* @__PURE__ */ jsx(RouteFocusModal.Header, {}),
10051
- /* @__PURE__ */ jsx(RouteFocusModal.Body, { className: "flex flex-1 flex-col overflow-hidden", children: /* @__PURE__ */ jsxs(
10052
- StackedFocusModal,
10053
- {
10054
- id: STACKED_MODAL_ID,
10055
- onOpenChangeCallback: (open) => {
10056
- if (!open) {
10057
- setModalContent(null);
10058
- }
10059
- },
10060
- children: [
10061
- /* @__PURE__ */ jsx("div", { className: "flex flex-1 flex-col items-center overflow-y-auto", children: /* @__PURE__ */ jsxs("div", { className: "flex w-full max-w-[720px] flex-col gap-y-6 px-6 py-16", children: [
10062
- /* @__PURE__ */ jsxs("div", { children: [
10063
- /* @__PURE__ */ jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Items" }) }),
10064
- /* @__PURE__ */ jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Edit the items in the draft order" }) })
9769
+ }
9770
+ return /* @__PURE__ */ jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxs(
9771
+ KeyboundForm,
9772
+ {
9773
+ onSubmit: handleSubmit,
9774
+ className: "flex flex-1 flex-col overflow-hidden",
9775
+ children: [
9776
+ /* @__PURE__ */ jsxs(RouteDrawer.Body, { className: "flex flex-1 flex-col gap-y-8 overflow-y-auto", children: [
9777
+ /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest grid grid-cols-1 divide-y rounded-lg", children: [
9778
+ /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-subtle grid grid-cols-2 divide-x rounded-t-lg", children: [
9779
+ /* @__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" }) }),
9780
+ /* @__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" }) })
10065
9781
  ] }),
10066
- /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
10067
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-y-6", children: [
10068
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 items-center gap-3", children: [
10069
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
10070
- /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: "Items" }),
10071
- /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Choose items from the product catalog." })
10072
- ] }),
10073
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
10074
- /* @__PURE__ */ jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsx(
10075
- Input,
10076
- {
10077
- type: "search",
10078
- placeholder: "Search items",
10079
- value: searchValue,
10080
- onChange: (e) => onSearchValueChange(e.target.value)
10081
- }
10082
- ) }),
10083
- /* @__PURE__ */ jsxs(DropdownMenu, { children: [
10084
- /* @__PURE__ */ jsx(DropdownMenu.Trigger, { asChild: true, children: /* @__PURE__ */ jsx(IconButton, { type: "button", children: /* @__PURE__ */ jsx(Plus, {}) }) }),
10085
- /* @__PURE__ */ jsxs(DropdownMenu.Content, { children: [
9782
+ fields.map((field, index) => {
9783
+ const isDisabled = field.disabled || false;
9784
+ let placeholder = "-";
9785
+ if (typeof field.value === "object") {
9786
+ placeholder = "{ ... }";
9787
+ }
9788
+ if (Array.isArray(field.value)) {
9789
+ placeholder = "[ ... ]";
9790
+ }
9791
+ return /* @__PURE__ */ jsx(
9792
+ ConditionalTooltip,
9793
+ {
9794
+ showTooltip: isDisabled,
9795
+ content: "This row is disabled because it contains non-primitive data.",
9796
+ children: /* @__PURE__ */ jsxs("div", { className: "group/table relative", children: [
9797
+ /* @__PURE__ */ jsxs(
9798
+ "div",
9799
+ {
9800
+ className: clx("grid grid-cols-2 divide-x", {
9801
+ "overflow-hidden rounded-b-lg": index === fields.length - 1
9802
+ }),
9803
+ children: [
9804
+ /* @__PURE__ */ jsx(
9805
+ Form$2.Field,
9806
+ {
9807
+ control: form.control,
9808
+ name: `metadata.${index}.key`,
9809
+ render: ({ field: field2 }) => {
9810
+ return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
9811
+ GridInput,
9812
+ {
9813
+ "aria-labelledby": METADATA_KEY_LABEL_ID,
9814
+ ...field2,
9815
+ disabled: isDisabled,
9816
+ placeholder: "Key"
9817
+ }
9818
+ ) }) });
9819
+ }
9820
+ }
9821
+ ),
9822
+ /* @__PURE__ */ jsx(
9823
+ Form$2.Field,
9824
+ {
9825
+ control: form.control,
9826
+ name: `metadata.${index}.value`,
9827
+ render: ({ field: { value, ...field2 } }) => {
9828
+ return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
9829
+ GridInput,
9830
+ {
9831
+ "aria-labelledby": METADATA_VALUE_LABEL_ID,
9832
+ ...field2,
9833
+ value: isDisabled ? placeholder : value,
9834
+ disabled: isDisabled,
9835
+ placeholder: "Value"
9836
+ }
9837
+ ) }) });
9838
+ }
9839
+ }
9840
+ )
9841
+ ]
9842
+ }
9843
+ ),
9844
+ /* @__PURE__ */ jsxs(DropdownMenu, { children: [
10086
9845
  /* @__PURE__ */ jsx(
10087
- StackedModalTrigger$1,
9846
+ DropdownMenu.Trigger,
10088
9847
  {
10089
- type: "add-items",
10090
- setModalContent
9848
+ className: clx(
9849
+ "invisible absolute inset-y-0 -right-2.5 my-auto group-hover/table:visible data-[state='open']:visible",
9850
+ {
9851
+ hidden: isDisabled
9852
+ }
9853
+ ),
9854
+ disabled: isDisabled,
9855
+ asChild: true,
9856
+ children: /* @__PURE__ */ jsx(IconButton, { size: "2xsmall", children: /* @__PURE__ */ jsx(EllipsisVertical, {}) })
10091
9857
  }
10092
9858
  ),
10093
- /* @__PURE__ */ jsx(
10094
- StackedModalTrigger$1,
10095
- {
10096
- type: "add-custom-item",
10097
- setModalContent
10098
- }
10099
- )
9859
+ /* @__PURE__ */ jsxs(DropdownMenu.Content, { children: [
9860
+ /* @__PURE__ */ jsxs(
9861
+ DropdownMenu.Item,
9862
+ {
9863
+ className: "gap-x-2",
9864
+ onClick: () => insertRow(index, "above"),
9865
+ children: [
9866
+ /* @__PURE__ */ jsx(ArrowUpMini, { className: "text-ui-fg-subtle" }),
9867
+ "Insert row above"
9868
+ ]
9869
+ }
9870
+ ),
9871
+ /* @__PURE__ */ jsxs(
9872
+ DropdownMenu.Item,
9873
+ {
9874
+ className: "gap-x-2",
9875
+ onClick: () => insertRow(index, "below"),
9876
+ children: [
9877
+ /* @__PURE__ */ jsx(ArrowDownMini, { className: "text-ui-fg-subtle" }),
9878
+ "Insert row below"
9879
+ ]
9880
+ }
9881
+ ),
9882
+ /* @__PURE__ */ jsx(DropdownMenu.Separator, {}),
9883
+ /* @__PURE__ */ jsxs(
9884
+ DropdownMenu.Item,
9885
+ {
9886
+ className: "gap-x-2",
9887
+ onClick: () => deleteRow(index),
9888
+ children: [
9889
+ /* @__PURE__ */ jsx(Trash, { className: "text-ui-fg-subtle" }),
9890
+ "Delete row"
9891
+ ]
9892
+ }
9893
+ )
9894
+ ] })
10100
9895
  ] })
10101
9896
  ] })
10102
- ] })
10103
- ] }),
10104
- /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-subtle shadow-elevation-card-rest rounded-xl", children: [
10105
- /* @__PURE__ */ jsx("div", { className: "px-[5px]", children: /* @__PURE__ */ jsxs("div", { className: "text-ui-fg-muted grid grid-cols-[2fr_1fr_2fr_28px] gap-3 px-4 py-2", children: [
10106
- /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: "Item" }) }),
10107
- /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: "Quantity" }) }),
10108
- /* @__PURE__ */ jsx("div", { className: "text-right", children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: "Price" }) }),
10109
- /* @__PURE__ */ jsx("div", {})
10110
- ] }) }),
10111
- /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-y-1.5 px-[5px] pb-[5px]", children: itemCount <= 0 ? /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest flex flex-col items-center justify-center gap-1 gap-x-3 rounded-lg p-4", children: [
10112
- /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: "There are no items in this order" }),
10113
- /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Add items to the order to get started." })
10114
- ] }) : matches.length > 0 ? matches == null ? void 0 : matches.map((item) => /* @__PURE__ */ jsx(
10115
- Item,
10116
- {
10117
- item,
10118
- preview,
10119
- currencyCode
10120
- },
10121
- item.id
10122
- )) : /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest flex flex-col items-center justify-center gap-1 gap-x-3 rounded-lg p-4", children: [
10123
- /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: "No items found" }),
10124
- /* @__PURE__ */ jsxs(Text, { size: "small", className: "text-ui-fg-subtle", children: [
10125
- 'No items found for "',
10126
- query2,
10127
- '".'
10128
- ] })
10129
- ] }) })
10130
- ] })
10131
- ] }),
10132
- /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
10133
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-[1fr_0.5fr_0.5fr] gap-3", children: [
10134
- /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: "Subtotal" }) }),
10135
- /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsxs(
10136
- Text,
10137
- {
10138
- size: "small",
10139
- leading: "compact",
10140
- className: "text-ui-fg-subtle",
10141
- children: [
10142
- itemCount,
10143
- " ",
10144
- itemCount === 1 ? "item" : "items"
10145
- ]
10146
- }
10147
- ) }),
10148
- /* @__PURE__ */ jsx("div", { className: "text-right", children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: getStylizedAmount(preview.item_subtotal, currencyCode) }) })
10149
- ] })
10150
- ] }) }),
10151
- modalContent && (modalContent === "add-items" ? /* @__PURE__ */ jsx(ExistingItemsForm, { orderId: preview.id, items: preview.items }) : modalContent === "add-custom-item" ? /* @__PURE__ */ jsx(
10152
- CustomItemForm,
10153
- {
10154
- orderId: preview.id,
10155
- currencyCode
10156
- }
10157
- ) : null)
10158
- ]
10159
- }
10160
- ) }),
10161
- /* @__PURE__ */ jsx(RouteFocusModal.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
10162
- /* @__PURE__ */ jsx(RouteFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
10163
- /* @__PURE__ */ jsx(
10164
- Button,
10165
- {
10166
- size: "small",
10167
- type: "button",
10168
- onClick: onSubmit,
10169
- isLoading: isSubmitting,
10170
- children: "Save"
10171
- }
10172
- )
10173
- ] }) })
10174
- ] });
9897
+ },
9898
+ field.id
9899
+ );
9900
+ })
9901
+ ] }),
9902
+ 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." })
9903
+ ] }),
9904
+ /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
9905
+ /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
9906
+ /* @__PURE__ */ jsx(Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
9907
+ ] }) })
9908
+ ]
9909
+ }
9910
+ ) });
10175
9911
  };
10176
- const Item = ({ item, preview, currencyCode }) => {
10177
- if (item.variant_id) {
10178
- return /* @__PURE__ */ jsx(VariantItem, { item, preview, currencyCode });
10179
- }
10180
- return /* @__PURE__ */ jsx(CustomItem, { item, preview, currencyCode });
9912
+ const GridInput = forwardRef(({ className, ...props }, ref) => {
9913
+ return /* @__PURE__ */ jsx(
9914
+ "input",
9915
+ {
9916
+ ref,
9917
+ ...props,
9918
+ autoComplete: "off",
9919
+ className: clx(
9920
+ "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",
9921
+ className
9922
+ )
9923
+ }
9924
+ );
9925
+ });
9926
+ GridInput.displayName = "MetadataForm.GridInput";
9927
+ const PlaceholderInner = () => {
9928
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-1 flex-col overflow-hidden", children: [
9929
+ /* @__PURE__ */ jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsx(Skeleton, { className: "h-[148ox] w-full rounded-lg" }) }),
9930
+ /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
9931
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-7 w-12 rounded-md" }),
9932
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-7 w-12 rounded-md" })
9933
+ ] }) })
9934
+ ] });
10181
9935
  };
10182
- const VariantItem = ({ item, preview, currencyCode }) => {
10183
- const [editing, setEditing] = useState(false);
10184
- const form = useForm({
10185
- defaultValues: {
10186
- quantity: item.quantity,
10187
- unit_price: item.unit_price
10188
- },
10189
- resolver: zodResolver(variantItemSchema)
9936
+ const EDITABLE_TYPES = ["string", "number", "boolean"];
9937
+ function getDefaultValues(metadata) {
9938
+ if (!metadata || !Object.keys(metadata).length) {
9939
+ return [
9940
+ {
9941
+ key: "",
9942
+ value: "",
9943
+ disabled: false
9944
+ }
9945
+ ];
9946
+ }
9947
+ return Object.entries(metadata).map(([key, value]) => {
9948
+ if (!EDITABLE_TYPES.includes(typeof value)) {
9949
+ return {
9950
+ key,
9951
+ value,
9952
+ disabled: true
9953
+ };
9954
+ }
9955
+ let stringValue = value;
9956
+ if (typeof value !== "string") {
9957
+ stringValue = JSON.stringify(value);
9958
+ }
9959
+ return {
9960
+ key,
9961
+ value: stringValue,
9962
+ original_key: key
9963
+ };
10190
9964
  });
10191
- const actionId = useMemo(() => {
10192
- var _a, _b;
10193
- return (_b = (_a = item.actions) == null ? void 0 : _a.find((a) => a.action === "ITEM_ADD")) == null ? void 0 : _b.id;
10194
- }, [item]);
10195
- const { mutateAsync: updateActionItem, isPending: isUpdatingActionItem } = useDraftOrderUpdateActionItem(preview.id);
10196
- const { mutateAsync: updateOriginalItem, isPending: isUpdatingOriginalItem } = useDraftOrderUpdateItem(preview.id);
10197
- const isPending = isUpdatingActionItem || isUpdatingOriginalItem;
10198
- const onSubmit = form.handleSubmit(async (data) => {
10199
- if (convertNumber(data.unit_price) === item.unit_price && data.quantity === item.quantity) {
10200
- setEditing(false);
9965
+ }
9966
+ function parseValues(values) {
9967
+ const metadata = values.metadata;
9968
+ const isEmpty = !metadata.length || metadata.length === 1 && !metadata[0].key && !metadata[0].value;
9969
+ if (isEmpty) {
9970
+ return null;
9971
+ }
9972
+ const update = {};
9973
+ metadata.forEach((field) => {
9974
+ let key = field.key;
9975
+ let value = field.value;
9976
+ const disabled = field.disabled;
9977
+ if (!key || !value) {
10201
9978
  return;
10202
9979
  }
10203
- if (!actionId) {
10204
- await updateOriginalItem(
10205
- {
10206
- item_id: item.id,
10207
- quantity: data.quantity,
10208
- unit_price: convertNumber(data.unit_price)
10209
- },
10210
- {
10211
- onSuccess: () => {
10212
- setEditing(false);
10213
- },
10214
- onError: (e) => {
10215
- toast.error(e.message);
10216
- }
10217
- }
10218
- );
9980
+ if (disabled) {
9981
+ update[key] = value;
10219
9982
  return;
10220
9983
  }
10221
- await updateActionItem(
10222
- {
10223
- action_id: actionId,
10224
- quantity: data.quantity,
10225
- unit_price: convertNumber(data.unit_price)
10226
- },
10227
- {
10228
- onSuccess: () => {
10229
- setEditing(false);
10230
- },
10231
- onError: (e) => {
10232
- toast.error(e.message);
10233
- }
9984
+ key = key.trim();
9985
+ value = value.trim();
9986
+ if (value === "true") {
9987
+ update[key] = true;
9988
+ } else if (value === "false") {
9989
+ update[key] = false;
9990
+ } else {
9991
+ const parsedNumber = parseFloat(value);
9992
+ if (!isNaN(parsedNumber)) {
9993
+ update[key] = parsedNumber;
9994
+ } else {
9995
+ update[key] = value;
10234
9996
  }
10235
- );
9997
+ }
10236
9998
  });
10237
- 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: [
10238
- /* @__PURE__ */ jsxs("div", { className: "flex w-full items-center gap-x-3", children: [
10239
- /* @__PURE__ */ jsx(
10240
- Thumbnail,
10241
- {
10242
- thumbnail: item.thumbnail,
10243
- alt: item.product_title ?? void 0
10244
- }
10245
- ),
10246
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
10247
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-1", children: [
10248
- /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: item.product_title }),
9999
+ return update;
10000
+ }
10001
+ function getHasUneditableRows(metadata) {
10002
+ if (!metadata) {
10003
+ return false;
10004
+ }
10005
+ return Object.values(metadata).some(
10006
+ (value) => !EDITABLE_TYPES.includes(typeof value)
10007
+ );
10008
+ }
10009
+ const NumberInput = forwardRef(
10010
+ ({
10011
+ value,
10012
+ onChange,
10013
+ size = "base",
10014
+ min = 0,
10015
+ max = 100,
10016
+ step = 1,
10017
+ className,
10018
+ disabled,
10019
+ ...props
10020
+ }, ref) => {
10021
+ const handleChange = (event) => {
10022
+ const newValue = event.target.value === "" ? min : Number(event.target.value);
10023
+ if (!isNaN(newValue) && (max === void 0 || newValue <= max) && (min === void 0 || newValue >= min)) {
10024
+ onChange(newValue);
10025
+ }
10026
+ };
10027
+ const handleIncrement = () => {
10028
+ const newValue = value + step;
10029
+ if (max === void 0 || newValue <= max) {
10030
+ onChange(newValue);
10031
+ }
10032
+ };
10033
+ const handleDecrement = () => {
10034
+ const newValue = value - step;
10035
+ if (min === void 0 || newValue >= min) {
10036
+ onChange(newValue);
10037
+ }
10038
+ };
10039
+ return /* @__PURE__ */ jsxs(
10040
+ "div",
10041
+ {
10042
+ className: clx(
10043
+ "inline-flex rounded-md bg-ui-bg-field shadow-borders-base overflow-hidden divide-x transition-fg",
10044
+ "[&:has(input:focus)]:shadow-borders-interactive-with-active",
10045
+ {
10046
+ "h-7": size === "small",
10047
+ "h-8": size === "base"
10048
+ },
10049
+ className
10050
+ ),
10051
+ children: [
10052
+ /* @__PURE__ */ jsx(
10053
+ "input",
10054
+ {
10055
+ ref,
10056
+ type: "number",
10057
+ value,
10058
+ onChange: handleChange,
10059
+ min,
10060
+ max,
10061
+ step,
10062
+ className: clx(
10063
+ "flex-1 px-2 py-1 bg-transparent txt-compact-small text-ui-fg-base outline-none [appearance:textfield]",
10064
+ "[&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none",
10065
+ "placeholder:text-ui-fg-muted"
10066
+ ),
10067
+ ...props
10068
+ }
10069
+ ),
10249
10070
  /* @__PURE__ */ jsxs(
10250
- Text,
10071
+ "button",
10251
10072
  {
10252
- size: "small",
10253
- leading: "compact",
10254
- className: "text-ui-fg-subtle",
10073
+ className: clx(
10074
+ "flex items-center justify-center outline-none transition-fg",
10075
+ "disabled:cursor-not-allowed disabled:text-ui-fg-muted",
10076
+ "focus:bg-ui-bg-field-component-hover",
10077
+ "hover:bg-ui-bg-field-component-hover",
10078
+ {
10079
+ "size-7": size === "small",
10080
+ "size-8": size === "base"
10081
+ }
10082
+ ),
10083
+ type: "button",
10084
+ onClick: handleDecrement,
10085
+ disabled: min !== void 0 && value <= min || disabled,
10255
10086
  children: [
10256
- "(",
10257
- item.variant_title,
10258
- ")"
10087
+ /* @__PURE__ */ jsx(Minus, {}),
10088
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: `Decrease by ${step}` })
10259
10089
  ]
10260
10090
  }
10261
- )
10262
- ] }),
10263
- /* @__PURE__ */ jsx(
10264
- Text,
10265
- {
10266
- size: "small",
10267
- leading: "compact",
10268
- className: "text-ui-fg-subtle",
10269
- children: item.variant_sku
10270
- }
10271
- )
10272
- ] })
10273
- ] }),
10274
- editing ? /* @__PURE__ */ jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsx(
10275
- Form$2.Field,
10276
- {
10277
- control: form.control,
10278
- name: "quantity",
10279
- render: ({ field }) => {
10280
- return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(NumberInput, { ...field }) }) });
10281
- }
10282
- }
10283
- ) }) : /* @__PURE__ */ jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: item.quantity }) }),
10284
- editing ? /* @__PURE__ */ jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsx(
10285
- Form$2.Field,
10286
- {
10287
- control: form.control,
10288
- name: "unit_price",
10289
- render: ({ field: { onChange, ...field } }) => {
10290
- return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
10291
- CurrencyInput,
10091
+ ),
10092
+ /* @__PURE__ */ jsxs(
10093
+ "button",
10292
10094
  {
10293
- ...field,
10294
- symbol: getNativeSymbol(currencyCode),
10295
- code: currencyCode,
10296
- onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value)
10095
+ className: clx(
10096
+ "flex items-center justify-center outline-none transition-fg",
10097
+ "disabled:cursor-not-allowed disabled:text-ui-fg-muted",
10098
+ "focus:bg-ui-bg-field-hover",
10099
+ "hover:bg-ui-bg-field-hover",
10100
+ {
10101
+ "size-7": size === "small",
10102
+ "size-8": size === "base"
10103
+ }
10104
+ ),
10105
+ type: "button",
10106
+ onClick: handleIncrement,
10107
+ disabled: max !== void 0 && value >= max || disabled,
10108
+ children: [
10109
+ /* @__PURE__ */ jsx(Plus, {}),
10110
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: `Increase by ${step}` })
10111
+ ]
10297
10112
  }
10298
- ) }) });
10299
- }
10300
- }
10301
- ) }) : /* @__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) }) }),
10302
- /* @__PURE__ */ jsx(
10303
- IconButton,
10304
- {
10305
- type: "button",
10306
- size: "small",
10307
- onClick: editing ? onSubmit : () => {
10308
- setEditing(true);
10309
- },
10310
- disabled: isPending,
10311
- children: editing ? /* @__PURE__ */ jsx(Check, {}) : /* @__PURE__ */ jsx(PencilSquare, {})
10113
+ )
10114
+ ]
10312
10115
  }
10313
- )
10314
- ] }) }) });
10116
+ );
10117
+ }
10118
+ );
10119
+ const PRODUCT_VARIANTS_QUERY_KEY = "product-variants";
10120
+ const productVariantsQueryKeys = {
10121
+ list: (query2) => [
10122
+ PRODUCT_VARIANTS_QUERY_KEY,
10123
+ query2 ? query2 : void 0
10124
+ ]
10315
10125
  };
10316
- const variantItemSchema = objectType({
10317
- quantity: numberType(),
10318
- unit_price: unionType([numberType(), stringType()])
10319
- });
10320
- const CustomItem = ({ item, preview, currencyCode }) => {
10321
- const [editing, setEditing] = useState(false);
10322
- const { quantity, unit_price, title } = item;
10323
- const form = useForm({
10324
- defaultValues: {
10325
- title,
10326
- quantity,
10327
- unit_price
10328
- },
10329
- resolver: zodResolver(customItemSchema)
10126
+ const useProductVariants = (query2, options) => {
10127
+ const { data, ...rest } = useQuery({
10128
+ queryKey: productVariantsQueryKeys.list(query2),
10129
+ queryFn: async () => await sdk.admin.productVariant.list(query2),
10130
+ ...options
10330
10131
  });
10331
- useEffect(() => {
10332
- form.reset({
10333
- title,
10334
- quantity,
10335
- unit_price
10336
- });
10337
- }, [form, title, quantity, unit_price]);
10338
- const actionId = useMemo(() => {
10339
- var _a, _b;
10340
- return (_b = (_a = item.actions) == null ? void 0 : _a.find((a) => a.action === "ITEM_ADD")) == null ? void 0 : _b.id;
10341
- }, [item]);
10342
- const { mutateAsync: updateActionItem, isPending: isUpdatingActionItem } = useDraftOrderUpdateActionItem(preview.id);
10343
- const { mutateAsync: removeActionItem, isPending: isRemovingActionItem } = useDraftOrderRemoveActionItem(preview.id);
10344
- const { mutateAsync: updateOriginalItem, isPending: isUpdatingOriginalItem } = useDraftOrderUpdateItem(preview.id);
10345
- const isPending = isUpdatingActionItem || isUpdatingOriginalItem;
10346
- const onSubmit = form.handleSubmit(async (data) => {
10347
- if (convertNumber(data.unit_price) === item.unit_price && data.quantity === item.quantity && data.title === item.title) {
10348
- setEditing(false);
10349
- return;
10350
- }
10351
- if (!actionId) {
10352
- await updateOriginalItem(
10353
- {
10354
- item_id: item.id,
10355
- quantity: data.quantity,
10356
- unit_price: convertNumber(data.unit_price)
10357
- },
10358
- {
10359
- onSuccess: () => {
10360
- setEditing(false);
10361
- },
10362
- onError: (e) => {
10363
- toast.error(e.message);
10364
- }
10365
- }
10366
- );
10367
- return;
10132
+ return { ...data, ...rest };
10133
+ };
10134
+ const useCancelOrderEdit = ({ preview }) => {
10135
+ const { mutateAsync: cancelOrderEdit } = useDraftOrderCancelEdit(preview == null ? void 0 : preview.id);
10136
+ const onCancel = useCallback(async () => {
10137
+ if (!preview) {
10138
+ return true;
10368
10139
  }
10369
- if (data.quantity === 0) {
10370
- await removeActionItem(actionId, {
10371
- onSuccess: () => {
10372
- setEditing(false);
10373
- },
10140
+ let res = false;
10141
+ await cancelOrderEdit(void 0, {
10142
+ onError: (e) => {
10143
+ toast.error(e.message);
10144
+ },
10145
+ onSuccess: () => {
10146
+ res = true;
10147
+ }
10148
+ });
10149
+ return res;
10150
+ }, [preview, cancelOrderEdit]);
10151
+ return { onCancel };
10152
+ };
10153
+ let IS_REQUEST_RUNNING = false;
10154
+ const useInitiateOrderEdit = ({
10155
+ preview
10156
+ }) => {
10157
+ const navigate = useNavigate();
10158
+ const { mutateAsync } = useDraftOrderBeginEdit(preview == null ? void 0 : preview.id);
10159
+ useEffect(() => {
10160
+ async function run() {
10161
+ if (IS_REQUEST_RUNNING || !preview) {
10162
+ return;
10163
+ }
10164
+ if (preview.order_change) {
10165
+ return;
10166
+ }
10167
+ IS_REQUEST_RUNNING = true;
10168
+ await mutateAsync(void 0, {
10374
10169
  onError: (e) => {
10375
10170
  toast.error(e.message);
10171
+ navigate(`/draft-orders/${preview.id}`, { replace: true });
10172
+ return;
10376
10173
  }
10377
10174
  });
10378
- return;
10175
+ IS_REQUEST_RUNNING = false;
10379
10176
  }
10380
- await updateActionItem(
10381
- {
10382
- action_id: actionId,
10383
- quantity: data.quantity,
10384
- unit_price: convertNumber(data.unit_price)
10177
+ run();
10178
+ }, [preview, navigate, mutateAsync]);
10179
+ };
10180
+ function convertNumber(value) {
10181
+ return typeof value === "string" ? Number(value.replace(",", ".")) : value;
10182
+ }
10183
+ const STACKED_MODAL_ID = "items_stacked_modal";
10184
+ const Items = () => {
10185
+ const { id } = useParams();
10186
+ const {
10187
+ order: preview,
10188
+ isPending: isPreviewPending,
10189
+ isError: isPreviewError,
10190
+ error: previewError
10191
+ } = useOrderPreview(id, void 0, {
10192
+ placeholderData: keepPreviousData
10193
+ });
10194
+ useInitiateOrderEdit({ preview });
10195
+ const { draft_order, isPending, isError, error } = useDraftOrder(
10196
+ id,
10197
+ {
10198
+ fields: "currency_code"
10199
+ },
10200
+ {
10201
+ enabled: !!id
10202
+ }
10203
+ );
10204
+ const { onCancel } = useCancelOrderEdit({ preview });
10205
+ if (isError) {
10206
+ throw error;
10207
+ }
10208
+ if (isPreviewError) {
10209
+ throw previewError;
10210
+ }
10211
+ const ready = !!preview && !isPreviewPending && !!draft_order && !isPending;
10212
+ return /* @__PURE__ */ jsx(RouteFocusModal, { onClose: onCancel, children: ready ? /* @__PURE__ */ jsx(ItemsForm, { preview, currencyCode: draft_order.currency_code }) : /* @__PURE__ */ jsxs("div", { children: [
10213
+ /* @__PURE__ */ jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Edit Items" }) }),
10214
+ /* @__PURE__ */ jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Loading data for the draft order, please wait..." }) })
10215
+ ] }) });
10216
+ };
10217
+ const ItemsForm = ({ preview, currencyCode }) => {
10218
+ var _a;
10219
+ const [isSubmitting, setIsSubmitting] = useState(false);
10220
+ const [modalContent, setModalContent] = useState(
10221
+ null
10222
+ );
10223
+ const { handleSuccess } = useRouteModal();
10224
+ const { searchValue, onSearchValueChange, query: query2 } = useDebouncedSearch();
10225
+ const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
10226
+ const { mutateAsync: requestOrderEdit } = useDraftOrderRequestEdit(preview.id);
10227
+ const itemCount = ((_a = preview.items) == null ? void 0 : _a.reduce((acc, item) => acc + item.quantity, 0)) || 0;
10228
+ const matches = useMemo(() => {
10229
+ return matchSorter(preview.items, query2, {
10230
+ keys: ["product_title", "variant_title", "variant_sku", "title"]
10231
+ });
10232
+ }, [preview.items, query2]);
10233
+ const onSubmit = async () => {
10234
+ setIsSubmitting(true);
10235
+ let requestSucceeded = false;
10236
+ await requestOrderEdit(void 0, {
10237
+ onError: (e) => {
10238
+ toast.error(`Failed to request order edit: ${e.message}`);
10385
10239
  },
10386
- {
10387
- onSuccess: () => {
10388
- setEditing(false);
10389
- },
10390
- onError: (e) => {
10391
- toast.error(e.message);
10392
- }
10240
+ onSuccess: () => {
10241
+ requestSucceeded = true;
10393
10242
  }
10394
- );
10395
- });
10396
- 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: [
10397
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-3", children: [
10243
+ });
10244
+ if (!requestSucceeded) {
10245
+ setIsSubmitting(false);
10246
+ return;
10247
+ }
10248
+ await confirmOrderEdit(void 0, {
10249
+ onError: (e) => {
10250
+ toast.error(`Failed to confirm order edit: ${e.message}`);
10251
+ },
10252
+ onSuccess: () => {
10253
+ handleSuccess();
10254
+ },
10255
+ onSettled: () => {
10256
+ setIsSubmitting(false);
10257
+ }
10258
+ });
10259
+ };
10260
+ const onKeyDown = useCallback(
10261
+ (e) => {
10262
+ if (e.key === "Enter" && (e.ctrlKey || e.metaKey)) {
10263
+ if (modalContent || isSubmitting) {
10264
+ return;
10265
+ }
10266
+ onSubmit();
10267
+ }
10268
+ },
10269
+ [modalContent, isSubmitting, onSubmit]
10270
+ );
10271
+ useEffect(() => {
10272
+ document.addEventListener("keydown", onKeyDown);
10273
+ return () => {
10274
+ document.removeEventListener("keydown", onKeyDown);
10275
+ };
10276
+ }, [onKeyDown]);
10277
+ return /* @__PURE__ */ jsxs("div", { className: "flex h-full flex-col overflow-hidden", children: [
10278
+ /* @__PURE__ */ jsx(RouteFocusModal.Header, {}),
10279
+ /* @__PURE__ */ jsx(RouteFocusModal.Body, { className: "flex flex-1 flex-col overflow-hidden", children: /* @__PURE__ */ jsxs(
10280
+ StackedFocusModal,
10281
+ {
10282
+ id: STACKED_MODAL_ID,
10283
+ onOpenChangeCallback: (open) => {
10284
+ if (!open) {
10285
+ setModalContent(null);
10286
+ }
10287
+ },
10288
+ children: [
10289
+ /* @__PURE__ */ jsx("div", { className: "flex flex-1 flex-col items-center overflow-y-auto", children: /* @__PURE__ */ jsxs("div", { className: "flex w-full max-w-[720px] flex-col gap-y-6 px-6 py-16", children: [
10290
+ /* @__PURE__ */ jsxs("div", { children: [
10291
+ /* @__PURE__ */ jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Items" }) }),
10292
+ /* @__PURE__ */ jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Edit the items in the draft order" }) })
10293
+ ] }),
10294
+ /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
10295
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-y-6", children: [
10296
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 items-center gap-3", children: [
10297
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
10298
+ /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: "Items" }),
10299
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Choose items from the product catalog." })
10300
+ ] }),
10301
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
10302
+ /* @__PURE__ */ jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsx(
10303
+ Input,
10304
+ {
10305
+ type: "search",
10306
+ placeholder: "Search items",
10307
+ value: searchValue,
10308
+ onChange: (e) => onSearchValueChange(e.target.value)
10309
+ }
10310
+ ) }),
10311
+ /* @__PURE__ */ jsxs(DropdownMenu, { children: [
10312
+ /* @__PURE__ */ jsx(DropdownMenu.Trigger, { asChild: true, children: /* @__PURE__ */ jsx(IconButton, { type: "button", children: /* @__PURE__ */ jsx(Plus, {}) }) }),
10313
+ /* @__PURE__ */ jsxs(DropdownMenu.Content, { children: [
10314
+ /* @__PURE__ */ jsx(
10315
+ StackedModalTrigger$1,
10316
+ {
10317
+ type: "add-items",
10318
+ setModalContent
10319
+ }
10320
+ ),
10321
+ /* @__PURE__ */ jsx(
10322
+ StackedModalTrigger$1,
10323
+ {
10324
+ type: "add-custom-item",
10325
+ setModalContent
10326
+ }
10327
+ )
10328
+ ] })
10329
+ ] })
10330
+ ] })
10331
+ ] }),
10332
+ /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-subtle shadow-elevation-card-rest rounded-xl", children: [
10333
+ /* @__PURE__ */ jsx("div", { className: "px-[5px]", children: /* @__PURE__ */ jsxs("div", { className: "text-ui-fg-muted grid grid-cols-[2fr_1fr_2fr_28px] gap-3 px-4 py-2", children: [
10334
+ /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: "Item" }) }),
10335
+ /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: "Quantity" }) }),
10336
+ /* @__PURE__ */ jsx("div", { className: "text-right", children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: "Price" }) }),
10337
+ /* @__PURE__ */ jsx("div", {})
10338
+ ] }) }),
10339
+ /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-y-1.5 px-[5px] pb-[5px]", children: itemCount <= 0 ? /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest flex flex-col items-center justify-center gap-1 gap-x-3 rounded-lg p-4", children: [
10340
+ /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: "There are no items in this order" }),
10341
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Add items to the order to get started." })
10342
+ ] }) : matches.length > 0 ? matches == null ? void 0 : matches.map((item) => /* @__PURE__ */ jsx(
10343
+ Item,
10344
+ {
10345
+ item,
10346
+ preview,
10347
+ currencyCode
10348
+ },
10349
+ item.id
10350
+ )) : /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest flex flex-col items-center justify-center gap-1 gap-x-3 rounded-lg p-4", children: [
10351
+ /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: "No items found" }),
10352
+ /* @__PURE__ */ jsxs(Text, { size: "small", className: "text-ui-fg-subtle", children: [
10353
+ 'No items found for "',
10354
+ query2,
10355
+ '".'
10356
+ ] })
10357
+ ] }) })
10358
+ ] })
10359
+ ] }),
10360
+ /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
10361
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-[1fr_0.5fr_0.5fr] gap-3", children: [
10362
+ /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: "Subtotal" }) }),
10363
+ /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsxs(
10364
+ Text,
10365
+ {
10366
+ size: "small",
10367
+ leading: "compact",
10368
+ className: "text-ui-fg-subtle",
10369
+ children: [
10370
+ itemCount,
10371
+ " ",
10372
+ itemCount === 1 ? "item" : "items"
10373
+ ]
10374
+ }
10375
+ ) }),
10376
+ /* @__PURE__ */ jsx("div", { className: "text-right", children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: getStylizedAmount(preview.item_subtotal, currencyCode) }) })
10377
+ ] })
10378
+ ] }) }),
10379
+ modalContent && (modalContent === "add-items" ? /* @__PURE__ */ jsx(ExistingItemsForm, { orderId: preview.id, items: preview.items }) : modalContent === "add-custom-item" ? /* @__PURE__ */ jsx(
10380
+ CustomItemForm,
10381
+ {
10382
+ orderId: preview.id,
10383
+ currencyCode
10384
+ }
10385
+ ) : null)
10386
+ ]
10387
+ }
10388
+ ) }),
10389
+ /* @__PURE__ */ jsx(RouteFocusModal.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
10390
+ /* @__PURE__ */ jsx(RouteFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
10398
10391
  /* @__PURE__ */ jsx(
10399
- Thumbnail,
10392
+ Button,
10400
10393
  {
10401
- thumbnail: item.thumbnail,
10402
- alt: item.title ?? void 0
10394
+ size: "small",
10395
+ type: "button",
10396
+ onClick: onSubmit,
10397
+ isLoading: isSubmitting,
10398
+ children: "Save"
10403
10399
  }
10404
- ),
10405
- editing ? /* @__PURE__ */ jsx(
10406
- Form$2.Field,
10400
+ )
10401
+ ] }) })
10402
+ ] });
10403
+ };
10404
+ const Item = ({ item, preview, currencyCode }) => {
10405
+ if (item.variant_id) {
10406
+ return /* @__PURE__ */ jsx(VariantItem, { item, preview, currencyCode });
10407
+ }
10408
+ return /* @__PURE__ */ jsx(CustomItem, { item, preview, currencyCode });
10409
+ };
10410
+ const VariantItem = ({ item, preview, currencyCode }) => {
10411
+ const [editing, setEditing] = useState(false);
10412
+ const form = useForm({
10413
+ defaultValues: {
10414
+ quantity: item.quantity,
10415
+ unit_price: item.unit_price
10416
+ },
10417
+ resolver: zodResolver(variantItemSchema)
10418
+ });
10419
+ const actionId = useMemo(() => {
10420
+ var _a, _b;
10421
+ return (_b = (_a = item.actions) == null ? void 0 : _a.find((a) => a.action === "ITEM_ADD")) == null ? void 0 : _b.id;
10422
+ }, [item]);
10423
+ const { mutateAsync: updateActionItem, isPending: isUpdatingActionItem } = useDraftOrderUpdateActionItem(preview.id);
10424
+ const { mutateAsync: updateOriginalItem, isPending: isUpdatingOriginalItem } = useDraftOrderUpdateItem(preview.id);
10425
+ const isPending = isUpdatingActionItem || isUpdatingOriginalItem;
10426
+ const onSubmit = form.handleSubmit(async (data) => {
10427
+ if (convertNumber(data.unit_price) === item.unit_price && data.quantity === item.quantity) {
10428
+ setEditing(false);
10429
+ return;
10430
+ }
10431
+ if (!actionId) {
10432
+ await updateOriginalItem(
10407
10433
  {
10408
- control: form.control,
10409
- name: "title",
10410
- render: ({ field }) => {
10411
- return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }) });
10434
+ item_id: item.id,
10435
+ quantity: data.quantity,
10436
+ unit_price: convertNumber(data.unit_price)
10437
+ },
10438
+ {
10439
+ onSuccess: () => {
10440
+ setEditing(false);
10441
+ },
10442
+ onError: (e) => {
10443
+ toast.error(e.message);
10412
10444
  }
10413
10445
  }
10414
- ) : /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: item.title })
10415
- ] }),
10416
- editing ? /* @__PURE__ */ jsx(
10417
- Form$2.Field,
10446
+ );
10447
+ return;
10448
+ }
10449
+ await updateActionItem(
10418
10450
  {
10419
- control: form.control,
10420
- name: "quantity",
10421
- render: ({ field }) => {
10422
- return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(NumberInput, { ...field }) }) });
10423
- }
10424
- }
10425
- ) : /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: item.quantity }),
10426
- editing ? /* @__PURE__ */ jsx(
10427
- Form$2.Field,
10451
+ action_id: actionId,
10452
+ quantity: data.quantity,
10453
+ unit_price: convertNumber(data.unit_price)
10454
+ },
10428
10455
  {
10429
- control: form.control,
10430
- name: "unit_price",
10431
- render: ({ field: { onChange, ...field } }) => {
10432
- return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
10433
- CurrencyInput,
10434
- {
10435
- ...field,
10436
- symbol: getNativeSymbol(currencyCode),
10437
- code: currencyCode,
10438
- onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value)
10439
- }
10440
- ) }) });
10456
+ onSuccess: () => {
10457
+ setEditing(false);
10458
+ },
10459
+ onError: (e) => {
10460
+ toast.error(e.message);
10441
10461
  }
10442
10462
  }
10443
- ) : /* @__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) }) }),
10444
- /* @__PURE__ */ jsx(
10445
- IconButton,
10446
- {
10447
- type: "button",
10448
- size: "small",
10449
- onClick: editing ? onSubmit : () => {
10450
- setEditing(true);
10463
+ );
10464
+ });
10465
+ 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: [
10466
+ /* @__PURE__ */ jsxs("div", { className: "flex w-full items-center gap-x-3", children: [
10467
+ /* @__PURE__ */ jsx(
10468
+ Thumbnail,
10469
+ {
10470
+ thumbnail: item.thumbnail,
10471
+ alt: item.product_title ?? void 0
10472
+ }
10473
+ ),
10474
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
10475
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-1", children: [
10476
+ /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: item.product_title }),
10477
+ /* @__PURE__ */ jsxs(
10478
+ Text,
10479
+ {
10480
+ size: "small",
10481
+ leading: "compact",
10482
+ className: "text-ui-fg-subtle",
10483
+ children: [
10484
+ "(",
10485
+ item.variant_title,
10486
+ ")"
10487
+ ]
10488
+ }
10489
+ )
10490
+ ] }),
10491
+ /* @__PURE__ */ jsx(
10492
+ Text,
10493
+ {
10494
+ size: "small",
10495
+ leading: "compact",
10496
+ className: "text-ui-fg-subtle",
10497
+ children: item.variant_sku
10498
+ }
10499
+ )
10500
+ ] })
10501
+ ] }),
10502
+ editing ? /* @__PURE__ */ jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsx(
10503
+ Form$2.Field,
10504
+ {
10505
+ control: form.control,
10506
+ name: "quantity",
10507
+ render: ({ field }) => {
10508
+ return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(NumberInput, { ...field }) }) });
10509
+ }
10510
+ }
10511
+ ) }) : /* @__PURE__ */ jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: item.quantity }) }),
10512
+ editing ? /* @__PURE__ */ jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsx(
10513
+ Form$2.Field,
10514
+ {
10515
+ control: form.control,
10516
+ name: "unit_price",
10517
+ render: ({ field: { onChange, ...field } }) => {
10518
+ return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
10519
+ CurrencyInput,
10520
+ {
10521
+ ...field,
10522
+ symbol: getNativeSymbol(currencyCode),
10523
+ code: currencyCode,
10524
+ onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value)
10525
+ }
10526
+ ) }) });
10527
+ }
10528
+ }
10529
+ ) }) : /* @__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) }) }),
10530
+ /* @__PURE__ */ jsx(
10531
+ IconButton,
10532
+ {
10533
+ type: "button",
10534
+ size: "small",
10535
+ onClick: editing ? onSubmit : () => {
10536
+ setEditing(true);
10537
+ },
10538
+ disabled: isPending,
10539
+ children: editing ? /* @__PURE__ */ jsx(Check, {}) : /* @__PURE__ */ jsx(PencilSquare, {})
10540
+ }
10541
+ )
10542
+ ] }) }) });
10543
+ };
10544
+ const variantItemSchema = objectType({
10545
+ quantity: numberType(),
10546
+ unit_price: unionType([numberType(), stringType()])
10547
+ });
10548
+ const CustomItem = ({ item, preview, currencyCode }) => {
10549
+ const [editing, setEditing] = useState(false);
10550
+ const { quantity, unit_price, title } = item;
10551
+ const form = useForm({
10552
+ defaultValues: {
10553
+ title,
10554
+ quantity,
10555
+ unit_price
10556
+ },
10557
+ resolver: zodResolver(customItemSchema)
10558
+ });
10559
+ useEffect(() => {
10560
+ form.reset({
10561
+ title,
10562
+ quantity,
10563
+ unit_price
10564
+ });
10565
+ }, [form, title, quantity, unit_price]);
10566
+ const actionId = useMemo(() => {
10567
+ var _a, _b;
10568
+ return (_b = (_a = item.actions) == null ? void 0 : _a.find((a) => a.action === "ITEM_ADD")) == null ? void 0 : _b.id;
10569
+ }, [item]);
10570
+ const { mutateAsync: updateActionItem, isPending: isUpdatingActionItem } = useDraftOrderUpdateActionItem(preview.id);
10571
+ const { mutateAsync: removeActionItem, isPending: isRemovingActionItem } = useDraftOrderRemoveActionItem(preview.id);
10572
+ const { mutateAsync: updateOriginalItem, isPending: isUpdatingOriginalItem } = useDraftOrderUpdateItem(preview.id);
10573
+ const isPending = isUpdatingActionItem || isUpdatingOriginalItem;
10574
+ const onSubmit = form.handleSubmit(async (data) => {
10575
+ if (convertNumber(data.unit_price) === item.unit_price && data.quantity === item.quantity && data.title === item.title) {
10576
+ setEditing(false);
10577
+ return;
10578
+ }
10579
+ if (!actionId) {
10580
+ await updateOriginalItem(
10581
+ {
10582
+ item_id: item.id,
10583
+ quantity: data.quantity,
10584
+ unit_price: convertNumber(data.unit_price)
10585
+ },
10586
+ {
10587
+ onSuccess: () => {
10588
+ setEditing(false);
10589
+ },
10590
+ onError: (e) => {
10591
+ toast.error(e.message);
10592
+ }
10593
+ }
10594
+ );
10595
+ return;
10596
+ }
10597
+ if (data.quantity === 0) {
10598
+ await removeActionItem(actionId, {
10599
+ onSuccess: () => {
10600
+ setEditing(false);
10601
+ },
10602
+ onError: (e) => {
10603
+ toast.error(e.message);
10604
+ }
10605
+ });
10606
+ return;
10607
+ }
10608
+ await updateActionItem(
10609
+ {
10610
+ action_id: actionId,
10611
+ quantity: data.quantity,
10612
+ unit_price: convertNumber(data.unit_price)
10613
+ },
10614
+ {
10615
+ onSuccess: () => {
10616
+ setEditing(false);
10617
+ },
10618
+ onError: (e) => {
10619
+ toast.error(e.message);
10620
+ }
10621
+ }
10622
+ );
10623
+ });
10624
+ 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: [
10625
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-3", children: [
10626
+ /* @__PURE__ */ jsx(
10627
+ Thumbnail,
10628
+ {
10629
+ thumbnail: item.thumbnail,
10630
+ alt: item.title ?? void 0
10631
+ }
10632
+ ),
10633
+ editing ? /* @__PURE__ */ jsx(
10634
+ Form$2.Field,
10635
+ {
10636
+ control: form.control,
10637
+ name: "title",
10638
+ render: ({ field }) => {
10639
+ return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }) });
10640
+ }
10641
+ }
10642
+ ) : /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: item.title })
10643
+ ] }),
10644
+ editing ? /* @__PURE__ */ jsx(
10645
+ Form$2.Field,
10646
+ {
10647
+ control: form.control,
10648
+ name: "quantity",
10649
+ render: ({ field }) => {
10650
+ return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(NumberInput, { ...field }) }) });
10651
+ }
10652
+ }
10653
+ ) : /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: item.quantity }),
10654
+ editing ? /* @__PURE__ */ jsx(
10655
+ Form$2.Field,
10656
+ {
10657
+ control: form.control,
10658
+ name: "unit_price",
10659
+ render: ({ field: { onChange, ...field } }) => {
10660
+ return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
10661
+ CurrencyInput,
10662
+ {
10663
+ ...field,
10664
+ symbol: getNativeSymbol(currencyCode),
10665
+ code: currencyCode,
10666
+ onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value)
10667
+ }
10668
+ ) }) });
10669
+ }
10670
+ }
10671
+ ) : /* @__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) }) }),
10672
+ /* @__PURE__ */ jsx(
10673
+ IconButton,
10674
+ {
10675
+ type: "button",
10676
+ size: "small",
10677
+ onClick: editing ? onSubmit : () => {
10678
+ setEditing(true);
10451
10679
  },
10452
10680
  disabled: isPending,
10453
10681
  children: editing ? /* @__PURE__ */ jsx(Check, {}) : /* @__PURE__ */ jsx(PencilSquare, {})
@@ -10752,91 +10980,23 @@ const customItemSchema = objectType({
10752
10980
  quantity: numberType(),
10753
10981
  unit_price: unionType([numberType(), stringType()])
10754
10982
  });
10755
- const Email = () => {
10756
- const { id } = useParams();
10757
- const { order, isPending, isError, error } = useOrder(id, {
10758
- fields: "+email"
10759
- });
10760
- if (isError) {
10761
- throw error;
10762
- }
10763
- const isReady = !isPending && !!order;
10764
- return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
10765
- /* @__PURE__ */ jsxs(RouteDrawer.Header, { children: [
10766
- /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Email" }) }),
10767
- /* @__PURE__ */ jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Edit the email for the draft order" }) })
10768
- ] }),
10769
- isReady && /* @__PURE__ */ jsx(EmailForm, { order })
10770
- ] });
10983
+ const PROMOTION_QUERY_KEY = "promotions";
10984
+ const promotionsQueryKeys = {
10985
+ list: (query2) => [
10986
+ PROMOTION_QUERY_KEY,
10987
+ query2 ? query2 : void 0
10988
+ ],
10989
+ detail: (id, query2) => [
10990
+ PROMOTION_QUERY_KEY,
10991
+ id,
10992
+ query2 ? query2 : void 0
10993
+ ]
10771
10994
  };
10772
- const EmailForm = ({ order }) => {
10773
- const form = useForm({
10774
- defaultValues: {
10775
- email: order.email ?? ""
10776
- },
10777
- resolver: zodResolver(schema$3)
10778
- });
10779
- const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
10780
- const { handleSuccess } = useRouteModal();
10781
- const onSubmit = form.handleSubmit(async (data) => {
10782
- await mutateAsync(
10783
- { email: data.email },
10784
- {
10785
- onSuccess: () => {
10786
- handleSuccess();
10787
- },
10788
- onError: (error) => {
10789
- toast.error(error.message);
10790
- }
10791
- }
10792
- );
10793
- });
10794
- return /* @__PURE__ */ jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxs(
10795
- KeyboundForm,
10796
- {
10797
- className: "flex flex-1 flex-col overflow-hidden",
10798
- onSubmit,
10799
- children: [
10800
- /* @__PURE__ */ jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsx(
10801
- Form$2.Field,
10802
- {
10803
- control: form.control,
10804
- name: "email",
10805
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
10806
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Email" }),
10807
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
10808
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
10809
- ] })
10810
- }
10811
- ) }),
10812
- /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
10813
- /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
10814
- /* @__PURE__ */ jsx(Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
10815
- ] }) })
10816
- ]
10817
- }
10818
- ) });
10819
- };
10820
- const schema$3 = objectType({
10821
- email: stringType().email()
10822
- });
10823
- const PROMOTION_QUERY_KEY = "promotions";
10824
- const promotionsQueryKeys = {
10825
- list: (query2) => [
10826
- PROMOTION_QUERY_KEY,
10827
- query2 ? query2 : void 0
10828
- ],
10829
- detail: (id, query2) => [
10830
- PROMOTION_QUERY_KEY,
10831
- id,
10832
- query2 ? query2 : void 0
10833
- ]
10834
- };
10835
- const usePromotions = (query2, options) => {
10836
- const { data, ...rest } = useQuery({
10837
- queryKey: promotionsQueryKeys.list(query2),
10838
- queryFn: async () => sdk.admin.promotion.list(query2),
10839
- ...options
10995
+ const usePromotions = (query2, options) => {
10996
+ const { data, ...rest } = useQuery({
10997
+ queryKey: promotionsQueryKeys.list(query2),
10998
+ queryFn: async () => sdk.admin.promotion.list(query2),
10999
+ ...options
10840
11000
  });
10841
11001
  return { ...data, ...rest };
10842
11002
  };
@@ -11097,54 +11257,116 @@ function getPromotionIds(items, shippingMethods) {
11097
11257
  }
11098
11258
  return Array.from(promotionIds);
11099
11259
  }
11100
- const InlineTip = forwardRef(
11101
- ({ variant = "tip", label, className, children, ...props }, ref) => {
11102
- const labelValue = label || (variant === "warning" ? "Warning" : "Tip");
11103
- return /* @__PURE__ */ jsxs(
11104
- "div",
11260
+ const SalesChannel = () => {
11261
+ const { id } = useParams();
11262
+ const { draft_order, isPending, isError, error } = useDraftOrder(
11263
+ id,
11264
+ {
11265
+ fields: "+sales_channel_id"
11266
+ },
11267
+ {
11268
+ enabled: !!id
11269
+ }
11270
+ );
11271
+ if (isError) {
11272
+ throw error;
11273
+ }
11274
+ const ISrEADY = !!draft_order && !isPending;
11275
+ return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
11276
+ /* @__PURE__ */ jsxs(RouteDrawer.Header, { children: [
11277
+ /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Sales Channel" }) }),
11278
+ /* @__PURE__ */ jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Update which sales channel the draft order is associated with" }) })
11279
+ ] }),
11280
+ ISrEADY && /* @__PURE__ */ jsx(SalesChannelForm, { order: draft_order })
11281
+ ] });
11282
+ };
11283
+ const SalesChannelForm = ({ order }) => {
11284
+ const form = useForm({
11285
+ defaultValues: {
11286
+ sales_channel_id: order.sales_channel_id || ""
11287
+ },
11288
+ resolver: zodResolver(schema$3)
11289
+ });
11290
+ const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
11291
+ const { handleSuccess } = useRouteModal();
11292
+ const onSubmit = form.handleSubmit(async (data) => {
11293
+ await mutateAsync(
11105
11294
  {
11106
- ref,
11107
- className: clx(
11108
- "bg-ui-bg-component txt-small text-ui-fg-subtle grid grid-cols-[4px_1fr] items-start gap-3 rounded-lg border p-3",
11109
- className
11110
- ),
11111
- ...props,
11112
- children: [
11113
- /* @__PURE__ */ jsx(
11114
- "div",
11295
+ sales_channel_id: data.sales_channel_id
11296
+ },
11297
+ {
11298
+ onSuccess: () => {
11299
+ toast.success("Sales channel updated");
11300
+ handleSuccess();
11301
+ },
11302
+ onError: (error) => {
11303
+ toast.error(error.message);
11304
+ }
11305
+ }
11306
+ );
11307
+ });
11308
+ return /* @__PURE__ */ jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxs(
11309
+ KeyboundForm,
11310
+ {
11311
+ className: "flex flex-1 flex-col overflow-hidden",
11312
+ onSubmit,
11313
+ children: [
11314
+ /* @__PURE__ */ jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsx(SalesChannelField, { control: form.control, order }) }),
11315
+ /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
11316
+ /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
11317
+ /* @__PURE__ */ jsx(Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
11318
+ ] }) })
11319
+ ]
11320
+ }
11321
+ ) });
11322
+ };
11323
+ const SalesChannelField = ({ control, order }) => {
11324
+ const salesChannels = useComboboxData({
11325
+ queryFn: async (params) => {
11326
+ return await sdk.admin.salesChannel.list(params);
11327
+ },
11328
+ queryKey: ["sales-channels"],
11329
+ getOptions: (data) => {
11330
+ return data.sales_channels.map((salesChannel) => ({
11331
+ label: salesChannel.name,
11332
+ value: salesChannel.id
11333
+ }));
11334
+ },
11335
+ defaultValue: order.sales_channel_id || void 0
11336
+ });
11337
+ return /* @__PURE__ */ jsx(
11338
+ Form$2.Field,
11339
+ {
11340
+ control,
11341
+ name: "sales_channel_id",
11342
+ render: ({ field }) => {
11343
+ return /* @__PURE__ */ jsxs(Form$2.Item, { children: [
11344
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Sales Channel" }),
11345
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
11346
+ Combobox,
11115
11347
  {
11116
- role: "presentation",
11117
- className: clx("w-4px bg-ui-tag-neutral-icon h-full rounded-full", {
11118
- "bg-ui-tag-orange-icon": variant === "warning"
11119
- })
11348
+ options: salesChannels.options,
11349
+ fetchNextPage: salesChannels.fetchNextPage,
11350
+ isFetchingNextPage: salesChannels.isFetchingNextPage,
11351
+ searchValue: salesChannels.searchValue,
11352
+ onSearchValueChange: salesChannels.onSearchValueChange,
11353
+ placeholder: "Select sales channel",
11354
+ ...field
11120
11355
  }
11121
- ),
11122
- /* @__PURE__ */ jsxs("div", { className: "text-pretty", children: [
11123
- /* @__PURE__ */ jsxs("strong", { className: "txt-small-plus text-ui-fg-base", children: [
11124
- labelValue,
11125
- ":"
11126
- ] }),
11127
- " ",
11128
- children
11129
- ] })
11130
- ]
11356
+ ) }),
11357
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11358
+ ] });
11131
11359
  }
11132
- );
11133
- }
11134
- );
11135
- InlineTip.displayName = "InlineTip";
11136
- const MetadataFieldSchema = objectType({
11137
- key: stringType(),
11138
- disabled: booleanType().optional(),
11139
- value: anyType()
11140
- });
11141
- const MetadataSchema = objectType({
11142
- metadata: arrayType(MetadataFieldSchema)
11360
+ }
11361
+ );
11362
+ };
11363
+ const schema$3 = objectType({
11364
+ sales_channel_id: stringType().min(1)
11143
11365
  });
11144
- const Metadata = () => {
11366
+ const ShippingAddress = () => {
11145
11367
  const { id } = useParams();
11146
11368
  const { order, isPending, isError, error } = useOrder(id, {
11147
- fields: "metadata"
11369
+ fields: "+shipping_address"
11148
11370
  });
11149
11371
  if (isError) {
11150
11372
  throw error;
@@ -11152,33 +11374,49 @@ const Metadata = () => {
11152
11374
  const isReady = !isPending && !!order;
11153
11375
  return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
11154
11376
  /* @__PURE__ */ jsxs(RouteDrawer.Header, { children: [
11155
- /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Metadata" }) }),
11156
- /* @__PURE__ */ jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Add metadata to the draft order." }) })
11377
+ /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Shipping Address" }) }),
11378
+ /* @__PURE__ */ jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Edit the shipping address for the draft order" }) })
11157
11379
  ] }),
11158
- !isReady ? /* @__PURE__ */ jsx(PlaceholderInner, {}) : /* @__PURE__ */ jsx(MetadataForm, { orderId: id, metadata: order == null ? void 0 : order.metadata })
11380
+ isReady && /* @__PURE__ */ jsx(ShippingAddressForm, { order })
11159
11381
  ] });
11160
11382
  };
11161
- const METADATA_KEY_LABEL_ID = "metadata-form-key-label";
11162
- const METADATA_VALUE_LABEL_ID = "metadata-form-value-label";
11163
- const MetadataForm = ({ orderId, metadata }) => {
11164
- const { handleSuccess } = useRouteModal();
11165
- const hasUneditableRows = getHasUneditableRows(metadata);
11166
- const { mutateAsync, isPending } = useUpdateDraftOrder(orderId);
11383
+ const ShippingAddressForm = ({ order }) => {
11384
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
11167
11385
  const form = useForm({
11168
11386
  defaultValues: {
11169
- metadata: getDefaultValues(metadata)
11387
+ first_name: ((_a = order.shipping_address) == null ? void 0 : _a.first_name) ?? "",
11388
+ last_name: ((_b = order.shipping_address) == null ? void 0 : _b.last_name) ?? "",
11389
+ company: ((_c = order.shipping_address) == null ? void 0 : _c.company) ?? "",
11390
+ address_1: ((_d = order.shipping_address) == null ? void 0 : _d.address_1) ?? "",
11391
+ address_2: ((_e = order.shipping_address) == null ? void 0 : _e.address_2) ?? "",
11392
+ city: ((_f = order.shipping_address) == null ? void 0 : _f.city) ?? "",
11393
+ province: ((_g = order.shipping_address) == null ? void 0 : _g.province) ?? "",
11394
+ country_code: ((_h = order.shipping_address) == null ? void 0 : _h.country_code) ?? "",
11395
+ postal_code: ((_i = order.shipping_address) == null ? void 0 : _i.postal_code) ?? "",
11396
+ phone: ((_j = order.shipping_address) == null ? void 0 : _j.phone) ?? ""
11170
11397
  },
11171
- resolver: zodResolver(MetadataSchema)
11398
+ resolver: zodResolver(schema$2)
11172
11399
  });
11173
- const handleSubmit = form.handleSubmit(async (data) => {
11174
- const parsedData = parseValues(data);
11400
+ const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
11401
+ const { handleSuccess } = useRouteModal();
11402
+ const onSubmit = form.handleSubmit(async (data) => {
11175
11403
  await mutateAsync(
11176
11404
  {
11177
- metadata: parsedData
11405
+ shipping_address: {
11406
+ first_name: data.first_name,
11407
+ last_name: data.last_name,
11408
+ company: data.company,
11409
+ address_1: data.address_1,
11410
+ address_2: data.address_2,
11411
+ city: data.city,
11412
+ province: data.province,
11413
+ country_code: data.country_code,
11414
+ postal_code: data.postal_code,
11415
+ phone: data.phone
11416
+ }
11178
11417
  },
11179
11418
  {
11180
11419
  onSuccess: () => {
11181
- toast.success("Metadata updated");
11182
11420
  handleSuccess();
11183
11421
  },
11184
11422
  onError: (error) => {
@@ -11187,266 +11425,147 @@ const MetadataForm = ({ orderId, metadata }) => {
11187
11425
  }
11188
11426
  );
11189
11427
  });
11190
- const { fields, insert, remove } = useFieldArray({
11191
- control: form.control,
11192
- name: "metadata"
11193
- });
11194
- function deleteRow(index) {
11195
- remove(index);
11196
- if (fields.length === 1) {
11197
- insert(0, {
11198
- key: "",
11199
- value: "",
11200
- disabled: false
11201
- });
11202
- }
11203
- }
11204
- function insertRow(index, position) {
11205
- insert(index + (position === "above" ? 0 : 1), {
11206
- key: "",
11207
- value: "",
11208
- disabled: false
11209
- });
11210
- }
11211
11428
  return /* @__PURE__ */ jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxs(
11212
11429
  KeyboundForm,
11213
11430
  {
11214
- onSubmit: handleSubmit,
11215
11431
  className: "flex flex-1 flex-col overflow-hidden",
11432
+ onSubmit,
11216
11433
  children: [
11217
- /* @__PURE__ */ jsxs(RouteDrawer.Body, { className: "flex flex-1 flex-col gap-y-8 overflow-y-auto", children: [
11218
- /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest grid grid-cols-1 divide-y rounded-lg", children: [
11219
- /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-subtle grid grid-cols-2 divide-x rounded-t-lg", children: [
11220
- /* @__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" }) }),
11221
- /* @__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" }) })
11222
- ] }),
11223
- fields.map((field, index) => {
11224
- const isDisabled = field.disabled || false;
11225
- let placeholder = "-";
11226
- if (typeof field.value === "object") {
11227
- placeholder = "{ ... }";
11434
+ /* @__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: [
11435
+ /* @__PURE__ */ jsx(
11436
+ Form$2.Field,
11437
+ {
11438
+ control: form.control,
11439
+ name: "country_code",
11440
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
11441
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Country" }),
11442
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(CountrySelect, { ...field }) }),
11443
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11444
+ ] })
11445
+ }
11446
+ ),
11447
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
11448
+ /* @__PURE__ */ jsx(
11449
+ Form$2.Field,
11450
+ {
11451
+ control: form.control,
11452
+ name: "first_name",
11453
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
11454
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "First name" }),
11455
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
11456
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11457
+ ] })
11228
11458
  }
11229
- if (Array.isArray(field.value)) {
11230
- placeholder = "[ ... ]";
11459
+ ),
11460
+ /* @__PURE__ */ jsx(
11461
+ Form$2.Field,
11462
+ {
11463
+ control: form.control,
11464
+ name: "last_name",
11465
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
11466
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Last name" }),
11467
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
11468
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11469
+ ] })
11231
11470
  }
11232
- return /* @__PURE__ */ jsx(
11233
- ConditionalTooltip,
11234
- {
11235
- showTooltip: isDisabled,
11236
- content: "This row is disabled because it contains non-primitive data.",
11237
- children: /* @__PURE__ */ jsxs("div", { className: "group/table relative", children: [
11238
- /* @__PURE__ */ jsxs(
11239
- "div",
11240
- {
11241
- className: clx("grid grid-cols-2 divide-x", {
11242
- "overflow-hidden rounded-b-lg": index === fields.length - 1
11243
- }),
11244
- children: [
11245
- /* @__PURE__ */ jsx(
11246
- Form$2.Field,
11247
- {
11248
- control: form.control,
11249
- name: `metadata.${index}.key`,
11250
- render: ({ field: field2 }) => {
11251
- return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
11252
- GridInput,
11253
- {
11254
- "aria-labelledby": METADATA_KEY_LABEL_ID,
11255
- ...field2,
11256
- disabled: isDisabled,
11257
- placeholder: "Key"
11258
- }
11259
- ) }) });
11260
- }
11261
- }
11262
- ),
11263
- /* @__PURE__ */ jsx(
11264
- Form$2.Field,
11265
- {
11266
- control: form.control,
11267
- name: `metadata.${index}.value`,
11268
- render: ({ field: { value, ...field2 } }) => {
11269
- return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
11270
- GridInput,
11271
- {
11272
- "aria-labelledby": METADATA_VALUE_LABEL_ID,
11273
- ...field2,
11274
- value: isDisabled ? placeholder : value,
11275
- disabled: isDisabled,
11276
- placeholder: "Value"
11277
- }
11278
- ) }) });
11279
- }
11280
- }
11281
- )
11282
- ]
11283
- }
11284
- ),
11285
- /* @__PURE__ */ jsxs(DropdownMenu, { children: [
11286
- /* @__PURE__ */ jsx(
11287
- DropdownMenu.Trigger,
11288
- {
11289
- className: clx(
11290
- "invisible absolute inset-y-0 -right-2.5 my-auto group-hover/table:visible data-[state='open']:visible",
11291
- {
11292
- hidden: isDisabled
11293
- }
11294
- ),
11295
- disabled: isDisabled,
11296
- asChild: true,
11297
- children: /* @__PURE__ */ jsx(IconButton, { size: "2xsmall", children: /* @__PURE__ */ jsx(EllipsisVertical, {}) })
11298
- }
11299
- ),
11300
- /* @__PURE__ */ jsxs(DropdownMenu.Content, { children: [
11301
- /* @__PURE__ */ jsxs(
11302
- DropdownMenu.Item,
11303
- {
11304
- className: "gap-x-2",
11305
- onClick: () => insertRow(index, "above"),
11306
- children: [
11307
- /* @__PURE__ */ jsx(ArrowUpMini, { className: "text-ui-fg-subtle" }),
11308
- "Insert row above"
11309
- ]
11310
- }
11311
- ),
11312
- /* @__PURE__ */ jsxs(
11313
- DropdownMenu.Item,
11314
- {
11315
- className: "gap-x-2",
11316
- onClick: () => insertRow(index, "below"),
11317
- children: [
11318
- /* @__PURE__ */ jsx(ArrowDownMini, { className: "text-ui-fg-subtle" }),
11319
- "Insert row below"
11320
- ]
11321
- }
11322
- ),
11323
- /* @__PURE__ */ jsx(DropdownMenu.Separator, {}),
11324
- /* @__PURE__ */ jsxs(
11325
- DropdownMenu.Item,
11326
- {
11327
- className: "gap-x-2",
11328
- onClick: () => deleteRow(index),
11329
- children: [
11330
- /* @__PURE__ */ jsx(Trash, { className: "text-ui-fg-subtle" }),
11331
- "Delete row"
11332
- ]
11333
- }
11334
- )
11335
- ] })
11336
- ] })
11337
- ] })
11338
- },
11339
- field.id
11340
- );
11341
- })
11471
+ )
11342
11472
  ] }),
11343
- 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." })
11344
- ] }),
11345
- /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
11346
- /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
11347
- /* @__PURE__ */ jsx(Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
11348
- ] }) })
11349
- ]
11350
- }
11351
- ) });
11352
- };
11353
- const GridInput = forwardRef(({ className, ...props }, ref) => {
11354
- return /* @__PURE__ */ jsx(
11355
- "input",
11356
- {
11357
- ref,
11358
- ...props,
11359
- autoComplete: "off",
11360
- className: clx(
11361
- "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",
11362
- className
11363
- )
11364
- }
11365
- );
11366
- });
11367
- GridInput.displayName = "MetadataForm.GridInput";
11368
- const PlaceholderInner = () => {
11369
- return /* @__PURE__ */ jsxs("div", { className: "flex flex-1 flex-col overflow-hidden", children: [
11370
- /* @__PURE__ */ jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsx(Skeleton, { className: "h-[148ox] w-full rounded-lg" }) }),
11371
- /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
11372
- /* @__PURE__ */ jsx(Skeleton, { className: "h-7 w-12 rounded-md" }),
11373
- /* @__PURE__ */ jsx(Skeleton, { className: "h-7 w-12 rounded-md" })
11374
- ] }) })
11375
- ] });
11376
- };
11377
- const EDITABLE_TYPES = ["string", "number", "boolean"];
11378
- function getDefaultValues(metadata) {
11379
- if (!metadata || !Object.keys(metadata).length) {
11380
- return [
11381
- {
11382
- key: "",
11383
- value: "",
11384
- disabled: false
11385
- }
11386
- ];
11387
- }
11388
- return Object.entries(metadata).map(([key, value]) => {
11389
- if (!EDITABLE_TYPES.includes(typeof value)) {
11390
- return {
11391
- key,
11392
- value,
11393
- disabled: true
11394
- };
11395
- }
11396
- let stringValue = value;
11397
- if (typeof value !== "string") {
11398
- stringValue = JSON.stringify(value);
11399
- }
11400
- return {
11401
- key,
11402
- value: stringValue,
11403
- original_key: key
11404
- };
11405
- });
11406
- }
11407
- function parseValues(values) {
11408
- const metadata = values.metadata;
11409
- const isEmpty = !metadata.length || metadata.length === 1 && !metadata[0].key && !metadata[0].value;
11410
- if (isEmpty) {
11411
- return null;
11412
- }
11413
- const update = {};
11414
- metadata.forEach((field) => {
11415
- let key = field.key;
11416
- let value = field.value;
11417
- const disabled = field.disabled;
11418
- if (!key || !value) {
11419
- return;
11420
- }
11421
- if (disabled) {
11422
- update[key] = value;
11423
- return;
11424
- }
11425
- key = key.trim();
11426
- value = value.trim();
11427
- if (value === "true") {
11428
- update[key] = true;
11429
- } else if (value === "false") {
11430
- update[key] = false;
11431
- } else {
11432
- const parsedNumber = parseFloat(value);
11433
- if (!isNaN(parsedNumber)) {
11434
- update[key] = parsedNumber;
11435
- } else {
11436
- update[key] = value;
11437
- }
11473
+ /* @__PURE__ */ jsx(
11474
+ Form$2.Field,
11475
+ {
11476
+ control: form.control,
11477
+ name: "company",
11478
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
11479
+ /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Company" }),
11480
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
11481
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11482
+ ] })
11483
+ }
11484
+ ),
11485
+ /* @__PURE__ */ jsx(
11486
+ Form$2.Field,
11487
+ {
11488
+ control: form.control,
11489
+ name: "address_1",
11490
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
11491
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Address" }),
11492
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
11493
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11494
+ ] })
11495
+ }
11496
+ ),
11497
+ /* @__PURE__ */ jsx(
11498
+ Form$2.Field,
11499
+ {
11500
+ control: form.control,
11501
+ name: "address_2",
11502
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
11503
+ /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Apartment, suite, etc." }),
11504
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
11505
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11506
+ ] })
11507
+ }
11508
+ ),
11509
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
11510
+ /* @__PURE__ */ jsx(
11511
+ Form$2.Field,
11512
+ {
11513
+ control: form.control,
11514
+ name: "postal_code",
11515
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
11516
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Postal code" }),
11517
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
11518
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11519
+ ] })
11520
+ }
11521
+ ),
11522
+ /* @__PURE__ */ jsx(
11523
+ Form$2.Field,
11524
+ {
11525
+ control: form.control,
11526
+ name: "city",
11527
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
11528
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "City" }),
11529
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
11530
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11531
+ ] })
11532
+ }
11533
+ )
11534
+ ] }),
11535
+ /* @__PURE__ */ jsx(
11536
+ Form$2.Field,
11537
+ {
11538
+ control: form.control,
11539
+ name: "province",
11540
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
11541
+ /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Province / State" }),
11542
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
11543
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11544
+ ] })
11545
+ }
11546
+ ),
11547
+ /* @__PURE__ */ jsx(
11548
+ Form$2.Field,
11549
+ {
11550
+ control: form.control,
11551
+ name: "phone",
11552
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
11553
+ /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Phone" }),
11554
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
11555
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11556
+ ] })
11557
+ }
11558
+ )
11559
+ ] }) }),
11560
+ /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
11561
+ /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
11562
+ /* @__PURE__ */ jsx(Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
11563
+ ] }) })
11564
+ ]
11438
11565
  }
11439
- });
11440
- return update;
11441
- }
11442
- function getHasUneditableRows(metadata) {
11443
- if (!metadata) {
11444
- return false;
11445
- }
11446
- return Object.values(metadata).some(
11447
- (value) => !EDITABLE_TYPES.includes(typeof value)
11448
- );
11449
- }
11566
+ ) });
11567
+ };
11568
+ const schema$2 = addressSchema;
11450
11569
  const STACKED_FOCUS_MODAL_ID = "shipping-form";
11451
11570
  const Shipping = () => {
11452
11571
  var _a;
@@ -11883,686 +12002,377 @@ const StackedModalTrigger = ({
11883
12002
  setData({
11884
12003
  shippingProfileId,
11885
12004
  shippingOption,
11886
- shippingMethod
11887
- });
11888
- }
11889
- };
11890
- return /* @__PURE__ */ jsx(
11891
- Button,
11892
- {
11893
- size: "small",
11894
- variant: "secondary",
11895
- onClick: onToggle,
11896
- className: "text-ui-fg-primary shrink-0",
11897
- children
11898
- }
11899
- );
11900
- };
11901
- const ShippingProfileForm = ({
11902
- data,
11903
- order,
11904
- preview
11905
- }) => {
11906
- var _a, _b, _c, _d, _e, _f;
11907
- const { setIsOpen } = useStackedModal();
11908
- const form = useForm({
11909
- resolver: zodResolver(shippingMethodSchema),
11910
- defaultValues: {
11911
- location_id: (_d = (_c = (_b = (_a = data.shippingOption) == null ? void 0 : _a.service_zone) == null ? void 0 : _b.fulfillment_set) == null ? void 0 : _c.location) == null ? void 0 : _d.id,
11912
- shipping_option_id: (_e = data.shippingOption) == null ? void 0 : _e.id,
11913
- custom_amount: (_f = data.shippingMethod) == null ? void 0 : _f.amount
11914
- }
11915
- });
11916
- const { mutateAsync: addShippingMethod, isPending } = useDraftOrderAddShippingMethod(order.id);
11917
- const {
11918
- mutateAsync: updateShippingMethod,
11919
- isPending: isUpdatingShippingMethod
11920
- } = useDraftOrderUpdateShippingMethod(order.id);
11921
- const onSubmit = form.handleSubmit(async (values) => {
11922
- if (isEqual(values, form.formState.defaultValues)) {
11923
- setIsOpen(STACKED_FOCUS_MODAL_ID, false);
11924
- return;
11925
- }
11926
- if (data.shippingMethod) {
11927
- await updateShippingMethod(
11928
- {
11929
- method_id: data.shippingMethod.id,
11930
- shipping_option_id: values.shipping_option_id,
11931
- custom_amount: values.custom_amount ? convertNumber(values.custom_amount) : void 0
11932
- },
11933
- {
11934
- onError: (e) => {
11935
- toast.error(e.message);
11936
- },
11937
- onSuccess: () => {
11938
- setIsOpen(STACKED_FOCUS_MODAL_ID, false);
11939
- }
11940
- }
11941
- );
11942
- return;
11943
- }
11944
- await addShippingMethod(
11945
- {
11946
- shipping_option_id: values.shipping_option_id,
11947
- custom_amount: values.custom_amount ? convertNumber(values.custom_amount) : void 0
11948
- },
11949
- {
11950
- onError: (e) => {
11951
- toast.error(e.message);
11952
- },
11953
- onSuccess: () => {
11954
- setIsOpen(STACKED_FOCUS_MODAL_ID, false);
11955
- }
11956
- }
11957
- );
11958
- });
11959
- return /* @__PURE__ */ jsx(StackedFocusModal.Content, { children: /* @__PURE__ */ jsx(Form$2, { ...form, children: /* @__PURE__ */ jsxs(
11960
- KeyboundForm,
11961
- {
11962
- className: "flex h-full flex-col overflow-hidden",
11963
- onSubmit,
11964
- children: [
11965
- /* @__PURE__ */ jsx(StackedFocusModal.Header, {}),
11966
- /* @__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 py-16 px-6", children: [
11967
- /* @__PURE__ */ jsxs("div", { children: [
11968
- /* @__PURE__ */ jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Shipping" }) }),
11969
- /* @__PURE__ */ jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Add a shipping method for the selected shipping profile. You can see the items that will be shipped using this method in the preview below." }) })
11970
- ] }),
11971
- /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
11972
- /* @__PURE__ */ jsx(
11973
- LocationField,
11974
- {
11975
- control: form.control,
11976
- setValue: form.setValue
11977
- }
11978
- ),
11979
- /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
11980
- /* @__PURE__ */ jsx(
11981
- ShippingOptionField,
11982
- {
11983
- shippingProfileId: data.shippingProfileId,
11984
- preview,
11985
- control: form.control
11986
- }
11987
- ),
11988
- /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
11989
- /* @__PURE__ */ jsx(
11990
- CustomAmountField,
11991
- {
11992
- control: form.control,
11993
- currencyCode: order.currency_code
11994
- }
11995
- ),
11996
- /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
11997
- /* @__PURE__ */ jsx(
11998
- ItemsPreview,
11999
- {
12000
- order,
12001
- shippingProfileId: data.shippingProfileId
12002
- }
12003
- )
12004
- ] }) }) }),
12005
- /* @__PURE__ */ jsx(StackedFocusModal.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-x-2", children: [
12006
- /* @__PURE__ */ jsx(StackedFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
12007
- /* @__PURE__ */ jsx(
12008
- Button,
12009
- {
12010
- size: "small",
12011
- type: "submit",
12012
- isLoading: isPending || isUpdatingShippingMethod,
12013
- children: data.shippingMethod ? "Update" : "Add"
12014
- }
12015
- )
12016
- ] }) })
12017
- ]
12018
- }
12019
- ) }) });
12020
- };
12021
- const shippingMethodSchema = objectType({
12022
- location_id: stringType(),
12023
- shipping_option_id: stringType(),
12024
- custom_amount: unionType([numberType(), stringType()]).optional()
12025
- });
12026
- const ItemsPreview = ({ order, shippingProfileId }) => {
12027
- const matches = order.items.filter(
12028
- (item) => {
12029
- var _a, _b, _c;
12030
- return ((_c = (_b = (_a = item.variant) == null ? void 0 : _a.product) == null ? void 0 : _b.shipping_profile) == null ? void 0 : _c.id) === shippingProfileId;
12031
- }
12032
- );
12033
- return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-y-6", children: [
12034
- /* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 items-center gap-3", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
12035
- /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: "Items to ship" }),
12036
- /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Items with the selected shipping profile." })
12037
- ] }) }),
12038
- /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-subtle shadow-elevation-card-rest rounded-xl", children: [
12039
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-3 px-4 py-2 text-ui-fg-muted", children: [
12040
- /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: "Item" }) }),
12041
- /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: "Quantity" }) })
12042
- ] }),
12043
- /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-y-1.5 px-[5px] pb-[5px]", children: matches.length > 0 ? matches == null ? void 0 : matches.map((item) => /* @__PURE__ */ jsxs(
12044
- "div",
12045
- {
12046
- className: "grid grid-cols-2 gap-3 px-4 py-2 bg-ui-bg-base shadow-elevation-card-rest rounded-lg items-center",
12047
- children: [
12048
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-3", children: [
12049
- /* @__PURE__ */ jsx(
12050
- Thumbnail,
12051
- {
12052
- thumbnail: item.thumbnail,
12053
- alt: item.product_title ?? void 0
12054
- }
12055
- ),
12056
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
12057
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-1", children: [
12058
- /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: item.product_title }),
12059
- /* @__PURE__ */ jsxs(
12060
- Text,
12061
- {
12062
- size: "small",
12063
- leading: "compact",
12064
- className: "text-ui-fg-subtle",
12065
- children: [
12066
- "(",
12067
- item.variant_title,
12068
- ")"
12069
- ]
12070
- }
12071
- )
12072
- ] }),
12073
- /* @__PURE__ */ jsx(
12074
- Text,
12075
- {
12076
- size: "small",
12077
- leading: "compact",
12078
- className: "text-ui-fg-subtle",
12079
- children: item.variant_sku
12080
- }
12081
- )
12082
- ] })
12083
- ] }),
12084
- /* @__PURE__ */ jsxs(
12085
- Text,
12086
- {
12087
- size: "small",
12088
- leading: "compact",
12089
- className: "text-ui-fg-subtle",
12090
- children: [
12091
- item.quantity,
12092
- "x"
12093
- ]
12094
- }
12095
- )
12096
- ]
12097
- },
12098
- item.id
12099
- )) : /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-center gap-x-3 bg-ui-bg-base rounded-lg p-4 shadow-elevation-card-rest flex-col gap-1", children: [
12100
- /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: "No items found" }),
12101
- /* @__PURE__ */ jsxs(Text, { size: "small", className: "text-ui-fg-subtle", children: [
12102
- 'No items found for "',
12103
- query,
12104
- '".'
12105
- ] })
12106
- ] }) })
12107
- ] })
12108
- ] });
12109
- };
12110
- const LocationField = ({ control, setValue }) => {
12111
- const locations = useComboboxData({
12112
- queryKey: ["locations"],
12113
- queryFn: async (params) => {
12114
- return await sdk.admin.stockLocation.list(params);
12115
- },
12116
- getOptions: (data) => {
12117
- return data.stock_locations.map((location) => ({
12118
- label: location.name,
12119
- value: location.id
12120
- }));
12121
- }
12122
- });
12123
- return /* @__PURE__ */ jsx(
12124
- Form$2.Field,
12125
- {
12126
- control,
12127
- name: "location_id",
12128
- render: ({ field: { onChange, ...field } }) => {
12129
- return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
12130
- /* @__PURE__ */ jsxs("div", { children: [
12131
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Location" }),
12132
- /* @__PURE__ */ jsx(Form$2.Hint, { children: "Choose where you want to ship the items from." })
12133
- ] }),
12134
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
12135
- Combobox,
12136
- {
12137
- options: locations.options,
12138
- fetchNextPage: locations.fetchNextPage,
12139
- isFetchingNextPage: locations.isFetchingNextPage,
12140
- searchValue: locations.searchValue,
12141
- onSearchValueChange: locations.onSearchValueChange,
12142
- placeholder: "Select location",
12143
- onChange: (value) => {
12144
- setValue("shipping_option_id", "", {
12145
- shouldDirty: true,
12146
- shouldTouch: true
12147
- });
12148
- onChange(value);
12149
- },
12150
- ...field
12151
- }
12152
- ) })
12153
- ] }) });
12154
- }
12155
- }
12156
- );
12157
- };
12158
- const ShippingOptionField = ({
12159
- shippingProfileId,
12160
- preview,
12161
- control
12162
- }) => {
12163
- var _a;
12164
- const locationId = useWatch({ control, name: "location_id" });
12165
- const shippingOptions = useComboboxData({
12166
- queryKey: ["shipping_options", locationId, shippingProfileId],
12167
- queryFn: async (params) => {
12168
- return await sdk.admin.shippingOption.list({
12169
- ...params,
12170
- stock_location_id: locationId,
12171
- shipping_profile_id: shippingProfileId
12172
- });
12173
- },
12174
- getOptions: (data) => {
12175
- return data.shipping_options.map((option) => {
12176
- var _a2;
12177
- if ((_a2 = option.rules) == null ? void 0 : _a2.find(
12178
- (r) => r.attribute === "is_return" && r.value === "true"
12179
- )) {
12180
- return void 0;
12181
- }
12182
- return {
12183
- label: option.name,
12184
- value: option.id
12185
- };
12186
- }).filter(Boolean);
12187
- },
12188
- enabled: !!locationId && !!shippingProfileId,
12189
- defaultValue: ((_a = preview.shipping_methods[0]) == null ? void 0 : _a.shipping_option_id) || void 0
12190
- });
12191
- const tooltipContent = !locationId && !shippingProfileId ? "Choose a location and shipping profile first." : !locationId ? "Choose a location first." : "Choose a shipping profile first.";
12192
- return /* @__PURE__ */ jsx(
12193
- Form$2.Field,
12194
- {
12195
- control,
12196
- name: "shipping_option_id",
12197
- render: ({ field }) => {
12198
- return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
12199
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
12200
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Shipping option" }),
12201
- /* @__PURE__ */ jsx(Form$2.Hint, { children: "Choose the shipping option to use." })
12202
- ] }),
12203
- /* @__PURE__ */ jsx(
12204
- ConditionalTooltip,
12205
- {
12206
- content: tooltipContent,
12207
- showTooltip: !locationId || !shippingProfileId,
12208
- children: /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
12209
- Combobox,
12210
- {
12211
- options: shippingOptions.options,
12212
- fetchNextPage: shippingOptions.fetchNextPage,
12213
- isFetchingNextPage: shippingOptions.isFetchingNextPage,
12214
- searchValue: shippingOptions.searchValue,
12215
- onSearchValueChange: shippingOptions.onSearchValueChange,
12216
- placeholder: "Select shipping option",
12217
- ...field,
12218
- disabled: !locationId || !shippingProfileId
12219
- }
12220
- ) }) })
12221
- }
12222
- )
12223
- ] }) });
12224
- }
12225
- }
12226
- );
12227
- };
12228
- const CustomAmountField = ({
12229
- control,
12230
- currencyCode
12231
- }) => {
12232
- return /* @__PURE__ */ jsx(
12233
- Form$2.Field,
12234
- {
12235
- control,
12236
- name: "custom_amount",
12237
- render: ({ field: { onChange, ...field } }) => {
12238
- return /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
12239
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
12240
- /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Custom amount" }),
12241
- /* @__PURE__ */ jsx(Form$2.Hint, { children: "Set a custom amount for the shipping option." })
12242
- ] }),
12243
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
12244
- CurrencyInput,
12245
- {
12246
- ...field,
12247
- onValueChange: (value) => onChange(value),
12248
- symbol: getNativeSymbol(currencyCode),
12249
- code: currencyCode
12250
- }
12251
- ) })
12252
- ] });
12253
- }
12254
- }
12255
- );
12256
- };
12257
- const ShippingAddress = () => {
12258
- const { id } = useParams();
12259
- const { order, isPending, isError, error } = useOrder(id, {
12260
- fields: "+shipping_address"
12261
- });
12262
- if (isError) {
12263
- throw error;
12264
- }
12265
- const isReady = !isPending && !!order;
12266
- return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
12267
- /* @__PURE__ */ jsxs(RouteDrawer.Header, { children: [
12268
- /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Shipping Address" }) }),
12269
- /* @__PURE__ */ jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Edit the shipping address for the draft order" }) })
12270
- ] }),
12271
- isReady && /* @__PURE__ */ jsx(ShippingAddressForm, { order })
12272
- ] });
12005
+ shippingMethod
12006
+ });
12007
+ }
12008
+ };
12009
+ return /* @__PURE__ */ jsx(
12010
+ Button,
12011
+ {
12012
+ size: "small",
12013
+ variant: "secondary",
12014
+ onClick: onToggle,
12015
+ className: "text-ui-fg-primary shrink-0",
12016
+ children
12017
+ }
12018
+ );
12273
12019
  };
12274
- const ShippingAddressForm = ({ order }) => {
12275
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
12020
+ const ShippingProfileForm = ({
12021
+ data,
12022
+ order,
12023
+ preview
12024
+ }) => {
12025
+ var _a, _b, _c, _d, _e, _f;
12026
+ const { setIsOpen } = useStackedModal();
12276
12027
  const form = useForm({
12028
+ resolver: zodResolver(shippingMethodSchema),
12277
12029
  defaultValues: {
12278
- first_name: ((_a = order.shipping_address) == null ? void 0 : _a.first_name) ?? "",
12279
- last_name: ((_b = order.shipping_address) == null ? void 0 : _b.last_name) ?? "",
12280
- company: ((_c = order.shipping_address) == null ? void 0 : _c.company) ?? "",
12281
- address_1: ((_d = order.shipping_address) == null ? void 0 : _d.address_1) ?? "",
12282
- address_2: ((_e = order.shipping_address) == null ? void 0 : _e.address_2) ?? "",
12283
- city: ((_f = order.shipping_address) == null ? void 0 : _f.city) ?? "",
12284
- province: ((_g = order.shipping_address) == null ? void 0 : _g.province) ?? "",
12285
- country_code: ((_h = order.shipping_address) == null ? void 0 : _h.country_code) ?? "",
12286
- postal_code: ((_i = order.shipping_address) == null ? void 0 : _i.postal_code) ?? "",
12287
- phone: ((_j = order.shipping_address) == null ? void 0 : _j.phone) ?? ""
12288
- },
12289
- resolver: zodResolver(schema$2)
12030
+ location_id: (_d = (_c = (_b = (_a = data.shippingOption) == null ? void 0 : _a.service_zone) == null ? void 0 : _b.fulfillment_set) == null ? void 0 : _c.location) == null ? void 0 : _d.id,
12031
+ shipping_option_id: (_e = data.shippingOption) == null ? void 0 : _e.id,
12032
+ custom_amount: (_f = data.shippingMethod) == null ? void 0 : _f.amount
12033
+ }
12290
12034
  });
12291
- const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
12292
- const { handleSuccess } = useRouteModal();
12293
- const onSubmit = form.handleSubmit(async (data) => {
12294
- await mutateAsync(
12295
- {
12296
- shipping_address: {
12297
- first_name: data.first_name,
12298
- last_name: data.last_name,
12299
- company: data.company,
12300
- address_1: data.address_1,
12301
- address_2: data.address_2,
12302
- city: data.city,
12303
- province: data.province,
12304
- country_code: data.country_code,
12305
- postal_code: data.postal_code,
12306
- phone: data.phone
12035
+ const { mutateAsync: addShippingMethod, isPending } = useDraftOrderAddShippingMethod(order.id);
12036
+ const {
12037
+ mutateAsync: updateShippingMethod,
12038
+ isPending: isUpdatingShippingMethod
12039
+ } = useDraftOrderUpdateShippingMethod(order.id);
12040
+ const onSubmit = form.handleSubmit(async (values) => {
12041
+ if (isEqual(values, form.formState.defaultValues)) {
12042
+ setIsOpen(STACKED_FOCUS_MODAL_ID, false);
12043
+ return;
12044
+ }
12045
+ if (data.shippingMethod) {
12046
+ await updateShippingMethod(
12047
+ {
12048
+ method_id: data.shippingMethod.id,
12049
+ shipping_option_id: values.shipping_option_id,
12050
+ custom_amount: values.custom_amount ? convertNumber(values.custom_amount) : void 0
12051
+ },
12052
+ {
12053
+ onError: (e) => {
12054
+ toast.error(e.message);
12055
+ },
12056
+ onSuccess: () => {
12057
+ setIsOpen(STACKED_FOCUS_MODAL_ID, false);
12058
+ }
12307
12059
  }
12060
+ );
12061
+ return;
12062
+ }
12063
+ await addShippingMethod(
12064
+ {
12065
+ shipping_option_id: values.shipping_option_id,
12066
+ custom_amount: values.custom_amount ? convertNumber(values.custom_amount) : void 0
12308
12067
  },
12309
12068
  {
12310
- onSuccess: () => {
12311
- handleSuccess();
12069
+ onError: (e) => {
12070
+ toast.error(e.message);
12312
12071
  },
12313
- onError: (error) => {
12314
- toast.error(error.message);
12072
+ onSuccess: () => {
12073
+ setIsOpen(STACKED_FOCUS_MODAL_ID, false);
12315
12074
  }
12316
12075
  }
12317
12076
  );
12318
12077
  });
12319
- return /* @__PURE__ */ jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxs(
12078
+ return /* @__PURE__ */ jsx(StackedFocusModal.Content, { children: /* @__PURE__ */ jsx(Form$2, { ...form, children: /* @__PURE__ */ jsxs(
12320
12079
  KeyboundForm,
12321
12080
  {
12322
- className: "flex flex-1 flex-col overflow-hidden",
12081
+ className: "flex h-full flex-col overflow-hidden",
12323
12082
  onSubmit,
12324
12083
  children: [
12325
- /* @__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: [
12084
+ /* @__PURE__ */ jsx(StackedFocusModal.Header, {}),
12085
+ /* @__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 py-16 px-6", children: [
12086
+ /* @__PURE__ */ jsxs("div", { children: [
12087
+ /* @__PURE__ */ jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Shipping" }) }),
12088
+ /* @__PURE__ */ jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Add a shipping method for the selected shipping profile. You can see the items that will be shipped using this method in the preview below." }) })
12089
+ ] }),
12090
+ /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
12326
12091
  /* @__PURE__ */ jsx(
12327
- Form$2.Field,
12092
+ LocationField,
12328
12093
  {
12329
12094
  control: form.control,
12330
- name: "country_code",
12331
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12332
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Country" }),
12333
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(CountrySelect, { ...field }) }),
12334
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12335
- ] })
12095
+ setValue: form.setValue
12336
12096
  }
12337
12097
  ),
12338
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
12339
- /* @__PURE__ */ jsx(
12340
- Form$2.Field,
12341
- {
12342
- control: form.control,
12343
- name: "first_name",
12344
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12345
- /* @__PURE__ */ jsx(Form$2.Label, { children: "First name" }),
12346
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12347
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12348
- ] })
12349
- }
12350
- ),
12351
- /* @__PURE__ */ jsx(
12352
- Form$2.Field,
12353
- {
12354
- control: form.control,
12355
- name: "last_name",
12356
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12357
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Last name" }),
12358
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12359
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12360
- ] })
12361
- }
12362
- )
12363
- ] }),
12098
+ /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
12364
12099
  /* @__PURE__ */ jsx(
12365
- Form$2.Field,
12100
+ ShippingOptionField,
12366
12101
  {
12367
- control: form.control,
12368
- name: "company",
12369
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12370
- /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Company" }),
12371
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12372
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12373
- ] })
12102
+ shippingProfileId: data.shippingProfileId,
12103
+ preview,
12104
+ control: form.control
12374
12105
  }
12375
12106
  ),
12107
+ /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
12376
12108
  /* @__PURE__ */ jsx(
12377
- Form$2.Field,
12109
+ CustomAmountField,
12378
12110
  {
12379
12111
  control: form.control,
12380
- name: "address_1",
12381
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12382
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Address" }),
12383
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12384
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12385
- ] })
12112
+ currencyCode: order.currency_code
12386
12113
  }
12387
12114
  ),
12115
+ /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
12388
12116
  /* @__PURE__ */ jsx(
12389
- Form$2.Field,
12117
+ ItemsPreview,
12390
12118
  {
12391
- control: form.control,
12392
- name: "address_2",
12393
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12394
- /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Apartment, suite, etc." }),
12395
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12396
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12119
+ order,
12120
+ shippingProfileId: data.shippingProfileId
12121
+ }
12122
+ )
12123
+ ] }) }) }),
12124
+ /* @__PURE__ */ jsx(StackedFocusModal.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-x-2", children: [
12125
+ /* @__PURE__ */ jsx(StackedFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
12126
+ /* @__PURE__ */ jsx(
12127
+ Button,
12128
+ {
12129
+ size: "small",
12130
+ type: "submit",
12131
+ isLoading: isPending || isUpdatingShippingMethod,
12132
+ children: data.shippingMethod ? "Update" : "Add"
12133
+ }
12134
+ )
12135
+ ] }) })
12136
+ ]
12137
+ }
12138
+ ) }) });
12139
+ };
12140
+ const shippingMethodSchema = objectType({
12141
+ location_id: stringType(),
12142
+ shipping_option_id: stringType(),
12143
+ custom_amount: unionType([numberType(), stringType()]).optional()
12144
+ });
12145
+ const ItemsPreview = ({ order, shippingProfileId }) => {
12146
+ const matches = order.items.filter(
12147
+ (item) => {
12148
+ var _a, _b, _c;
12149
+ return ((_c = (_b = (_a = item.variant) == null ? void 0 : _a.product) == null ? void 0 : _b.shipping_profile) == null ? void 0 : _c.id) === shippingProfileId;
12150
+ }
12151
+ );
12152
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-y-6", children: [
12153
+ /* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 items-center gap-3", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
12154
+ /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: "Items to ship" }),
12155
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Items with the selected shipping profile." })
12156
+ ] }) }),
12157
+ /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-subtle shadow-elevation-card-rest rounded-xl", children: [
12158
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-3 px-4 py-2 text-ui-fg-muted", children: [
12159
+ /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: "Item" }) }),
12160
+ /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: "Quantity" }) })
12161
+ ] }),
12162
+ /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-y-1.5 px-[5px] pb-[5px]", children: matches.length > 0 ? matches == null ? void 0 : matches.map((item) => /* @__PURE__ */ jsxs(
12163
+ "div",
12164
+ {
12165
+ className: "grid grid-cols-2 gap-3 px-4 py-2 bg-ui-bg-base shadow-elevation-card-rest rounded-lg items-center",
12166
+ children: [
12167
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-3", children: [
12168
+ /* @__PURE__ */ jsx(
12169
+ Thumbnail,
12170
+ {
12171
+ thumbnail: item.thumbnail,
12172
+ alt: item.product_title ?? void 0
12173
+ }
12174
+ ),
12175
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
12176
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-1", children: [
12177
+ /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: item.product_title }),
12178
+ /* @__PURE__ */ jsxs(
12179
+ Text,
12180
+ {
12181
+ size: "small",
12182
+ leading: "compact",
12183
+ className: "text-ui-fg-subtle",
12184
+ children: [
12185
+ "(",
12186
+ item.variant_title,
12187
+ ")"
12188
+ ]
12189
+ }
12190
+ )
12191
+ ] }),
12192
+ /* @__PURE__ */ jsx(
12193
+ Text,
12194
+ {
12195
+ size: "small",
12196
+ leading: "compact",
12197
+ className: "text-ui-fg-subtle",
12198
+ children: item.variant_sku
12199
+ }
12200
+ )
12397
12201
  ] })
12398
- }
12399
- ),
12400
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
12401
- /* @__PURE__ */ jsx(
12402
- Form$2.Field,
12403
- {
12404
- control: form.control,
12405
- name: "postal_code",
12406
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12407
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Postal code" }),
12408
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12409
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12410
- ] })
12411
- }
12412
- ),
12413
- /* @__PURE__ */ jsx(
12414
- Form$2.Field,
12202
+ ] }),
12203
+ /* @__PURE__ */ jsxs(
12204
+ Text,
12415
12205
  {
12416
- control: form.control,
12417
- name: "city",
12418
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12419
- /* @__PURE__ */ jsx(Form$2.Label, { children: "City" }),
12420
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12421
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12422
- ] })
12206
+ size: "small",
12207
+ leading: "compact",
12208
+ className: "text-ui-fg-subtle",
12209
+ children: [
12210
+ item.quantity,
12211
+ "x"
12212
+ ]
12423
12213
  }
12424
12214
  )
12425
- ] }),
12426
- /* @__PURE__ */ jsx(
12427
- Form$2.Field,
12428
- {
12429
- control: form.control,
12430
- name: "province",
12431
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12432
- /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Province / State" }),
12433
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12434
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12435
- ] })
12436
- }
12437
- ),
12438
- /* @__PURE__ */ jsx(
12439
- Form$2.Field,
12440
- {
12441
- control: form.control,
12442
- name: "phone",
12443
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12444
- /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Phone" }),
12445
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12446
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12447
- ] })
12448
- }
12449
- )
12450
- ] }) }),
12451
- /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
12452
- /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
12453
- /* @__PURE__ */ jsx(Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
12454
- ] }) })
12455
- ]
12456
- }
12457
- ) });
12458
- };
12459
- const schema$2 = addressSchema;
12460
- const SalesChannel = () => {
12461
- const { id } = useParams();
12462
- const { draft_order, isPending, isError, error } = useDraftOrder(
12463
- id,
12464
- {
12465
- fields: "+sales_channel_id"
12466
- },
12467
- {
12468
- enabled: !!id
12469
- }
12470
- );
12471
- if (isError) {
12472
- throw error;
12473
- }
12474
- const ISrEADY = !!draft_order && !isPending;
12475
- return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
12476
- /* @__PURE__ */ jsxs(RouteDrawer.Header, { children: [
12477
- /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Sales Channel" }) }),
12478
- /* @__PURE__ */ jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Update which sales channel the draft order is associated with" }) })
12479
- ] }),
12480
- ISrEADY && /* @__PURE__ */ jsx(SalesChannelForm, { order: draft_order })
12215
+ ]
12216
+ },
12217
+ item.id
12218
+ )) : /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-center gap-x-3 bg-ui-bg-base rounded-lg p-4 shadow-elevation-card-rest flex-col gap-1", children: [
12219
+ /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: "No items found" }),
12220
+ /* @__PURE__ */ jsxs(Text, { size: "small", className: "text-ui-fg-subtle", children: [
12221
+ 'No items found for "',
12222
+ query,
12223
+ '".'
12224
+ ] })
12225
+ ] }) })
12226
+ ] })
12481
12227
  ] });
12482
12228
  };
12483
- const SalesChannelForm = ({ order }) => {
12484
- const form = useForm({
12485
- defaultValues: {
12486
- sales_channel_id: order.sales_channel_id || ""
12229
+ const LocationField = ({ control, setValue }) => {
12230
+ const locations = useComboboxData({
12231
+ queryKey: ["locations"],
12232
+ queryFn: async (params) => {
12233
+ return await sdk.admin.stockLocation.list(params);
12487
12234
  },
12488
- resolver: zodResolver(schema$1)
12489
- });
12490
- const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
12491
- const { handleSuccess } = useRouteModal();
12492
- const onSubmit = form.handleSubmit(async (data) => {
12493
- await mutateAsync(
12494
- {
12495
- sales_channel_id: data.sales_channel_id
12496
- },
12497
- {
12498
- onSuccess: () => {
12499
- toast.success("Sales channel updated");
12500
- handleSuccess();
12501
- },
12502
- onError: (error) => {
12503
- toast.error(error.message);
12504
- }
12505
- }
12506
- );
12235
+ getOptions: (data) => {
12236
+ return data.stock_locations.map((location) => ({
12237
+ label: location.name,
12238
+ value: location.id
12239
+ }));
12240
+ }
12507
12241
  });
12508
- return /* @__PURE__ */ jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxs(
12509
- KeyboundForm,
12242
+ return /* @__PURE__ */ jsx(
12243
+ Form$2.Field,
12510
12244
  {
12511
- className: "flex flex-1 flex-col overflow-hidden",
12512
- onSubmit,
12513
- children: [
12514
- /* @__PURE__ */ jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsx(SalesChannelField, { control: form.control, order }) }),
12515
- /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
12516
- /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
12517
- /* @__PURE__ */ jsx(Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
12518
- ] }) })
12519
- ]
12245
+ control,
12246
+ name: "location_id",
12247
+ render: ({ field: { onChange, ...field } }) => {
12248
+ return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
12249
+ /* @__PURE__ */ jsxs("div", { children: [
12250
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Location" }),
12251
+ /* @__PURE__ */ jsx(Form$2.Hint, { children: "Choose where you want to ship the items from." })
12252
+ ] }),
12253
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
12254
+ Combobox,
12255
+ {
12256
+ options: locations.options,
12257
+ fetchNextPage: locations.fetchNextPage,
12258
+ isFetchingNextPage: locations.isFetchingNextPage,
12259
+ searchValue: locations.searchValue,
12260
+ onSearchValueChange: locations.onSearchValueChange,
12261
+ placeholder: "Select location",
12262
+ onChange: (value) => {
12263
+ setValue("shipping_option_id", "", {
12264
+ shouldDirty: true,
12265
+ shouldTouch: true
12266
+ });
12267
+ onChange(value);
12268
+ },
12269
+ ...field
12270
+ }
12271
+ ) })
12272
+ ] }) });
12273
+ }
12520
12274
  }
12521
- ) });
12275
+ );
12522
12276
  };
12523
- const SalesChannelField = ({ control, order }) => {
12524
- const salesChannels = useComboboxData({
12277
+ const ShippingOptionField = ({
12278
+ shippingProfileId,
12279
+ preview,
12280
+ control
12281
+ }) => {
12282
+ var _a;
12283
+ const locationId = useWatch({ control, name: "location_id" });
12284
+ const shippingOptions = useComboboxData({
12285
+ queryKey: ["shipping_options", locationId, shippingProfileId],
12525
12286
  queryFn: async (params) => {
12526
- return await sdk.admin.salesChannel.list(params);
12287
+ return await sdk.admin.shippingOption.list({
12288
+ ...params,
12289
+ stock_location_id: locationId,
12290
+ shipping_profile_id: shippingProfileId
12291
+ });
12527
12292
  },
12528
- queryKey: ["sales-channels"],
12529
12293
  getOptions: (data) => {
12530
- return data.sales_channels.map((salesChannel) => ({
12531
- label: salesChannel.name,
12532
- value: salesChannel.id
12533
- }));
12294
+ return data.shipping_options.map((option) => {
12295
+ var _a2;
12296
+ if ((_a2 = option.rules) == null ? void 0 : _a2.find(
12297
+ (r) => r.attribute === "is_return" && r.value === "true"
12298
+ )) {
12299
+ return void 0;
12300
+ }
12301
+ return {
12302
+ label: option.name,
12303
+ value: option.id
12304
+ };
12305
+ }).filter(Boolean);
12534
12306
  },
12535
- defaultValue: order.sales_channel_id || void 0
12307
+ enabled: !!locationId && !!shippingProfileId,
12308
+ defaultValue: ((_a = preview.shipping_methods[0]) == null ? void 0 : _a.shipping_option_id) || void 0
12536
12309
  });
12310
+ const tooltipContent = !locationId && !shippingProfileId ? "Choose a location and shipping profile first." : !locationId ? "Choose a location first." : "Choose a shipping profile first.";
12311
+ return /* @__PURE__ */ jsx(
12312
+ Form$2.Field,
12313
+ {
12314
+ control,
12315
+ name: "shipping_option_id",
12316
+ render: ({ field }) => {
12317
+ return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
12318
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
12319
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Shipping option" }),
12320
+ /* @__PURE__ */ jsx(Form$2.Hint, { children: "Choose the shipping option to use." })
12321
+ ] }),
12322
+ /* @__PURE__ */ jsx(
12323
+ ConditionalTooltip,
12324
+ {
12325
+ content: tooltipContent,
12326
+ showTooltip: !locationId || !shippingProfileId,
12327
+ children: /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
12328
+ Combobox,
12329
+ {
12330
+ options: shippingOptions.options,
12331
+ fetchNextPage: shippingOptions.fetchNextPage,
12332
+ isFetchingNextPage: shippingOptions.isFetchingNextPage,
12333
+ searchValue: shippingOptions.searchValue,
12334
+ onSearchValueChange: shippingOptions.onSearchValueChange,
12335
+ placeholder: "Select shipping option",
12336
+ ...field,
12337
+ disabled: !locationId || !shippingProfileId
12338
+ }
12339
+ ) }) })
12340
+ }
12341
+ )
12342
+ ] }) });
12343
+ }
12344
+ }
12345
+ );
12346
+ };
12347
+ const CustomAmountField = ({
12348
+ control,
12349
+ currencyCode
12350
+ }) => {
12537
12351
  return /* @__PURE__ */ jsx(
12538
12352
  Form$2.Field,
12539
12353
  {
12540
12354
  control,
12541
- name: "sales_channel_id",
12542
- render: ({ field }) => {
12543
- return /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12544
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Sales Channel" }),
12355
+ name: "custom_amount",
12356
+ render: ({ field: { onChange, ...field } }) => {
12357
+ return /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
12358
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
12359
+ /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Custom amount" }),
12360
+ /* @__PURE__ */ jsx(Form$2.Hint, { children: "Set a custom amount for the shipping option." })
12361
+ ] }),
12545
12362
  /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
12546
- Combobox,
12363
+ CurrencyInput,
12547
12364
  {
12548
- options: salesChannels.options,
12549
- fetchNextPage: salesChannels.fetchNextPage,
12550
- isFetchingNextPage: salesChannels.isFetchingNextPage,
12551
- searchValue: salesChannels.searchValue,
12552
- onSearchValueChange: salesChannels.onSearchValueChange,
12553
- placeholder: "Select sales channel",
12554
- ...field
12365
+ ...field,
12366
+ onValueChange: (value) => onChange(value),
12367
+ symbol: getNativeSymbol(currencyCode),
12368
+ code: currencyCode
12555
12369
  }
12556
- ) }),
12557
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12370
+ ) })
12558
12371
  ] });
12559
12372
  }
12560
12373
  }
12561
12374
  );
12562
12375
  };
12563
- const schema$1 = objectType({
12564
- sales_channel_id: stringType().min(1)
12565
- });
12566
12376
  const TransferOwnership = () => {
12567
12377
  const { id } = useParams();
12568
12378
  const { draft_order, isPending, isError, error } = useDraftOrder(id, {
@@ -12586,7 +12396,7 @@ const TransferOwnershipForm = ({ order }) => {
12586
12396
  defaultValues: {
12587
12397
  customer_id: order.customer_id || ""
12588
12398
  },
12589
- resolver: zodResolver(schema)
12399
+ resolver: zodResolver(schema$1)
12590
12400
  });
12591
12401
  const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
12592
12402
  const { handleSuccess } = useRouteModal();
@@ -13036,9 +12846,199 @@ const Illustration = () => {
13036
12846
  }
13037
12847
  );
13038
12848
  };
13039
- const schema = objectType({
12849
+ const schema$1 = objectType({
13040
12850
  customer_id: stringType().min(1)
13041
12851
  });
12852
+ const BillingAddress = () => {
12853
+ const { id } = useParams();
12854
+ const { order, isPending, isError, error } = useOrder(id, {
12855
+ fields: "+billing_address"
12856
+ });
12857
+ if (isError) {
12858
+ throw error;
12859
+ }
12860
+ const isReady = !isPending && !!order;
12861
+ return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
12862
+ /* @__PURE__ */ jsxs(RouteDrawer.Header, { children: [
12863
+ /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Billing Address" }) }),
12864
+ /* @__PURE__ */ jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Edit the billing address for the draft order" }) })
12865
+ ] }),
12866
+ isReady && /* @__PURE__ */ jsx(BillingAddressForm, { order })
12867
+ ] });
12868
+ };
12869
+ const BillingAddressForm = ({ order }) => {
12870
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
12871
+ const form = useForm({
12872
+ defaultValues: {
12873
+ first_name: ((_a = order.billing_address) == null ? void 0 : _a.first_name) ?? "",
12874
+ last_name: ((_b = order.billing_address) == null ? void 0 : _b.last_name) ?? "",
12875
+ company: ((_c = order.billing_address) == null ? void 0 : _c.company) ?? "",
12876
+ address_1: ((_d = order.billing_address) == null ? void 0 : _d.address_1) ?? "",
12877
+ address_2: ((_e = order.billing_address) == null ? void 0 : _e.address_2) ?? "",
12878
+ city: ((_f = order.billing_address) == null ? void 0 : _f.city) ?? "",
12879
+ province: ((_g = order.billing_address) == null ? void 0 : _g.province) ?? "",
12880
+ country_code: ((_h = order.billing_address) == null ? void 0 : _h.country_code) ?? "",
12881
+ postal_code: ((_i = order.billing_address) == null ? void 0 : _i.postal_code) ?? "",
12882
+ phone: ((_j = order.billing_address) == null ? void 0 : _j.phone) ?? ""
12883
+ },
12884
+ resolver: zodResolver(schema)
12885
+ });
12886
+ const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
12887
+ const { handleSuccess } = useRouteModal();
12888
+ const onSubmit = form.handleSubmit(async (data) => {
12889
+ await mutateAsync(
12890
+ { billing_address: data },
12891
+ {
12892
+ onSuccess: () => {
12893
+ handleSuccess();
12894
+ },
12895
+ onError: (error) => {
12896
+ toast.error(error.message);
12897
+ }
12898
+ }
12899
+ );
12900
+ });
12901
+ return /* @__PURE__ */ jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxs(
12902
+ KeyboundForm,
12903
+ {
12904
+ className: "flex flex-1 flex-col overflow-hidden",
12905
+ onSubmit,
12906
+ children: [
12907
+ /* @__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: [
12908
+ /* @__PURE__ */ jsx(
12909
+ Form$2.Field,
12910
+ {
12911
+ control: form.control,
12912
+ name: "country_code",
12913
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12914
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Country" }),
12915
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(CountrySelect, { ...field }) }),
12916
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12917
+ ] })
12918
+ }
12919
+ ),
12920
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
12921
+ /* @__PURE__ */ jsx(
12922
+ Form$2.Field,
12923
+ {
12924
+ control: form.control,
12925
+ name: "first_name",
12926
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12927
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "First name" }),
12928
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12929
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12930
+ ] })
12931
+ }
12932
+ ),
12933
+ /* @__PURE__ */ jsx(
12934
+ Form$2.Field,
12935
+ {
12936
+ control: form.control,
12937
+ name: "last_name",
12938
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12939
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Last name" }),
12940
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12941
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12942
+ ] })
12943
+ }
12944
+ )
12945
+ ] }),
12946
+ /* @__PURE__ */ jsx(
12947
+ Form$2.Field,
12948
+ {
12949
+ control: form.control,
12950
+ name: "company",
12951
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12952
+ /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Company" }),
12953
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12954
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12955
+ ] })
12956
+ }
12957
+ ),
12958
+ /* @__PURE__ */ jsx(
12959
+ Form$2.Field,
12960
+ {
12961
+ control: form.control,
12962
+ name: "address_1",
12963
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12964
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Address" }),
12965
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12966
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12967
+ ] })
12968
+ }
12969
+ ),
12970
+ /* @__PURE__ */ jsx(
12971
+ Form$2.Field,
12972
+ {
12973
+ control: form.control,
12974
+ name: "address_2",
12975
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12976
+ /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Apartment, suite, etc." }),
12977
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12978
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12979
+ ] })
12980
+ }
12981
+ ),
12982
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
12983
+ /* @__PURE__ */ jsx(
12984
+ Form$2.Field,
12985
+ {
12986
+ control: form.control,
12987
+ name: "postal_code",
12988
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12989
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Postal code" }),
12990
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12991
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12992
+ ] })
12993
+ }
12994
+ ),
12995
+ /* @__PURE__ */ jsx(
12996
+ Form$2.Field,
12997
+ {
12998
+ control: form.control,
12999
+ name: "city",
13000
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
13001
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "City" }),
13002
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
13003
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
13004
+ ] })
13005
+ }
13006
+ )
13007
+ ] }),
13008
+ /* @__PURE__ */ jsx(
13009
+ Form$2.Field,
13010
+ {
13011
+ control: form.control,
13012
+ name: "province",
13013
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
13014
+ /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Province / State" }),
13015
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
13016
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
13017
+ ] })
13018
+ }
13019
+ ),
13020
+ /* @__PURE__ */ jsx(
13021
+ Form$2.Field,
13022
+ {
13023
+ control: form.control,
13024
+ name: "phone",
13025
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
13026
+ /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Phone" }),
13027
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
13028
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
13029
+ ] })
13030
+ }
13031
+ )
13032
+ ] }) }),
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", isLoading: isPending, children: "Save" })
13036
+ ] }) })
13037
+ ]
13038
+ }
13039
+ ) });
13040
+ };
13041
+ const schema = addressSchema;
13042
13042
  const widgetModule = { widgets: [] };
13043
13043
  const routeModule = {
13044
13044
  routes: [
@@ -13059,45 +13059,45 @@ const routeModule = {
13059
13059
  handle,
13060
13060
  loader,
13061
13061
  children: [
13062
- {
13063
- Component: BillingAddress,
13064
- path: "/draft-orders/:id/billing-address"
13065
- },
13066
13062
  {
13067
13063
  Component: CustomItems,
13068
13064
  path: "/draft-orders/:id/custom-items"
13069
13065
  },
13070
- {
13071
- Component: Items,
13072
- path: "/draft-orders/:id/items"
13073
- },
13074
13066
  {
13075
13067
  Component: Email,
13076
13068
  path: "/draft-orders/:id/email"
13077
13069
  },
13078
- {
13079
- Component: Promotions,
13080
- path: "/draft-orders/:id/promotions"
13081
- },
13082
13070
  {
13083
13071
  Component: Metadata,
13084
13072
  path: "/draft-orders/:id/metadata"
13085
13073
  },
13086
13074
  {
13087
- Component: Shipping,
13088
- path: "/draft-orders/:id/shipping"
13075
+ Component: Items,
13076
+ path: "/draft-orders/:id/items"
13089
13077
  },
13090
13078
  {
13091
- Component: ShippingAddress,
13092
- path: "/draft-orders/:id/shipping-address"
13079
+ Component: Promotions,
13080
+ path: "/draft-orders/:id/promotions"
13093
13081
  },
13094
13082
  {
13095
13083
  Component: SalesChannel,
13096
13084
  path: "/draft-orders/:id/sales-channel"
13097
13085
  },
13086
+ {
13087
+ Component: ShippingAddress,
13088
+ path: "/draft-orders/:id/shipping-address"
13089
+ },
13090
+ {
13091
+ Component: Shipping,
13092
+ path: "/draft-orders/:id/shipping"
13093
+ },
13098
13094
  {
13099
13095
  Component: TransferOwnership,
13100
13096
  path: "/draft-orders/:id/transfer-ownership"
13097
+ },
13098
+ {
13099
+ Component: BillingAddress,
13100
+ path: "/draft-orders/:id/billing-address"
13101
13101
  }
13102
13102
  ]
13103
13103
  }