@medusajs/draft-order 2.11.0-snapshot-20251017164419 → 2.11.0-snapshot-20251017170018

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,6 +9567,95 @@ const ID = () => {
9567
9567
  /* @__PURE__ */ jsx(Outlet, {})
9568
9568
  ] });
9569
9569
  };
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 = () => {
9592
+ const { id } = useParams();
9593
+ const { order, isPending, isError, error } = useOrder(id, {
9594
+ fields: "+email"
9595
+ });
9596
+ if (isError) {
9597
+ throw error;
9598
+ }
9599
+ const isReady = !isPending && !!order;
9600
+ return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
9601
+ /* @__PURE__ */ jsxs(RouteDrawer.Header, { children: [
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" }) })
9604
+ ] }),
9605
+ isReady && /* @__PURE__ */ jsx(EmailForm, { order })
9606
+ ] });
9607
+ };
9608
+ const EmailForm = ({ order }) => {
9609
+ const form = useForm({
9610
+ defaultValues: {
9611
+ email: order.email ?? ""
9612
+ },
9613
+ resolver: zodResolver(schema$4)
9614
+ });
9615
+ const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
9616
+ const { handleSuccess } = useRouteModal();
9617
+ const onSubmit = form.handleSubmit(async (data) => {
9618
+ await mutateAsync(
9619
+ { email: data.email },
9620
+ {
9621
+ onSuccess: () => {
9622
+ handleSuccess();
9623
+ },
9624
+ onError: (error) => {
9625
+ toast.error(error.message);
9626
+ }
9627
+ }
9628
+ );
9629
+ });
9630
+ return /* @__PURE__ */ jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxs(
9631
+ KeyboundForm,
9632
+ {
9633
+ className: "flex flex-1 flex-col overflow-hidden",
9634
+ onSubmit,
9635
+ children: [
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
+ ) }),
9648
+ /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
9649
+ /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
9650
+ /* @__PURE__ */ jsx(Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
9651
+ ] }) })
9652
+ ]
9653
+ }
9654
+ ) });
9655
+ };
9656
+ const schema$4 = objectType({
9657
+ email: stringType().email()
9658
+ });
9570
9659
  const BillingAddress = () => {
9571
9660
  const { id } = useParams();
9572
9661
  const { order, isPending, isError, error } = useOrder(id, {
@@ -9599,7 +9688,7 @@ const BillingAddressForm = ({ order }) => {
9599
9688
  postal_code: ((_i = order.billing_address) == null ? void 0 : _i.postal_code) ?? "",
9600
9689
  phone: ((_j = order.billing_address) == null ? void 0 : _j.phone) ?? ""
9601
9690
  },
9602
- resolver: zodResolver(schema$5)
9691
+ resolver: zodResolver(schema$3)
9603
9692
  });
9604
9693
  const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
9605
9694
  const { handleSuccess } = useRouteModal();
@@ -9756,11 +9845,55 @@ const BillingAddressForm = ({ order }) => {
9756
9845
  }
9757
9846
  ) });
9758
9847
  };
9759
- const schema$5 = addressSchema;
9760
- const Email = () => {
9848
+ const schema$3 = addressSchema;
9849
+ const InlineTip = forwardRef(
9850
+ ({ variant = "tip", label, className, children, ...props }, ref) => {
9851
+ const labelValue = label || (variant === "warning" ? "Warning" : "Tip");
9852
+ return /* @__PURE__ */ jsxs(
9853
+ "div",
9854
+ {
9855
+ ref,
9856
+ className: clx(
9857
+ "bg-ui-bg-component txt-small text-ui-fg-subtle grid grid-cols-[4px_1fr] items-start gap-3 rounded-lg border p-3",
9858
+ className
9859
+ ),
9860
+ ...props,
9861
+ children: [
9862
+ /* @__PURE__ */ jsx(
9863
+ "div",
9864
+ {
9865
+ role: "presentation",
9866
+ className: clx("w-4px bg-ui-tag-neutral-icon h-full rounded-full", {
9867
+ "bg-ui-tag-orange-icon": variant === "warning"
9868
+ })
9869
+ }
9870
+ ),
9871
+ /* @__PURE__ */ jsxs("div", { className: "text-pretty", children: [
9872
+ /* @__PURE__ */ jsxs("strong", { className: "txt-small-plus text-ui-fg-base", children: [
9873
+ labelValue,
9874
+ ":"
9875
+ ] }),
9876
+ " ",
9877
+ children
9878
+ ] })
9879
+ ]
9880
+ }
9881
+ );
9882
+ }
9883
+ );
9884
+ InlineTip.displayName = "InlineTip";
9885
+ const MetadataFieldSchema = objectType({
9886
+ key: stringType(),
9887
+ disabled: booleanType().optional(),
9888
+ value: anyType()
9889
+ });
9890
+ const MetadataSchema = objectType({
9891
+ metadata: arrayType(MetadataFieldSchema)
9892
+ });
9893
+ const Metadata = () => {
9761
9894
  const { id } = useParams();
9762
9895
  const { order, isPending, isError, error } = useOrder(id, {
9763
- fields: "+email"
9896
+ fields: "metadata"
9764
9897
  });
9765
9898
  if (isError) {
9766
9899
  throw error;
@@ -9768,26 +9901,33 @@ const Email = () => {
9768
9901
  const isReady = !isPending && !!order;
9769
9902
  return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
9770
9903
  /* @__PURE__ */ jsxs(RouteDrawer.Header, { children: [
9771
- /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Email" }) }),
9772
- /* @__PURE__ */ jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Edit the email for the draft order" }) })
9904
+ /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Metadata" }) }),
9905
+ /* @__PURE__ */ jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Add metadata to the draft order." }) })
9773
9906
  ] }),
9774
- isReady && /* @__PURE__ */ jsx(EmailForm, { order })
9907
+ !isReady ? /* @__PURE__ */ jsx(PlaceholderInner, {}) : /* @__PURE__ */ jsx(MetadataForm, { orderId: id, metadata: order == null ? void 0 : order.metadata })
9775
9908
  ] });
9776
9909
  };
9777
- const EmailForm = ({ order }) => {
9910
+ const METADATA_KEY_LABEL_ID = "metadata-form-key-label";
9911
+ const METADATA_VALUE_LABEL_ID = "metadata-form-value-label";
9912
+ const MetadataForm = ({ orderId, metadata }) => {
9913
+ const { handleSuccess } = useRouteModal();
9914
+ const hasUneditableRows = getHasUneditableRows(metadata);
9915
+ const { mutateAsync, isPending } = useUpdateDraftOrder(orderId);
9778
9916
  const form = useForm({
9779
9917
  defaultValues: {
9780
- email: order.email ?? ""
9918
+ metadata: getDefaultValues(metadata)
9781
9919
  },
9782
- resolver: zodResolver(schema$4)
9920
+ resolver: zodResolver(MetadataSchema)
9783
9921
  });
9784
- const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
9785
- const { handleSuccess } = useRouteModal();
9786
- const onSubmit = form.handleSubmit(async (data) => {
9922
+ const handleSubmit = form.handleSubmit(async (data) => {
9923
+ const parsedData = parseValues(data);
9787
9924
  await mutateAsync(
9788
- { email: data.email },
9925
+ {
9926
+ metadata: parsedData
9927
+ },
9789
9928
  {
9790
9929
  onSuccess: () => {
9930
+ toast.success("Metadata updated");
9791
9931
  handleSuccess();
9792
9932
  },
9793
9933
  onError: (error) => {
@@ -9796,921 +9936,874 @@ const EmailForm = ({ order }) => {
9796
9936
  }
9797
9937
  );
9798
9938
  });
9939
+ const { fields, insert, remove } = useFieldArray({
9940
+ control: form.control,
9941
+ name: "metadata"
9942
+ });
9943
+ function deleteRow(index) {
9944
+ remove(index);
9945
+ if (fields.length === 1) {
9946
+ insert(0, {
9947
+ key: "",
9948
+ value: "",
9949
+ disabled: false
9950
+ });
9951
+ }
9952
+ }
9953
+ function insertRow(index, position) {
9954
+ insert(index + (position === "above" ? 0 : 1), {
9955
+ key: "",
9956
+ value: "",
9957
+ disabled: false
9958
+ });
9959
+ }
9799
9960
  return /* @__PURE__ */ jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxs(
9800
9961
  KeyboundForm,
9801
9962
  {
9963
+ onSubmit: handleSubmit,
9802
9964
  className: "flex flex-1 flex-col overflow-hidden",
9803
- onSubmit,
9804
9965
  children: [
9805
- /* @__PURE__ */ jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsx(
9806
- Form$2.Field,
9807
- {
9808
- control: form.control,
9809
- name: "email",
9810
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
9811
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Email" }),
9812
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
9813
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
9814
- ] })
9815
- }
9816
- ) }),
9817
- /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
9818
- /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
9819
- /* @__PURE__ */ jsx(Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
9820
- ] }) })
9821
- ]
9822
- }
9823
- ) });
9824
- };
9825
- const schema$4 = objectType({
9826
- email: stringType().email()
9827
- });
9828
- const NumberInput = forwardRef(
9829
- ({
9830
- value,
9831
- onChange,
9832
- size = "base",
9833
- min = 0,
9834
- max = 100,
9835
- step = 1,
9836
- className,
9837
- disabled,
9838
- ...props
9839
- }, ref) => {
9840
- const handleChange = (event) => {
9841
- const newValue = event.target.value === "" ? min : Number(event.target.value);
9842
- if (!isNaN(newValue) && (max === void 0 || newValue <= max) && (min === void 0 || newValue >= min)) {
9843
- onChange(newValue);
9844
- }
9845
- };
9846
- const handleIncrement = () => {
9847
- const newValue = value + step;
9848
- if (max === void 0 || newValue <= max) {
9849
- onChange(newValue);
9850
- }
9851
- };
9852
- const handleDecrement = () => {
9853
- const newValue = value - step;
9854
- if (min === void 0 || newValue >= min) {
9855
- onChange(newValue);
9856
- }
9857
- };
9858
- return /* @__PURE__ */ jsxs(
9859
- "div",
9860
- {
9861
- className: clx(
9862
- "inline-flex rounded-md bg-ui-bg-field shadow-borders-base overflow-hidden divide-x transition-fg",
9863
- "[&:has(input:focus)]:shadow-borders-interactive-with-active",
9864
- {
9865
- "h-7": size === "small",
9866
- "h-8": size === "base"
9867
- },
9868
- className
9869
- ),
9870
- children: [
9871
- /* @__PURE__ */ jsx(
9872
- "input",
9873
- {
9874
- ref,
9875
- type: "number",
9876
- value,
9877
- onChange: handleChange,
9878
- min,
9879
- max,
9880
- step,
9881
- className: clx(
9882
- "flex-1 px-2 py-1 bg-transparent txt-compact-small text-ui-fg-base outline-none [appearance:textfield]",
9883
- "[&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none",
9884
- "placeholder:text-ui-fg-muted"
9885
- ),
9886
- ...props
9887
- }
9888
- ),
9889
- /* @__PURE__ */ jsxs(
9890
- "button",
9891
- {
9892
- className: clx(
9893
- "flex items-center justify-center outline-none transition-fg",
9894
- "disabled:cursor-not-allowed disabled:text-ui-fg-muted",
9895
- "focus:bg-ui-bg-field-component-hover",
9896
- "hover:bg-ui-bg-field-component-hover",
9897
- {
9898
- "size-7": size === "small",
9899
- "size-8": size === "base"
9900
- }
9901
- ),
9902
- type: "button",
9903
- onClick: handleDecrement,
9904
- disabled: min !== void 0 && value <= min || disabled,
9905
- children: [
9906
- /* @__PURE__ */ jsx(Minus, {}),
9907
- /* @__PURE__ */ jsx("span", { className: "sr-only", children: `Decrease by ${step}` })
9908
- ]
9909
- }
9910
- ),
9911
- /* @__PURE__ */ jsxs(
9912
- "button",
9913
- {
9914
- className: clx(
9915
- "flex items-center justify-center outline-none transition-fg",
9916
- "disabled:cursor-not-allowed disabled:text-ui-fg-muted",
9917
- "focus:bg-ui-bg-field-hover",
9918
- "hover:bg-ui-bg-field-hover",
9919
- {
9920
- "size-7": size === "small",
9921
- "size-8": size === "base"
9922
- }
9923
- ),
9924
- type: "button",
9925
- onClick: handleIncrement,
9926
- disabled: max !== void 0 && value >= max || disabled,
9927
- children: [
9928
- /* @__PURE__ */ jsx(Plus, {}),
9929
- /* @__PURE__ */ jsx("span", { className: "sr-only", children: `Increase by ${step}` })
9930
- ]
9931
- }
9932
- )
9933
- ]
9934
- }
9935
- );
9936
- }
9937
- );
9938
- const PRODUCT_VARIANTS_QUERY_KEY = "product-variants";
9939
- const productVariantsQueryKeys = {
9940
- list: (query2) => [
9941
- PRODUCT_VARIANTS_QUERY_KEY,
9942
- query2 ? query2 : void 0
9943
- ]
9944
- };
9945
- const useProductVariants = (query2, options) => {
9946
- const { data, ...rest } = useQuery({
9947
- queryKey: productVariantsQueryKeys.list(query2),
9948
- queryFn: async () => await sdk.admin.productVariant.list(query2),
9949
- ...options
9950
- });
9951
- return { ...data, ...rest };
9952
- };
9953
- const useCancelOrderEdit = ({ preview }) => {
9954
- const { mutateAsync: cancelOrderEdit } = useDraftOrderCancelEdit(preview == null ? void 0 : preview.id);
9955
- const onCancel = useCallback(async () => {
9956
- if (!preview) {
9957
- return true;
9958
- }
9959
- let res = false;
9960
- await cancelOrderEdit(void 0, {
9961
- onError: (e) => {
9962
- toast.error(e.message);
9963
- },
9964
- onSuccess: () => {
9965
- res = true;
9966
- }
9967
- });
9968
- return res;
9969
- }, [preview, cancelOrderEdit]);
9970
- return { onCancel };
9971
- };
9972
- let IS_REQUEST_RUNNING = false;
9973
- const useInitiateOrderEdit = ({
9974
- preview
9975
- }) => {
9976
- const navigate = useNavigate();
9977
- const { mutateAsync } = useDraftOrderBeginEdit(preview == null ? void 0 : preview.id);
9978
- useEffect(() => {
9979
- async function run() {
9980
- if (IS_REQUEST_RUNNING || !preview) {
9981
- return;
9982
- }
9983
- if (preview.order_change) {
9984
- return;
9985
- }
9986
- IS_REQUEST_RUNNING = true;
9987
- await mutateAsync(void 0, {
9988
- onError: (e) => {
9989
- toast.error(e.message);
9990
- navigate(`/draft-orders/${preview.id}`, { replace: true });
9991
- return;
9992
- }
9993
- });
9994
- IS_REQUEST_RUNNING = false;
9995
- }
9996
- run();
9997
- }, [preview, navigate, mutateAsync]);
9998
- };
9999
- function convertNumber(value) {
10000
- return typeof value === "string" ? Number(value.replace(",", ".")) : value;
10001
- }
10002
- const STACKED_MODAL_ID = "items_stacked_modal";
10003
- const Items = () => {
10004
- const { id } = useParams();
10005
- const {
10006
- order: preview,
10007
- isPending: isPreviewPending,
10008
- isError: isPreviewError,
10009
- error: previewError
10010
- } = useOrderPreview(id, void 0, {
10011
- placeholderData: keepPreviousData
10012
- });
10013
- useInitiateOrderEdit({ preview });
10014
- const { draft_order, isPending, isError, error } = useDraftOrder(
10015
- id,
10016
- {
10017
- fields: "currency_code"
10018
- },
10019
- {
10020
- enabled: !!id
10021
- }
10022
- );
10023
- const { onCancel } = useCancelOrderEdit({ preview });
10024
- if (isError) {
10025
- throw error;
10026
- }
10027
- if (isPreviewError) {
10028
- throw previewError;
10029
- }
10030
- const ready = !!preview && !isPreviewPending && !!draft_order && !isPending;
10031
- return /* @__PURE__ */ jsx(RouteFocusModal, { onClose: onCancel, children: ready ? /* @__PURE__ */ jsx(ItemsForm, { preview, currencyCode: draft_order.currency_code }) : /* @__PURE__ */ jsxs("div", { children: [
10032
- /* @__PURE__ */ jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Edit Items" }) }),
10033
- /* @__PURE__ */ jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Loading data for the draft order, please wait..." }) })
10034
- ] }) });
10035
- };
10036
- const ItemsForm = ({ preview, currencyCode }) => {
10037
- var _a;
10038
- const [isSubmitting, setIsSubmitting] = useState(false);
10039
- const [modalContent, setModalContent] = useState(
10040
- null
10041
- );
10042
- const { handleSuccess } = useRouteModal();
10043
- const { searchValue, onSearchValueChange, query: query2 } = useDebouncedSearch();
10044
- const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
10045
- const { mutateAsync: requestOrderEdit } = useDraftOrderRequestEdit(preview.id);
10046
- const itemCount = ((_a = preview.items) == null ? void 0 : _a.reduce((acc, item) => acc + item.quantity, 0)) || 0;
10047
- const matches = useMemo(() => {
10048
- return matchSorter(preview.items, query2, {
10049
- keys: ["product_title", "variant_title", "variant_sku", "title"]
10050
- });
10051
- }, [preview.items, query2]);
10052
- const onSubmit = async () => {
10053
- setIsSubmitting(true);
10054
- let requestSucceeded = false;
10055
- await requestOrderEdit(void 0, {
10056
- onError: (e) => {
10057
- toast.error(`Failed to request order edit: ${e.message}`);
10058
- },
10059
- onSuccess: () => {
10060
- requestSucceeded = true;
10061
- }
10062
- });
10063
- if (!requestSucceeded) {
10064
- setIsSubmitting(false);
10065
- return;
10066
- }
10067
- await confirmOrderEdit(void 0, {
10068
- onError: (e) => {
10069
- toast.error(`Failed to confirm order edit: ${e.message}`);
10070
- },
10071
- onSuccess: () => {
10072
- handleSuccess();
10073
- },
10074
- onSettled: () => {
10075
- setIsSubmitting(false);
10076
- }
10077
- });
10078
- };
10079
- const onKeyDown = useCallback(
10080
- (e) => {
10081
- if (e.key === "Enter" && (e.ctrlKey || e.metaKey)) {
10082
- if (modalContent || isSubmitting) {
10083
- return;
10084
- }
10085
- onSubmit();
10086
- }
10087
- },
10088
- [modalContent, isSubmitting, onSubmit]
10089
- );
10090
- useEffect(() => {
10091
- document.addEventListener("keydown", onKeyDown);
10092
- return () => {
10093
- document.removeEventListener("keydown", onKeyDown);
10094
- };
10095
- }, [onKeyDown]);
10096
- return /* @__PURE__ */ jsxs("div", { className: "flex h-full flex-col overflow-hidden", children: [
10097
- /* @__PURE__ */ jsx(RouteFocusModal.Header, {}),
10098
- /* @__PURE__ */ jsx(RouteFocusModal.Body, { className: "flex flex-1 flex-col overflow-hidden", children: /* @__PURE__ */ jsxs(
10099
- StackedFocusModal,
10100
- {
10101
- id: STACKED_MODAL_ID,
10102
- onOpenChangeCallback: (open) => {
10103
- if (!open) {
10104
- setModalContent(null);
10105
- }
10106
- },
10107
- children: [
10108
- /* @__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: [
10109
- /* @__PURE__ */ jsxs("div", { children: [
10110
- /* @__PURE__ */ jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Items" }) }),
10111
- /* @__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" }) })
9966
+ /* @__PURE__ */ jsxs(RouteDrawer.Body, { className: "flex flex-1 flex-col gap-y-8 overflow-y-auto", children: [
9967
+ /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest grid grid-cols-1 divide-y rounded-lg", children: [
9968
+ /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-subtle grid grid-cols-2 divide-x rounded-t-lg", children: [
9969
+ /* @__PURE__ */ jsx("div", { className: "txt-compact-small-plus text-ui-fg-subtle px-2 py-1.5", children: /* @__PURE__ */ jsx("label", { id: METADATA_KEY_LABEL_ID, children: "Key" }) }),
9970
+ /* @__PURE__ */ jsx("div", { className: "txt-compact-small-plus text-ui-fg-subtle px-2 py-1.5", children: /* @__PURE__ */ jsx("label", { id: METADATA_VALUE_LABEL_ID, children: "Value" }) })
10112
9971
  ] }),
10113
- /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
10114
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-y-6", children: [
10115
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 items-center gap-3", children: [
10116
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
10117
- /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: "Items" }),
10118
- /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Choose items from the product catalog." })
10119
- ] }),
10120
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
10121
- /* @__PURE__ */ jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsx(
10122
- Input,
10123
- {
10124
- type: "search",
10125
- placeholder: "Search items",
10126
- value: searchValue,
10127
- onChange: (e) => onSearchValueChange(e.target.value)
10128
- }
10129
- ) }),
10130
- /* @__PURE__ */ jsxs(DropdownMenu, { children: [
10131
- /* @__PURE__ */ jsx(DropdownMenu.Trigger, { asChild: true, children: /* @__PURE__ */ jsx(IconButton, { type: "button", children: /* @__PURE__ */ jsx(Plus, {}) }) }),
10132
- /* @__PURE__ */ jsxs(DropdownMenu.Content, { children: [
10133
- /* @__PURE__ */ jsx(
10134
- StackedModalTrigger$1,
10135
- {
10136
- type: "add-items",
10137
- setModalContent
10138
- }
10139
- ),
9972
+ fields.map((field, index) => {
9973
+ const isDisabled = field.disabled || false;
9974
+ let placeholder = "-";
9975
+ if (typeof field.value === "object") {
9976
+ placeholder = "{ ... }";
9977
+ }
9978
+ if (Array.isArray(field.value)) {
9979
+ placeholder = "[ ... ]";
9980
+ }
9981
+ return /* @__PURE__ */ jsx(
9982
+ ConditionalTooltip,
9983
+ {
9984
+ showTooltip: isDisabled,
9985
+ content: "This row is disabled because it contains non-primitive data.",
9986
+ children: /* @__PURE__ */ jsxs("div", { className: "group/table relative", children: [
9987
+ /* @__PURE__ */ jsxs(
9988
+ "div",
9989
+ {
9990
+ className: clx("grid grid-cols-2 divide-x", {
9991
+ "overflow-hidden rounded-b-lg": index === fields.length - 1
9992
+ }),
9993
+ children: [
9994
+ /* @__PURE__ */ jsx(
9995
+ Form$2.Field,
9996
+ {
9997
+ control: form.control,
9998
+ name: `metadata.${index}.key`,
9999
+ render: ({ field: field2 }) => {
10000
+ return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
10001
+ GridInput,
10002
+ {
10003
+ "aria-labelledby": METADATA_KEY_LABEL_ID,
10004
+ ...field2,
10005
+ disabled: isDisabled,
10006
+ placeholder: "Key"
10007
+ }
10008
+ ) }) });
10009
+ }
10010
+ }
10011
+ ),
10012
+ /* @__PURE__ */ jsx(
10013
+ Form$2.Field,
10014
+ {
10015
+ control: form.control,
10016
+ name: `metadata.${index}.value`,
10017
+ render: ({ field: { value, ...field2 } }) => {
10018
+ return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
10019
+ GridInput,
10020
+ {
10021
+ "aria-labelledby": METADATA_VALUE_LABEL_ID,
10022
+ ...field2,
10023
+ value: isDisabled ? placeholder : value,
10024
+ disabled: isDisabled,
10025
+ placeholder: "Value"
10026
+ }
10027
+ ) }) });
10028
+ }
10029
+ }
10030
+ )
10031
+ ]
10032
+ }
10033
+ ),
10034
+ /* @__PURE__ */ jsxs(DropdownMenu, { children: [
10140
10035
  /* @__PURE__ */ jsx(
10141
- StackedModalTrigger$1,
10036
+ DropdownMenu.Trigger,
10142
10037
  {
10143
- type: "add-custom-item",
10144
- setModalContent
10038
+ className: clx(
10039
+ "invisible absolute inset-y-0 -right-2.5 my-auto group-hover/table:visible data-[state='open']:visible",
10040
+ {
10041
+ hidden: isDisabled
10042
+ }
10043
+ ),
10044
+ disabled: isDisabled,
10045
+ asChild: true,
10046
+ children: /* @__PURE__ */ jsx(IconButton, { size: "2xsmall", children: /* @__PURE__ */ jsx(EllipsisVertical, {}) })
10145
10047
  }
10146
- )
10147
- ] })
10148
- ] })
10149
- ] })
10150
- ] }),
10151
- /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-subtle shadow-elevation-card-rest rounded-xl", children: [
10152
- /* @__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: [
10153
- /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: "Item" }) }),
10154
- /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: "Quantity" }) }),
10155
- /* @__PURE__ */ jsx("div", { className: "text-right", children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: "Price" }) }),
10156
- /* @__PURE__ */ jsx("div", {})
10157
- ] }) }),
10158
- /* @__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: [
10159
- /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: "There are no items in this order" }),
10160
- /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Add items to the order to get started." })
10161
- ] }) : matches.length > 0 ? matches == null ? void 0 : matches.map((item) => /* @__PURE__ */ jsx(
10162
- Item,
10163
- {
10164
- item,
10165
- preview,
10166
- currencyCode
10167
- },
10168
- item.id
10169
- )) : /* @__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: [
10170
- /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: "No items found" }),
10171
- /* @__PURE__ */ jsxs(Text, { size: "small", className: "text-ui-fg-subtle", children: [
10172
- 'No items found for "',
10173
- query2,
10174
- '".'
10175
- ] })
10176
- ] }) })
10177
- ] })
10178
- ] }),
10179
- /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
10180
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-[1fr_0.5fr_0.5fr] gap-3", children: [
10181
- /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: "Subtotal" }) }),
10182
- /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsxs(
10183
- Text,
10184
- {
10185
- size: "small",
10186
- leading: "compact",
10187
- className: "text-ui-fg-subtle",
10188
- children: [
10189
- itemCount,
10190
- " ",
10191
- itemCount === 1 ? "item" : "items"
10192
- ]
10193
- }
10194
- ) }),
10195
- /* @__PURE__ */ jsx("div", { className: "text-right", children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: getStylizedAmount(preview.item_subtotal, currencyCode) }) })
10196
- ] })
10197
- ] }) }),
10198
- modalContent && (modalContent === "add-items" ? /* @__PURE__ */ jsx(ExistingItemsForm, { orderId: preview.id, items: preview.items }) : modalContent === "add-custom-item" ? /* @__PURE__ */ jsx(
10199
- CustomItemForm,
10200
- {
10201
- orderId: preview.id,
10202
- currencyCode
10203
- }
10204
- ) : null)
10205
- ]
10206
- }
10207
- ) }),
10208
- /* @__PURE__ */ jsx(RouteFocusModal.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
10209
- /* @__PURE__ */ jsx(RouteFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
10210
- /* @__PURE__ */ jsx(
10211
- Button,
10212
- {
10213
- size: "small",
10214
- type: "button",
10215
- onClick: onSubmit,
10216
- isLoading: isSubmitting,
10217
- children: "Save"
10218
- }
10219
- )
10220
- ] }) })
10221
- ] });
10222
- };
10223
- const Item = ({ item, preview, currencyCode }) => {
10224
- if (item.variant_id) {
10225
- return /* @__PURE__ */ jsx(VariantItem, { item, preview, currencyCode });
10226
- }
10227
- return /* @__PURE__ */ jsx(CustomItem, { item, preview, currencyCode });
10228
- };
10229
- const VariantItem = ({ item, preview, currencyCode }) => {
10230
- const [editing, setEditing] = useState(false);
10231
- const form = useForm({
10232
- defaultValues: {
10233
- quantity: item.quantity,
10234
- unit_price: item.unit_price
10235
- },
10236
- resolver: zodResolver(variantItemSchema)
10237
- });
10238
- const actionId = useMemo(() => {
10239
- var _a, _b;
10240
- return (_b = (_a = item.actions) == null ? void 0 : _a.find((a) => a.action === "ITEM_ADD")) == null ? void 0 : _b.id;
10241
- }, [item]);
10242
- const { mutateAsync: updateActionItem, isPending: isUpdatingActionItem } = useDraftOrderUpdateActionItem(preview.id);
10243
- const { mutateAsync: updateOriginalItem, isPending: isUpdatingOriginalItem } = useDraftOrderUpdateItem(preview.id);
10244
- const isPending = isUpdatingActionItem || isUpdatingOriginalItem;
10245
- const onSubmit = form.handleSubmit(async (data) => {
10246
- if (convertNumber(data.unit_price) === item.unit_price && data.quantity === item.quantity) {
10247
- setEditing(false);
10248
- return;
10249
- }
10250
- if (!actionId) {
10251
- await updateOriginalItem(
10252
- {
10253
- item_id: item.id,
10254
- quantity: data.quantity,
10255
- unit_price: convertNumber(data.unit_price)
10256
- },
10257
- {
10258
- onSuccess: () => {
10259
- setEditing(false);
10260
- },
10261
- onError: (e) => {
10262
- toast.error(e.message);
10263
- }
10264
- }
10265
- );
10266
- return;
10267
- }
10268
- await updateActionItem(
10269
- {
10270
- action_id: actionId,
10271
- quantity: data.quantity,
10272
- unit_price: convertNumber(data.unit_price)
10273
- },
10274
- {
10275
- onSuccess: () => {
10276
- setEditing(false);
10277
- },
10278
- onError: (e) => {
10279
- toast.error(e.message);
10280
- }
10281
- }
10282
- );
10283
- });
10284
- 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: [
10285
- /* @__PURE__ */ jsxs("div", { className: "flex w-full items-center gap-x-3", children: [
10286
- /* @__PURE__ */ jsx(
10287
- Thumbnail,
10288
- {
10289
- thumbnail: item.thumbnail,
10290
- alt: item.product_title ?? void 0
10291
- }
10292
- ),
10293
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
10294
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-1", children: [
10295
- /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: item.product_title }),
10296
- /* @__PURE__ */ jsxs(
10297
- Text,
10298
- {
10299
- size: "small",
10300
- leading: "compact",
10301
- className: "text-ui-fg-subtle",
10302
- children: [
10303
- "(",
10304
- item.variant_title,
10305
- ")"
10306
- ]
10307
- }
10308
- )
10309
- ] }),
10310
- /* @__PURE__ */ jsx(
10311
- Text,
10312
- {
10313
- size: "small",
10314
- leading: "compact",
10315
- className: "text-ui-fg-subtle",
10316
- children: item.variant_sku
10317
- }
10318
- )
10319
- ] })
10320
- ] }),
10321
- editing ? /* @__PURE__ */ jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsx(
10322
- Form$2.Field,
10323
- {
10324
- control: form.control,
10325
- name: "quantity",
10326
- render: ({ field }) => {
10327
- return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(NumberInput, { ...field }) }) });
10328
- }
10329
- }
10330
- ) }) : /* @__PURE__ */ jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: item.quantity }) }),
10331
- editing ? /* @__PURE__ */ jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsx(
10332
- Form$2.Field,
10333
- {
10334
- control: form.control,
10335
- name: "unit_price",
10336
- render: ({ field: { onChange, ...field } }) => {
10337
- return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
10338
- CurrencyInput,
10339
- {
10340
- ...field,
10341
- symbol: getNativeSymbol(currencyCode),
10342
- code: currencyCode,
10343
- onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value)
10344
- }
10345
- ) }) });
10346
- }
10347
- }
10348
- ) }) : /* @__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) }) }),
10349
- /* @__PURE__ */ jsx(
10350
- IconButton,
10351
- {
10352
- type: "button",
10353
- size: "small",
10354
- onClick: editing ? onSubmit : () => {
10355
- setEditing(true);
10356
- },
10357
- disabled: isPending,
10358
- children: editing ? /* @__PURE__ */ jsx(Check, {}) : /* @__PURE__ */ jsx(PencilSquare, {})
10359
- }
10360
- )
10361
- ] }) }) });
10048
+ ),
10049
+ /* @__PURE__ */ jsxs(DropdownMenu.Content, { children: [
10050
+ /* @__PURE__ */ jsxs(
10051
+ DropdownMenu.Item,
10052
+ {
10053
+ className: "gap-x-2",
10054
+ onClick: () => insertRow(index, "above"),
10055
+ children: [
10056
+ /* @__PURE__ */ jsx(ArrowUpMini, { className: "text-ui-fg-subtle" }),
10057
+ "Insert row above"
10058
+ ]
10059
+ }
10060
+ ),
10061
+ /* @__PURE__ */ jsxs(
10062
+ DropdownMenu.Item,
10063
+ {
10064
+ className: "gap-x-2",
10065
+ onClick: () => insertRow(index, "below"),
10066
+ children: [
10067
+ /* @__PURE__ */ jsx(ArrowDownMini, { className: "text-ui-fg-subtle" }),
10068
+ "Insert row below"
10069
+ ]
10070
+ }
10071
+ ),
10072
+ /* @__PURE__ */ jsx(DropdownMenu.Separator, {}),
10073
+ /* @__PURE__ */ jsxs(
10074
+ DropdownMenu.Item,
10075
+ {
10076
+ className: "gap-x-2",
10077
+ onClick: () => deleteRow(index),
10078
+ children: [
10079
+ /* @__PURE__ */ jsx(Trash, { className: "text-ui-fg-subtle" }),
10080
+ "Delete row"
10081
+ ]
10082
+ }
10083
+ )
10084
+ ] })
10085
+ ] })
10086
+ ] })
10087
+ },
10088
+ field.id
10089
+ );
10090
+ })
10091
+ ] }),
10092
+ hasUneditableRows && /* @__PURE__ */ jsx(InlineTip, { variant: "warning", label: "Some rows are disabled", children: "This object contains non-primitive metadata, such as arrays or objects, that can't be edited here. To edit the disabled rows, use the API directly." })
10093
+ ] }),
10094
+ /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
10095
+ /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
10096
+ /* @__PURE__ */ jsx(Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
10097
+ ] }) })
10098
+ ]
10099
+ }
10100
+ ) });
10362
10101
  };
10363
- const variantItemSchema = objectType({
10364
- quantity: numberType(),
10365
- unit_price: unionType([numberType(), stringType()])
10102
+ const GridInput = forwardRef(({ className, ...props }, ref) => {
10103
+ return /* @__PURE__ */ jsx(
10104
+ "input",
10105
+ {
10106
+ ref,
10107
+ ...props,
10108
+ autoComplete: "off",
10109
+ className: clx(
10110
+ "txt-compact-small text-ui-fg-base placeholder:text-ui-fg-muted disabled:text-ui-fg-disabled disabled:bg-ui-bg-base bg-transparent px-2 py-1.5 outline-none",
10111
+ className
10112
+ )
10113
+ }
10114
+ );
10366
10115
  });
10367
- const CustomItem = ({ item, preview, currencyCode }) => {
10368
- const [editing, setEditing] = useState(false);
10369
- const { quantity, unit_price, title } = item;
10370
- const form = useForm({
10371
- defaultValues: {
10372
- title,
10373
- quantity,
10374
- unit_price
10375
- },
10376
- resolver: zodResolver(customItemSchema)
10116
+ GridInput.displayName = "MetadataForm.GridInput";
10117
+ const PlaceholderInner = () => {
10118
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-1 flex-col overflow-hidden", children: [
10119
+ /* @__PURE__ */ jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsx(Skeleton, { className: "h-[148ox] w-full rounded-lg" }) }),
10120
+ /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
10121
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-7 w-12 rounded-md" }),
10122
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-7 w-12 rounded-md" })
10123
+ ] }) })
10124
+ ] });
10125
+ };
10126
+ const EDITABLE_TYPES = ["string", "number", "boolean"];
10127
+ function getDefaultValues(metadata) {
10128
+ if (!metadata || !Object.keys(metadata).length) {
10129
+ return [
10130
+ {
10131
+ key: "",
10132
+ value: "",
10133
+ disabled: false
10134
+ }
10135
+ ];
10136
+ }
10137
+ return Object.entries(metadata).map(([key, value]) => {
10138
+ if (!EDITABLE_TYPES.includes(typeof value)) {
10139
+ return {
10140
+ key,
10141
+ value,
10142
+ disabled: true
10143
+ };
10144
+ }
10145
+ let stringValue = value;
10146
+ if (typeof value !== "string") {
10147
+ stringValue = JSON.stringify(value);
10148
+ }
10149
+ return {
10150
+ key,
10151
+ value: stringValue,
10152
+ original_key: key
10153
+ };
10377
10154
  });
10378
- useEffect(() => {
10379
- form.reset({
10380
- title,
10381
- quantity,
10382
- unit_price
10383
- });
10384
- }, [form, title, quantity, unit_price]);
10385
- const actionId = useMemo(() => {
10386
- var _a, _b;
10387
- return (_b = (_a = item.actions) == null ? void 0 : _a.find((a) => a.action === "ITEM_ADD")) == null ? void 0 : _b.id;
10388
- }, [item]);
10389
- const { mutateAsync: updateActionItem, isPending: isUpdatingActionItem } = useDraftOrderUpdateActionItem(preview.id);
10390
- const { mutateAsync: removeActionItem, isPending: isRemovingActionItem } = useDraftOrderRemoveActionItem(preview.id);
10391
- const { mutateAsync: updateOriginalItem, isPending: isUpdatingOriginalItem } = useDraftOrderUpdateItem(preview.id);
10392
- const isPending = isUpdatingActionItem || isUpdatingOriginalItem;
10393
- const onSubmit = form.handleSubmit(async (data) => {
10394
- if (convertNumber(data.unit_price) === item.unit_price && data.quantity === item.quantity && data.title === item.title) {
10395
- setEditing(false);
10155
+ }
10156
+ function parseValues(values) {
10157
+ const metadata = values.metadata;
10158
+ const isEmpty = !metadata.length || metadata.length === 1 && !metadata[0].key && !metadata[0].value;
10159
+ if (isEmpty) {
10160
+ return null;
10161
+ }
10162
+ const update = {};
10163
+ metadata.forEach((field) => {
10164
+ let key = field.key;
10165
+ let value = field.value;
10166
+ const disabled = field.disabled;
10167
+ if (!key || !value) {
10396
10168
  return;
10397
10169
  }
10398
- if (!actionId) {
10399
- await updateOriginalItem(
10400
- {
10401
- item_id: item.id,
10402
- quantity: data.quantity,
10403
- unit_price: convertNumber(data.unit_price)
10404
- },
10405
- {
10406
- onSuccess: () => {
10407
- setEditing(false);
10408
- },
10409
- onError: (e) => {
10410
- toast.error(e.message);
10411
- }
10412
- }
10413
- );
10170
+ if (disabled) {
10171
+ update[key] = value;
10414
10172
  return;
10415
10173
  }
10416
- if (data.quantity === 0) {
10417
- await removeActionItem(actionId, {
10418
- onSuccess: () => {
10419
- setEditing(false);
10420
- },
10421
- onError: (e) => {
10422
- toast.error(e.message);
10423
- }
10424
- });
10425
- return;
10174
+ key = key.trim();
10175
+ value = value.trim();
10176
+ if (value === "true") {
10177
+ update[key] = true;
10178
+ } else if (value === "false") {
10179
+ update[key] = false;
10180
+ } else {
10181
+ const parsedNumber = parseFloat(value);
10182
+ if (!isNaN(parsedNumber)) {
10183
+ update[key] = parsedNumber;
10184
+ } else {
10185
+ update[key] = value;
10186
+ }
10426
10187
  }
10427
- await updateActionItem(
10428
- {
10429
- action_id: actionId,
10430
- quantity: data.quantity,
10431
- unit_price: convertNumber(data.unit_price)
10432
- },
10188
+ });
10189
+ return update;
10190
+ }
10191
+ function getHasUneditableRows(metadata) {
10192
+ if (!metadata) {
10193
+ return false;
10194
+ }
10195
+ return Object.values(metadata).some(
10196
+ (value) => !EDITABLE_TYPES.includes(typeof value)
10197
+ );
10198
+ }
10199
+ const NumberInput = forwardRef(
10200
+ ({
10201
+ value,
10202
+ onChange,
10203
+ size = "base",
10204
+ min = 0,
10205
+ max = 100,
10206
+ step = 1,
10207
+ className,
10208
+ disabled,
10209
+ ...props
10210
+ }, ref) => {
10211
+ const handleChange = (event) => {
10212
+ const newValue = event.target.value === "" ? min : Number(event.target.value);
10213
+ if (!isNaN(newValue) && (max === void 0 || newValue <= max) && (min === void 0 || newValue >= min)) {
10214
+ onChange(newValue);
10215
+ }
10216
+ };
10217
+ const handleIncrement = () => {
10218
+ const newValue = value + step;
10219
+ if (max === void 0 || newValue <= max) {
10220
+ onChange(newValue);
10221
+ }
10222
+ };
10223
+ const handleDecrement = () => {
10224
+ const newValue = value - step;
10225
+ if (min === void 0 || newValue >= min) {
10226
+ onChange(newValue);
10227
+ }
10228
+ };
10229
+ return /* @__PURE__ */ jsxs(
10230
+ "div",
10433
10231
  {
10434
- onSuccess: () => {
10435
- setEditing(false);
10436
- },
10437
- onError: (e) => {
10438
- toast.error(e.message);
10439
- }
10232
+ className: clx(
10233
+ "inline-flex rounded-md bg-ui-bg-field shadow-borders-base overflow-hidden divide-x transition-fg",
10234
+ "[&:has(input:focus)]:shadow-borders-interactive-with-active",
10235
+ {
10236
+ "h-7": size === "small",
10237
+ "h-8": size === "base"
10238
+ },
10239
+ className
10240
+ ),
10241
+ children: [
10242
+ /* @__PURE__ */ jsx(
10243
+ "input",
10244
+ {
10245
+ ref,
10246
+ type: "number",
10247
+ value,
10248
+ onChange: handleChange,
10249
+ min,
10250
+ max,
10251
+ step,
10252
+ className: clx(
10253
+ "flex-1 px-2 py-1 bg-transparent txt-compact-small text-ui-fg-base outline-none [appearance:textfield]",
10254
+ "[&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none",
10255
+ "placeholder:text-ui-fg-muted"
10256
+ ),
10257
+ ...props
10258
+ }
10259
+ ),
10260
+ /* @__PURE__ */ jsxs(
10261
+ "button",
10262
+ {
10263
+ className: clx(
10264
+ "flex items-center justify-center outline-none transition-fg",
10265
+ "disabled:cursor-not-allowed disabled:text-ui-fg-muted",
10266
+ "focus:bg-ui-bg-field-component-hover",
10267
+ "hover:bg-ui-bg-field-component-hover",
10268
+ {
10269
+ "size-7": size === "small",
10270
+ "size-8": size === "base"
10271
+ }
10272
+ ),
10273
+ type: "button",
10274
+ onClick: handleDecrement,
10275
+ disabled: min !== void 0 && value <= min || disabled,
10276
+ children: [
10277
+ /* @__PURE__ */ jsx(Minus, {}),
10278
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: `Decrease by ${step}` })
10279
+ ]
10280
+ }
10281
+ ),
10282
+ /* @__PURE__ */ jsxs(
10283
+ "button",
10284
+ {
10285
+ className: clx(
10286
+ "flex items-center justify-center outline-none transition-fg",
10287
+ "disabled:cursor-not-allowed disabled:text-ui-fg-muted",
10288
+ "focus:bg-ui-bg-field-hover",
10289
+ "hover:bg-ui-bg-field-hover",
10290
+ {
10291
+ "size-7": size === "small",
10292
+ "size-8": size === "base"
10293
+ }
10294
+ ),
10295
+ type: "button",
10296
+ onClick: handleIncrement,
10297
+ disabled: max !== void 0 && value >= max || disabled,
10298
+ children: [
10299
+ /* @__PURE__ */ jsx(Plus, {}),
10300
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: `Increase by ${step}` })
10301
+ ]
10302
+ }
10303
+ )
10304
+ ]
10440
10305
  }
10441
10306
  );
10307
+ }
10308
+ );
10309
+ const PRODUCT_VARIANTS_QUERY_KEY = "product-variants";
10310
+ const productVariantsQueryKeys = {
10311
+ list: (query2) => [
10312
+ PRODUCT_VARIANTS_QUERY_KEY,
10313
+ query2 ? query2 : void 0
10314
+ ]
10315
+ };
10316
+ const useProductVariants = (query2, options) => {
10317
+ const { data, ...rest } = useQuery({
10318
+ queryKey: productVariantsQueryKeys.list(query2),
10319
+ queryFn: async () => await sdk.admin.productVariant.list(query2),
10320
+ ...options
10442
10321
  });
10443
- 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: [
10444
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-3", children: [
10445
- /* @__PURE__ */ jsx(
10446
- Thumbnail,
10447
- {
10448
- thumbnail: item.thumbnail,
10449
- alt: item.title ?? void 0
10450
- }
10451
- ),
10452
- editing ? /* @__PURE__ */ jsx(
10453
- Form$2.Field,
10454
- {
10455
- control: form.control,
10456
- name: "title",
10457
- render: ({ field }) => {
10458
- return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }) });
10459
- }
10460
- }
10461
- ) : /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: item.title })
10462
- ] }),
10463
- editing ? /* @__PURE__ */ jsx(
10464
- Form$2.Field,
10465
- {
10466
- control: form.control,
10467
- name: "quantity",
10468
- render: ({ field }) => {
10469
- return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(NumberInput, { ...field }) }) });
10470
- }
10322
+ return { ...data, ...rest };
10323
+ };
10324
+ const useCancelOrderEdit = ({ preview }) => {
10325
+ const { mutateAsync: cancelOrderEdit } = useDraftOrderCancelEdit(preview == null ? void 0 : preview.id);
10326
+ const onCancel = useCallback(async () => {
10327
+ if (!preview) {
10328
+ return true;
10329
+ }
10330
+ let res = false;
10331
+ await cancelOrderEdit(void 0, {
10332
+ onError: (e) => {
10333
+ toast.error(e.message);
10334
+ },
10335
+ onSuccess: () => {
10336
+ res = true;
10471
10337
  }
10472
- ) : /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: item.quantity }),
10473
- editing ? /* @__PURE__ */ jsx(
10474
- Form$2.Field,
10475
- {
10476
- control: form.control,
10477
- name: "unit_price",
10478
- render: ({ field: { onChange, ...field } }) => {
10479
- return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
10480
- CurrencyInput,
10481
- {
10482
- ...field,
10483
- symbol: getNativeSymbol(currencyCode),
10484
- code: currencyCode,
10485
- onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value)
10486
- }
10487
- ) }) });
10488
- }
10338
+ });
10339
+ return res;
10340
+ }, [preview, cancelOrderEdit]);
10341
+ return { onCancel };
10342
+ };
10343
+ let IS_REQUEST_RUNNING = false;
10344
+ const useInitiateOrderEdit = ({
10345
+ preview
10346
+ }) => {
10347
+ const navigate = useNavigate();
10348
+ const { mutateAsync } = useDraftOrderBeginEdit(preview == null ? void 0 : preview.id);
10349
+ useEffect(() => {
10350
+ async function run() {
10351
+ if (IS_REQUEST_RUNNING || !preview) {
10352
+ return;
10489
10353
  }
10490
- ) : /* @__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) }) }),
10491
- /* @__PURE__ */ jsx(
10492
- IconButton,
10493
- {
10494
- type: "button",
10495
- size: "small",
10496
- onClick: editing ? onSubmit : () => {
10497
- setEditing(true);
10498
- },
10499
- disabled: isPending,
10500
- children: editing ? /* @__PURE__ */ jsx(Check, {}) : /* @__PURE__ */ jsx(PencilSquare, {})
10354
+ if (preview.order_change) {
10355
+ return;
10501
10356
  }
10502
- )
10503
- ] }) }) });
10357
+ IS_REQUEST_RUNNING = true;
10358
+ await mutateAsync(void 0, {
10359
+ onError: (e) => {
10360
+ toast.error(e.message);
10361
+ navigate(`/draft-orders/${preview.id}`, { replace: true });
10362
+ return;
10363
+ }
10364
+ });
10365
+ IS_REQUEST_RUNNING = false;
10366
+ }
10367
+ run();
10368
+ }, [preview, navigate, mutateAsync]);
10504
10369
  };
10505
- const StackedModalTrigger$1 = ({
10506
- type,
10507
- setModalContent
10508
- }) => {
10509
- const { setIsOpen } = useStackedModal();
10510
- const onClick = useCallback(() => {
10511
- setModalContent(type);
10512
- setIsOpen(STACKED_MODAL_ID, true);
10513
- }, [setModalContent, setIsOpen, type]);
10514
- return /* @__PURE__ */ jsx(StackedFocusModal.Trigger, { asChild: true, children: /* @__PURE__ */ jsx(DropdownMenu.Item, { onClick, children: type === "add-items" ? "Add items" : "Add custom item" }) });
10370
+ function convertNumber(value) {
10371
+ return typeof value === "string" ? Number(value.replace(",", ".")) : value;
10372
+ }
10373
+ const STACKED_MODAL_ID = "items_stacked_modal";
10374
+ const Items = () => {
10375
+ const { id } = useParams();
10376
+ const {
10377
+ order: preview,
10378
+ isPending: isPreviewPending,
10379
+ isError: isPreviewError,
10380
+ error: previewError
10381
+ } = useOrderPreview(id, void 0, {
10382
+ placeholderData: keepPreviousData
10383
+ });
10384
+ useInitiateOrderEdit({ preview });
10385
+ const { draft_order, isPending, isError, error } = useDraftOrder(
10386
+ id,
10387
+ {
10388
+ fields: "currency_code"
10389
+ },
10390
+ {
10391
+ enabled: !!id
10392
+ }
10393
+ );
10394
+ const { onCancel } = useCancelOrderEdit({ preview });
10395
+ if (isError) {
10396
+ throw error;
10397
+ }
10398
+ if (isPreviewError) {
10399
+ throw previewError;
10400
+ }
10401
+ const ready = !!preview && !isPreviewPending && !!draft_order && !isPending;
10402
+ return /* @__PURE__ */ jsx(RouteFocusModal, { onClose: onCancel, children: ready ? /* @__PURE__ */ jsx(ItemsForm, { preview, currencyCode: draft_order.currency_code }) : /* @__PURE__ */ jsxs("div", { children: [
10403
+ /* @__PURE__ */ jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Edit Items" }) }),
10404
+ /* @__PURE__ */ jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Loading data for the draft order, please wait..." }) })
10405
+ ] }) });
10515
10406
  };
10516
- const VARIANT_PREFIX = "items";
10517
- const LIMIT = 50;
10518
- const ExistingItemsForm = ({ orderId, items }) => {
10519
- const { setIsOpen } = useStackedModal();
10520
- const [rowSelection, setRowSelection] = useState(
10521
- items.reduce((acc, item) => {
10522
- acc[item.variant_id] = true;
10523
- return acc;
10524
- }, {})
10407
+ const ItemsForm = ({ preview, currencyCode }) => {
10408
+ var _a;
10409
+ const [isSubmitting, setIsSubmitting] = useState(false);
10410
+ const [modalContent, setModalContent] = useState(
10411
+ null
10525
10412
  );
10526
- useEffect(() => {
10527
- setRowSelection(
10528
- items.reduce((acc, item) => {
10529
- if (item.variant_id) {
10530
- acc[item.variant_id] = true;
10413
+ const { handleSuccess } = useRouteModal();
10414
+ const { searchValue, onSearchValueChange, query: query2 } = useDebouncedSearch();
10415
+ const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
10416
+ const { mutateAsync: requestOrderEdit } = useDraftOrderRequestEdit(preview.id);
10417
+ const itemCount = ((_a = preview.items) == null ? void 0 : _a.reduce((acc, item) => acc + item.quantity, 0)) || 0;
10418
+ const matches = useMemo(() => {
10419
+ return matchSorter(preview.items, query2, {
10420
+ keys: ["product_title", "variant_title", "variant_sku", "title"]
10421
+ });
10422
+ }, [preview.items, query2]);
10423
+ const onSubmit = async () => {
10424
+ setIsSubmitting(true);
10425
+ let requestSucceeded = false;
10426
+ await requestOrderEdit(void 0, {
10427
+ onError: (e) => {
10428
+ toast.error(`Failed to request order edit: ${e.message}`);
10429
+ },
10430
+ onSuccess: () => {
10431
+ requestSucceeded = true;
10432
+ }
10433
+ });
10434
+ if (!requestSucceeded) {
10435
+ setIsSubmitting(false);
10436
+ return;
10437
+ }
10438
+ await confirmOrderEdit(void 0, {
10439
+ onError: (e) => {
10440
+ toast.error(`Failed to confirm order edit: ${e.message}`);
10441
+ },
10442
+ onSuccess: () => {
10443
+ handleSuccess();
10444
+ },
10445
+ onSettled: () => {
10446
+ setIsSubmitting(false);
10447
+ }
10448
+ });
10449
+ };
10450
+ const onKeyDown = useCallback(
10451
+ (e) => {
10452
+ if (e.key === "Enter" && (e.ctrlKey || e.metaKey)) {
10453
+ if (modalContent || isSubmitting) {
10454
+ return;
10531
10455
  }
10532
- return acc;
10533
- }, {})
10534
- );
10535
- }, [items]);
10536
- const { q, order, offset } = useQueryParams(
10537
- ["q", "order", "offset"],
10538
- VARIANT_PREFIX
10539
- );
10540
- const { variants, count, isPending, isError, error } = useProductVariants(
10541
- {
10542
- q,
10543
- order,
10544
- offset: offset ? parseInt(offset) : void 0,
10545
- limit: LIMIT
10456
+ onSubmit();
10457
+ }
10546
10458
  },
10547
- {
10548
- placeholderData: keepPreviousData
10549
- }
10459
+ [modalContent, isSubmitting, onSubmit]
10550
10460
  );
10551
- const columns = useColumns();
10552
- const { mutateAsync } = useDraftOrderAddItems(orderId);
10553
- const onSubmit = async () => {
10554
- const ids = Object.keys(rowSelection).filter(
10555
- (id) => !items.find((i) => i.variant_id === id)
10556
- );
10557
- await mutateAsync(
10558
- {
10559
- items: ids.map((id) => ({
10560
- variant_id: id,
10561
- quantity: 1
10562
- }))
10563
- },
10461
+ useEffect(() => {
10462
+ document.addEventListener("keydown", onKeyDown);
10463
+ return () => {
10464
+ document.removeEventListener("keydown", onKeyDown);
10465
+ };
10466
+ }, [onKeyDown]);
10467
+ return /* @__PURE__ */ jsxs("div", { className: "flex h-full flex-col overflow-hidden", children: [
10468
+ /* @__PURE__ */ jsx(RouteFocusModal.Header, {}),
10469
+ /* @__PURE__ */ jsx(RouteFocusModal.Body, { className: "flex flex-1 flex-col overflow-hidden", children: /* @__PURE__ */ jsxs(
10470
+ StackedFocusModal,
10564
10471
  {
10565
- onSuccess: () => {
10566
- setRowSelection({});
10567
- setIsOpen(STACKED_MODAL_ID, false);
10472
+ id: STACKED_MODAL_ID,
10473
+ onOpenChangeCallback: (open) => {
10474
+ if (!open) {
10475
+ setModalContent(null);
10476
+ }
10568
10477
  },
10569
- onError: (e) => {
10570
- toast.error(e.message);
10571
- }
10478
+ children: [
10479
+ /* @__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: [
10480
+ /* @__PURE__ */ jsxs("div", { children: [
10481
+ /* @__PURE__ */ jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Items" }) }),
10482
+ /* @__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" }) })
10483
+ ] }),
10484
+ /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
10485
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-y-6", children: [
10486
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 items-center gap-3", children: [
10487
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
10488
+ /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: "Items" }),
10489
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Choose items from the product catalog." })
10490
+ ] }),
10491
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
10492
+ /* @__PURE__ */ jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsx(
10493
+ Input,
10494
+ {
10495
+ type: "search",
10496
+ placeholder: "Search items",
10497
+ value: searchValue,
10498
+ onChange: (e) => onSearchValueChange(e.target.value)
10499
+ }
10500
+ ) }),
10501
+ /* @__PURE__ */ jsxs(DropdownMenu, { children: [
10502
+ /* @__PURE__ */ jsx(DropdownMenu.Trigger, { asChild: true, children: /* @__PURE__ */ jsx(IconButton, { type: "button", children: /* @__PURE__ */ jsx(Plus, {}) }) }),
10503
+ /* @__PURE__ */ jsxs(DropdownMenu.Content, { children: [
10504
+ /* @__PURE__ */ jsx(
10505
+ StackedModalTrigger$1,
10506
+ {
10507
+ type: "add-items",
10508
+ setModalContent
10509
+ }
10510
+ ),
10511
+ /* @__PURE__ */ jsx(
10512
+ StackedModalTrigger$1,
10513
+ {
10514
+ type: "add-custom-item",
10515
+ setModalContent
10516
+ }
10517
+ )
10518
+ ] })
10519
+ ] })
10520
+ ] })
10521
+ ] }),
10522
+ /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-subtle shadow-elevation-card-rest rounded-xl", children: [
10523
+ /* @__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: [
10524
+ /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: "Item" }) }),
10525
+ /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: "Quantity" }) }),
10526
+ /* @__PURE__ */ jsx("div", { className: "text-right", children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: "Price" }) }),
10527
+ /* @__PURE__ */ jsx("div", {})
10528
+ ] }) }),
10529
+ /* @__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: [
10530
+ /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: "There are no items in this order" }),
10531
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Add items to the order to get started." })
10532
+ ] }) : matches.length > 0 ? matches == null ? void 0 : matches.map((item) => /* @__PURE__ */ jsx(
10533
+ Item,
10534
+ {
10535
+ item,
10536
+ preview,
10537
+ currencyCode
10538
+ },
10539
+ item.id
10540
+ )) : /* @__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: [
10541
+ /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: "No items found" }),
10542
+ /* @__PURE__ */ jsxs(Text, { size: "small", className: "text-ui-fg-subtle", children: [
10543
+ 'No items found for "',
10544
+ query2,
10545
+ '".'
10546
+ ] })
10547
+ ] }) })
10548
+ ] })
10549
+ ] }),
10550
+ /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
10551
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-[1fr_0.5fr_0.5fr] gap-3", children: [
10552
+ /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: "Subtotal" }) }),
10553
+ /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsxs(
10554
+ Text,
10555
+ {
10556
+ size: "small",
10557
+ leading: "compact",
10558
+ className: "text-ui-fg-subtle",
10559
+ children: [
10560
+ itemCount,
10561
+ " ",
10562
+ itemCount === 1 ? "item" : "items"
10563
+ ]
10564
+ }
10565
+ ) }),
10566
+ /* @__PURE__ */ jsx("div", { className: "text-right", children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: getStylizedAmount(preview.item_subtotal, currencyCode) }) })
10567
+ ] })
10568
+ ] }) }),
10569
+ modalContent && (modalContent === "add-items" ? /* @__PURE__ */ jsx(ExistingItemsForm, { orderId: preview.id, items: preview.items }) : modalContent === "add-custom-item" ? /* @__PURE__ */ jsx(
10570
+ CustomItemForm,
10571
+ {
10572
+ orderId: preview.id,
10573
+ currencyCode
10574
+ }
10575
+ ) : null)
10576
+ ]
10572
10577
  }
10573
- );
10574
- };
10575
- if (isError) {
10576
- throw error;
10577
- }
10578
- return /* @__PURE__ */ jsxs(
10579
- StackedFocusModal.Content,
10580
- {
10581
- onOpenAutoFocus: (e) => {
10582
- e.preventDefault();
10583
- const searchInput = document.querySelector(
10584
- "[data-modal-id='modal-search-input']"
10585
- );
10586
- if (searchInput) {
10587
- searchInput.focus();
10578
+ ) }),
10579
+ /* @__PURE__ */ jsx(RouteFocusModal.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
10580
+ /* @__PURE__ */ jsx(RouteFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
10581
+ /* @__PURE__ */ jsx(
10582
+ Button,
10583
+ {
10584
+ size: "small",
10585
+ type: "button",
10586
+ onClick: onSubmit,
10587
+ isLoading: isSubmitting,
10588
+ children: "Save"
10588
10589
  }
10589
- },
10590
- children: [
10591
- /* @__PURE__ */ jsxs(StackedFocusModal.Header, { children: [
10592
- /* @__PURE__ */ jsx(StackedFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Product Variants" }) }),
10593
- /* @__PURE__ */ jsx(StackedFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Choose product variants to add to the order." }) })
10594
- ] }),
10595
- /* @__PURE__ */ jsx(StackedFocusModal.Body, { className: "flex-1 overflow-hidden", children: /* @__PURE__ */ jsx(
10596
- DataTable,
10597
- {
10598
- data: variants,
10599
- columns,
10600
- isLoading: isPending,
10601
- getRowId: (row) => row.id,
10602
- rowCount: count,
10603
- prefix: VARIANT_PREFIX,
10604
- layout: "fill",
10605
- rowSelection: {
10606
- state: rowSelection,
10607
- onRowSelectionChange: setRowSelection,
10608
- enableRowSelection: (row) => {
10609
- return !items.find((i) => i.variant_id === row.original.id);
10610
- }
10611
- },
10612
- autoFocusSearch: true
10613
- }
10614
- ) }),
10615
- /* @__PURE__ */ jsx(StackedFocusModal.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
10616
- /* @__PURE__ */ jsx(StackedFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
10617
- /* @__PURE__ */ jsx(Button, { size: "small", type: "button", onClick: onSubmit, children: "Update items" })
10618
- ] }) })
10619
- ]
10620
- }
10621
- );
10590
+ )
10591
+ ] }) })
10592
+ ] });
10622
10593
  };
10623
- const columnHelper = createDataTableColumnHelper();
10624
- const useColumns = () => {
10625
- return useMemo(() => {
10626
- return [
10627
- columnHelper.select(),
10628
- columnHelper.accessor("product.title", {
10629
- header: "Product",
10630
- cell: ({ row }) => {
10631
- var _a, _b, _c;
10632
- return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-2", children: [
10633
- /* @__PURE__ */ jsx(
10634
- Thumbnail,
10635
- {
10636
- thumbnail: (_a = row.original.product) == null ? void 0 : _a.thumbnail,
10637
- alt: (_b = row.original.product) == null ? void 0 : _b.title
10638
- }
10639
- ),
10640
- /* @__PURE__ */ jsx("span", { children: (_c = row.original.product) == null ? void 0 : _c.title })
10641
- ] });
10594
+ const Item = ({ item, preview, currencyCode }) => {
10595
+ if (item.variant_id) {
10596
+ return /* @__PURE__ */ jsx(VariantItem, { item, preview, currencyCode });
10597
+ }
10598
+ return /* @__PURE__ */ jsx(CustomItem, { item, preview, currencyCode });
10599
+ };
10600
+ const VariantItem = ({ item, preview, currencyCode }) => {
10601
+ const [editing, setEditing] = useState(false);
10602
+ const form = useForm({
10603
+ defaultValues: {
10604
+ quantity: item.quantity,
10605
+ unit_price: item.unit_price
10606
+ },
10607
+ resolver: zodResolver(variantItemSchema)
10608
+ });
10609
+ const actionId = useMemo(() => {
10610
+ var _a, _b;
10611
+ return (_b = (_a = item.actions) == null ? void 0 : _a.find((a) => a.action === "ITEM_ADD")) == null ? void 0 : _b.id;
10612
+ }, [item]);
10613
+ const { mutateAsync: updateActionItem, isPending: isUpdatingActionItem } = useDraftOrderUpdateActionItem(preview.id);
10614
+ const { mutateAsync: updateOriginalItem, isPending: isUpdatingOriginalItem } = useDraftOrderUpdateItem(preview.id);
10615
+ const isPending = isUpdatingActionItem || isUpdatingOriginalItem;
10616
+ const onSubmit = form.handleSubmit(async (data) => {
10617
+ if (convertNumber(data.unit_price) === item.unit_price && data.quantity === item.quantity) {
10618
+ setEditing(false);
10619
+ return;
10620
+ }
10621
+ if (!actionId) {
10622
+ await updateOriginalItem(
10623
+ {
10624
+ item_id: item.id,
10625
+ quantity: data.quantity,
10626
+ unit_price: convertNumber(data.unit_price)
10642
10627
  },
10643
- enableSorting: true
10644
- }),
10645
- columnHelper.accessor("title", {
10646
- header: "Variant",
10647
- enableSorting: true
10648
- }),
10649
- columnHelper.accessor("sku", {
10650
- header: "SKU",
10651
- cell: ({ getValue }) => {
10652
- return getValue() ?? "-";
10628
+ {
10629
+ onSuccess: () => {
10630
+ setEditing(false);
10631
+ },
10632
+ onError: (e) => {
10633
+ toast.error(e.message);
10634
+ }
10635
+ }
10636
+ );
10637
+ return;
10638
+ }
10639
+ await updateActionItem(
10640
+ {
10641
+ action_id: actionId,
10642
+ quantity: data.quantity,
10643
+ unit_price: convertNumber(data.unit_price)
10644
+ },
10645
+ {
10646
+ onSuccess: () => {
10647
+ setEditing(false);
10653
10648
  },
10654
- enableSorting: true
10655
- }),
10656
- columnHelper.accessor("updated_at", {
10657
- header: "Updated",
10658
- cell: ({ getValue }) => {
10659
- return /* @__PURE__ */ jsx(
10660
- Tooltip,
10649
+ onError: (e) => {
10650
+ toast.error(e.message);
10651
+ }
10652
+ }
10653
+ );
10654
+ });
10655
+ 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: [
10656
+ /* @__PURE__ */ jsxs("div", { className: "flex w-full items-center gap-x-3", children: [
10657
+ /* @__PURE__ */ jsx(
10658
+ Thumbnail,
10659
+ {
10660
+ thumbnail: item.thumbnail,
10661
+ alt: item.product_title ?? void 0
10662
+ }
10663
+ ),
10664
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
10665
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-1", children: [
10666
+ /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: item.product_title }),
10667
+ /* @__PURE__ */ jsxs(
10668
+ Text,
10661
10669
  {
10662
- content: getFullDate({ date: getValue(), includeTime: true }),
10663
- children: /* @__PURE__ */ jsx("span", { children: getFullDate({ date: getValue() }) })
10670
+ size: "small",
10671
+ leading: "compact",
10672
+ className: "text-ui-fg-subtle",
10673
+ children: [
10674
+ "(",
10675
+ item.variant_title,
10676
+ ")"
10677
+ ]
10664
10678
  }
10665
- );
10666
- },
10667
- enableSorting: true,
10668
- sortAscLabel: "Oldest first",
10669
- sortDescLabel: "Newest first"
10670
- }),
10671
- columnHelper.accessor("created_at", {
10672
- header: "Created",
10673
- cell: ({ getValue }) => {
10674
- return /* @__PURE__ */ jsx(
10675
- Tooltip,
10679
+ )
10680
+ ] }),
10681
+ /* @__PURE__ */ jsx(
10682
+ Text,
10683
+ {
10684
+ size: "small",
10685
+ leading: "compact",
10686
+ className: "text-ui-fg-subtle",
10687
+ children: item.variant_sku
10688
+ }
10689
+ )
10690
+ ] })
10691
+ ] }),
10692
+ editing ? /* @__PURE__ */ jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsx(
10693
+ Form$2.Field,
10694
+ {
10695
+ control: form.control,
10696
+ name: "quantity",
10697
+ render: ({ field }) => {
10698
+ return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(NumberInput, { ...field }) }) });
10699
+ }
10700
+ }
10701
+ ) }) : /* @__PURE__ */ jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: item.quantity }) }),
10702
+ editing ? /* @__PURE__ */ jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsx(
10703
+ Form$2.Field,
10704
+ {
10705
+ control: form.control,
10706
+ name: "unit_price",
10707
+ render: ({ field: { onChange, ...field } }) => {
10708
+ return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
10709
+ CurrencyInput,
10676
10710
  {
10677
- content: getFullDate({ date: getValue(), includeTime: true }),
10678
- children: /* @__PURE__ */ jsx("span", { children: getFullDate({ date: getValue() }) })
10711
+ ...field,
10712
+ symbol: getNativeSymbol(currencyCode),
10713
+ code: currencyCode,
10714
+ onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value)
10679
10715
  }
10680
- );
10716
+ ) }) });
10717
+ }
10718
+ }
10719
+ ) }) : /* @__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) }) }),
10720
+ /* @__PURE__ */ jsx(
10721
+ IconButton,
10722
+ {
10723
+ type: "button",
10724
+ size: "small",
10725
+ onClick: editing ? onSubmit : () => {
10726
+ setEditing(true);
10681
10727
  },
10682
- enableSorting: true,
10683
- sortAscLabel: "Oldest first",
10684
- sortDescLabel: "Newest first"
10685
- })
10686
- ];
10687
- }, []);
10728
+ disabled: isPending,
10729
+ children: editing ? /* @__PURE__ */ jsx(Check, {}) : /* @__PURE__ */ jsx(PencilSquare, {})
10730
+ }
10731
+ )
10732
+ ] }) }) });
10688
10733
  };
10689
- const CustomItemForm = ({ orderId, currencyCode }) => {
10690
- const { setIsOpen } = useStackedModal();
10691
- const { mutateAsync: addItems } = useDraftOrderAddItems(orderId);
10734
+ const variantItemSchema = objectType({
10735
+ quantity: numberType(),
10736
+ unit_price: unionType([numberType(), stringType()])
10737
+ });
10738
+ const CustomItem = ({ item, preview, currencyCode }) => {
10739
+ const [editing, setEditing] = useState(false);
10740
+ const { quantity, unit_price, title } = item;
10692
10741
  const form = useForm({
10693
10742
  defaultValues: {
10694
- title: "",
10695
- quantity: 1,
10696
- unit_price: ""
10743
+ title,
10744
+ quantity,
10745
+ unit_price
10697
10746
  },
10698
10747
  resolver: zodResolver(customItemSchema)
10699
10748
  });
10749
+ useEffect(() => {
10750
+ form.reset({
10751
+ title,
10752
+ quantity,
10753
+ unit_price
10754
+ });
10755
+ }, [form, title, quantity, unit_price]);
10756
+ const actionId = useMemo(() => {
10757
+ var _a, _b;
10758
+ return (_b = (_a = item.actions) == null ? void 0 : _a.find((a) => a.action === "ITEM_ADD")) == null ? void 0 : _b.id;
10759
+ }, [item]);
10760
+ const { mutateAsync: updateActionItem, isPending: isUpdatingActionItem } = useDraftOrderUpdateActionItem(preview.id);
10761
+ const { mutateAsync: removeActionItem, isPending: isRemovingActionItem } = useDraftOrderRemoveActionItem(preview.id);
10762
+ const { mutateAsync: updateOriginalItem, isPending: isUpdatingOriginalItem } = useDraftOrderUpdateItem(preview.id);
10763
+ const isPending = isUpdatingActionItem || isUpdatingOriginalItem;
10700
10764
  const onSubmit = form.handleSubmit(async (data) => {
10701
- await addItems(
10702
- {
10703
- items: [
10704
- {
10705
- title: data.title,
10706
- quantity: data.quantity,
10707
- unit_price: convertNumber(data.unit_price)
10765
+ if (convertNumber(data.unit_price) === item.unit_price && data.quantity === item.quantity && data.title === item.title) {
10766
+ setEditing(false);
10767
+ return;
10768
+ }
10769
+ if (!actionId) {
10770
+ await updateOriginalItem(
10771
+ {
10772
+ item_id: item.id,
10773
+ quantity: data.quantity,
10774
+ unit_price: convertNumber(data.unit_price)
10775
+ },
10776
+ {
10777
+ onSuccess: () => {
10778
+ setEditing(false);
10779
+ },
10780
+ onError: (e) => {
10781
+ toast.error(e.message);
10708
10782
  }
10709
- ]
10783
+ }
10784
+ );
10785
+ return;
10786
+ }
10787
+ if (data.quantity === 0) {
10788
+ await removeActionItem(actionId, {
10789
+ onSuccess: () => {
10790
+ setEditing(false);
10791
+ },
10792
+ onError: (e) => {
10793
+ toast.error(e.message);
10794
+ }
10795
+ });
10796
+ return;
10797
+ }
10798
+ await updateActionItem(
10799
+ {
10800
+ action_id: actionId,
10801
+ quantity: data.quantity,
10802
+ unit_price: convertNumber(data.unit_price)
10710
10803
  },
10711
10804
  {
10712
10805
  onSuccess: () => {
10713
- setIsOpen(STACKED_MODAL_ID, false);
10806
+ setEditing(false);
10714
10807
  },
10715
10808
  onError: (e) => {
10716
10809
  toast.error(e.message);
@@ -10718,437 +10811,365 @@ const CustomItemForm = ({ orderId, currencyCode }) => {
10718
10811
  }
10719
10812
  );
10720
10813
  });
10721
- return /* @__PURE__ */ jsx(Form$2, { ...form, children: /* @__PURE__ */ jsx(KeyboundForm, { onSubmit, children: /* @__PURE__ */ jsxs(StackedFocusModal.Content, { children: [
10722
- /* @__PURE__ */ jsx(StackedFocusModal.Header, {}),
10723
- /* @__PURE__ */ jsx(StackedFocusModal.Body, { className: "flex flex-1 flex-col overflow-hidden", children: /* @__PURE__ */ jsx("div", { className: "flex flex-1 flex-col items-center overflow-y-auto", children: /* @__PURE__ */ jsxs("div", { className: "flex w-full max-w-[720px] flex-col gap-y-6 px-2 py-16", children: [
10724
- /* @__PURE__ */ jsxs("div", { children: [
10725
- /* @__PURE__ */ jsx(StackedFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Add custom item" }) }),
10726
- /* @__PURE__ */ jsx(StackedFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Add a custom item to the order. This will add a new line item that is not associated with an existing product." }) })
10727
- ] }),
10728
- /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
10729
- /* @__PURE__ */ jsx(
10730
- Form$2.Field,
10731
- {
10732
- control: form.control,
10733
- name: "title",
10734
- render: ({ field }) => /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
10735
- /* @__PURE__ */ jsxs("div", { children: [
10736
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Title" }),
10737
- /* @__PURE__ */ jsx(Form$2.Hint, { children: "Enter the title of the item" })
10738
- ] }),
10739
- /* @__PURE__ */ jsxs("div", { children: [
10740
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
10741
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
10742
- ] })
10743
- ] }) })
10744
- }
10745
- ),
10746
- /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
10814
+ 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: [
10815
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-3", children: [
10747
10816
  /* @__PURE__ */ jsx(
10748
- Form$2.Field,
10817
+ Thumbnail,
10749
10818
  {
10750
- control: form.control,
10751
- name: "unit_price",
10752
- render: ({ field: { onChange, ...field } }) => /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
10753
- /* @__PURE__ */ jsxs("div", { children: [
10754
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Unit price" }),
10755
- /* @__PURE__ */ jsx(Form$2.Hint, { children: "Enter the unit price of the item" })
10756
- ] }),
10757
- /* @__PURE__ */ jsxs("div", { children: [
10758
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
10759
- CurrencyInput,
10760
- {
10761
- symbol: getNativeSymbol(currencyCode),
10762
- code: currencyCode,
10763
- onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value),
10764
- ...field
10765
- }
10766
- ) }),
10767
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
10768
- ] })
10769
- ] }) })
10819
+ thumbnail: item.thumbnail,
10820
+ alt: item.title ?? void 0
10770
10821
  }
10771
10822
  ),
10772
- /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
10773
- /* @__PURE__ */ jsx(
10823
+ editing ? /* @__PURE__ */ jsx(
10774
10824
  Form$2.Field,
10775
10825
  {
10776
10826
  control: form.control,
10777
- name: "quantity",
10778
- render: ({ field }) => /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
10779
- /* @__PURE__ */ jsxs("div", { children: [
10780
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Quantity" }),
10781
- /* @__PURE__ */ jsx(Form$2.Hint, { children: "Enter the quantity of the item" })
10782
- ] }),
10783
- /* @__PURE__ */ jsxs("div", { className: "w-full flex-1", children: [
10784
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsx(NumberInput, { ...field, className: "w-full" }) }) }),
10785
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
10786
- ] })
10787
- ] }) })
10827
+ name: "title",
10828
+ render: ({ field }) => {
10829
+ return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }) });
10830
+ }
10788
10831
  }
10789
- )
10790
- ] }) }) }),
10791
- /* @__PURE__ */ jsx(StackedFocusModal.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
10792
- /* @__PURE__ */ jsx(StackedFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
10793
- /* @__PURE__ */ jsx(Button, { size: "small", type: "button", onClick: onSubmit, children: "Add item" })
10794
- ] }) })
10795
- ] }) }) });
10796
- };
10797
- const customItemSchema = objectType({
10798
- title: stringType().min(1),
10799
- quantity: numberType(),
10800
- unit_price: unionType([numberType(), stringType()])
10801
- });
10802
- const InlineTip = forwardRef(
10803
- ({ variant = "tip", label, className, children, ...props }, ref) => {
10804
- const labelValue = label || (variant === "warning" ? "Warning" : "Tip");
10805
- return /* @__PURE__ */ jsxs(
10806
- "div",
10832
+ ) : /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: item.title })
10833
+ ] }),
10834
+ editing ? /* @__PURE__ */ jsx(
10835
+ Form$2.Field,
10807
10836
  {
10808
- ref,
10809
- className: clx(
10810
- "bg-ui-bg-component txt-small text-ui-fg-subtle grid grid-cols-[4px_1fr] items-start gap-3 rounded-lg border p-3",
10811
- className
10812
- ),
10813
- ...props,
10814
- children: [
10815
- /* @__PURE__ */ jsx(
10816
- "div",
10837
+ control: form.control,
10838
+ name: "quantity",
10839
+ render: ({ field }) => {
10840
+ return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(NumberInput, { ...field }) }) });
10841
+ }
10842
+ }
10843
+ ) : /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: item.quantity }),
10844
+ editing ? /* @__PURE__ */ jsx(
10845
+ Form$2.Field,
10846
+ {
10847
+ control: form.control,
10848
+ name: "unit_price",
10849
+ render: ({ field: { onChange, ...field } }) => {
10850
+ return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
10851
+ CurrencyInput,
10817
10852
  {
10818
- role: "presentation",
10819
- className: clx("w-4px bg-ui-tag-neutral-icon h-full rounded-full", {
10820
- "bg-ui-tag-orange-icon": variant === "warning"
10821
- })
10853
+ ...field,
10854
+ symbol: getNativeSymbol(currencyCode),
10855
+ code: currencyCode,
10856
+ onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value)
10822
10857
  }
10823
- ),
10824
- /* @__PURE__ */ jsxs("div", { className: "text-pretty", children: [
10825
- /* @__PURE__ */ jsxs("strong", { className: "txt-small-plus text-ui-fg-base", children: [
10826
- labelValue,
10827
- ":"
10828
- ] }),
10829
- " ",
10830
- children
10831
- ] })
10832
- ]
10858
+ ) }) });
10859
+ }
10833
10860
  }
10834
- );
10835
- }
10836
- );
10837
- InlineTip.displayName = "InlineTip";
10838
- const MetadataFieldSchema = objectType({
10839
- key: stringType(),
10840
- disabled: booleanType().optional(),
10841
- value: anyType()
10842
- });
10843
- const MetadataSchema = objectType({
10844
- metadata: arrayType(MetadataFieldSchema)
10845
- });
10846
- const Metadata = () => {
10847
- const { id } = useParams();
10848
- const { order, isPending, isError, error } = useOrder(id, {
10849
- fields: "metadata"
10850
- });
10851
- if (isError) {
10852
- throw error;
10853
- }
10854
- const isReady = !isPending && !!order;
10855
- return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
10856
- /* @__PURE__ */ jsxs(RouteDrawer.Header, { children: [
10857
- /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Metadata" }) }),
10858
- /* @__PURE__ */ jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Add metadata to the draft order." }) })
10859
- ] }),
10860
- !isReady ? /* @__PURE__ */ jsx(PlaceholderInner, {}) : /* @__PURE__ */ jsx(MetadataForm, { orderId: id, metadata: order == null ? void 0 : order.metadata })
10861
- ] });
10861
+ ) : /* @__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) }) }),
10862
+ /* @__PURE__ */ jsx(
10863
+ IconButton,
10864
+ {
10865
+ type: "button",
10866
+ size: "small",
10867
+ onClick: editing ? onSubmit : () => {
10868
+ setEditing(true);
10869
+ },
10870
+ disabled: isPending,
10871
+ children: editing ? /* @__PURE__ */ jsx(Check, {}) : /* @__PURE__ */ jsx(PencilSquare, {})
10872
+ }
10873
+ )
10874
+ ] }) }) });
10862
10875
  };
10863
- const METADATA_KEY_LABEL_ID = "metadata-form-key-label";
10864
- const METADATA_VALUE_LABEL_ID = "metadata-form-value-label";
10865
- const MetadataForm = ({ orderId, metadata }) => {
10866
- const { handleSuccess } = useRouteModal();
10867
- const hasUneditableRows = getHasUneditableRows(metadata);
10868
- const { mutateAsync, isPending } = useUpdateDraftOrder(orderId);
10869
- const form = useForm({
10870
- defaultValues: {
10871
- metadata: getDefaultValues(metadata)
10876
+ const StackedModalTrigger$1 = ({
10877
+ type,
10878
+ setModalContent
10879
+ }) => {
10880
+ const { setIsOpen } = useStackedModal();
10881
+ const onClick = useCallback(() => {
10882
+ setModalContent(type);
10883
+ setIsOpen(STACKED_MODAL_ID, true);
10884
+ }, [setModalContent, setIsOpen, type]);
10885
+ return /* @__PURE__ */ jsx(StackedFocusModal.Trigger, { asChild: true, children: /* @__PURE__ */ jsx(DropdownMenu.Item, { onClick, children: type === "add-items" ? "Add items" : "Add custom item" }) });
10886
+ };
10887
+ const VARIANT_PREFIX = "items";
10888
+ const LIMIT = 50;
10889
+ const ExistingItemsForm = ({ orderId, items }) => {
10890
+ const { setIsOpen } = useStackedModal();
10891
+ const [rowSelection, setRowSelection] = useState(
10892
+ items.reduce((acc, item) => {
10893
+ acc[item.variant_id] = true;
10894
+ return acc;
10895
+ }, {})
10896
+ );
10897
+ useEffect(() => {
10898
+ setRowSelection(
10899
+ items.reduce((acc, item) => {
10900
+ if (item.variant_id) {
10901
+ acc[item.variant_id] = true;
10902
+ }
10903
+ return acc;
10904
+ }, {})
10905
+ );
10906
+ }, [items]);
10907
+ const { q, order, offset } = useQueryParams(
10908
+ ["q", "order", "offset"],
10909
+ VARIANT_PREFIX
10910
+ );
10911
+ const { variants, count, isPending, isError, error } = useProductVariants(
10912
+ {
10913
+ q,
10914
+ order,
10915
+ offset: offset ? parseInt(offset) : void 0,
10916
+ limit: LIMIT
10872
10917
  },
10873
- resolver: zodResolver(MetadataSchema)
10874
- });
10875
- const handleSubmit = form.handleSubmit(async (data) => {
10876
- const parsedData = parseValues(data);
10918
+ {
10919
+ placeholderData: keepPreviousData
10920
+ }
10921
+ );
10922
+ const columns = useColumns();
10923
+ const { mutateAsync } = useDraftOrderAddItems(orderId);
10924
+ const onSubmit = async () => {
10925
+ const ids = Object.keys(rowSelection).filter(
10926
+ (id) => !items.find((i) => i.variant_id === id)
10927
+ );
10877
10928
  await mutateAsync(
10878
10929
  {
10879
- metadata: parsedData
10930
+ items: ids.map((id) => ({
10931
+ variant_id: id,
10932
+ quantity: 1
10933
+ }))
10880
10934
  },
10881
10935
  {
10882
10936
  onSuccess: () => {
10883
- toast.success("Metadata updated");
10884
- handleSuccess();
10937
+ setRowSelection({});
10938
+ setIsOpen(STACKED_MODAL_ID, false);
10885
10939
  },
10886
- onError: (error) => {
10887
- toast.error(error.message);
10940
+ onError: (e) => {
10941
+ toast.error(e.message);
10888
10942
  }
10889
10943
  }
10890
10944
  );
10891
- });
10892
- const { fields, insert, remove } = useFieldArray({
10893
- control: form.control,
10894
- name: "metadata"
10895
- });
10896
- function deleteRow(index) {
10897
- remove(index);
10898
- if (fields.length === 1) {
10899
- insert(0, {
10900
- key: "",
10901
- value: "",
10902
- disabled: false
10903
- });
10904
- }
10905
- }
10906
- function insertRow(index, position) {
10907
- insert(index + (position === "above" ? 0 : 1), {
10908
- key: "",
10909
- value: "",
10910
- disabled: false
10911
- });
10912
- }
10913
- return /* @__PURE__ */ jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxs(
10914
- KeyboundForm,
10945
+ };
10946
+ if (isError) {
10947
+ throw error;
10948
+ }
10949
+ return /* @__PURE__ */ jsxs(
10950
+ StackedFocusModal.Content,
10915
10951
  {
10916
- onSubmit: handleSubmit,
10917
- className: "flex flex-1 flex-col overflow-hidden",
10952
+ onOpenAutoFocus: (e) => {
10953
+ e.preventDefault();
10954
+ const searchInput = document.querySelector(
10955
+ "[data-modal-id='modal-search-input']"
10956
+ );
10957
+ if (searchInput) {
10958
+ searchInput.focus();
10959
+ }
10960
+ },
10918
10961
  children: [
10919
- /* @__PURE__ */ jsxs(RouteDrawer.Body, { className: "flex flex-1 flex-col gap-y-8 overflow-y-auto", children: [
10920
- /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest grid grid-cols-1 divide-y rounded-lg", children: [
10921
- /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-subtle grid grid-cols-2 divide-x rounded-t-lg", children: [
10922
- /* @__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" }) }),
10923
- /* @__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" }) })
10924
- ] }),
10925
- fields.map((field, index) => {
10926
- const isDisabled = field.disabled || false;
10927
- let placeholder = "-";
10928
- if (typeof field.value === "object") {
10929
- placeholder = "{ ... }";
10930
- }
10931
- if (Array.isArray(field.value)) {
10932
- placeholder = "[ ... ]";
10933
- }
10934
- return /* @__PURE__ */ jsx(
10935
- ConditionalTooltip,
10936
- {
10937
- showTooltip: isDisabled,
10938
- content: "This row is disabled because it contains non-primitive data.",
10939
- children: /* @__PURE__ */ jsxs("div", { className: "group/table relative", children: [
10940
- /* @__PURE__ */ jsxs(
10941
- "div",
10942
- {
10943
- className: clx("grid grid-cols-2 divide-x", {
10944
- "overflow-hidden rounded-b-lg": index === fields.length - 1
10945
- }),
10946
- children: [
10947
- /* @__PURE__ */ jsx(
10948
- Form$2.Field,
10949
- {
10950
- control: form.control,
10951
- name: `metadata.${index}.key`,
10952
- render: ({ field: field2 }) => {
10953
- return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
10954
- GridInput,
10955
- {
10956
- "aria-labelledby": METADATA_KEY_LABEL_ID,
10957
- ...field2,
10958
- disabled: isDisabled,
10959
- placeholder: "Key"
10960
- }
10961
- ) }) });
10962
- }
10963
- }
10964
- ),
10965
- /* @__PURE__ */ jsx(
10966
- Form$2.Field,
10967
- {
10968
- control: form.control,
10969
- name: `metadata.${index}.value`,
10970
- render: ({ field: { value, ...field2 } }) => {
10971
- return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
10972
- GridInput,
10973
- {
10974
- "aria-labelledby": METADATA_VALUE_LABEL_ID,
10975
- ...field2,
10976
- value: isDisabled ? placeholder : value,
10977
- disabled: isDisabled,
10978
- placeholder: "Value"
10979
- }
10980
- ) }) });
10981
- }
10982
- }
10983
- )
10984
- ]
10985
- }
10986
- ),
10987
- /* @__PURE__ */ jsxs(DropdownMenu, { children: [
10988
- /* @__PURE__ */ jsx(
10989
- DropdownMenu.Trigger,
10990
- {
10991
- className: clx(
10992
- "invisible absolute inset-y-0 -right-2.5 my-auto group-hover/table:visible data-[state='open']:visible",
10993
- {
10994
- hidden: isDisabled
10995
- }
10996
- ),
10997
- disabled: isDisabled,
10998
- asChild: true,
10999
- children: /* @__PURE__ */ jsx(IconButton, { size: "2xsmall", children: /* @__PURE__ */ jsx(EllipsisVertical, {}) })
11000
- }
11001
- ),
11002
- /* @__PURE__ */ jsxs(DropdownMenu.Content, { children: [
11003
- /* @__PURE__ */ jsxs(
11004
- DropdownMenu.Item,
11005
- {
11006
- className: "gap-x-2",
11007
- onClick: () => insertRow(index, "above"),
11008
- children: [
11009
- /* @__PURE__ */ jsx(ArrowUpMini, { className: "text-ui-fg-subtle" }),
11010
- "Insert row above"
11011
- ]
11012
- }
11013
- ),
11014
- /* @__PURE__ */ jsxs(
11015
- DropdownMenu.Item,
11016
- {
11017
- className: "gap-x-2",
11018
- onClick: () => insertRow(index, "below"),
11019
- children: [
11020
- /* @__PURE__ */ jsx(ArrowDownMini, { className: "text-ui-fg-subtle" }),
11021
- "Insert row below"
11022
- ]
11023
- }
11024
- ),
11025
- /* @__PURE__ */ jsx(DropdownMenu.Separator, {}),
11026
- /* @__PURE__ */ jsxs(
11027
- DropdownMenu.Item,
11028
- {
11029
- className: "gap-x-2",
11030
- onClick: () => deleteRow(index),
11031
- children: [
11032
- /* @__PURE__ */ jsx(Trash, { className: "text-ui-fg-subtle" }),
11033
- "Delete row"
11034
- ]
11035
- }
11036
- )
11037
- ] })
11038
- ] })
11039
- ] })
11040
- },
11041
- field.id
11042
- );
11043
- })
11044
- ] }),
11045
- 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." })
10962
+ /* @__PURE__ */ jsxs(StackedFocusModal.Header, { children: [
10963
+ /* @__PURE__ */ jsx(StackedFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Product Variants" }) }),
10964
+ /* @__PURE__ */ jsx(StackedFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Choose product variants to add to the order." }) })
11046
10965
  ] }),
11047
- /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
11048
- /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
11049
- /* @__PURE__ */ jsx(Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
10966
+ /* @__PURE__ */ jsx(StackedFocusModal.Body, { className: "flex-1 overflow-hidden", children: /* @__PURE__ */ jsx(
10967
+ DataTable,
10968
+ {
10969
+ data: variants,
10970
+ columns,
10971
+ isLoading: isPending,
10972
+ getRowId: (row) => row.id,
10973
+ rowCount: count,
10974
+ prefix: VARIANT_PREFIX,
10975
+ layout: "fill",
10976
+ rowSelection: {
10977
+ state: rowSelection,
10978
+ onRowSelectionChange: setRowSelection,
10979
+ enableRowSelection: (row) => {
10980
+ return !items.find((i) => i.variant_id === row.original.id);
10981
+ }
10982
+ },
10983
+ autoFocusSearch: true
10984
+ }
10985
+ ) }),
10986
+ /* @__PURE__ */ jsx(StackedFocusModal.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
10987
+ /* @__PURE__ */ jsx(StackedFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
10988
+ /* @__PURE__ */ jsx(Button, { size: "small", type: "button", onClick: onSubmit, children: "Update items" })
11050
10989
  ] }) })
11051
10990
  ]
11052
10991
  }
11053
- ) });
11054
- };
11055
- const GridInput = forwardRef(({ className, ...props }, ref) => {
11056
- return /* @__PURE__ */ jsx(
11057
- "input",
11058
- {
11059
- ref,
11060
- ...props,
11061
- autoComplete: "off",
11062
- className: clx(
11063
- "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",
11064
- className
11065
- )
11066
- }
11067
10992
  );
11068
- });
11069
- GridInput.displayName = "MetadataForm.GridInput";
11070
- const PlaceholderInner = () => {
11071
- return /* @__PURE__ */ jsxs("div", { className: "flex flex-1 flex-col overflow-hidden", children: [
11072
- /* @__PURE__ */ jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsx(Skeleton, { className: "h-[148ox] w-full rounded-lg" }) }),
11073
- /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
11074
- /* @__PURE__ */ jsx(Skeleton, { className: "h-7 w-12 rounded-md" }),
11075
- /* @__PURE__ */ jsx(Skeleton, { className: "h-7 w-12 rounded-md" })
11076
- ] }) })
11077
- ] });
11078
10993
  };
11079
- const EDITABLE_TYPES = ["string", "number", "boolean"];
11080
- function getDefaultValues(metadata) {
11081
- if (!metadata || !Object.keys(metadata).length) {
10994
+ const columnHelper = createDataTableColumnHelper();
10995
+ const useColumns = () => {
10996
+ return useMemo(() => {
11082
10997
  return [
11083
- {
11084
- key: "",
11085
- value: "",
11086
- disabled: false
11087
- }
10998
+ columnHelper.select(),
10999
+ columnHelper.accessor("product.title", {
11000
+ header: "Product",
11001
+ cell: ({ row }) => {
11002
+ var _a, _b, _c;
11003
+ return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-2", children: [
11004
+ /* @__PURE__ */ jsx(
11005
+ Thumbnail,
11006
+ {
11007
+ thumbnail: (_a = row.original.product) == null ? void 0 : _a.thumbnail,
11008
+ alt: (_b = row.original.product) == null ? void 0 : _b.title
11009
+ }
11010
+ ),
11011
+ /* @__PURE__ */ jsx("span", { children: (_c = row.original.product) == null ? void 0 : _c.title })
11012
+ ] });
11013
+ },
11014
+ enableSorting: true
11015
+ }),
11016
+ columnHelper.accessor("title", {
11017
+ header: "Variant",
11018
+ enableSorting: true
11019
+ }),
11020
+ columnHelper.accessor("sku", {
11021
+ header: "SKU",
11022
+ cell: ({ getValue }) => {
11023
+ return getValue() ?? "-";
11024
+ },
11025
+ enableSorting: true
11026
+ }),
11027
+ columnHelper.accessor("updated_at", {
11028
+ header: "Updated",
11029
+ cell: ({ getValue }) => {
11030
+ return /* @__PURE__ */ jsx(
11031
+ Tooltip,
11032
+ {
11033
+ content: getFullDate({ date: getValue(), includeTime: true }),
11034
+ children: /* @__PURE__ */ jsx("span", { children: getFullDate({ date: getValue() }) })
11035
+ }
11036
+ );
11037
+ },
11038
+ enableSorting: true,
11039
+ sortAscLabel: "Oldest first",
11040
+ sortDescLabel: "Newest first"
11041
+ }),
11042
+ columnHelper.accessor("created_at", {
11043
+ header: "Created",
11044
+ cell: ({ getValue }) => {
11045
+ return /* @__PURE__ */ jsx(
11046
+ Tooltip,
11047
+ {
11048
+ content: getFullDate({ date: getValue(), includeTime: true }),
11049
+ children: /* @__PURE__ */ jsx("span", { children: getFullDate({ date: getValue() }) })
11050
+ }
11051
+ );
11052
+ },
11053
+ enableSorting: true,
11054
+ sortAscLabel: "Oldest first",
11055
+ sortDescLabel: "Newest first"
11056
+ })
11088
11057
  ];
11089
- }
11090
- return Object.entries(metadata).map(([key, value]) => {
11091
- if (!EDITABLE_TYPES.includes(typeof value)) {
11092
- return {
11093
- key,
11094
- value,
11095
- disabled: true
11096
- };
11097
- }
11098
- let stringValue = value;
11099
- if (typeof value !== "string") {
11100
- stringValue = JSON.stringify(value);
11101
- }
11102
- return {
11103
- key,
11104
- value: stringValue,
11105
- original_key: key
11106
- };
11058
+ }, []);
11059
+ };
11060
+ const CustomItemForm = ({ orderId, currencyCode }) => {
11061
+ const { setIsOpen } = useStackedModal();
11062
+ const { mutateAsync: addItems } = useDraftOrderAddItems(orderId);
11063
+ const form = useForm({
11064
+ defaultValues: {
11065
+ title: "",
11066
+ quantity: 1,
11067
+ unit_price: ""
11068
+ },
11069
+ resolver: zodResolver(customItemSchema)
11107
11070
  });
11108
- }
11109
- function parseValues(values) {
11110
- const metadata = values.metadata;
11111
- const isEmpty = !metadata.length || metadata.length === 1 && !metadata[0].key && !metadata[0].value;
11112
- if (isEmpty) {
11113
- return null;
11114
- }
11115
- const update = {};
11116
- metadata.forEach((field) => {
11117
- let key = field.key;
11118
- let value = field.value;
11119
- const disabled = field.disabled;
11120
- if (!key || !value) {
11121
- return;
11122
- }
11123
- if (disabled) {
11124
- update[key] = value;
11125
- return;
11126
- }
11127
- key = key.trim();
11128
- value = value.trim();
11129
- if (value === "true") {
11130
- update[key] = true;
11131
- } else if (value === "false") {
11132
- update[key] = false;
11133
- } else {
11134
- const parsedNumber = parseFloat(value);
11135
- if (!isNaN(parsedNumber)) {
11136
- update[key] = parsedNumber;
11137
- } else {
11138
- update[key] = value;
11071
+ const onSubmit = form.handleSubmit(async (data) => {
11072
+ await addItems(
11073
+ {
11074
+ items: [
11075
+ {
11076
+ title: data.title,
11077
+ quantity: data.quantity,
11078
+ unit_price: convertNumber(data.unit_price)
11079
+ }
11080
+ ]
11081
+ },
11082
+ {
11083
+ onSuccess: () => {
11084
+ setIsOpen(STACKED_MODAL_ID, false);
11085
+ },
11086
+ onError: (e) => {
11087
+ toast.error(e.message);
11088
+ }
11139
11089
  }
11140
- }
11090
+ );
11141
11091
  });
11142
- return update;
11143
- }
11144
- function getHasUneditableRows(metadata) {
11145
- if (!metadata) {
11146
- return false;
11147
- }
11148
- return Object.values(metadata).some(
11149
- (value) => !EDITABLE_TYPES.includes(typeof value)
11150
- );
11151
- }
11092
+ return /* @__PURE__ */ jsx(Form$2, { ...form, children: /* @__PURE__ */ jsx(KeyboundForm, { onSubmit, children: /* @__PURE__ */ jsxs(StackedFocusModal.Content, { children: [
11093
+ /* @__PURE__ */ jsx(StackedFocusModal.Header, {}),
11094
+ /* @__PURE__ */ jsx(StackedFocusModal.Body, { className: "flex flex-1 flex-col overflow-hidden", children: /* @__PURE__ */ jsx("div", { className: "flex flex-1 flex-col items-center overflow-y-auto", children: /* @__PURE__ */ jsxs("div", { className: "flex w-full max-w-[720px] flex-col gap-y-6 px-2 py-16", children: [
11095
+ /* @__PURE__ */ jsxs("div", { children: [
11096
+ /* @__PURE__ */ jsx(StackedFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Add custom item" }) }),
11097
+ /* @__PURE__ */ jsx(StackedFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Add a custom item to the order. This will add a new line item that is not associated with an existing product." }) })
11098
+ ] }),
11099
+ /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
11100
+ /* @__PURE__ */ jsx(
11101
+ Form$2.Field,
11102
+ {
11103
+ control: form.control,
11104
+ name: "title",
11105
+ render: ({ field }) => /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
11106
+ /* @__PURE__ */ jsxs("div", { children: [
11107
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Title" }),
11108
+ /* @__PURE__ */ jsx(Form$2.Hint, { children: "Enter the title of the item" })
11109
+ ] }),
11110
+ /* @__PURE__ */ jsxs("div", { children: [
11111
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
11112
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11113
+ ] })
11114
+ ] }) })
11115
+ }
11116
+ ),
11117
+ /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
11118
+ /* @__PURE__ */ jsx(
11119
+ Form$2.Field,
11120
+ {
11121
+ control: form.control,
11122
+ name: "unit_price",
11123
+ render: ({ field: { onChange, ...field } }) => /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
11124
+ /* @__PURE__ */ jsxs("div", { children: [
11125
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Unit price" }),
11126
+ /* @__PURE__ */ jsx(Form$2.Hint, { children: "Enter the unit price of the item" })
11127
+ ] }),
11128
+ /* @__PURE__ */ jsxs("div", { children: [
11129
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
11130
+ CurrencyInput,
11131
+ {
11132
+ symbol: getNativeSymbol(currencyCode),
11133
+ code: currencyCode,
11134
+ onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value),
11135
+ ...field
11136
+ }
11137
+ ) }),
11138
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11139
+ ] })
11140
+ ] }) })
11141
+ }
11142
+ ),
11143
+ /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
11144
+ /* @__PURE__ */ jsx(
11145
+ Form$2.Field,
11146
+ {
11147
+ control: form.control,
11148
+ name: "quantity",
11149
+ render: ({ field }) => /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
11150
+ /* @__PURE__ */ jsxs("div", { children: [
11151
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Quantity" }),
11152
+ /* @__PURE__ */ jsx(Form$2.Hint, { children: "Enter the quantity of the item" })
11153
+ ] }),
11154
+ /* @__PURE__ */ jsxs("div", { className: "w-full flex-1", children: [
11155
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsx(NumberInput, { ...field, className: "w-full" }) }) }),
11156
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11157
+ ] })
11158
+ ] }) })
11159
+ }
11160
+ )
11161
+ ] }) }) }),
11162
+ /* @__PURE__ */ jsx(StackedFocusModal.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
11163
+ /* @__PURE__ */ jsx(StackedFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
11164
+ /* @__PURE__ */ jsx(Button, { size: "small", type: "button", onClick: onSubmit, children: "Add item" })
11165
+ ] }) })
11166
+ ] }) }) });
11167
+ };
11168
+ const customItemSchema = objectType({
11169
+ title: stringType().min(1),
11170
+ quantity: numberType(),
11171
+ unit_price: unionType([numberType(), stringType()])
11172
+ });
11152
11173
  const PROMOTION_QUERY_KEY = "promotions";
11153
11174
  const promotionsQueryKeys = {
11154
11175
  list: (query2) => [
@@ -11423,9 +11444,115 @@ function getPromotionIds(items, shippingMethods) {
11423
11444
  }
11424
11445
  }
11425
11446
  }
11426
- }
11427
- return Array.from(promotionIds);
11428
- }
11447
+ }
11448
+ return Array.from(promotionIds);
11449
+ }
11450
+ const SalesChannel = () => {
11451
+ const { id } = useParams();
11452
+ const { draft_order, isPending, isError, error } = useDraftOrder(
11453
+ id,
11454
+ {
11455
+ fields: "+sales_channel_id"
11456
+ },
11457
+ {
11458
+ enabled: !!id
11459
+ }
11460
+ );
11461
+ if (isError) {
11462
+ throw error;
11463
+ }
11464
+ const ISrEADY = !!draft_order && !isPending;
11465
+ return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
11466
+ /* @__PURE__ */ jsxs(RouteDrawer.Header, { children: [
11467
+ /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Sales Channel" }) }),
11468
+ /* @__PURE__ */ jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Update which sales channel the draft order is associated with" }) })
11469
+ ] }),
11470
+ ISrEADY && /* @__PURE__ */ jsx(SalesChannelForm, { order: draft_order })
11471
+ ] });
11472
+ };
11473
+ const SalesChannelForm = ({ order }) => {
11474
+ const form = useForm({
11475
+ defaultValues: {
11476
+ sales_channel_id: order.sales_channel_id || ""
11477
+ },
11478
+ resolver: zodResolver(schema$2)
11479
+ });
11480
+ const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
11481
+ const { handleSuccess } = useRouteModal();
11482
+ const onSubmit = form.handleSubmit(async (data) => {
11483
+ await mutateAsync(
11484
+ {
11485
+ sales_channel_id: data.sales_channel_id
11486
+ },
11487
+ {
11488
+ onSuccess: () => {
11489
+ toast.success("Sales channel updated");
11490
+ handleSuccess();
11491
+ },
11492
+ onError: (error) => {
11493
+ toast.error(error.message);
11494
+ }
11495
+ }
11496
+ );
11497
+ });
11498
+ return /* @__PURE__ */ jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxs(
11499
+ KeyboundForm,
11500
+ {
11501
+ className: "flex flex-1 flex-col overflow-hidden",
11502
+ onSubmit,
11503
+ children: [
11504
+ /* @__PURE__ */ jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsx(SalesChannelField, { control: form.control, order }) }),
11505
+ /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
11506
+ /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
11507
+ /* @__PURE__ */ jsx(Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
11508
+ ] }) })
11509
+ ]
11510
+ }
11511
+ ) });
11512
+ };
11513
+ const SalesChannelField = ({ control, order }) => {
11514
+ const salesChannels = useComboboxData({
11515
+ queryFn: async (params) => {
11516
+ return await sdk.admin.salesChannel.list(params);
11517
+ },
11518
+ queryKey: ["sales-channels"],
11519
+ getOptions: (data) => {
11520
+ return data.sales_channels.map((salesChannel) => ({
11521
+ label: salesChannel.name,
11522
+ value: salesChannel.id
11523
+ }));
11524
+ },
11525
+ defaultValue: order.sales_channel_id || void 0
11526
+ });
11527
+ return /* @__PURE__ */ jsx(
11528
+ Form$2.Field,
11529
+ {
11530
+ control,
11531
+ name: "sales_channel_id",
11532
+ render: ({ field }) => {
11533
+ return /* @__PURE__ */ jsxs(Form$2.Item, { children: [
11534
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Sales Channel" }),
11535
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
11536
+ Combobox,
11537
+ {
11538
+ options: salesChannels.options,
11539
+ fetchNextPage: salesChannels.fetchNextPage,
11540
+ isFetchingNextPage: salesChannels.isFetchingNextPage,
11541
+ searchValue: salesChannels.searchValue,
11542
+ onSearchValueChange: salesChannels.onSearchValueChange,
11543
+ placeholder: "Select sales channel",
11544
+ ...field
11545
+ }
11546
+ ) }),
11547
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11548
+ ] });
11549
+ }
11550
+ }
11551
+ );
11552
+ };
11553
+ const schema$2 = objectType({
11554
+ sales_channel_id: stringType().min(1)
11555
+ });
11429
11556
  const STACKED_FOCUS_MODAL_ID = "shipping-form";
11430
11557
  const Shipping = () => {
11431
11558
  var _a;
@@ -12233,46 +12360,60 @@ const CustomAmountField = ({
12233
12360
  }
12234
12361
  );
12235
12362
  };
12236
- const SalesChannel = () => {
12363
+ const ShippingAddress = () => {
12237
12364
  const { id } = useParams();
12238
- const { draft_order, isPending, isError, error } = useDraftOrder(
12239
- id,
12240
- {
12241
- fields: "+sales_channel_id"
12242
- },
12243
- {
12244
- enabled: !!id
12245
- }
12246
- );
12365
+ const { order, isPending, isError, error } = useOrder(id, {
12366
+ fields: "+shipping_address"
12367
+ });
12247
12368
  if (isError) {
12248
12369
  throw error;
12249
12370
  }
12250
- const ISrEADY = !!draft_order && !isPending;
12371
+ const isReady = !isPending && !!order;
12251
12372
  return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
12252
12373
  /* @__PURE__ */ jsxs(RouteDrawer.Header, { children: [
12253
- /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Sales Channel" }) }),
12254
- /* @__PURE__ */ jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Update which sales channel the draft order is associated with" }) })
12374
+ /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Shipping Address" }) }),
12375
+ /* @__PURE__ */ jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Edit the shipping address for the draft order" }) })
12255
12376
  ] }),
12256
- ISrEADY && /* @__PURE__ */ jsx(SalesChannelForm, { order: draft_order })
12377
+ isReady && /* @__PURE__ */ jsx(ShippingAddressForm, { order })
12257
12378
  ] });
12258
12379
  };
12259
- const SalesChannelForm = ({ order }) => {
12380
+ const ShippingAddressForm = ({ order }) => {
12381
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
12260
12382
  const form = useForm({
12261
12383
  defaultValues: {
12262
- sales_channel_id: order.sales_channel_id || ""
12384
+ first_name: ((_a = order.shipping_address) == null ? void 0 : _a.first_name) ?? "",
12385
+ last_name: ((_b = order.shipping_address) == null ? void 0 : _b.last_name) ?? "",
12386
+ company: ((_c = order.shipping_address) == null ? void 0 : _c.company) ?? "",
12387
+ address_1: ((_d = order.shipping_address) == null ? void 0 : _d.address_1) ?? "",
12388
+ address_2: ((_e = order.shipping_address) == null ? void 0 : _e.address_2) ?? "",
12389
+ city: ((_f = order.shipping_address) == null ? void 0 : _f.city) ?? "",
12390
+ province: ((_g = order.shipping_address) == null ? void 0 : _g.province) ?? "",
12391
+ country_code: ((_h = order.shipping_address) == null ? void 0 : _h.country_code) ?? "",
12392
+ postal_code: ((_i = order.shipping_address) == null ? void 0 : _i.postal_code) ?? "",
12393
+ phone: ((_j = order.shipping_address) == null ? void 0 : _j.phone) ?? ""
12263
12394
  },
12264
- resolver: zodResolver(schema$3)
12395
+ resolver: zodResolver(schema$1)
12265
12396
  });
12266
12397
  const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
12267
12398
  const { handleSuccess } = useRouteModal();
12268
12399
  const onSubmit = form.handleSubmit(async (data) => {
12269
12400
  await mutateAsync(
12270
12401
  {
12271
- sales_channel_id: data.sales_channel_id
12402
+ shipping_address: {
12403
+ first_name: data.first_name,
12404
+ last_name: data.last_name,
12405
+ company: data.company,
12406
+ address_1: data.address_1,
12407
+ address_2: data.address_2,
12408
+ city: data.city,
12409
+ province: data.province,
12410
+ country_code: data.country_code,
12411
+ postal_code: data.postal_code,
12412
+ phone: data.phone
12413
+ }
12272
12414
  },
12273
12415
  {
12274
12416
  onSuccess: () => {
12275
- toast.success("Sales channel updated");
12276
12417
  handleSuccess();
12277
12418
  },
12278
12419
  onError: (error) => {
@@ -12287,58 +12428,141 @@ const SalesChannelForm = ({ order }) => {
12287
12428
  className: "flex flex-1 flex-col overflow-hidden",
12288
12429
  onSubmit,
12289
12430
  children: [
12290
- /* @__PURE__ */ jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsx(SalesChannelField, { control: form.control, order }) }),
12431
+ /* @__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: [
12432
+ /* @__PURE__ */ jsx(
12433
+ Form$2.Field,
12434
+ {
12435
+ control: form.control,
12436
+ name: "country_code",
12437
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12438
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Country" }),
12439
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(CountrySelect, { ...field }) }),
12440
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12441
+ ] })
12442
+ }
12443
+ ),
12444
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
12445
+ /* @__PURE__ */ jsx(
12446
+ Form$2.Field,
12447
+ {
12448
+ control: form.control,
12449
+ name: "first_name",
12450
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12451
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "First name" }),
12452
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12453
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12454
+ ] })
12455
+ }
12456
+ ),
12457
+ /* @__PURE__ */ jsx(
12458
+ Form$2.Field,
12459
+ {
12460
+ control: form.control,
12461
+ name: "last_name",
12462
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12463
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Last name" }),
12464
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12465
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12466
+ ] })
12467
+ }
12468
+ )
12469
+ ] }),
12470
+ /* @__PURE__ */ jsx(
12471
+ Form$2.Field,
12472
+ {
12473
+ control: form.control,
12474
+ name: "company",
12475
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12476
+ /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Company" }),
12477
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12478
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12479
+ ] })
12480
+ }
12481
+ ),
12482
+ /* @__PURE__ */ jsx(
12483
+ Form$2.Field,
12484
+ {
12485
+ control: form.control,
12486
+ name: "address_1",
12487
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12488
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Address" }),
12489
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12490
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12491
+ ] })
12492
+ }
12493
+ ),
12494
+ /* @__PURE__ */ jsx(
12495
+ Form$2.Field,
12496
+ {
12497
+ control: form.control,
12498
+ name: "address_2",
12499
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12500
+ /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Apartment, suite, etc." }),
12501
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12502
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12503
+ ] })
12504
+ }
12505
+ ),
12506
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
12507
+ /* @__PURE__ */ jsx(
12508
+ Form$2.Field,
12509
+ {
12510
+ control: form.control,
12511
+ name: "postal_code",
12512
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12513
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Postal code" }),
12514
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12515
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12516
+ ] })
12517
+ }
12518
+ ),
12519
+ /* @__PURE__ */ jsx(
12520
+ Form$2.Field,
12521
+ {
12522
+ control: form.control,
12523
+ name: "city",
12524
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12525
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "City" }),
12526
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12527
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12528
+ ] })
12529
+ }
12530
+ )
12531
+ ] }),
12532
+ /* @__PURE__ */ jsx(
12533
+ Form$2.Field,
12534
+ {
12535
+ control: form.control,
12536
+ name: "province",
12537
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12538
+ /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Province / State" }),
12539
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12540
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12541
+ ] })
12542
+ }
12543
+ ),
12544
+ /* @__PURE__ */ jsx(
12545
+ Form$2.Field,
12546
+ {
12547
+ control: form.control,
12548
+ name: "phone",
12549
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12550
+ /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Phone" }),
12551
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12552
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12553
+ ] })
12554
+ }
12555
+ )
12556
+ ] }) }),
12291
12557
  /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
12292
12558
  /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
12293
12559
  /* @__PURE__ */ jsx(Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
12294
12560
  ] }) })
12295
12561
  ]
12296
12562
  }
12297
- ) });
12298
- };
12299
- const SalesChannelField = ({ control, order }) => {
12300
- const salesChannels = useComboboxData({
12301
- queryFn: async (params) => {
12302
- return await sdk.admin.salesChannel.list(params);
12303
- },
12304
- queryKey: ["sales-channels"],
12305
- getOptions: (data) => {
12306
- return data.sales_channels.map((salesChannel) => ({
12307
- label: salesChannel.name,
12308
- value: salesChannel.id
12309
- }));
12310
- },
12311
- defaultValue: order.sales_channel_id || void 0
12312
- });
12313
- return /* @__PURE__ */ jsx(
12314
- Form$2.Field,
12315
- {
12316
- control,
12317
- name: "sales_channel_id",
12318
- render: ({ field }) => {
12319
- return /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12320
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Sales Channel" }),
12321
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
12322
- Combobox,
12323
- {
12324
- options: salesChannels.options,
12325
- fetchNextPage: salesChannels.fetchNextPage,
12326
- isFetchingNextPage: salesChannels.isFetchingNextPage,
12327
- searchValue: salesChannels.searchValue,
12328
- onSearchValueChange: salesChannels.onSearchValueChange,
12329
- placeholder: "Select sales channel",
12330
- ...field
12331
- }
12332
- ) }),
12333
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12334
- ] });
12335
- }
12336
- }
12337
- );
12563
+ ) });
12338
12564
  };
12339
- const schema$3 = objectType({
12340
- sales_channel_id: stringType().min(1)
12341
- });
12565
+ const schema$1 = addressSchema;
12342
12566
  const TransferOwnership = () => {
12343
12567
  const { id } = useParams();
12344
12568
  const { draft_order, isPending, isError, error } = useDraftOrder(id, {
@@ -12362,7 +12586,7 @@ const TransferOwnershipForm = ({ order }) => {
12362
12586
  defaultValues: {
12363
12587
  customer_id: order.customer_id || ""
12364
12588
  },
12365
- resolver: zodResolver(schema$2)
12589
+ resolver: zodResolver(schema)
12366
12590
  });
12367
12591
  const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
12368
12592
  const { handleSuccess } = useRouteModal();
@@ -12812,232 +13036,8 @@ const Illustration = () => {
12812
13036
  }
12813
13037
  );
12814
13038
  };
12815
- const schema$2 = objectType({
12816
- customer_id: stringType().min(1)
12817
- });
12818
- const ShippingAddress = () => {
12819
- const { id } = useParams();
12820
- const { order, isPending, isError, error } = useOrder(id, {
12821
- fields: "+shipping_address"
12822
- });
12823
- if (isError) {
12824
- throw error;
12825
- }
12826
- const isReady = !isPending && !!order;
12827
- return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
12828
- /* @__PURE__ */ jsxs(RouteDrawer.Header, { children: [
12829
- /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Shipping Address" }) }),
12830
- /* @__PURE__ */ jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Edit the shipping address for the draft order" }) })
12831
- ] }),
12832
- isReady && /* @__PURE__ */ jsx(ShippingAddressForm, { order })
12833
- ] });
12834
- };
12835
- const ShippingAddressForm = ({ order }) => {
12836
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
12837
- const form = useForm({
12838
- defaultValues: {
12839
- first_name: ((_a = order.shipping_address) == null ? void 0 : _a.first_name) ?? "",
12840
- last_name: ((_b = order.shipping_address) == null ? void 0 : _b.last_name) ?? "",
12841
- company: ((_c = order.shipping_address) == null ? void 0 : _c.company) ?? "",
12842
- address_1: ((_d = order.shipping_address) == null ? void 0 : _d.address_1) ?? "",
12843
- address_2: ((_e = order.shipping_address) == null ? void 0 : _e.address_2) ?? "",
12844
- city: ((_f = order.shipping_address) == null ? void 0 : _f.city) ?? "",
12845
- province: ((_g = order.shipping_address) == null ? void 0 : _g.province) ?? "",
12846
- country_code: ((_h = order.shipping_address) == null ? void 0 : _h.country_code) ?? "",
12847
- postal_code: ((_i = order.shipping_address) == null ? void 0 : _i.postal_code) ?? "",
12848
- phone: ((_j = order.shipping_address) == null ? void 0 : _j.phone) ?? ""
12849
- },
12850
- resolver: zodResolver(schema$1)
12851
- });
12852
- const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
12853
- const { handleSuccess } = useRouteModal();
12854
- const onSubmit = form.handleSubmit(async (data) => {
12855
- await mutateAsync(
12856
- {
12857
- shipping_address: {
12858
- first_name: data.first_name,
12859
- last_name: data.last_name,
12860
- company: data.company,
12861
- address_1: data.address_1,
12862
- address_2: data.address_2,
12863
- city: data.city,
12864
- province: data.province,
12865
- country_code: data.country_code,
12866
- postal_code: data.postal_code,
12867
- phone: data.phone
12868
- }
12869
- },
12870
- {
12871
- onSuccess: () => {
12872
- handleSuccess();
12873
- },
12874
- onError: (error) => {
12875
- toast.error(error.message);
12876
- }
12877
- }
12878
- );
12879
- });
12880
- return /* @__PURE__ */ jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxs(
12881
- KeyboundForm,
12882
- {
12883
- className: "flex flex-1 flex-col overflow-hidden",
12884
- onSubmit,
12885
- children: [
12886
- /* @__PURE__ */ jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-y-4", children: [
12887
- /* @__PURE__ */ jsx(
12888
- Form$2.Field,
12889
- {
12890
- control: form.control,
12891
- name: "country_code",
12892
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12893
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Country" }),
12894
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(CountrySelect, { ...field }) }),
12895
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12896
- ] })
12897
- }
12898
- ),
12899
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
12900
- /* @__PURE__ */ jsx(
12901
- Form$2.Field,
12902
- {
12903
- control: form.control,
12904
- name: "first_name",
12905
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12906
- /* @__PURE__ */ jsx(Form$2.Label, { children: "First name" }),
12907
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12908
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12909
- ] })
12910
- }
12911
- ),
12912
- /* @__PURE__ */ jsx(
12913
- Form$2.Field,
12914
- {
12915
- control: form.control,
12916
- name: "last_name",
12917
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12918
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Last name" }),
12919
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12920
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12921
- ] })
12922
- }
12923
- )
12924
- ] }),
12925
- /* @__PURE__ */ jsx(
12926
- Form$2.Field,
12927
- {
12928
- control: form.control,
12929
- name: "company",
12930
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12931
- /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Company" }),
12932
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12933
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12934
- ] })
12935
- }
12936
- ),
12937
- /* @__PURE__ */ jsx(
12938
- Form$2.Field,
12939
- {
12940
- control: form.control,
12941
- name: "address_1",
12942
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12943
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Address" }),
12944
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12945
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12946
- ] })
12947
- }
12948
- ),
12949
- /* @__PURE__ */ jsx(
12950
- Form$2.Field,
12951
- {
12952
- control: form.control,
12953
- name: "address_2",
12954
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12955
- /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Apartment, suite, etc." }),
12956
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12957
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12958
- ] })
12959
- }
12960
- ),
12961
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
12962
- /* @__PURE__ */ jsx(
12963
- Form$2.Field,
12964
- {
12965
- control: form.control,
12966
- name: "postal_code",
12967
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12968
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Postal code" }),
12969
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12970
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12971
- ] })
12972
- }
12973
- ),
12974
- /* @__PURE__ */ jsx(
12975
- Form$2.Field,
12976
- {
12977
- control: form.control,
12978
- name: "city",
12979
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12980
- /* @__PURE__ */ jsx(Form$2.Label, { children: "City" }),
12981
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12982
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12983
- ] })
12984
- }
12985
- )
12986
- ] }),
12987
- /* @__PURE__ */ jsx(
12988
- Form$2.Field,
12989
- {
12990
- control: form.control,
12991
- name: "province",
12992
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12993
- /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Province / State" }),
12994
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12995
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12996
- ] })
12997
- }
12998
- ),
12999
- /* @__PURE__ */ jsx(
13000
- Form$2.Field,
13001
- {
13002
- control: form.control,
13003
- name: "phone",
13004
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
13005
- /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Phone" }),
13006
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
13007
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
13008
- ] })
13009
- }
13010
- )
13011
- ] }) }),
13012
- /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
13013
- /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
13014
- /* @__PURE__ */ jsx(Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
13015
- ] }) })
13016
- ]
13017
- }
13018
- ) });
13019
- };
13020
- const schema$1 = addressSchema;
13021
- const CustomItems = () => {
13022
- return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
13023
- /* @__PURE__ */ jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Custom Items" }) }) }),
13024
- /* @__PURE__ */ jsx(CustomItemsForm, {})
13025
- ] });
13026
- };
13027
- const CustomItemsForm = () => {
13028
- const form = useForm({
13029
- resolver: zodResolver(schema)
13030
- });
13031
- return /* @__PURE__ */ jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxs(KeyboundForm, { className: "flex flex-1 flex-col", children: [
13032
- /* @__PURE__ */ jsx(RouteDrawer.Body, {}),
13033
- /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
13034
- /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
13035
- /* @__PURE__ */ jsx(Button, { size: "small", type: "submit", children: "Save" })
13036
- ] }) })
13037
- ] }) });
13038
- };
13039
13039
  const schema = objectType({
13040
- email: stringType().email()
13040
+ customer_id: stringType().min(1)
13041
13041
  });
13042
13042
  const widgetModule = { widgets: [] };
13043
13043
  const routeModule = {
@@ -13060,44 +13060,44 @@ const routeModule = {
13060
13060
  loader,
13061
13061
  children: [
13062
13062
  {
13063
- Component: BillingAddress,
13064
- path: "/draft-orders/:id/billing-address"
13063
+ Component: CustomItems,
13064
+ path: "/draft-orders/:id/custom-items"
13065
13065
  },
13066
13066
  {
13067
13067
  Component: Email,
13068
13068
  path: "/draft-orders/:id/email"
13069
13069
  },
13070
13070
  {
13071
- Component: Items,
13072
- path: "/draft-orders/:id/items"
13071
+ Component: BillingAddress,
13072
+ path: "/draft-orders/:id/billing-address"
13073
13073
  },
13074
13074
  {
13075
13075
  Component: Metadata,
13076
13076
  path: "/draft-orders/:id/metadata"
13077
13077
  },
13078
13078
  {
13079
- Component: Promotions,
13080
- path: "/draft-orders/:id/promotions"
13079
+ Component: Items,
13080
+ path: "/draft-orders/:id/items"
13081
13081
  },
13082
13082
  {
13083
- Component: Shipping,
13084
- path: "/draft-orders/:id/shipping"
13083
+ Component: Promotions,
13084
+ path: "/draft-orders/:id/promotions"
13085
13085
  },
13086
13086
  {
13087
13087
  Component: SalesChannel,
13088
13088
  path: "/draft-orders/:id/sales-channel"
13089
13089
  },
13090
13090
  {
13091
- Component: TransferOwnership,
13092
- path: "/draft-orders/:id/transfer-ownership"
13091
+ Component: Shipping,
13092
+ path: "/draft-orders/:id/shipping"
13093
13093
  },
13094
13094
  {
13095
13095
  Component: ShippingAddress,
13096
13096
  path: "/draft-orders/:id/shipping-address"
13097
13097
  },
13098
13098
  {
13099
- Component: CustomItems,
13100
- path: "/draft-orders/:id/custom-items"
13099
+ Component: TransferOwnership,
13100
+ path: "/draft-orders/:id/transfer-ownership"
13101
13101
  }
13102
13102
  ]
13103
13103
  }