@medusajs/draft-order 2.11.1-preview-20251024090150 → 2.11.1-preview-20251024150200

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.
@@ -9592,683 +9592,573 @@ const CustomItemsForm = () => {
9592
9592
  const schema$5 = objectType({
9593
9593
  email: stringType().email()
9594
9594
  });
9595
- const Email = () => {
9596
- const { id } = reactRouterDom.useParams();
9597
- const { order, isPending, isError, error } = useOrder(id, {
9598
- fields: "+email"
9599
- });
9600
- if (isError) {
9601
- throw error;
9602
- }
9603
- const isReady = !isPending && !!order;
9604
- return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
9605
- /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Header, { children: [
9606
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Email" }) }),
9607
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Edit the email for the draft order" }) })
9608
- ] }),
9609
- isReady && /* @__PURE__ */ jsxRuntime.jsx(EmailForm, { order })
9610
- ] });
9611
- };
9612
- const EmailForm = ({ order }) => {
9613
- const form = reactHookForm.useForm({
9614
- defaultValues: {
9615
- email: order.email ?? ""
9616
- },
9617
- resolver: zod.zodResolver(schema$4)
9618
- });
9619
- const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
9620
- const { handleSuccess } = useRouteModal();
9621
- const onSubmit = form.handleSubmit(async (data) => {
9622
- await mutateAsync(
9623
- { email: data.email },
9595
+ const NumberInput = React.forwardRef(
9596
+ ({
9597
+ value,
9598
+ onChange,
9599
+ size = "base",
9600
+ min = 0,
9601
+ max = 100,
9602
+ step = 1,
9603
+ className,
9604
+ disabled,
9605
+ ...props
9606
+ }, ref) => {
9607
+ const handleChange = (event) => {
9608
+ const newValue = event.target.value === "" ? min : Number(event.target.value);
9609
+ if (!isNaN(newValue) && (max === void 0 || newValue <= max) && (min === void 0 || newValue >= min)) {
9610
+ onChange(newValue);
9611
+ }
9612
+ };
9613
+ const handleIncrement = () => {
9614
+ const newValue = value + step;
9615
+ if (max === void 0 || newValue <= max) {
9616
+ onChange(newValue);
9617
+ }
9618
+ };
9619
+ const handleDecrement = () => {
9620
+ const newValue = value - step;
9621
+ if (min === void 0 || newValue >= min) {
9622
+ onChange(newValue);
9623
+ }
9624
+ };
9625
+ return /* @__PURE__ */ jsxRuntime.jsxs(
9626
+ "div",
9624
9627
  {
9625
- onSuccess: () => {
9626
- handleSuccess();
9627
- },
9628
- onError: (error) => {
9629
- ui.toast.error(error.message);
9630
- }
9628
+ className: ui.clx(
9629
+ "inline-flex rounded-md bg-ui-bg-field shadow-borders-base overflow-hidden divide-x transition-fg",
9630
+ "[&:has(input:focus)]:shadow-borders-interactive-with-active",
9631
+ {
9632
+ "h-7": size === "small",
9633
+ "h-8": size === "base"
9634
+ },
9635
+ className
9636
+ ),
9637
+ children: [
9638
+ /* @__PURE__ */ jsxRuntime.jsx(
9639
+ "input",
9640
+ {
9641
+ ref,
9642
+ type: "number",
9643
+ value,
9644
+ onChange: handleChange,
9645
+ min,
9646
+ max,
9647
+ step,
9648
+ className: ui.clx(
9649
+ "flex-1 px-2 py-1 bg-transparent txt-compact-small text-ui-fg-base outline-none [appearance:textfield]",
9650
+ "[&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none",
9651
+ "placeholder:text-ui-fg-muted"
9652
+ ),
9653
+ ...props
9654
+ }
9655
+ ),
9656
+ /* @__PURE__ */ jsxRuntime.jsxs(
9657
+ "button",
9658
+ {
9659
+ className: ui.clx(
9660
+ "flex items-center justify-center outline-none transition-fg",
9661
+ "disabled:cursor-not-allowed disabled:text-ui-fg-muted",
9662
+ "focus:bg-ui-bg-field-component-hover",
9663
+ "hover:bg-ui-bg-field-component-hover",
9664
+ {
9665
+ "size-7": size === "small",
9666
+ "size-8": size === "base"
9667
+ }
9668
+ ),
9669
+ type: "button",
9670
+ onClick: handleDecrement,
9671
+ disabled: min !== void 0 && value <= min || disabled,
9672
+ children: [
9673
+ /* @__PURE__ */ jsxRuntime.jsx(icons.Minus, {}),
9674
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: `Decrease by ${step}` })
9675
+ ]
9676
+ }
9677
+ ),
9678
+ /* @__PURE__ */ jsxRuntime.jsxs(
9679
+ "button",
9680
+ {
9681
+ className: ui.clx(
9682
+ "flex items-center justify-center outline-none transition-fg",
9683
+ "disabled:cursor-not-allowed disabled:text-ui-fg-muted",
9684
+ "focus:bg-ui-bg-field-hover",
9685
+ "hover:bg-ui-bg-field-hover",
9686
+ {
9687
+ "size-7": size === "small",
9688
+ "size-8": size === "base"
9689
+ }
9690
+ ),
9691
+ type: "button",
9692
+ onClick: handleIncrement,
9693
+ disabled: max !== void 0 && value >= max || disabled,
9694
+ children: [
9695
+ /* @__PURE__ */ jsxRuntime.jsx(icons.Plus, {}),
9696
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: `Increase by ${step}` })
9697
+ ]
9698
+ }
9699
+ )
9700
+ ]
9631
9701
  }
9632
9702
  );
9703
+ }
9704
+ );
9705
+ const PRODUCT_VARIANTS_QUERY_KEY = "product-variants";
9706
+ const productVariantsQueryKeys = {
9707
+ list: (query2) => [
9708
+ PRODUCT_VARIANTS_QUERY_KEY,
9709
+ query2 ? query2 : void 0
9710
+ ]
9711
+ };
9712
+ const useProductVariants = (query2, options) => {
9713
+ const { data, ...rest } = reactQuery.useQuery({
9714
+ queryKey: productVariantsQueryKeys.list(query2),
9715
+ queryFn: async () => await sdk.admin.productVariant.list(query2),
9716
+ ...options
9633
9717
  });
9634
- return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(
9635
- KeyboundForm,
9636
- {
9637
- className: "flex flex-1 flex-col overflow-hidden",
9638
- onSubmit,
9639
- children: [
9640
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsx(
9641
- Form$2.Field,
9642
- {
9643
- control: form.control,
9644
- name: "email",
9645
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
9646
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Email" }),
9647
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
9648
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
9649
- ] })
9650
- }
9651
- ) }),
9652
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
9653
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
9654
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
9655
- ] }) })
9656
- ]
9718
+ return { ...data, ...rest };
9719
+ };
9720
+ const useCancelOrderEdit = ({ preview }) => {
9721
+ const { mutateAsync: cancelOrderEdit } = useDraftOrderCancelEdit(preview == null ? void 0 : preview.id);
9722
+ const onCancel = React.useCallback(async () => {
9723
+ if (!preview) {
9724
+ return true;
9657
9725
  }
9658
- ) });
9726
+ let res = false;
9727
+ await cancelOrderEdit(void 0, {
9728
+ onError: (e) => {
9729
+ ui.toast.error(e.message);
9730
+ },
9731
+ onSuccess: () => {
9732
+ res = true;
9733
+ }
9734
+ });
9735
+ return res;
9736
+ }, [preview, cancelOrderEdit]);
9737
+ return { onCancel };
9659
9738
  };
9660
- const schema$4 = objectType({
9661
- email: stringType().email()
9662
- });
9663
- const BillingAddress = () => {
9739
+ let IS_REQUEST_RUNNING = false;
9740
+ const useInitiateOrderEdit = ({
9741
+ preview
9742
+ }) => {
9743
+ const navigate = reactRouterDom.useNavigate();
9744
+ const { mutateAsync } = useDraftOrderBeginEdit(preview == null ? void 0 : preview.id);
9745
+ React.useEffect(() => {
9746
+ async function run() {
9747
+ if (IS_REQUEST_RUNNING || !preview) {
9748
+ return;
9749
+ }
9750
+ if (preview.order_change) {
9751
+ return;
9752
+ }
9753
+ IS_REQUEST_RUNNING = true;
9754
+ await mutateAsync(void 0, {
9755
+ onError: (e) => {
9756
+ ui.toast.error(e.message);
9757
+ navigate(`/draft-orders/${preview.id}`, { replace: true });
9758
+ return;
9759
+ }
9760
+ });
9761
+ IS_REQUEST_RUNNING = false;
9762
+ }
9763
+ run();
9764
+ }, [preview, navigate, mutateAsync]);
9765
+ };
9766
+ function convertNumber(value) {
9767
+ return typeof value === "string" ? Number(value.replace(",", ".")) : value;
9768
+ }
9769
+ const STACKED_MODAL_ID = "items_stacked_modal";
9770
+ const Items = () => {
9664
9771
  const { id } = reactRouterDom.useParams();
9665
- const { order, isPending, isError, error } = useOrder(id, {
9666
- fields: "+billing_address"
9772
+ const {
9773
+ order: preview,
9774
+ isPending: isPreviewPending,
9775
+ isError: isPreviewError,
9776
+ error: previewError
9777
+ } = useOrderPreview(id, void 0, {
9778
+ placeholderData: reactQuery.keepPreviousData
9667
9779
  });
9780
+ useInitiateOrderEdit({ preview });
9781
+ const { draft_order, isPending, isError, error } = useDraftOrder(
9782
+ id,
9783
+ {
9784
+ fields: "currency_code"
9785
+ },
9786
+ {
9787
+ enabled: !!id
9788
+ }
9789
+ );
9790
+ const { onCancel } = useCancelOrderEdit({ preview });
9668
9791
  if (isError) {
9669
9792
  throw error;
9670
9793
  }
9671
- const isReady = !isPending && !!order;
9672
- return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
9673
- /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Header, { children: [
9674
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Billing Address" }) }),
9675
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Edit the billing address for the draft order" }) })
9676
- ] }),
9677
- isReady && /* @__PURE__ */ jsxRuntime.jsx(BillingAddressForm, { order })
9794
+ if (isPreviewError) {
9795
+ throw previewError;
9796
+ }
9797
+ const ready = !!preview && !isPreviewPending && !!draft_order && !isPending;
9798
+ return /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal, { onClose: onCancel, children: ready ? /* @__PURE__ */ jsxRuntime.jsx(ItemsForm, { preview, currencyCode: draft_order.currency_code }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
9799
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Edit Items" }) }),
9800
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Loading data for the draft order, please wait..." }) })
9801
+ ] }) });
9802
+ };
9803
+ const ItemsForm = ({ preview, currencyCode }) => {
9804
+ var _a;
9805
+ const [isSubmitting, setIsSubmitting] = React.useState(false);
9806
+ const [modalContent, setModalContent] = React.useState(
9807
+ null
9808
+ );
9809
+ const { handleSuccess } = useRouteModal();
9810
+ const { searchValue, onSearchValueChange, query: query2 } = useDebouncedSearch();
9811
+ const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
9812
+ const { mutateAsync: requestOrderEdit } = useDraftOrderRequestEdit(preview.id);
9813
+ const itemCount = ((_a = preview.items) == null ? void 0 : _a.reduce((acc, item) => acc + item.quantity, 0)) || 0;
9814
+ const matches = React.useMemo(() => {
9815
+ return matchSorter.matchSorter(preview.items, query2, {
9816
+ keys: ["product_title", "variant_title", "variant_sku", "title"]
9817
+ });
9818
+ }, [preview.items, query2]);
9819
+ const onSubmit = async () => {
9820
+ setIsSubmitting(true);
9821
+ let requestSucceeded = false;
9822
+ await requestOrderEdit(void 0, {
9823
+ onError: (e) => {
9824
+ ui.toast.error(`Failed to request order edit: ${e.message}`);
9825
+ },
9826
+ onSuccess: () => {
9827
+ requestSucceeded = true;
9828
+ }
9829
+ });
9830
+ if (!requestSucceeded) {
9831
+ setIsSubmitting(false);
9832
+ return;
9833
+ }
9834
+ await confirmOrderEdit(void 0, {
9835
+ onError: (e) => {
9836
+ ui.toast.error(`Failed to confirm order edit: ${e.message}`);
9837
+ },
9838
+ onSuccess: () => {
9839
+ handleSuccess();
9840
+ },
9841
+ onSettled: () => {
9842
+ setIsSubmitting(false);
9843
+ }
9844
+ });
9845
+ };
9846
+ const onKeyDown = React.useCallback(
9847
+ (e) => {
9848
+ if (e.key === "Enter" && (e.ctrlKey || e.metaKey)) {
9849
+ if (modalContent || isSubmitting) {
9850
+ return;
9851
+ }
9852
+ onSubmit();
9853
+ }
9854
+ },
9855
+ [modalContent, isSubmitting, onSubmit]
9856
+ );
9857
+ React.useEffect(() => {
9858
+ document.addEventListener("keydown", onKeyDown);
9859
+ return () => {
9860
+ document.removeEventListener("keydown", onKeyDown);
9861
+ };
9862
+ }, [onKeyDown]);
9863
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-full flex-col overflow-hidden", children: [
9864
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Header, {}),
9865
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Body, { className: "flex flex-1 flex-col overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsxs(
9866
+ StackedFocusModal,
9867
+ {
9868
+ id: STACKED_MODAL_ID,
9869
+ onOpenChangeCallback: (open) => {
9870
+ if (!open) {
9871
+ setModalContent(null);
9872
+ }
9873
+ },
9874
+ children: [
9875
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-1 flex-col items-center overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full max-w-[720px] flex-col gap-y-6 px-6 py-16", children: [
9876
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
9877
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Items" }) }),
9878
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Edit the items in the draft order" }) })
9879
+ ] }),
9880
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
9881
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-6", children: [
9882
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 items-center gap-3", children: [
9883
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
9884
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "Items" }),
9885
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Choose items from the product catalog." })
9886
+ ] }),
9887
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
9888
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(
9889
+ ui.Input,
9890
+ {
9891
+ type: "search",
9892
+ placeholder: "Search items",
9893
+ value: searchValue,
9894
+ onChange: (e) => onSearchValueChange(e.target.value)
9895
+ }
9896
+ ) }),
9897
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu, { children: [
9898
+ /* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenu.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { type: "button", children: /* @__PURE__ */ jsxRuntime.jsx(icons.Plus, {}) }) }),
9899
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu.Content, { children: [
9900
+ /* @__PURE__ */ jsxRuntime.jsx(
9901
+ StackedModalTrigger$1,
9902
+ {
9903
+ type: "add-items",
9904
+ setModalContent
9905
+ }
9906
+ ),
9907
+ /* @__PURE__ */ jsxRuntime.jsx(
9908
+ StackedModalTrigger$1,
9909
+ {
9910
+ type: "add-custom-item",
9911
+ setModalContent
9912
+ }
9913
+ )
9914
+ ] })
9915
+ ] })
9916
+ ] })
9917
+ ] }),
9918
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-subtle shadow-elevation-card-rest rounded-xl", children: [
9919
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-[5px]", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-ui-fg-muted grid grid-cols-[2fr_1fr_2fr_28px] gap-3 px-4 py-2", children: [
9920
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: "Item" }) }),
9921
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: "Quantity" }) }),
9922
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-right", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: "Price" }) }),
9923
+ /* @__PURE__ */ jsxRuntime.jsx("div", {})
9924
+ ] }) }),
9925
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-y-1.5 px-[5px] pb-[5px]", children: itemCount <= 0 ? /* @__PURE__ */ jsxRuntime.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: [
9926
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "There are no items in this order" }),
9927
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Add items to the order to get started." })
9928
+ ] }) : matches.length > 0 ? matches == null ? void 0 : matches.map((item) => /* @__PURE__ */ jsxRuntime.jsx(
9929
+ Item,
9930
+ {
9931
+ item,
9932
+ preview,
9933
+ currencyCode
9934
+ },
9935
+ item.id
9936
+ )) : /* @__PURE__ */ jsxRuntime.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: [
9937
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "No items found" }),
9938
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: [
9939
+ 'No items found for "',
9940
+ query2,
9941
+ '".'
9942
+ ] })
9943
+ ] }) })
9944
+ ] })
9945
+ ] }),
9946
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
9947
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-[1fr_0.5fr_0.5fr] gap-3", children: [
9948
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "Subtotal" }) }),
9949
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsxs(
9950
+ ui.Text,
9951
+ {
9952
+ size: "small",
9953
+ leading: "compact",
9954
+ className: "text-ui-fg-subtle",
9955
+ children: [
9956
+ itemCount,
9957
+ " ",
9958
+ itemCount === 1 ? "item" : "items"
9959
+ ]
9960
+ }
9961
+ ) }),
9962
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-right", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: getStylizedAmount(preview.item_subtotal, currencyCode) }) })
9963
+ ] })
9964
+ ] }) }),
9965
+ modalContent && (modalContent === "add-items" ? /* @__PURE__ */ jsxRuntime.jsx(ExistingItemsForm, { orderId: preview.id, items: preview.items }) : modalContent === "add-custom-item" ? /* @__PURE__ */ jsxRuntime.jsx(
9966
+ CustomItemForm,
9967
+ {
9968
+ orderId: preview.id,
9969
+ currencyCode
9970
+ }
9971
+ ) : null)
9972
+ ]
9973
+ }
9974
+ ) }),
9975
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
9976
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
9977
+ /* @__PURE__ */ jsxRuntime.jsx(
9978
+ ui.Button,
9979
+ {
9980
+ size: "small",
9981
+ type: "button",
9982
+ onClick: onSubmit,
9983
+ isLoading: isSubmitting,
9984
+ children: "Save"
9985
+ }
9986
+ )
9987
+ ] }) })
9678
9988
  ] });
9679
9989
  };
9680
- const BillingAddressForm = ({ order }) => {
9681
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
9990
+ const Item = ({ item, preview, currencyCode }) => {
9991
+ if (item.variant_id) {
9992
+ return /* @__PURE__ */ jsxRuntime.jsx(VariantItem, { item, preview, currencyCode });
9993
+ }
9994
+ return /* @__PURE__ */ jsxRuntime.jsx(CustomItem, { item, preview, currencyCode });
9995
+ };
9996
+ const VariantItem = ({ item, preview, currencyCode }) => {
9997
+ const [editing, setEditing] = React.useState(false);
9682
9998
  const form = reactHookForm.useForm({
9683
9999
  defaultValues: {
9684
- first_name: ((_a = order.billing_address) == null ? void 0 : _a.first_name) ?? "",
9685
- last_name: ((_b = order.billing_address) == null ? void 0 : _b.last_name) ?? "",
9686
- company: ((_c = order.billing_address) == null ? void 0 : _c.company) ?? "",
9687
- address_1: ((_d = order.billing_address) == null ? void 0 : _d.address_1) ?? "",
9688
- address_2: ((_e = order.billing_address) == null ? void 0 : _e.address_2) ?? "",
9689
- city: ((_f = order.billing_address) == null ? void 0 : _f.city) ?? "",
9690
- province: ((_g = order.billing_address) == null ? void 0 : _g.province) ?? "",
9691
- country_code: ((_h = order.billing_address) == null ? void 0 : _h.country_code) ?? "",
9692
- postal_code: ((_i = order.billing_address) == null ? void 0 : _i.postal_code) ?? "",
9693
- phone: ((_j = order.billing_address) == null ? void 0 : _j.phone) ?? ""
10000
+ quantity: item.quantity,
10001
+ unit_price: item.unit_price
9694
10002
  },
9695
- resolver: zod.zodResolver(schema$3)
10003
+ resolver: zod.zodResolver(variantItemSchema)
9696
10004
  });
9697
- const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
9698
- const { handleSuccess } = useRouteModal();
10005
+ const actionId = React.useMemo(() => {
10006
+ var _a, _b;
10007
+ return (_b = (_a = item.actions) == null ? void 0 : _a.find((a) => a.action === "ITEM_ADD")) == null ? void 0 : _b.id;
10008
+ }, [item]);
10009
+ const { mutateAsync: updateActionItem, isPending: isUpdatingActionItem } = useDraftOrderUpdateActionItem(preview.id);
10010
+ const { mutateAsync: updateOriginalItem, isPending: isUpdatingOriginalItem } = useDraftOrderUpdateItem(preview.id);
10011
+ const isPending = isUpdatingActionItem || isUpdatingOriginalItem;
9699
10012
  const onSubmit = form.handleSubmit(async (data) => {
9700
- await mutateAsync(
9701
- { billing_address: data },
9702
- {
9703
- onSuccess: () => {
9704
- handleSuccess();
10013
+ if (convertNumber(data.unit_price) === item.unit_price && data.quantity === item.quantity) {
10014
+ setEditing(false);
10015
+ return;
10016
+ }
10017
+ if (!actionId) {
10018
+ await updateOriginalItem(
10019
+ {
10020
+ item_id: item.id,
10021
+ quantity: data.quantity,
10022
+ unit_price: convertNumber(data.unit_price)
9705
10023
  },
9706
- onError: (error) => {
9707
- ui.toast.error(error.message);
10024
+ {
10025
+ onSuccess: () => {
10026
+ setEditing(false);
10027
+ },
10028
+ onError: (e) => {
10029
+ ui.toast.error(e.message);
10030
+ }
9708
10031
  }
9709
- }
9710
- );
9711
- });
9712
- return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(
9713
- KeyboundForm,
9714
- {
9715
- className: "flex flex-1 flex-col overflow-hidden",
9716
- onSubmit,
9717
- children: [
9718
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-4", children: [
9719
- /* @__PURE__ */ jsxRuntime.jsx(
9720
- Form$2.Field,
9721
- {
9722
- control: form.control,
9723
- name: "country_code",
9724
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
9725
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Country" }),
9726
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(CountrySelect, { ...field }) }),
9727
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
9728
- ] })
9729
- }
9730
- ),
9731
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
9732
- /* @__PURE__ */ jsxRuntime.jsx(
9733
- Form$2.Field,
9734
- {
9735
- control: form.control,
9736
- name: "first_name",
9737
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
9738
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "First name" }),
9739
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
9740
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
9741
- ] })
9742
- }
9743
- ),
9744
- /* @__PURE__ */ jsxRuntime.jsx(
9745
- Form$2.Field,
9746
- {
9747
- control: form.control,
9748
- name: "last_name",
9749
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
9750
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Last name" }),
9751
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
9752
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
9753
- ] })
9754
- }
9755
- )
9756
- ] }),
9757
- /* @__PURE__ */ jsxRuntime.jsx(
9758
- Form$2.Field,
9759
- {
9760
- control: form.control,
9761
- name: "company",
9762
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
9763
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { optional: true, children: "Company" }),
9764
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
9765
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
9766
- ] })
9767
- }
9768
- ),
9769
- /* @__PURE__ */ jsxRuntime.jsx(
9770
- Form$2.Field,
9771
- {
9772
- control: form.control,
9773
- name: "address_1",
9774
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
9775
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Address" }),
9776
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
9777
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
9778
- ] })
9779
- }
9780
- ),
9781
- /* @__PURE__ */ jsxRuntime.jsx(
9782
- Form$2.Field,
9783
- {
9784
- control: form.control,
9785
- name: "address_2",
9786
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
9787
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { optional: true, children: "Apartment, suite, etc." }),
9788
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
9789
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
9790
- ] })
9791
- }
9792
- ),
9793
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
9794
- /* @__PURE__ */ jsxRuntime.jsx(
9795
- Form$2.Field,
9796
- {
9797
- control: form.control,
9798
- name: "postal_code",
9799
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
9800
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Postal code" }),
9801
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
9802
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
9803
- ] })
9804
- }
9805
- ),
9806
- /* @__PURE__ */ jsxRuntime.jsx(
9807
- Form$2.Field,
9808
- {
9809
- control: form.control,
9810
- name: "city",
9811
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
9812
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "City" }),
9813
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
9814
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
9815
- ] })
9816
- }
9817
- )
9818
- ] }),
9819
- /* @__PURE__ */ jsxRuntime.jsx(
9820
- Form$2.Field,
9821
- {
9822
- control: form.control,
9823
- name: "province",
9824
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
9825
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { optional: true, children: "Province / State" }),
9826
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
9827
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
9828
- ] })
9829
- }
9830
- ),
9831
- /* @__PURE__ */ jsxRuntime.jsx(
9832
- Form$2.Field,
9833
- {
9834
- control: form.control,
9835
- name: "phone",
9836
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
9837
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { optional: true, children: "Phone" }),
9838
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
9839
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
9840
- ] })
9841
- }
9842
- )
9843
- ] }) }),
9844
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
9845
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
9846
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
9847
- ] }) })
9848
- ]
9849
- }
9850
- ) });
9851
- };
9852
- const schema$3 = addressSchema;
9853
- const NumberInput = React.forwardRef(
9854
- ({
9855
- value,
9856
- onChange,
9857
- size = "base",
9858
- min = 0,
9859
- max = 100,
9860
- step = 1,
9861
- className,
9862
- disabled,
9863
- ...props
9864
- }, ref) => {
9865
- const handleChange = (event) => {
9866
- const newValue = event.target.value === "" ? min : Number(event.target.value);
9867
- if (!isNaN(newValue) && (max === void 0 || newValue <= max) && (min === void 0 || newValue >= min)) {
9868
- onChange(newValue);
9869
- }
9870
- };
9871
- const handleIncrement = () => {
9872
- const newValue = value + step;
9873
- if (max === void 0 || newValue <= max) {
9874
- onChange(newValue);
9875
- }
9876
- };
9877
- const handleDecrement = () => {
9878
- const newValue = value - step;
9879
- if (min === void 0 || newValue >= min) {
9880
- onChange(newValue);
9881
- }
9882
- };
9883
- return /* @__PURE__ */ jsxRuntime.jsxs(
9884
- "div",
9885
- {
9886
- className: ui.clx(
9887
- "inline-flex rounded-md bg-ui-bg-field shadow-borders-base overflow-hidden divide-x transition-fg",
9888
- "[&:has(input:focus)]:shadow-borders-interactive-with-active",
9889
- {
9890
- "h-7": size === "small",
9891
- "h-8": size === "base"
9892
- },
9893
- className
9894
- ),
9895
- children: [
9896
- /* @__PURE__ */ jsxRuntime.jsx(
9897
- "input",
9898
- {
9899
- ref,
9900
- type: "number",
9901
- value,
9902
- onChange: handleChange,
9903
- min,
9904
- max,
9905
- step,
9906
- className: ui.clx(
9907
- "flex-1 px-2 py-1 bg-transparent txt-compact-small text-ui-fg-base outline-none [appearance:textfield]",
9908
- "[&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none",
9909
- "placeholder:text-ui-fg-muted"
9910
- ),
9911
- ...props
9912
- }
9913
- ),
9914
- /* @__PURE__ */ jsxRuntime.jsxs(
9915
- "button",
9916
- {
9917
- className: ui.clx(
9918
- "flex items-center justify-center outline-none transition-fg",
9919
- "disabled:cursor-not-allowed disabled:text-ui-fg-muted",
9920
- "focus:bg-ui-bg-field-component-hover",
9921
- "hover:bg-ui-bg-field-component-hover",
9922
- {
9923
- "size-7": size === "small",
9924
- "size-8": size === "base"
9925
- }
9926
- ),
9927
- type: "button",
9928
- onClick: handleDecrement,
9929
- disabled: min !== void 0 && value <= min || disabled,
9930
- children: [
9931
- /* @__PURE__ */ jsxRuntime.jsx(icons.Minus, {}),
9932
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: `Decrease by ${step}` })
9933
- ]
9934
- }
9935
- ),
9936
- /* @__PURE__ */ jsxRuntime.jsxs(
9937
- "button",
9938
- {
9939
- className: ui.clx(
9940
- "flex items-center justify-center outline-none transition-fg",
9941
- "disabled:cursor-not-allowed disabled:text-ui-fg-muted",
9942
- "focus:bg-ui-bg-field-hover",
9943
- "hover:bg-ui-bg-field-hover",
9944
- {
9945
- "size-7": size === "small",
9946
- "size-8": size === "base"
9947
- }
9948
- ),
9949
- type: "button",
9950
- onClick: handleIncrement,
9951
- disabled: max !== void 0 && value >= max || disabled,
9952
- children: [
9953
- /* @__PURE__ */ jsxRuntime.jsx(icons.Plus, {}),
9954
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: `Increase by ${step}` })
9955
- ]
9956
- }
9957
- )
9958
- ]
9959
- }
9960
- );
9961
- }
9962
- );
9963
- const PRODUCT_VARIANTS_QUERY_KEY = "product-variants";
9964
- const productVariantsQueryKeys = {
9965
- list: (query2) => [
9966
- PRODUCT_VARIANTS_QUERY_KEY,
9967
- query2 ? query2 : void 0
9968
- ]
9969
- };
9970
- const useProductVariants = (query2, options) => {
9971
- const { data, ...rest } = reactQuery.useQuery({
9972
- queryKey: productVariantsQueryKeys.list(query2),
9973
- queryFn: async () => await sdk.admin.productVariant.list(query2),
9974
- ...options
9975
- });
9976
- return { ...data, ...rest };
9977
- };
9978
- const useCancelOrderEdit = ({ preview }) => {
9979
- const { mutateAsync: cancelOrderEdit } = useDraftOrderCancelEdit(preview == null ? void 0 : preview.id);
9980
- const onCancel = React.useCallback(async () => {
9981
- if (!preview) {
9982
- return true;
9983
- }
9984
- let res = false;
9985
- await cancelOrderEdit(void 0, {
9986
- onError: (e) => {
9987
- ui.toast.error(e.message);
9988
- },
9989
- onSuccess: () => {
9990
- res = true;
9991
- }
9992
- });
9993
- return res;
9994
- }, [preview, cancelOrderEdit]);
9995
- return { onCancel };
9996
- };
9997
- let IS_REQUEST_RUNNING = false;
9998
- const useInitiateOrderEdit = ({
9999
- preview
10000
- }) => {
10001
- const navigate = reactRouterDom.useNavigate();
10002
- const { mutateAsync } = useDraftOrderBeginEdit(preview == null ? void 0 : preview.id);
10003
- React.useEffect(() => {
10004
- async function run() {
10005
- if (IS_REQUEST_RUNNING || !preview) {
10006
- return;
10007
- }
10008
- if (preview.order_change) {
10009
- return;
10010
- }
10011
- IS_REQUEST_RUNNING = true;
10012
- await mutateAsync(void 0, {
10013
- onError: (e) => {
10014
- ui.toast.error(e.message);
10015
- navigate(`/draft-orders/${preview.id}`, { replace: true });
10016
- return;
10017
- }
10018
- });
10019
- IS_REQUEST_RUNNING = false;
10020
- }
10021
- run();
10022
- }, [preview, navigate, mutateAsync]);
10023
- };
10024
- function convertNumber(value) {
10025
- return typeof value === "string" ? Number(value.replace(",", ".")) : value;
10026
- }
10027
- const STACKED_MODAL_ID = "items_stacked_modal";
10028
- const Items = () => {
10029
- const { id } = reactRouterDom.useParams();
10030
- const {
10031
- order: preview,
10032
- isPending: isPreviewPending,
10033
- isError: isPreviewError,
10034
- error: previewError
10035
- } = useOrderPreview(id, void 0, {
10036
- placeholderData: reactQuery.keepPreviousData
10037
- });
10038
- useInitiateOrderEdit({ preview });
10039
- const { draft_order, isPending, isError, error } = useDraftOrder(
10040
- id,
10041
- {
10042
- fields: "currency_code"
10043
- },
10044
- {
10045
- enabled: !!id
10046
- }
10047
- );
10048
- const { onCancel } = useCancelOrderEdit({ preview });
10049
- if (isError) {
10050
- throw error;
10051
- }
10052
- if (isPreviewError) {
10053
- throw previewError;
10054
- }
10055
- const ready = !!preview && !isPreviewPending && !!draft_order && !isPending;
10056
- return /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal, { onClose: onCancel, children: ready ? /* @__PURE__ */ jsxRuntime.jsx(ItemsForm, { preview, currencyCode: draft_order.currency_code }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10057
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Edit Items" }) }),
10058
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Loading data for the draft order, please wait..." }) })
10059
- ] }) });
10060
- };
10061
- const ItemsForm = ({ preview, currencyCode }) => {
10062
- var _a;
10063
- const [isSubmitting, setIsSubmitting] = React.useState(false);
10064
- const [modalContent, setModalContent] = React.useState(
10065
- null
10066
- );
10067
- const { handleSuccess } = useRouteModal();
10068
- const { searchValue, onSearchValueChange, query: query2 } = useDebouncedSearch();
10069
- const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
10070
- const { mutateAsync: requestOrderEdit } = useDraftOrderRequestEdit(preview.id);
10071
- const itemCount = ((_a = preview.items) == null ? void 0 : _a.reduce((acc, item) => acc + item.quantity, 0)) || 0;
10072
- const matches = React.useMemo(() => {
10073
- return matchSorter.matchSorter(preview.items, query2, {
10074
- keys: ["product_title", "variant_title", "variant_sku", "title"]
10075
- });
10076
- }, [preview.items, query2]);
10077
- const onSubmit = async () => {
10078
- setIsSubmitting(true);
10079
- let requestSucceeded = false;
10080
- await requestOrderEdit(void 0, {
10081
- onError: (e) => {
10082
- ui.toast.error(`Failed to request order edit: ${e.message}`);
10083
- },
10084
- onSuccess: () => {
10085
- requestSucceeded = true;
10086
- }
10087
- });
10088
- if (!requestSucceeded) {
10089
- setIsSubmitting(false);
10032
+ );
10090
10033
  return;
10091
10034
  }
10092
- await confirmOrderEdit(void 0, {
10093
- onError: (e) => {
10094
- ui.toast.error(`Failed to confirm order edit: ${e.message}`);
10095
- },
10096
- onSuccess: () => {
10097
- handleSuccess();
10035
+ await updateActionItem(
10036
+ {
10037
+ action_id: actionId,
10038
+ quantity: data.quantity,
10039
+ unit_price: convertNumber(data.unit_price)
10098
10040
  },
10099
- onSettled: () => {
10100
- setIsSubmitting(false);
10041
+ {
10042
+ onSuccess: () => {
10043
+ setEditing(false);
10044
+ },
10045
+ onError: (e) => {
10046
+ ui.toast.error(e.message);
10047
+ }
10101
10048
  }
10102
- });
10103
- };
10104
- const onKeyDown = React.useCallback(
10105
- (e) => {
10106
- if (e.key === "Enter" && (e.ctrlKey || e.metaKey)) {
10107
- if (modalContent || isSubmitting) {
10108
- return;
10049
+ );
10050
+ });
10051
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2, { ...form, children: /* @__PURE__ */ jsxRuntime.jsx("form", { onSubmit, children: /* @__PURE__ */ jsxRuntime.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: [
10052
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full items-center gap-x-3", children: [
10053
+ /* @__PURE__ */ jsxRuntime.jsx(
10054
+ Thumbnail,
10055
+ {
10056
+ thumbnail: item.thumbnail,
10057
+ alt: item.product_title ?? void 0
10058
+ }
10059
+ ),
10060
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
10061
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-1", children: [
10062
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: item.product_title }),
10063
+ /* @__PURE__ */ jsxRuntime.jsxs(
10064
+ ui.Text,
10065
+ {
10066
+ size: "small",
10067
+ leading: "compact",
10068
+ className: "text-ui-fg-subtle",
10069
+ children: [
10070
+ "(",
10071
+ item.variant_title,
10072
+ ")"
10073
+ ]
10074
+ }
10075
+ )
10076
+ ] }),
10077
+ /* @__PURE__ */ jsxRuntime.jsx(
10078
+ ui.Text,
10079
+ {
10080
+ size: "small",
10081
+ leading: "compact",
10082
+ className: "text-ui-fg-subtle",
10083
+ children: item.variant_sku
10084
+ }
10085
+ )
10086
+ ] })
10087
+ ] }),
10088
+ editing ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(
10089
+ Form$2.Field,
10090
+ {
10091
+ control: form.control,
10092
+ name: "quantity",
10093
+ render: ({ field }) => {
10094
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(NumberInput, { ...field }) }) });
10109
10095
  }
10110
- onSubmit();
10111
10096
  }
10112
- },
10113
- [modalContent, isSubmitting, onSubmit]
10114
- );
10115
- React.useEffect(() => {
10116
- document.addEventListener("keydown", onKeyDown);
10117
- return () => {
10118
- document.removeEventListener("keydown", onKeyDown);
10119
- };
10120
- }, [onKeyDown]);
10121
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-full flex-col overflow-hidden", children: [
10122
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Header, {}),
10123
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Body, { className: "flex flex-1 flex-col overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsxs(
10124
- StackedFocusModal,
10097
+ ) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: item.quantity }) }),
10098
+ editing ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(
10099
+ Form$2.Field,
10125
10100
  {
10126
- id: STACKED_MODAL_ID,
10127
- onOpenChangeCallback: (open) => {
10128
- if (!open) {
10129
- setModalContent(null);
10130
- }
10131
- },
10132
- children: [
10133
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-1 flex-col items-center overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full max-w-[720px] flex-col gap-y-6 px-6 py-16", children: [
10134
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10135
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Items" }) }),
10136
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Edit the items in the draft order" }) })
10137
- ] }),
10138
- /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
10139
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-6", children: [
10140
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 items-center gap-3", children: [
10141
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
10142
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "Items" }),
10143
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Choose items from the product catalog." })
10144
- ] }),
10145
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
10146
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(
10147
- ui.Input,
10148
- {
10149
- type: "search",
10150
- placeholder: "Search items",
10151
- value: searchValue,
10152
- onChange: (e) => onSearchValueChange(e.target.value)
10153
- }
10154
- ) }),
10155
- /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu, { children: [
10156
- /* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenu.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { type: "button", children: /* @__PURE__ */ jsxRuntime.jsx(icons.Plus, {}) }) }),
10157
- /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu.Content, { children: [
10158
- /* @__PURE__ */ jsxRuntime.jsx(
10159
- StackedModalTrigger$1,
10160
- {
10161
- type: "add-items",
10162
- setModalContent
10163
- }
10164
- ),
10165
- /* @__PURE__ */ jsxRuntime.jsx(
10166
- StackedModalTrigger$1,
10167
- {
10168
- type: "add-custom-item",
10169
- setModalContent
10170
- }
10171
- )
10172
- ] })
10173
- ] })
10174
- ] })
10175
- ] }),
10176
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-subtle shadow-elevation-card-rest rounded-xl", children: [
10177
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-[5px]", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-ui-fg-muted grid grid-cols-[2fr_1fr_2fr_28px] gap-3 px-4 py-2", children: [
10178
- /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: "Item" }) }),
10179
- /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: "Quantity" }) }),
10180
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-right", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: "Price" }) }),
10181
- /* @__PURE__ */ jsxRuntime.jsx("div", {})
10182
- ] }) }),
10183
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-y-1.5 px-[5px] pb-[5px]", children: itemCount <= 0 ? /* @__PURE__ */ jsxRuntime.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: [
10184
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "There are no items in this order" }),
10185
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Add items to the order to get started." })
10186
- ] }) : matches.length > 0 ? matches == null ? void 0 : matches.map((item) => /* @__PURE__ */ jsxRuntime.jsx(
10187
- Item,
10188
- {
10189
- item,
10190
- preview,
10191
- currencyCode
10192
- },
10193
- item.id
10194
- )) : /* @__PURE__ */ jsxRuntime.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: [
10195
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "No items found" }),
10196
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: [
10197
- 'No items found for "',
10198
- query2,
10199
- '".'
10200
- ] })
10201
- ] }) })
10202
- ] })
10203
- ] }),
10204
- /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
10205
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-[1fr_0.5fr_0.5fr] gap-3", children: [
10206
- /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "Subtotal" }) }),
10207
- /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsxs(
10208
- ui.Text,
10209
- {
10210
- size: "small",
10211
- leading: "compact",
10212
- className: "text-ui-fg-subtle",
10213
- children: [
10214
- itemCount,
10215
- " ",
10216
- itemCount === 1 ? "item" : "items"
10217
- ]
10218
- }
10219
- ) }),
10220
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-right", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: getStylizedAmount(preview.item_subtotal, currencyCode) }) })
10221
- ] })
10222
- ] }) }),
10223
- modalContent && (modalContent === "add-items" ? /* @__PURE__ */ jsxRuntime.jsx(ExistingItemsForm, { orderId: preview.id, items: preview.items }) : modalContent === "add-custom-item" ? /* @__PURE__ */ jsxRuntime.jsx(
10224
- CustomItemForm,
10101
+ control: form.control,
10102
+ name: "unit_price",
10103
+ render: ({ field: { onChange, ...field } }) => {
10104
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
10105
+ ui.CurrencyInput,
10225
10106
  {
10226
- orderId: preview.id,
10227
- currencyCode
10107
+ ...field,
10108
+ symbol: getNativeSymbol(currencyCode),
10109
+ code: currencyCode,
10110
+ onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value)
10228
10111
  }
10229
- ) : null)
10230
- ]
10231
- }
10232
- ) }),
10233
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
10234
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
10235
- /* @__PURE__ */ jsxRuntime.jsx(
10236
- ui.Button,
10237
- {
10238
- size: "small",
10239
- type: "button",
10240
- onClick: onSubmit,
10241
- isLoading: isSubmitting,
10242
- children: "Save"
10112
+ ) }) });
10243
10113
  }
10244
- )
10245
- ] }) })
10246
- ] });
10247
- };
10248
- const Item = ({ item, preview, currencyCode }) => {
10249
- if (item.variant_id) {
10250
- return /* @__PURE__ */ jsxRuntime.jsx(VariantItem, { item, preview, currencyCode });
10251
- }
10252
- return /* @__PURE__ */ jsxRuntime.jsx(CustomItem, { item, preview, currencyCode });
10114
+ }
10115
+ ) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex w-full flex-1 items-center justify-end", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: getLocaleAmount(item.unit_price, currencyCode) }) }),
10116
+ /* @__PURE__ */ jsxRuntime.jsx(
10117
+ ui.IconButton,
10118
+ {
10119
+ type: "button",
10120
+ size: "small",
10121
+ onClick: editing ? onSubmit : () => {
10122
+ setEditing(true);
10123
+ },
10124
+ disabled: isPending,
10125
+ children: editing ? /* @__PURE__ */ jsxRuntime.jsx(icons.Check, {}) : /* @__PURE__ */ jsxRuntime.jsx(icons.PencilSquare, {})
10126
+ }
10127
+ )
10128
+ ] }) }) });
10253
10129
  };
10254
- const VariantItem = ({ item, preview, currencyCode }) => {
10130
+ const variantItemSchema = objectType({
10131
+ quantity: numberType(),
10132
+ unit_price: unionType([numberType(), stringType()])
10133
+ });
10134
+ const CustomItem = ({ item, preview, currencyCode }) => {
10255
10135
  const [editing, setEditing] = React.useState(false);
10136
+ const { quantity, unit_price, title } = item;
10256
10137
  const form = reactHookForm.useForm({
10257
10138
  defaultValues: {
10258
- quantity: item.quantity,
10259
- unit_price: item.unit_price
10139
+ title,
10140
+ quantity,
10141
+ unit_price
10260
10142
  },
10261
- resolver: zod.zodResolver(variantItemSchema)
10143
+ resolver: zod.zodResolver(customItemSchema)
10262
10144
  });
10145
+ React.useEffect(() => {
10146
+ form.reset({
10147
+ title,
10148
+ quantity,
10149
+ unit_price
10150
+ });
10151
+ }, [form, title, quantity, unit_price]);
10263
10152
  const actionId = React.useMemo(() => {
10264
10153
  var _a, _b;
10265
10154
  return (_b = (_a = item.actions) == null ? void 0 : _a.find((a) => a.action === "ITEM_ADD")) == null ? void 0 : _b.id;
10266
10155
  }, [item]);
10267
10156
  const { mutateAsync: updateActionItem, isPending: isUpdatingActionItem } = useDraftOrderUpdateActionItem(preview.id);
10157
+ const { mutateAsync: removeActionItem, isPending: isRemovingActionItem } = useDraftOrderRemoveActionItem(preview.id);
10268
10158
  const { mutateAsync: updateOriginalItem, isPending: isUpdatingOriginalItem } = useDraftOrderUpdateItem(preview.id);
10269
10159
  const isPending = isUpdatingActionItem || isUpdatingOriginalItem;
10270
10160
  const onSubmit = form.handleSubmit(async (data) => {
10271
- if (convertNumber(data.unit_price) === item.unit_price && data.quantity === item.quantity) {
10161
+ if (convertNumber(data.unit_price) === item.unit_price && data.quantity === item.quantity && data.title === item.title) {
10272
10162
  setEditing(false);
10273
10163
  return;
10274
10164
  }
@@ -10290,6 +10180,17 @@ const VariantItem = ({ item, preview, currencyCode }) => {
10290
10180
  );
10291
10181
  return;
10292
10182
  }
10183
+ if (data.quantity === 0) {
10184
+ await removeActionItem(actionId, {
10185
+ onSuccess: () => {
10186
+ setEditing(false);
10187
+ },
10188
+ onError: (e) => {
10189
+ ui.toast.error(e.message);
10190
+ }
10191
+ });
10192
+ return;
10193
+ }
10293
10194
  await updateActionItem(
10294
10195
  {
10295
10196
  action_id: actionId,
@@ -10307,43 +10208,26 @@ const VariantItem = ({ item, preview, currencyCode }) => {
10307
10208
  );
10308
10209
  });
10309
10210
  return /* @__PURE__ */ jsxRuntime.jsx(Form$2, { ...form, children: /* @__PURE__ */ jsxRuntime.jsx("form", { onSubmit, children: /* @__PURE__ */ jsxRuntime.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: [
10310
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full items-center gap-x-3", children: [
10211
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-3", children: [
10311
10212
  /* @__PURE__ */ jsxRuntime.jsx(
10312
10213
  Thumbnail,
10313
10214
  {
10314
10215
  thumbnail: item.thumbnail,
10315
- alt: item.product_title ?? void 0
10216
+ alt: item.title ?? void 0
10316
10217
  }
10317
10218
  ),
10318
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
10319
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-1", children: [
10320
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: item.product_title }),
10321
- /* @__PURE__ */ jsxRuntime.jsxs(
10322
- ui.Text,
10323
- {
10324
- size: "small",
10325
- leading: "compact",
10326
- className: "text-ui-fg-subtle",
10327
- children: [
10328
- "(",
10329
- item.variant_title,
10330
- ")"
10331
- ]
10332
- }
10333
- )
10334
- ] }),
10335
- /* @__PURE__ */ jsxRuntime.jsx(
10336
- ui.Text,
10337
- {
10338
- size: "small",
10339
- leading: "compact",
10340
- className: "text-ui-fg-subtle",
10341
- children: item.variant_sku
10219
+ editing ? /* @__PURE__ */ jsxRuntime.jsx(
10220
+ Form$2.Field,
10221
+ {
10222
+ control: form.control,
10223
+ name: "title",
10224
+ render: ({ field }) => {
10225
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }) });
10342
10226
  }
10343
- )
10344
- ] })
10227
+ }
10228
+ ) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: item.title })
10345
10229
  ] }),
10346
- editing ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(
10230
+ editing ? /* @__PURE__ */ jsxRuntime.jsx(
10347
10231
  Form$2.Field,
10348
10232
  {
10349
10233
  control: form.control,
@@ -10352,8 +10236,8 @@ const VariantItem = ({ item, preview, currencyCode }) => {
10352
10236
  return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(NumberInput, { ...field }) }) });
10353
10237
  }
10354
10238
  }
10355
- ) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: item.quantity }) }),
10356
- editing ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(
10239
+ ) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: item.quantity }),
10240
+ editing ? /* @__PURE__ */ jsxRuntime.jsx(
10357
10241
  Form$2.Field,
10358
10242
  {
10359
10243
  control: form.control,
@@ -10362,102 +10246,238 @@ const VariantItem = ({ item, preview, currencyCode }) => {
10362
10246
  return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
10363
10247
  ui.CurrencyInput,
10364
10248
  {
10365
- ...field,
10366
- symbol: getNativeSymbol(currencyCode),
10367
- code: currencyCode,
10368
- onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value)
10249
+ ...field,
10250
+ symbol: getNativeSymbol(currencyCode),
10251
+ code: currencyCode,
10252
+ onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value)
10253
+ }
10254
+ ) }) });
10255
+ }
10256
+ }
10257
+ ) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-1 items-center justify-end", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: getLocaleAmount(item.unit_price, currencyCode) }) }),
10258
+ /* @__PURE__ */ jsxRuntime.jsx(
10259
+ ui.IconButton,
10260
+ {
10261
+ type: "button",
10262
+ size: "small",
10263
+ onClick: editing ? onSubmit : () => {
10264
+ setEditing(true);
10265
+ },
10266
+ disabled: isPending,
10267
+ children: editing ? /* @__PURE__ */ jsxRuntime.jsx(icons.Check, {}) : /* @__PURE__ */ jsxRuntime.jsx(icons.PencilSquare, {})
10268
+ }
10269
+ )
10270
+ ] }) }) });
10271
+ };
10272
+ const StackedModalTrigger$1 = ({
10273
+ type,
10274
+ setModalContent
10275
+ }) => {
10276
+ const { setIsOpen } = useStackedModal();
10277
+ const onClick = React.useCallback(() => {
10278
+ setModalContent(type);
10279
+ setIsOpen(STACKED_MODAL_ID, true);
10280
+ }, [setModalContent, setIsOpen, type]);
10281
+ return /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenu.Item, { onClick, children: type === "add-items" ? "Add items" : "Add custom item" }) });
10282
+ };
10283
+ const VARIANT_PREFIX = "items";
10284
+ const LIMIT = 50;
10285
+ const ExistingItemsForm = ({ orderId, items }) => {
10286
+ const { setIsOpen } = useStackedModal();
10287
+ const [rowSelection, setRowSelection] = React.useState(
10288
+ items.reduce((acc, item) => {
10289
+ acc[item.variant_id] = true;
10290
+ return acc;
10291
+ }, {})
10292
+ );
10293
+ React.useEffect(() => {
10294
+ setRowSelection(
10295
+ items.reduce((acc, item) => {
10296
+ if (item.variant_id) {
10297
+ acc[item.variant_id] = true;
10298
+ }
10299
+ return acc;
10300
+ }, {})
10301
+ );
10302
+ }, [items]);
10303
+ const { q, order, offset } = useQueryParams(
10304
+ ["q", "order", "offset"],
10305
+ VARIANT_PREFIX
10306
+ );
10307
+ const { variants, count, isPending, isError, error } = useProductVariants(
10308
+ {
10309
+ q,
10310
+ order,
10311
+ offset: offset ? parseInt(offset) : void 0,
10312
+ limit: LIMIT
10313
+ },
10314
+ {
10315
+ placeholderData: reactQuery.keepPreviousData
10316
+ }
10317
+ );
10318
+ const columns = useColumns();
10319
+ const { mutateAsync } = useDraftOrderAddItems(orderId);
10320
+ const onSubmit = async () => {
10321
+ const ids = Object.keys(rowSelection).filter(
10322
+ (id) => !items.find((i) => i.variant_id === id)
10323
+ );
10324
+ await mutateAsync(
10325
+ {
10326
+ items: ids.map((id) => ({
10327
+ variant_id: id,
10328
+ quantity: 1
10329
+ }))
10330
+ },
10331
+ {
10332
+ onSuccess: () => {
10333
+ setRowSelection({});
10334
+ setIsOpen(STACKED_MODAL_ID, false);
10335
+ },
10336
+ onError: (e) => {
10337
+ ui.toast.error(e.message);
10338
+ }
10339
+ }
10340
+ );
10341
+ };
10342
+ if (isError) {
10343
+ throw error;
10344
+ }
10345
+ return /* @__PURE__ */ jsxRuntime.jsxs(
10346
+ StackedFocusModal.Content,
10347
+ {
10348
+ onOpenAutoFocus: (e) => {
10349
+ e.preventDefault();
10350
+ const searchInput = document.querySelector(
10351
+ "[data-modal-id='modal-search-input']"
10352
+ );
10353
+ if (searchInput) {
10354
+ searchInput.focus();
10355
+ }
10356
+ },
10357
+ children: [
10358
+ /* @__PURE__ */ jsxRuntime.jsxs(StackedFocusModal.Header, { children: [
10359
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Product Variants" }) }),
10360
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Choose product variants to add to the order." }) })
10361
+ ] }),
10362
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Body, { className: "flex-1 overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(
10363
+ DataTable,
10364
+ {
10365
+ data: variants,
10366
+ columns,
10367
+ isLoading: isPending,
10368
+ getRowId: (row) => row.id,
10369
+ rowCount: count,
10370
+ prefix: VARIANT_PREFIX,
10371
+ layout: "fill",
10372
+ rowSelection: {
10373
+ state: rowSelection,
10374
+ onRowSelectionChange: setRowSelection,
10375
+ enableRowSelection: (row) => {
10376
+ return !items.find((i) => i.variant_id === row.original.id);
10377
+ }
10378
+ },
10379
+ autoFocusSearch: true
10380
+ }
10381
+ ) }),
10382
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
10383
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
10384
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "button", onClick: onSubmit, children: "Update items" })
10385
+ ] }) })
10386
+ ]
10387
+ }
10388
+ );
10389
+ };
10390
+ const columnHelper = ui.createDataTableColumnHelper();
10391
+ const useColumns = () => {
10392
+ return React.useMemo(() => {
10393
+ return [
10394
+ columnHelper.select(),
10395
+ columnHelper.accessor("product.title", {
10396
+ header: "Product",
10397
+ cell: ({ row }) => {
10398
+ var _a, _b, _c;
10399
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-2", children: [
10400
+ /* @__PURE__ */ jsxRuntime.jsx(
10401
+ Thumbnail,
10402
+ {
10403
+ thumbnail: (_a = row.original.product) == null ? void 0 : _a.thumbnail,
10404
+ alt: (_b = row.original.product) == null ? void 0 : _b.title
10405
+ }
10406
+ ),
10407
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: (_c = row.original.product) == null ? void 0 : _c.title })
10408
+ ] });
10409
+ },
10410
+ enableSorting: true
10411
+ }),
10412
+ columnHelper.accessor("title", {
10413
+ header: "Variant",
10414
+ enableSorting: true
10415
+ }),
10416
+ columnHelper.accessor("sku", {
10417
+ header: "SKU",
10418
+ cell: ({ getValue }) => {
10419
+ return getValue() ?? "-";
10420
+ },
10421
+ enableSorting: true
10422
+ }),
10423
+ columnHelper.accessor("updated_at", {
10424
+ header: "Updated",
10425
+ cell: ({ getValue }) => {
10426
+ return /* @__PURE__ */ jsxRuntime.jsx(
10427
+ ui.Tooltip,
10428
+ {
10429
+ content: getFullDate({ date: getValue(), includeTime: true }),
10430
+ children: /* @__PURE__ */ jsxRuntime.jsx("span", { children: getFullDate({ date: getValue() }) })
10431
+ }
10432
+ );
10433
+ },
10434
+ enableSorting: true,
10435
+ sortAscLabel: "Oldest first",
10436
+ sortDescLabel: "Newest first"
10437
+ }),
10438
+ columnHelper.accessor("created_at", {
10439
+ header: "Created",
10440
+ cell: ({ getValue }) => {
10441
+ return /* @__PURE__ */ jsxRuntime.jsx(
10442
+ ui.Tooltip,
10443
+ {
10444
+ content: getFullDate({ date: getValue(), includeTime: true }),
10445
+ children: /* @__PURE__ */ jsxRuntime.jsx("span", { children: getFullDate({ date: getValue() }) })
10369
10446
  }
10370
- ) }) });
10371
- }
10372
- }
10373
- ) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex w-full flex-1 items-center justify-end", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: getLocaleAmount(item.unit_price, currencyCode) }) }),
10374
- /* @__PURE__ */ jsxRuntime.jsx(
10375
- ui.IconButton,
10376
- {
10377
- type: "button",
10378
- size: "small",
10379
- onClick: editing ? onSubmit : () => {
10380
- setEditing(true);
10447
+ );
10381
10448
  },
10382
- disabled: isPending,
10383
- children: editing ? /* @__PURE__ */ jsxRuntime.jsx(icons.Check, {}) : /* @__PURE__ */ jsxRuntime.jsx(icons.PencilSquare, {})
10384
- }
10385
- )
10386
- ] }) }) });
10449
+ enableSorting: true,
10450
+ sortAscLabel: "Oldest first",
10451
+ sortDescLabel: "Newest first"
10452
+ })
10453
+ ];
10454
+ }, []);
10387
10455
  };
10388
- const variantItemSchema = objectType({
10389
- quantity: numberType(),
10390
- unit_price: unionType([numberType(), stringType()])
10391
- });
10392
- const CustomItem = ({ item, preview, currencyCode }) => {
10393
- const [editing, setEditing] = React.useState(false);
10394
- const { quantity, unit_price, title } = item;
10456
+ const CustomItemForm = ({ orderId, currencyCode }) => {
10457
+ const { setIsOpen } = useStackedModal();
10458
+ const { mutateAsync: addItems } = useDraftOrderAddItems(orderId);
10395
10459
  const form = reactHookForm.useForm({
10396
10460
  defaultValues: {
10397
- title,
10398
- quantity,
10399
- unit_price
10461
+ title: "",
10462
+ quantity: 1,
10463
+ unit_price: ""
10400
10464
  },
10401
10465
  resolver: zod.zodResolver(customItemSchema)
10402
10466
  });
10403
- React.useEffect(() => {
10404
- form.reset({
10405
- title,
10406
- quantity,
10407
- unit_price
10408
- });
10409
- }, [form, title, quantity, unit_price]);
10410
- const actionId = React.useMemo(() => {
10411
- var _a, _b;
10412
- return (_b = (_a = item.actions) == null ? void 0 : _a.find((a) => a.action === "ITEM_ADD")) == null ? void 0 : _b.id;
10413
- }, [item]);
10414
- const { mutateAsync: updateActionItem, isPending: isUpdatingActionItem } = useDraftOrderUpdateActionItem(preview.id);
10415
- const { mutateAsync: removeActionItem, isPending: isRemovingActionItem } = useDraftOrderRemoveActionItem(preview.id);
10416
- const { mutateAsync: updateOriginalItem, isPending: isUpdatingOriginalItem } = useDraftOrderUpdateItem(preview.id);
10417
- const isPending = isUpdatingActionItem || isUpdatingOriginalItem;
10418
10467
  const onSubmit = form.handleSubmit(async (data) => {
10419
- if (convertNumber(data.unit_price) === item.unit_price && data.quantity === item.quantity && data.title === item.title) {
10420
- setEditing(false);
10421
- return;
10422
- }
10423
- if (!actionId) {
10424
- await updateOriginalItem(
10425
- {
10426
- item_id: item.id,
10427
- quantity: data.quantity,
10428
- unit_price: convertNumber(data.unit_price)
10429
- },
10430
- {
10431
- onSuccess: () => {
10432
- setEditing(false);
10433
- },
10434
- onError: (e) => {
10435
- ui.toast.error(e.message);
10436
- }
10437
- }
10438
- );
10439
- return;
10440
- }
10441
- if (data.quantity === 0) {
10442
- await removeActionItem(actionId, {
10443
- onSuccess: () => {
10444
- setEditing(false);
10445
- },
10446
- onError: (e) => {
10447
- ui.toast.error(e.message);
10448
- }
10449
- });
10450
- return;
10451
- }
10452
- await updateActionItem(
10468
+ await addItems(
10453
10469
  {
10454
- action_id: actionId,
10455
- quantity: data.quantity,
10456
- unit_price: convertNumber(data.unit_price)
10470
+ items: [
10471
+ {
10472
+ title: data.title,
10473
+ quantity: data.quantity,
10474
+ unit_price: convertNumber(data.unit_price)
10475
+ }
10476
+ ]
10457
10477
  },
10458
10478
  {
10459
10479
  onSuccess: () => {
10460
- setEditing(false);
10480
+ setIsOpen(STACKED_MODAL_ID, false);
10461
10481
  },
10462
10482
  onError: (e) => {
10463
10483
  ui.toast.error(e.message);
@@ -10465,365 +10485,437 @@ const CustomItem = ({ item, preview, currencyCode }) => {
10465
10485
  }
10466
10486
  );
10467
10487
  });
10468
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2, { ...form, children: /* @__PURE__ */ jsxRuntime.jsx("form", { onSubmit, children: /* @__PURE__ */ jsxRuntime.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: [
10469
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-3", children: [
10488
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2, { ...form, children: /* @__PURE__ */ jsxRuntime.jsx(KeyboundForm, { onSubmit, children: /* @__PURE__ */ jsxRuntime.jsxs(StackedFocusModal.Content, { children: [
10489
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Header, {}),
10490
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Body, { className: "flex flex-1 flex-col overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-1 flex-col items-center overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full max-w-[720px] flex-col gap-y-6 px-2 py-16", children: [
10491
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10492
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Add custom item" }) }),
10493
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.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." }) })
10494
+ ] }),
10495
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
10470
10496
  /* @__PURE__ */ jsxRuntime.jsx(
10471
- Thumbnail,
10497
+ Form$2.Field,
10472
10498
  {
10473
- thumbnail: item.thumbnail,
10474
- alt: item.title ?? void 0
10499
+ control: form.control,
10500
+ name: "title",
10501
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
10502
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10503
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Title" }),
10504
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Enter the title of the item" })
10505
+ ] }),
10506
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10507
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
10508
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
10509
+ ] })
10510
+ ] }) })
10475
10511
  }
10476
10512
  ),
10477
- editing ? /* @__PURE__ */ jsxRuntime.jsx(
10513
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
10514
+ /* @__PURE__ */ jsxRuntime.jsx(
10478
10515
  Form$2.Field,
10479
10516
  {
10480
10517
  control: form.control,
10481
- name: "title",
10482
- render: ({ field }) => {
10483
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }) });
10484
- }
10518
+ name: "unit_price",
10519
+ render: ({ field: { onChange, ...field } }) => /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
10520
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10521
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Unit price" }),
10522
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Enter the unit price of the item" })
10523
+ ] }),
10524
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10525
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
10526
+ ui.CurrencyInput,
10527
+ {
10528
+ symbol: getNativeSymbol(currencyCode),
10529
+ code: currencyCode,
10530
+ onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value),
10531
+ ...field
10532
+ }
10533
+ ) }),
10534
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
10535
+ ] })
10536
+ ] }) })
10485
10537
  }
10486
- ) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: item.title })
10487
- ] }),
10488
- editing ? /* @__PURE__ */ jsxRuntime.jsx(
10489
- Form$2.Field,
10490
- {
10491
- control: form.control,
10492
- name: "quantity",
10493
- render: ({ field }) => {
10494
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(NumberInput, { ...field }) }) });
10538
+ ),
10539
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
10540
+ /* @__PURE__ */ jsxRuntime.jsx(
10541
+ Form$2.Field,
10542
+ {
10543
+ control: form.control,
10544
+ name: "quantity",
10545
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
10546
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10547
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Quantity" }),
10548
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Enter the quantity of the item" })
10549
+ ] }),
10550
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full flex-1", children: [
10551
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(NumberInput, { ...field, className: "w-full" }) }) }),
10552
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
10553
+ ] })
10554
+ ] }) })
10495
10555
  }
10496
- }
10497
- ) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: item.quantity }),
10498
- editing ? /* @__PURE__ */ jsxRuntime.jsx(
10499
- Form$2.Field,
10556
+ )
10557
+ ] }) }) }),
10558
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
10559
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
10560
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "button", onClick: onSubmit, children: "Add item" })
10561
+ ] }) })
10562
+ ] }) }) });
10563
+ };
10564
+ const customItemSchema = objectType({
10565
+ title: stringType().min(1),
10566
+ quantity: numberType(),
10567
+ unit_price: unionType([numberType(), stringType()])
10568
+ });
10569
+ const InlineTip = React.forwardRef(
10570
+ ({ variant = "tip", label, className, children, ...props }, ref) => {
10571
+ const labelValue = label || (variant === "warning" ? "Warning" : "Tip");
10572
+ return /* @__PURE__ */ jsxRuntime.jsxs(
10573
+ "div",
10500
10574
  {
10501
- control: form.control,
10502
- name: "unit_price",
10503
- render: ({ field: { onChange, ...field } }) => {
10504
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
10505
- ui.CurrencyInput,
10575
+ ref,
10576
+ className: ui.clx(
10577
+ "bg-ui-bg-component txt-small text-ui-fg-subtle grid grid-cols-[4px_1fr] items-start gap-3 rounded-lg border p-3",
10578
+ className
10579
+ ),
10580
+ ...props,
10581
+ children: [
10582
+ /* @__PURE__ */ jsxRuntime.jsx(
10583
+ "div",
10506
10584
  {
10507
- ...field,
10508
- symbol: getNativeSymbol(currencyCode),
10509
- code: currencyCode,
10510
- onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value)
10585
+ role: "presentation",
10586
+ className: ui.clx("w-4px bg-ui-tag-neutral-icon h-full rounded-full", {
10587
+ "bg-ui-tag-orange-icon": variant === "warning"
10588
+ })
10511
10589
  }
10512
- ) }) });
10513
- }
10514
- }
10515
- ) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-1 items-center justify-end", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: getLocaleAmount(item.unit_price, currencyCode) }) }),
10516
- /* @__PURE__ */ jsxRuntime.jsx(
10517
- ui.IconButton,
10518
- {
10519
- type: "button",
10520
- size: "small",
10521
- onClick: editing ? onSubmit : () => {
10522
- setEditing(true);
10523
- },
10524
- disabled: isPending,
10525
- children: editing ? /* @__PURE__ */ jsxRuntime.jsx(icons.Check, {}) : /* @__PURE__ */ jsxRuntime.jsx(icons.PencilSquare, {})
10590
+ ),
10591
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-pretty", children: [
10592
+ /* @__PURE__ */ jsxRuntime.jsxs("strong", { className: "txt-small-plus text-ui-fg-base", children: [
10593
+ labelValue,
10594
+ ":"
10595
+ ] }),
10596
+ " ",
10597
+ children
10598
+ ] })
10599
+ ]
10526
10600
  }
10527
- )
10528
- ] }) }) });
10529
- };
10530
- const StackedModalTrigger$1 = ({
10531
- type,
10532
- setModalContent
10533
- }) => {
10534
- const { setIsOpen } = useStackedModal();
10535
- const onClick = React.useCallback(() => {
10536
- setModalContent(type);
10537
- setIsOpen(STACKED_MODAL_ID, true);
10538
- }, [setModalContent, setIsOpen, type]);
10539
- return /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenu.Item, { onClick, children: type === "add-items" ? "Add items" : "Add custom item" }) });
10540
- };
10541
- const VARIANT_PREFIX = "items";
10542
- const LIMIT = 50;
10543
- const ExistingItemsForm = ({ orderId, items }) => {
10544
- const { setIsOpen } = useStackedModal();
10545
- const [rowSelection, setRowSelection] = React.useState(
10546
- items.reduce((acc, item) => {
10547
- acc[item.variant_id] = true;
10548
- return acc;
10549
- }, {})
10550
- );
10551
- React.useEffect(() => {
10552
- setRowSelection(
10553
- items.reduce((acc, item) => {
10554
- if (item.variant_id) {
10555
- acc[item.variant_id] = true;
10556
- }
10557
- return acc;
10558
- }, {})
10559
10601
  );
10560
- }, [items]);
10561
- const { q, order, offset } = useQueryParams(
10562
- ["q", "order", "offset"],
10563
- VARIANT_PREFIX
10564
- );
10565
- const { variants, count, isPending, isError, error } = useProductVariants(
10566
- {
10567
- q,
10568
- order,
10569
- offset: offset ? parseInt(offset) : void 0,
10570
- limit: LIMIT
10602
+ }
10603
+ );
10604
+ InlineTip.displayName = "InlineTip";
10605
+ const MetadataFieldSchema = objectType({
10606
+ key: stringType(),
10607
+ disabled: booleanType().optional(),
10608
+ value: anyType()
10609
+ });
10610
+ const MetadataSchema = objectType({
10611
+ metadata: arrayType(MetadataFieldSchema)
10612
+ });
10613
+ const Metadata = () => {
10614
+ const { id } = reactRouterDom.useParams();
10615
+ const { order, isPending, isError, error } = useOrder(id, {
10616
+ fields: "metadata"
10617
+ });
10618
+ if (isError) {
10619
+ throw error;
10620
+ }
10621
+ const isReady = !isPending && !!order;
10622
+ return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
10623
+ /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Header, { children: [
10624
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Metadata" }) }),
10625
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Add metadata to the draft order." }) })
10626
+ ] }),
10627
+ !isReady ? /* @__PURE__ */ jsxRuntime.jsx(PlaceholderInner, {}) : /* @__PURE__ */ jsxRuntime.jsx(MetadataForm, { orderId: id, metadata: order == null ? void 0 : order.metadata })
10628
+ ] });
10629
+ };
10630
+ const METADATA_KEY_LABEL_ID = "metadata-form-key-label";
10631
+ const METADATA_VALUE_LABEL_ID = "metadata-form-value-label";
10632
+ const MetadataForm = ({ orderId, metadata }) => {
10633
+ const { handleSuccess } = useRouteModal();
10634
+ const hasUneditableRows = getHasUneditableRows(metadata);
10635
+ const { mutateAsync, isPending } = useUpdateDraftOrder(orderId);
10636
+ const form = reactHookForm.useForm({
10637
+ defaultValues: {
10638
+ metadata: getDefaultValues(metadata)
10571
10639
  },
10572
- {
10573
- placeholderData: reactQuery.keepPreviousData
10574
- }
10575
- );
10576
- const columns = useColumns();
10577
- const { mutateAsync } = useDraftOrderAddItems(orderId);
10578
- const onSubmit = async () => {
10579
- const ids = Object.keys(rowSelection).filter(
10580
- (id) => !items.find((i) => i.variant_id === id)
10581
- );
10640
+ resolver: zod.zodResolver(MetadataSchema)
10641
+ });
10642
+ const handleSubmit = form.handleSubmit(async (data) => {
10643
+ const parsedData = parseValues(data);
10582
10644
  await mutateAsync(
10583
10645
  {
10584
- items: ids.map((id) => ({
10585
- variant_id: id,
10586
- quantity: 1
10587
- }))
10646
+ metadata: parsedData
10588
10647
  },
10589
10648
  {
10590
10649
  onSuccess: () => {
10591
- setRowSelection({});
10592
- setIsOpen(STACKED_MODAL_ID, false);
10650
+ ui.toast.success("Metadata updated");
10651
+ handleSuccess();
10593
10652
  },
10594
- onError: (e) => {
10595
- ui.toast.error(e.message);
10653
+ onError: (error) => {
10654
+ ui.toast.error(error.message);
10596
10655
  }
10597
10656
  }
10598
10657
  );
10599
- };
10600
- if (isError) {
10601
- throw error;
10658
+ });
10659
+ const { fields, insert, remove } = reactHookForm.useFieldArray({
10660
+ control: form.control,
10661
+ name: "metadata"
10662
+ });
10663
+ function deleteRow(index) {
10664
+ remove(index);
10665
+ if (fields.length === 1) {
10666
+ insert(0, {
10667
+ key: "",
10668
+ value: "",
10669
+ disabled: false
10670
+ });
10671
+ }
10602
10672
  }
10603
- return /* @__PURE__ */ jsxRuntime.jsxs(
10604
- StackedFocusModal.Content,
10673
+ function insertRow(index, position) {
10674
+ insert(index + (position === "above" ? 0 : 1), {
10675
+ key: "",
10676
+ value: "",
10677
+ disabled: false
10678
+ });
10679
+ }
10680
+ return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(
10681
+ KeyboundForm,
10605
10682
  {
10606
- onOpenAutoFocus: (e) => {
10607
- e.preventDefault();
10608
- const searchInput = document.querySelector(
10609
- "[data-modal-id='modal-search-input']"
10610
- );
10611
- if (searchInput) {
10612
- searchInput.focus();
10613
- }
10614
- },
10683
+ onSubmit: handleSubmit,
10684
+ className: "flex flex-1 flex-col overflow-hidden",
10615
10685
  children: [
10616
- /* @__PURE__ */ jsxRuntime.jsxs(StackedFocusModal.Header, { children: [
10617
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Product Variants" }) }),
10618
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Choose product variants to add to the order." }) })
10686
+ /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Body, { className: "flex flex-1 flex-col gap-y-8 overflow-y-auto", children: [
10687
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest grid grid-cols-1 divide-y rounded-lg", children: [
10688
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-subtle grid grid-cols-2 divide-x rounded-t-lg", children: [
10689
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "txt-compact-small-plus text-ui-fg-subtle px-2 py-1.5", children: /* @__PURE__ */ jsxRuntime.jsx("label", { id: METADATA_KEY_LABEL_ID, children: "Key" }) }),
10690
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "txt-compact-small-plus text-ui-fg-subtle px-2 py-1.5", children: /* @__PURE__ */ jsxRuntime.jsx("label", { id: METADATA_VALUE_LABEL_ID, children: "Value" }) })
10691
+ ] }),
10692
+ fields.map((field, index) => {
10693
+ const isDisabled = field.disabled || false;
10694
+ let placeholder = "-";
10695
+ if (typeof field.value === "object") {
10696
+ placeholder = "{ ... }";
10697
+ }
10698
+ if (Array.isArray(field.value)) {
10699
+ placeholder = "[ ... ]";
10700
+ }
10701
+ return /* @__PURE__ */ jsxRuntime.jsx(
10702
+ ConditionalTooltip,
10703
+ {
10704
+ showTooltip: isDisabled,
10705
+ content: "This row is disabled because it contains non-primitive data.",
10706
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "group/table relative", children: [
10707
+ /* @__PURE__ */ jsxRuntime.jsxs(
10708
+ "div",
10709
+ {
10710
+ className: ui.clx("grid grid-cols-2 divide-x", {
10711
+ "overflow-hidden rounded-b-lg": index === fields.length - 1
10712
+ }),
10713
+ children: [
10714
+ /* @__PURE__ */ jsxRuntime.jsx(
10715
+ Form$2.Field,
10716
+ {
10717
+ control: form.control,
10718
+ name: `metadata.${index}.key`,
10719
+ render: ({ field: field2 }) => {
10720
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
10721
+ GridInput,
10722
+ {
10723
+ "aria-labelledby": METADATA_KEY_LABEL_ID,
10724
+ ...field2,
10725
+ disabled: isDisabled,
10726
+ placeholder: "Key"
10727
+ }
10728
+ ) }) });
10729
+ }
10730
+ }
10731
+ ),
10732
+ /* @__PURE__ */ jsxRuntime.jsx(
10733
+ Form$2.Field,
10734
+ {
10735
+ control: form.control,
10736
+ name: `metadata.${index}.value`,
10737
+ render: ({ field: { value, ...field2 } }) => {
10738
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
10739
+ GridInput,
10740
+ {
10741
+ "aria-labelledby": METADATA_VALUE_LABEL_ID,
10742
+ ...field2,
10743
+ value: isDisabled ? placeholder : value,
10744
+ disabled: isDisabled,
10745
+ placeholder: "Value"
10746
+ }
10747
+ ) }) });
10748
+ }
10749
+ }
10750
+ )
10751
+ ]
10752
+ }
10753
+ ),
10754
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu, { children: [
10755
+ /* @__PURE__ */ jsxRuntime.jsx(
10756
+ ui.DropdownMenu.Trigger,
10757
+ {
10758
+ className: ui.clx(
10759
+ "invisible absolute inset-y-0 -right-2.5 my-auto group-hover/table:visible data-[state='open']:visible",
10760
+ {
10761
+ hidden: isDisabled
10762
+ }
10763
+ ),
10764
+ disabled: isDisabled,
10765
+ asChild: true,
10766
+ children: /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { size: "2xsmall", children: /* @__PURE__ */ jsxRuntime.jsx(icons.EllipsisVertical, {}) })
10767
+ }
10768
+ ),
10769
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu.Content, { children: [
10770
+ /* @__PURE__ */ jsxRuntime.jsxs(
10771
+ ui.DropdownMenu.Item,
10772
+ {
10773
+ className: "gap-x-2",
10774
+ onClick: () => insertRow(index, "above"),
10775
+ children: [
10776
+ /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowUpMini, { className: "text-ui-fg-subtle" }),
10777
+ "Insert row above"
10778
+ ]
10779
+ }
10780
+ ),
10781
+ /* @__PURE__ */ jsxRuntime.jsxs(
10782
+ ui.DropdownMenu.Item,
10783
+ {
10784
+ className: "gap-x-2",
10785
+ onClick: () => insertRow(index, "below"),
10786
+ children: [
10787
+ /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowDownMini, { className: "text-ui-fg-subtle" }),
10788
+ "Insert row below"
10789
+ ]
10790
+ }
10791
+ ),
10792
+ /* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenu.Separator, {}),
10793
+ /* @__PURE__ */ jsxRuntime.jsxs(
10794
+ ui.DropdownMenu.Item,
10795
+ {
10796
+ className: "gap-x-2",
10797
+ onClick: () => deleteRow(index),
10798
+ children: [
10799
+ /* @__PURE__ */ jsxRuntime.jsx(icons.Trash, { className: "text-ui-fg-subtle" }),
10800
+ "Delete row"
10801
+ ]
10802
+ }
10803
+ )
10804
+ ] })
10805
+ ] })
10806
+ ] })
10807
+ },
10808
+ field.id
10809
+ );
10810
+ })
10811
+ ] }),
10812
+ hasUneditableRows && /* @__PURE__ */ jsxRuntime.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." })
10619
10813
  ] }),
10620
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Body, { className: "flex-1 overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(
10621
- DataTable,
10622
- {
10623
- data: variants,
10624
- columns,
10625
- isLoading: isPending,
10626
- getRowId: (row) => row.id,
10627
- rowCount: count,
10628
- prefix: VARIANT_PREFIX,
10629
- layout: "fill",
10630
- rowSelection: {
10631
- state: rowSelection,
10632
- onRowSelectionChange: setRowSelection,
10633
- enableRowSelection: (row) => {
10634
- return !items.find((i) => i.variant_id === row.original.id);
10635
- }
10636
- },
10637
- autoFocusSearch: true
10638
- }
10639
- ) }),
10640
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
10641
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
10642
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "button", onClick: onSubmit, children: "Update items" })
10814
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
10815
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
10816
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
10643
10817
  ] }) })
10644
10818
  ]
10645
10819
  }
10646
- );
10647
- };
10648
- const columnHelper = ui.createDataTableColumnHelper();
10649
- const useColumns = () => {
10650
- return React.useMemo(() => {
10651
- return [
10652
- columnHelper.select(),
10653
- columnHelper.accessor("product.title", {
10654
- header: "Product",
10655
- cell: ({ row }) => {
10656
- var _a, _b, _c;
10657
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-2", children: [
10658
- /* @__PURE__ */ jsxRuntime.jsx(
10659
- Thumbnail,
10660
- {
10661
- thumbnail: (_a = row.original.product) == null ? void 0 : _a.thumbnail,
10662
- alt: (_b = row.original.product) == null ? void 0 : _b.title
10663
- }
10664
- ),
10665
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: (_c = row.original.product) == null ? void 0 : _c.title })
10666
- ] });
10667
- },
10668
- enableSorting: true
10669
- }),
10670
- columnHelper.accessor("title", {
10671
- header: "Variant",
10672
- enableSorting: true
10673
- }),
10674
- columnHelper.accessor("sku", {
10675
- header: "SKU",
10676
- cell: ({ getValue }) => {
10677
- return getValue() ?? "-";
10678
- },
10679
- enableSorting: true
10680
- }),
10681
- columnHelper.accessor("updated_at", {
10682
- header: "Updated",
10683
- cell: ({ getValue }) => {
10684
- return /* @__PURE__ */ jsxRuntime.jsx(
10685
- ui.Tooltip,
10686
- {
10687
- content: getFullDate({ date: getValue(), includeTime: true }),
10688
- children: /* @__PURE__ */ jsxRuntime.jsx("span", { children: getFullDate({ date: getValue() }) })
10689
- }
10690
- );
10691
- },
10692
- enableSorting: true,
10693
- sortAscLabel: "Oldest first",
10694
- sortDescLabel: "Newest first"
10695
- }),
10696
- columnHelper.accessor("created_at", {
10697
- header: "Created",
10698
- cell: ({ getValue }) => {
10699
- return /* @__PURE__ */ jsxRuntime.jsx(
10700
- ui.Tooltip,
10701
- {
10702
- content: getFullDate({ date: getValue(), includeTime: true }),
10703
- children: /* @__PURE__ */ jsxRuntime.jsx("span", { children: getFullDate({ date: getValue() }) })
10704
- }
10705
- );
10706
- },
10707
- enableSorting: true,
10708
- sortAscLabel: "Oldest first",
10709
- sortDescLabel: "Newest first"
10710
- })
10711
- ];
10712
- }, []);
10820
+ ) });
10713
10821
  };
10714
- const CustomItemForm = ({ orderId, currencyCode }) => {
10715
- const { setIsOpen } = useStackedModal();
10716
- const { mutateAsync: addItems } = useDraftOrderAddItems(orderId);
10717
- const form = reactHookForm.useForm({
10718
- defaultValues: {
10719
- title: "",
10720
- quantity: 1,
10721
- unit_price: ""
10722
- },
10723
- resolver: zod.zodResolver(customItemSchema)
10724
- });
10725
- const onSubmit = form.handleSubmit(async (data) => {
10726
- await addItems(
10727
- {
10728
- items: [
10729
- {
10730
- title: data.title,
10731
- quantity: data.quantity,
10732
- unit_price: convertNumber(data.unit_price)
10733
- }
10734
- ]
10735
- },
10736
- {
10737
- onSuccess: () => {
10738
- setIsOpen(STACKED_MODAL_ID, false);
10739
- },
10740
- onError: (e) => {
10741
- ui.toast.error(e.message);
10742
- }
10743
- }
10744
- );
10745
- });
10746
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2, { ...form, children: /* @__PURE__ */ jsxRuntime.jsx(KeyboundForm, { onSubmit, children: /* @__PURE__ */ jsxRuntime.jsxs(StackedFocusModal.Content, { children: [
10747
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Header, {}),
10748
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Body, { className: "flex flex-1 flex-col overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-1 flex-col items-center overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full max-w-[720px] flex-col gap-y-6 px-2 py-16", children: [
10749
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10750
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Add custom item" }) }),
10751
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.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." }) })
10752
- ] }),
10753
- /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
10754
- /* @__PURE__ */ jsxRuntime.jsx(
10755
- Form$2.Field,
10756
- {
10757
- control: form.control,
10758
- name: "title",
10759
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
10760
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10761
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Title" }),
10762
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Enter the title of the item" })
10763
- ] }),
10764
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10765
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
10766
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
10767
- ] })
10768
- ] }) })
10769
- }
10770
- ),
10771
- /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
10772
- /* @__PURE__ */ jsxRuntime.jsx(
10773
- Form$2.Field,
10774
- {
10775
- control: form.control,
10776
- name: "unit_price",
10777
- render: ({ field: { onChange, ...field } }) => /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
10778
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10779
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Unit price" }),
10780
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Enter the unit price of the item" })
10781
- ] }),
10782
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10783
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
10784
- ui.CurrencyInput,
10785
- {
10786
- symbol: getNativeSymbol(currencyCode),
10787
- code: currencyCode,
10788
- onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value),
10789
- ...field
10790
- }
10791
- ) }),
10792
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
10793
- ] })
10794
- ] }) })
10795
- }
10796
- ),
10797
- /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
10798
- /* @__PURE__ */ jsxRuntime.jsx(
10799
- Form$2.Field,
10800
- {
10801
- control: form.control,
10802
- name: "quantity",
10803
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
10804
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10805
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Quantity" }),
10806
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Enter the quantity of the item" })
10807
- ] }),
10808
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full flex-1", children: [
10809
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(NumberInput, { ...field, className: "w-full" }) }) }),
10810
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
10811
- ] })
10812
- ] }) })
10813
- }
10822
+ const GridInput = React.forwardRef(({ className, ...props }, ref) => {
10823
+ return /* @__PURE__ */ jsxRuntime.jsx(
10824
+ "input",
10825
+ {
10826
+ ref,
10827
+ ...props,
10828
+ autoComplete: "off",
10829
+ className: ui.clx(
10830
+ "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",
10831
+ className
10814
10832
  )
10815
- ] }) }) }),
10816
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
10817
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
10818
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "button", onClick: onSubmit, children: "Add item" })
10833
+ }
10834
+ );
10835
+ });
10836
+ GridInput.displayName = "MetadataForm.GridInput";
10837
+ const PlaceholderInner = () => {
10838
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-1 flex-col overflow-hidden", children: [
10839
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-[148ox] w-full rounded-lg" }) }),
10840
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
10841
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-7 w-12 rounded-md" }),
10842
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-7 w-12 rounded-md" })
10819
10843
  ] }) })
10820
- ] }) }) });
10844
+ ] });
10821
10845
  };
10822
- const customItemSchema = objectType({
10823
- title: stringType().min(1),
10824
- quantity: numberType(),
10825
- unit_price: unionType([numberType(), stringType()])
10826
- });
10846
+ const EDITABLE_TYPES = ["string", "number", "boolean"];
10847
+ function getDefaultValues(metadata) {
10848
+ if (!metadata || !Object.keys(metadata).length) {
10849
+ return [
10850
+ {
10851
+ key: "",
10852
+ value: "",
10853
+ disabled: false
10854
+ }
10855
+ ];
10856
+ }
10857
+ return Object.entries(metadata).map(([key, value]) => {
10858
+ if (!EDITABLE_TYPES.includes(typeof value)) {
10859
+ return {
10860
+ key,
10861
+ value,
10862
+ disabled: true
10863
+ };
10864
+ }
10865
+ let stringValue = value;
10866
+ if (typeof value !== "string") {
10867
+ stringValue = JSON.stringify(value);
10868
+ }
10869
+ return {
10870
+ key,
10871
+ value: stringValue,
10872
+ original_key: key
10873
+ };
10874
+ });
10875
+ }
10876
+ function parseValues(values) {
10877
+ const metadata = values.metadata;
10878
+ const isEmpty = !metadata.length || metadata.length === 1 && !metadata[0].key && !metadata[0].value;
10879
+ if (isEmpty) {
10880
+ return null;
10881
+ }
10882
+ const update = {};
10883
+ metadata.forEach((field) => {
10884
+ let key = field.key;
10885
+ let value = field.value;
10886
+ const disabled = field.disabled;
10887
+ if (!key || !value) {
10888
+ return;
10889
+ }
10890
+ if (disabled) {
10891
+ update[key] = value;
10892
+ return;
10893
+ }
10894
+ key = key.trim();
10895
+ value = value.trim();
10896
+ if (value === "true") {
10897
+ update[key] = true;
10898
+ } else if (value === "false") {
10899
+ update[key] = false;
10900
+ } else {
10901
+ const parsedNumber = parseFloat(value);
10902
+ if (!isNaN(parsedNumber)) {
10903
+ update[key] = parsedNumber;
10904
+ } else {
10905
+ update[key] = value;
10906
+ }
10907
+ }
10908
+ });
10909
+ return update;
10910
+ }
10911
+ function getHasUneditableRows(metadata) {
10912
+ if (!metadata) {
10913
+ return false;
10914
+ }
10915
+ return Object.values(metadata).some(
10916
+ (value) => !EDITABLE_TYPES.includes(typeof value)
10917
+ );
10918
+ }
10827
10919
  const PROMOTION_QUERY_KEY = "promotions";
10828
10920
  const promotionsQueryKeys = {
10829
10921
  list: (query2) => [
@@ -11005,102 +11097,276 @@ const PromotionItem = ({
11005
11097
  const onRemove = async () => {
11006
11098
  removePromotions(
11007
11099
  {
11008
- promo_codes: [promotion.code]
11100
+ promo_codes: [promotion.code]
11101
+ },
11102
+ {
11103
+ onError: (e) => {
11104
+ ui.toast.error(e.message);
11105
+ }
11106
+ }
11107
+ );
11108
+ };
11109
+ const displayValue = getDisplayValue(promotion);
11110
+ return /* @__PURE__ */ jsxRuntime.jsxs(
11111
+ "div",
11112
+ {
11113
+ className: ui.clx(
11114
+ "bg-ui-bg-component shadow-elevation-card-rest flex items-center justify-between rounded-lg px-3 py-2",
11115
+ {
11116
+ "animate-pulse": isLoading
11117
+ }
11118
+ ),
11119
+ children: [
11120
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
11121
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: promotion.code }),
11122
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-ui-fg-subtle flex items-center gap-1.5", children: [
11123
+ displayValue && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
11124
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", children: displayValue }),
11125
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", children: "·" })
11126
+ ] }),
11127
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", className: "capitalize", children: (_a = promotion.application_method) == null ? void 0 : _a.allocation })
11128
+ ] })
11129
+ ] }),
11130
+ /* @__PURE__ */ jsxRuntime.jsx(
11131
+ ui.IconButton,
11132
+ {
11133
+ size: "small",
11134
+ type: "button",
11135
+ variant: "transparent",
11136
+ onClick: onRemove,
11137
+ isLoading: isPending || isLoading,
11138
+ children: /* @__PURE__ */ jsxRuntime.jsx(icons.XMark, {})
11139
+ }
11140
+ )
11141
+ ]
11142
+ },
11143
+ promotion.id
11144
+ );
11145
+ };
11146
+ function getDisplayValue(promotion) {
11147
+ var _a, _b, _c, _d;
11148
+ const value = (_a = promotion.application_method) == null ? void 0 : _a.value;
11149
+ if (!value) {
11150
+ return null;
11151
+ }
11152
+ if (((_b = promotion.application_method) == null ? void 0 : _b.type) === "fixed") {
11153
+ const currency = (_c = promotion.application_method) == null ? void 0 : _c.currency_code;
11154
+ if (!currency) {
11155
+ return null;
11156
+ }
11157
+ return getLocaleAmount(value, currency);
11158
+ } else if (((_d = promotion.application_method) == null ? void 0 : _d.type) === "percentage") {
11159
+ return formatPercentage(value);
11160
+ }
11161
+ return null;
11162
+ }
11163
+ const formatter = new Intl.NumberFormat([], {
11164
+ style: "percent",
11165
+ minimumFractionDigits: 2
11166
+ });
11167
+ const formatPercentage = (value, isPercentageValue = false) => {
11168
+ let val = value || 0;
11169
+ if (!isPercentageValue) {
11170
+ val = val / 100;
11171
+ }
11172
+ return formatter.format(val);
11173
+ };
11174
+ function getPromotionIds(items, shippingMethods) {
11175
+ const promotionIds = /* @__PURE__ */ new Set();
11176
+ for (const item of items) {
11177
+ if (item.adjustments) {
11178
+ for (const adjustment of item.adjustments) {
11179
+ if (adjustment.promotion_id) {
11180
+ promotionIds.add(adjustment.promotion_id);
11181
+ }
11182
+ }
11183
+ }
11184
+ }
11185
+ for (const shippingMethod of shippingMethods) {
11186
+ if (shippingMethod.adjustments) {
11187
+ for (const adjustment of shippingMethod.adjustments) {
11188
+ if (adjustment.promotion_id) {
11189
+ promotionIds.add(adjustment.promotion_id);
11190
+ }
11191
+ }
11192
+ }
11193
+ }
11194
+ return Array.from(promotionIds);
11195
+ }
11196
+ const Email = () => {
11197
+ const { id } = reactRouterDom.useParams();
11198
+ const { order, isPending, isError, error } = useOrder(id, {
11199
+ fields: "+email"
11200
+ });
11201
+ if (isError) {
11202
+ throw error;
11203
+ }
11204
+ const isReady = !isPending && !!order;
11205
+ return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
11206
+ /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Header, { children: [
11207
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Email" }) }),
11208
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Edit the email for the draft order" }) })
11209
+ ] }),
11210
+ isReady && /* @__PURE__ */ jsxRuntime.jsx(EmailForm, { order })
11211
+ ] });
11212
+ };
11213
+ const EmailForm = ({ order }) => {
11214
+ const form = reactHookForm.useForm({
11215
+ defaultValues: {
11216
+ email: order.email ?? ""
11217
+ },
11218
+ resolver: zod.zodResolver(schema$4)
11219
+ });
11220
+ const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
11221
+ const { handleSuccess } = useRouteModal();
11222
+ const onSubmit = form.handleSubmit(async (data) => {
11223
+ await mutateAsync(
11224
+ { email: data.email },
11225
+ {
11226
+ onSuccess: () => {
11227
+ handleSuccess();
11228
+ },
11229
+ onError: (error) => {
11230
+ ui.toast.error(error.message);
11231
+ }
11232
+ }
11233
+ );
11234
+ });
11235
+ return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(
11236
+ KeyboundForm,
11237
+ {
11238
+ className: "flex flex-1 flex-col overflow-hidden",
11239
+ onSubmit,
11240
+ children: [
11241
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsx(
11242
+ Form$2.Field,
11243
+ {
11244
+ control: form.control,
11245
+ name: "email",
11246
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
11247
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Email" }),
11248
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
11249
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
11250
+ ] })
11251
+ }
11252
+ ) }),
11253
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
11254
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
11255
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
11256
+ ] }) })
11257
+ ]
11258
+ }
11259
+ ) });
11260
+ };
11261
+ const schema$4 = objectType({
11262
+ email: stringType().email()
11263
+ });
11264
+ const SalesChannel = () => {
11265
+ const { id } = reactRouterDom.useParams();
11266
+ const { draft_order, isPending, isError, error } = useDraftOrder(
11267
+ id,
11268
+ {
11269
+ fields: "+sales_channel_id"
11270
+ },
11271
+ {
11272
+ enabled: !!id
11273
+ }
11274
+ );
11275
+ if (isError) {
11276
+ throw error;
11277
+ }
11278
+ const ISrEADY = !!draft_order && !isPending;
11279
+ return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
11280
+ /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Header, { children: [
11281
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Sales Channel" }) }),
11282
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Update which sales channel the draft order is associated with" }) })
11283
+ ] }),
11284
+ ISrEADY && /* @__PURE__ */ jsxRuntime.jsx(SalesChannelForm, { order: draft_order })
11285
+ ] });
11286
+ };
11287
+ const SalesChannelForm = ({ order }) => {
11288
+ const form = reactHookForm.useForm({
11289
+ defaultValues: {
11290
+ sales_channel_id: order.sales_channel_id || ""
11291
+ },
11292
+ resolver: zod.zodResolver(schema$3)
11293
+ });
11294
+ const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
11295
+ const { handleSuccess } = useRouteModal();
11296
+ const onSubmit = form.handleSubmit(async (data) => {
11297
+ await mutateAsync(
11298
+ {
11299
+ sales_channel_id: data.sales_channel_id
11009
11300
  },
11010
11301
  {
11011
- onError: (e) => {
11012
- ui.toast.error(e.message);
11302
+ onSuccess: () => {
11303
+ ui.toast.success("Sales channel updated");
11304
+ handleSuccess();
11305
+ },
11306
+ onError: (error) => {
11307
+ ui.toast.error(error.message);
11013
11308
  }
11014
11309
  }
11015
11310
  );
11016
- };
11017
- const displayValue = getDisplayValue(promotion);
11018
- return /* @__PURE__ */ jsxRuntime.jsxs(
11019
- "div",
11311
+ });
11312
+ return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(
11313
+ KeyboundForm,
11020
11314
  {
11021
- className: ui.clx(
11022
- "bg-ui-bg-component shadow-elevation-card-rest flex items-center justify-between rounded-lg px-3 py-2",
11023
- {
11024
- "animate-pulse": isLoading
11025
- }
11026
- ),
11315
+ className: "flex flex-1 flex-col overflow-hidden",
11316
+ onSubmit,
11027
11317
  children: [
11028
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
11029
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: promotion.code }),
11030
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-ui-fg-subtle flex items-center gap-1.5", children: [
11031
- displayValue && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
11032
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", children: displayValue }),
11033
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", children: "·" })
11034
- ] }),
11035
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", className: "capitalize", children: (_a = promotion.application_method) == null ? void 0 : _a.allocation })
11036
- ] })
11037
- ] }),
11038
- /* @__PURE__ */ jsxRuntime.jsx(
11039
- ui.IconButton,
11040
- {
11041
- size: "small",
11042
- type: "button",
11043
- variant: "transparent",
11044
- onClick: onRemove,
11045
- isLoading: isPending || isLoading,
11046
- children: /* @__PURE__ */ jsxRuntime.jsx(icons.XMark, {})
11047
- }
11048
- )
11318
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsx(SalesChannelField, { control: form.control, order }) }),
11319
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
11320
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
11321
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
11322
+ ] }) })
11049
11323
  ]
11050
- },
11051
- promotion.id
11052
- );
11053
- };
11054
- function getDisplayValue(promotion) {
11055
- var _a, _b, _c, _d;
11056
- const value = (_a = promotion.application_method) == null ? void 0 : _a.value;
11057
- if (!value) {
11058
- return null;
11059
- }
11060
- if (((_b = promotion.application_method) == null ? void 0 : _b.type) === "fixed") {
11061
- const currency = (_c = promotion.application_method) == null ? void 0 : _c.currency_code;
11062
- if (!currency) {
11063
- return null;
11064
11324
  }
11065
- return getLocaleAmount(value, currency);
11066
- } else if (((_d = promotion.application_method) == null ? void 0 : _d.type) === "percentage") {
11067
- return formatPercentage(value);
11068
- }
11069
- return null;
11070
- }
11071
- const formatter = new Intl.NumberFormat([], {
11072
- style: "percent",
11073
- minimumFractionDigits: 2
11074
- });
11075
- const formatPercentage = (value, isPercentageValue = false) => {
11076
- let val = value || 0;
11077
- if (!isPercentageValue) {
11078
- val = val / 100;
11079
- }
11080
- return formatter.format(val);
11325
+ ) });
11081
11326
  };
11082
- function getPromotionIds(items, shippingMethods) {
11083
- const promotionIds = /* @__PURE__ */ new Set();
11084
- for (const item of items) {
11085
- if (item.adjustments) {
11086
- for (const adjustment of item.adjustments) {
11087
- if (adjustment.promotion_id) {
11088
- promotionIds.add(adjustment.promotion_id);
11089
- }
11090
- }
11091
- }
11092
- }
11093
- for (const shippingMethod of shippingMethods) {
11094
- if (shippingMethod.adjustments) {
11095
- for (const adjustment of shippingMethod.adjustments) {
11096
- if (adjustment.promotion_id) {
11097
- promotionIds.add(adjustment.promotion_id);
11098
- }
11327
+ const SalesChannelField = ({ control, order }) => {
11328
+ const salesChannels = useComboboxData({
11329
+ queryFn: async (params) => {
11330
+ return await sdk.admin.salesChannel.list(params);
11331
+ },
11332
+ queryKey: ["sales-channels"],
11333
+ getOptions: (data) => {
11334
+ return data.sales_channels.map((salesChannel) => ({
11335
+ label: salesChannel.name,
11336
+ value: salesChannel.id
11337
+ }));
11338
+ },
11339
+ defaultValue: order.sales_channel_id || void 0
11340
+ });
11341
+ return /* @__PURE__ */ jsxRuntime.jsx(
11342
+ Form$2.Field,
11343
+ {
11344
+ control,
11345
+ name: "sales_channel_id",
11346
+ render: ({ field }) => {
11347
+ return /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
11348
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Sales Channel" }),
11349
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
11350
+ Combobox,
11351
+ {
11352
+ options: salesChannels.options,
11353
+ fetchNextPage: salesChannels.fetchNextPage,
11354
+ isFetchingNextPage: salesChannels.isFetchingNextPage,
11355
+ searchValue: salesChannels.searchValue,
11356
+ onSearchValueChange: salesChannels.onSearchValueChange,
11357
+ placeholder: "Select sales channel",
11358
+ ...field
11359
+ }
11360
+ ) }),
11361
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
11362
+ ] });
11099
11363
  }
11100
11364
  }
11101
- }
11102
- return Array.from(promotionIds);
11103
- }
11365
+ );
11366
+ };
11367
+ const schema$3 = objectType({
11368
+ sales_channel_id: stringType().min(1)
11369
+ });
11104
11370
  const STACKED_FOCUS_MODAL_ID = "shipping-form";
11105
11371
  const Shipping = () => {
11106
11372
  var _a;
@@ -11895,125 +12161,19 @@ const CustomAmountField = ({
11895
12161
  /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Set a custom amount for the shipping option." })
11896
12162
  ] }),
11897
12163
  /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
11898
- ui.CurrencyInput,
11899
- {
11900
- ...field,
11901
- onValueChange: (value) => onChange(value),
11902
- symbol: getNativeSymbol(currencyCode),
11903
- code: currencyCode
11904
- }
11905
- ) })
11906
- ] });
11907
- }
11908
- }
11909
- );
11910
- };
11911
- const SalesChannel = () => {
11912
- const { id } = reactRouterDom.useParams();
11913
- const { draft_order, isPending, isError, error } = useDraftOrder(
11914
- id,
11915
- {
11916
- fields: "+sales_channel_id"
11917
- },
11918
- {
11919
- enabled: !!id
11920
- }
11921
- );
11922
- if (isError) {
11923
- throw error;
11924
- }
11925
- const ISrEADY = !!draft_order && !isPending;
11926
- return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
11927
- /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Header, { children: [
11928
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Sales Channel" }) }),
11929
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Update which sales channel the draft order is associated with" }) })
11930
- ] }),
11931
- ISrEADY && /* @__PURE__ */ jsxRuntime.jsx(SalesChannelForm, { order: draft_order })
11932
- ] });
11933
- };
11934
- const SalesChannelForm = ({ order }) => {
11935
- const form = reactHookForm.useForm({
11936
- defaultValues: {
11937
- sales_channel_id: order.sales_channel_id || ""
11938
- },
11939
- resolver: zod.zodResolver(schema$2)
11940
- });
11941
- const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
11942
- const { handleSuccess } = useRouteModal();
11943
- const onSubmit = form.handleSubmit(async (data) => {
11944
- await mutateAsync(
11945
- {
11946
- sales_channel_id: data.sales_channel_id
11947
- },
11948
- {
11949
- onSuccess: () => {
11950
- ui.toast.success("Sales channel updated");
11951
- handleSuccess();
11952
- },
11953
- onError: (error) => {
11954
- ui.toast.error(error.message);
11955
- }
11956
- }
11957
- );
11958
- });
11959
- return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(
11960
- KeyboundForm,
11961
- {
11962
- className: "flex flex-1 flex-col overflow-hidden",
11963
- onSubmit,
11964
- children: [
11965
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsx(SalesChannelField, { control: form.control, order }) }),
11966
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
11967
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
11968
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
11969
- ] }) })
11970
- ]
11971
- }
11972
- ) });
11973
- };
11974
- const SalesChannelField = ({ control, order }) => {
11975
- const salesChannels = useComboboxData({
11976
- queryFn: async (params) => {
11977
- return await sdk.admin.salesChannel.list(params);
11978
- },
11979
- queryKey: ["sales-channels"],
11980
- getOptions: (data) => {
11981
- return data.sales_channels.map((salesChannel) => ({
11982
- label: salesChannel.name,
11983
- value: salesChannel.id
11984
- }));
11985
- },
11986
- defaultValue: order.sales_channel_id || void 0
11987
- });
11988
- return /* @__PURE__ */ jsxRuntime.jsx(
11989
- Form$2.Field,
11990
- {
11991
- control,
11992
- name: "sales_channel_id",
11993
- render: ({ field }) => {
11994
- return /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
11995
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Sales Channel" }),
11996
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
11997
- Combobox,
12164
+ ui.CurrencyInput,
11998
12165
  {
11999
- options: salesChannels.options,
12000
- fetchNextPage: salesChannels.fetchNextPage,
12001
- isFetchingNextPage: salesChannels.isFetchingNextPage,
12002
- searchValue: salesChannels.searchValue,
12003
- onSearchValueChange: salesChannels.onSearchValueChange,
12004
- placeholder: "Select sales channel",
12005
- ...field
12166
+ ...field,
12167
+ onValueChange: (value) => onChange(value),
12168
+ symbol: getNativeSymbol(currencyCode),
12169
+ code: currencyCode
12006
12170
  }
12007
- ) }),
12008
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12171
+ ) })
12009
12172
  ] });
12010
12173
  }
12011
12174
  }
12012
12175
  );
12013
12176
  };
12014
- const schema$2 = objectType({
12015
- sales_channel_id: stringType().min(1)
12016
- });
12017
12177
  const ShippingAddress = () => {
12018
12178
  const { id } = reactRouterDom.useParams();
12019
12179
  const { order, isPending, isError, error } = useOrder(id, {
@@ -12046,7 +12206,7 @@ const ShippingAddressForm = ({ order }) => {
12046
12206
  postal_code: ((_i = order.shipping_address) == null ? void 0 : _i.postal_code) ?? "",
12047
12207
  phone: ((_j = order.shipping_address) == null ? void 0 : _j.phone) ?? ""
12048
12208
  },
12049
- resolver: zod.zodResolver(schema$1)
12209
+ resolver: zod.zodResolver(schema$2)
12050
12210
  });
12051
12211
  const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
12052
12212
  const { handleSuccess } = useRouteModal();
@@ -12216,7 +12376,7 @@ const ShippingAddressForm = ({ order }) => {
12216
12376
  }
12217
12377
  ) });
12218
12378
  };
12219
- const schema$1 = addressSchema;
12379
+ const schema$2 = addressSchema;
12220
12380
  const TransferOwnership = () => {
12221
12381
  const { id } = reactRouterDom.useParams();
12222
12382
  const { draft_order, isPending, isError, error } = useDraftOrder(id, {
@@ -12240,7 +12400,7 @@ const TransferOwnershipForm = ({ order }) => {
12240
12400
  defaultValues: {
12241
12401
  customer_id: order.customer_id || ""
12242
12402
  },
12243
- resolver: zod.zodResolver(schema)
12403
+ resolver: zod.zodResolver(schema$1)
12244
12404
  });
12245
12405
  const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
12246
12406
  const { handleSuccess } = useRouteModal();
@@ -12690,57 +12850,13 @@ const Illustration = () => {
12690
12850
  }
12691
12851
  );
12692
12852
  };
12693
- const schema = objectType({
12853
+ const schema$1 = objectType({
12694
12854
  customer_id: stringType().min(1)
12695
12855
  });
12696
- const InlineTip = React.forwardRef(
12697
- ({ variant = "tip", label, className, children, ...props }, ref) => {
12698
- const labelValue = label || (variant === "warning" ? "Warning" : "Tip");
12699
- return /* @__PURE__ */ jsxRuntime.jsxs(
12700
- "div",
12701
- {
12702
- ref,
12703
- className: ui.clx(
12704
- "bg-ui-bg-component txt-small text-ui-fg-subtle grid grid-cols-[4px_1fr] items-start gap-3 rounded-lg border p-3",
12705
- className
12706
- ),
12707
- ...props,
12708
- children: [
12709
- /* @__PURE__ */ jsxRuntime.jsx(
12710
- "div",
12711
- {
12712
- role: "presentation",
12713
- className: ui.clx("w-4px bg-ui-tag-neutral-icon h-full rounded-full", {
12714
- "bg-ui-tag-orange-icon": variant === "warning"
12715
- })
12716
- }
12717
- ),
12718
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-pretty", children: [
12719
- /* @__PURE__ */ jsxRuntime.jsxs("strong", { className: "txt-small-plus text-ui-fg-base", children: [
12720
- labelValue,
12721
- ":"
12722
- ] }),
12723
- " ",
12724
- children
12725
- ] })
12726
- ]
12727
- }
12728
- );
12729
- }
12730
- );
12731
- InlineTip.displayName = "InlineTip";
12732
- const MetadataFieldSchema = objectType({
12733
- key: stringType(),
12734
- disabled: booleanType().optional(),
12735
- value: anyType()
12736
- });
12737
- const MetadataSchema = objectType({
12738
- metadata: arrayType(MetadataFieldSchema)
12739
- });
12740
- const Metadata = () => {
12856
+ const BillingAddress = () => {
12741
12857
  const { id } = reactRouterDom.useParams();
12742
12858
  const { order, isPending, isError, error } = useOrder(id, {
12743
- fields: "metadata"
12859
+ fields: "+billing_address"
12744
12860
  });
12745
12861
  if (isError) {
12746
12862
  throw error;
@@ -12748,33 +12864,36 @@ const Metadata = () => {
12748
12864
  const isReady = !isPending && !!order;
12749
12865
  return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
12750
12866
  /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Header, { children: [
12751
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Metadata" }) }),
12752
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Add metadata to the draft order." }) })
12867
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Billing Address" }) }),
12868
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Edit the billing address for the draft order" }) })
12753
12869
  ] }),
12754
- !isReady ? /* @__PURE__ */ jsxRuntime.jsx(PlaceholderInner, {}) : /* @__PURE__ */ jsxRuntime.jsx(MetadataForm, { orderId: id, metadata: order == null ? void 0 : order.metadata })
12870
+ isReady && /* @__PURE__ */ jsxRuntime.jsx(BillingAddressForm, { order })
12755
12871
  ] });
12756
12872
  };
12757
- const METADATA_KEY_LABEL_ID = "metadata-form-key-label";
12758
- const METADATA_VALUE_LABEL_ID = "metadata-form-value-label";
12759
- const MetadataForm = ({ orderId, metadata }) => {
12760
- const { handleSuccess } = useRouteModal();
12761
- const hasUneditableRows = getHasUneditableRows(metadata);
12762
- const { mutateAsync, isPending } = useUpdateDraftOrder(orderId);
12873
+ const BillingAddressForm = ({ order }) => {
12874
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
12763
12875
  const form = reactHookForm.useForm({
12764
12876
  defaultValues: {
12765
- metadata: getDefaultValues(metadata)
12877
+ first_name: ((_a = order.billing_address) == null ? void 0 : _a.first_name) ?? "",
12878
+ last_name: ((_b = order.billing_address) == null ? void 0 : _b.last_name) ?? "",
12879
+ company: ((_c = order.billing_address) == null ? void 0 : _c.company) ?? "",
12880
+ address_1: ((_d = order.billing_address) == null ? void 0 : _d.address_1) ?? "",
12881
+ address_2: ((_e = order.billing_address) == null ? void 0 : _e.address_2) ?? "",
12882
+ city: ((_f = order.billing_address) == null ? void 0 : _f.city) ?? "",
12883
+ province: ((_g = order.billing_address) == null ? void 0 : _g.province) ?? "",
12884
+ country_code: ((_h = order.billing_address) == null ? void 0 : _h.country_code) ?? "",
12885
+ postal_code: ((_i = order.billing_address) == null ? void 0 : _i.postal_code) ?? "",
12886
+ phone: ((_j = order.billing_address) == null ? void 0 : _j.phone) ?? ""
12766
12887
  },
12767
- resolver: zod.zodResolver(MetadataSchema)
12888
+ resolver: zod.zodResolver(schema)
12768
12889
  });
12769
- const handleSubmit = form.handleSubmit(async (data) => {
12770
- const parsedData = parseValues(data);
12890
+ const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
12891
+ const { handleSuccess } = useRouteModal();
12892
+ const onSubmit = form.handleSubmit(async (data) => {
12771
12893
  await mutateAsync(
12772
- {
12773
- metadata: parsedData
12774
- },
12894
+ { billing_address: data },
12775
12895
  {
12776
12896
  onSuccess: () => {
12777
- ui.toast.success("Metadata updated");
12778
12897
  handleSuccess();
12779
12898
  },
12780
12899
  onError: (error) => {
@@ -12783,266 +12902,147 @@ const MetadataForm = ({ orderId, metadata }) => {
12783
12902
  }
12784
12903
  );
12785
12904
  });
12786
- const { fields, insert, remove } = reactHookForm.useFieldArray({
12787
- control: form.control,
12788
- name: "metadata"
12789
- });
12790
- function deleteRow(index) {
12791
- remove(index);
12792
- if (fields.length === 1) {
12793
- insert(0, {
12794
- key: "",
12795
- value: "",
12796
- disabled: false
12797
- });
12798
- }
12799
- }
12800
- function insertRow(index, position) {
12801
- insert(index + (position === "above" ? 0 : 1), {
12802
- key: "",
12803
- value: "",
12804
- disabled: false
12805
- });
12806
- }
12807
12905
  return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(
12808
12906
  KeyboundForm,
12809
- {
12810
- onSubmit: handleSubmit,
12811
- className: "flex flex-1 flex-col overflow-hidden",
12812
- children: [
12813
- /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Body, { className: "flex flex-1 flex-col gap-y-8 overflow-y-auto", children: [
12814
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest grid grid-cols-1 divide-y rounded-lg", children: [
12815
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-subtle grid grid-cols-2 divide-x rounded-t-lg", children: [
12816
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "txt-compact-small-plus text-ui-fg-subtle px-2 py-1.5", children: /* @__PURE__ */ jsxRuntime.jsx("label", { id: METADATA_KEY_LABEL_ID, children: "Key" }) }),
12817
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "txt-compact-small-plus text-ui-fg-subtle px-2 py-1.5", children: /* @__PURE__ */ jsxRuntime.jsx("label", { id: METADATA_VALUE_LABEL_ID, children: "Value" }) })
12818
- ] }),
12819
- fields.map((field, index) => {
12820
- const isDisabled = field.disabled || false;
12821
- let placeholder = "-";
12822
- if (typeof field.value === "object") {
12823
- placeholder = "{ ... }";
12824
- }
12825
- if (Array.isArray(field.value)) {
12826
- placeholder = "[ ... ]";
12827
- }
12828
- return /* @__PURE__ */ jsxRuntime.jsx(
12829
- ConditionalTooltip,
12830
- {
12831
- showTooltip: isDisabled,
12832
- content: "This row is disabled because it contains non-primitive data.",
12833
- children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "group/table relative", children: [
12834
- /* @__PURE__ */ jsxRuntime.jsxs(
12835
- "div",
12836
- {
12837
- className: ui.clx("grid grid-cols-2 divide-x", {
12838
- "overflow-hidden rounded-b-lg": index === fields.length - 1
12839
- }),
12840
- children: [
12841
- /* @__PURE__ */ jsxRuntime.jsx(
12842
- Form$2.Field,
12843
- {
12844
- control: form.control,
12845
- name: `metadata.${index}.key`,
12846
- render: ({ field: field2 }) => {
12847
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
12848
- GridInput,
12849
- {
12850
- "aria-labelledby": METADATA_KEY_LABEL_ID,
12851
- ...field2,
12852
- disabled: isDisabled,
12853
- placeholder: "Key"
12854
- }
12855
- ) }) });
12856
- }
12857
- }
12858
- ),
12859
- /* @__PURE__ */ jsxRuntime.jsx(
12860
- Form$2.Field,
12861
- {
12862
- control: form.control,
12863
- name: `metadata.${index}.value`,
12864
- render: ({ field: { value, ...field2 } }) => {
12865
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
12866
- GridInput,
12867
- {
12868
- "aria-labelledby": METADATA_VALUE_LABEL_ID,
12869
- ...field2,
12870
- value: isDisabled ? placeholder : value,
12871
- disabled: isDisabled,
12872
- placeholder: "Value"
12873
- }
12874
- ) }) });
12875
- }
12876
- }
12877
- )
12878
- ]
12879
- }
12880
- ),
12881
- /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu, { children: [
12882
- /* @__PURE__ */ jsxRuntime.jsx(
12883
- ui.DropdownMenu.Trigger,
12884
- {
12885
- className: ui.clx(
12886
- "invisible absolute inset-y-0 -right-2.5 my-auto group-hover/table:visible data-[state='open']:visible",
12887
- {
12888
- hidden: isDisabled
12889
- }
12890
- ),
12891
- disabled: isDisabled,
12892
- asChild: true,
12893
- children: /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { size: "2xsmall", children: /* @__PURE__ */ jsxRuntime.jsx(icons.EllipsisVertical, {}) })
12894
- }
12895
- ),
12896
- /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu.Content, { children: [
12897
- /* @__PURE__ */ jsxRuntime.jsxs(
12898
- ui.DropdownMenu.Item,
12899
- {
12900
- className: "gap-x-2",
12901
- onClick: () => insertRow(index, "above"),
12902
- children: [
12903
- /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowUpMini, { className: "text-ui-fg-subtle" }),
12904
- "Insert row above"
12905
- ]
12906
- }
12907
- ),
12908
- /* @__PURE__ */ jsxRuntime.jsxs(
12909
- ui.DropdownMenu.Item,
12910
- {
12911
- className: "gap-x-2",
12912
- onClick: () => insertRow(index, "below"),
12913
- children: [
12914
- /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowDownMini, { className: "text-ui-fg-subtle" }),
12915
- "Insert row below"
12916
- ]
12917
- }
12918
- ),
12919
- /* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenu.Separator, {}),
12920
- /* @__PURE__ */ jsxRuntime.jsxs(
12921
- ui.DropdownMenu.Item,
12922
- {
12923
- className: "gap-x-2",
12924
- onClick: () => deleteRow(index),
12925
- children: [
12926
- /* @__PURE__ */ jsxRuntime.jsx(icons.Trash, { className: "text-ui-fg-subtle" }),
12927
- "Delete row"
12928
- ]
12929
- }
12930
- )
12931
- ] })
12932
- ] })
12933
- ] })
12934
- },
12935
- field.id
12936
- );
12937
- })
12907
+ {
12908
+ className: "flex flex-1 flex-col overflow-hidden",
12909
+ onSubmit,
12910
+ children: [
12911
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-4", children: [
12912
+ /* @__PURE__ */ jsxRuntime.jsx(
12913
+ Form$2.Field,
12914
+ {
12915
+ control: form.control,
12916
+ name: "country_code",
12917
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
12918
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Country" }),
12919
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(CountrySelect, { ...field }) }),
12920
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12921
+ ] })
12922
+ }
12923
+ ),
12924
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
12925
+ /* @__PURE__ */ jsxRuntime.jsx(
12926
+ Form$2.Field,
12927
+ {
12928
+ control: form.control,
12929
+ name: "first_name",
12930
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
12931
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "First name" }),
12932
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
12933
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12934
+ ] })
12935
+ }
12936
+ ),
12937
+ /* @__PURE__ */ jsxRuntime.jsx(
12938
+ Form$2.Field,
12939
+ {
12940
+ control: form.control,
12941
+ name: "last_name",
12942
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
12943
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Last name" }),
12944
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
12945
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12946
+ ] })
12947
+ }
12948
+ )
12938
12949
  ] }),
12939
- hasUneditableRows && /* @__PURE__ */ jsxRuntime.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." })
12940
- ] }),
12941
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
12942
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
12950
+ /* @__PURE__ */ jsxRuntime.jsx(
12951
+ Form$2.Field,
12952
+ {
12953
+ control: form.control,
12954
+ name: "company",
12955
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
12956
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { optional: true, children: "Company" }),
12957
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
12958
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12959
+ ] })
12960
+ }
12961
+ ),
12962
+ /* @__PURE__ */ jsxRuntime.jsx(
12963
+ Form$2.Field,
12964
+ {
12965
+ control: form.control,
12966
+ name: "address_1",
12967
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
12968
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Address" }),
12969
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
12970
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12971
+ ] })
12972
+ }
12973
+ ),
12974
+ /* @__PURE__ */ jsxRuntime.jsx(
12975
+ Form$2.Field,
12976
+ {
12977
+ control: form.control,
12978
+ name: "address_2",
12979
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
12980
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { optional: true, children: "Apartment, suite, etc." }),
12981
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
12982
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12983
+ ] })
12984
+ }
12985
+ ),
12986
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
12987
+ /* @__PURE__ */ jsxRuntime.jsx(
12988
+ Form$2.Field,
12989
+ {
12990
+ control: form.control,
12991
+ name: "postal_code",
12992
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
12993
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Postal code" }),
12994
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
12995
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12996
+ ] })
12997
+ }
12998
+ ),
12999
+ /* @__PURE__ */ jsxRuntime.jsx(
13000
+ Form$2.Field,
13001
+ {
13002
+ control: form.control,
13003
+ name: "city",
13004
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
13005
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "City" }),
13006
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
13007
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
13008
+ ] })
13009
+ }
13010
+ )
13011
+ ] }),
13012
+ /* @__PURE__ */ jsxRuntime.jsx(
13013
+ Form$2.Field,
13014
+ {
13015
+ control: form.control,
13016
+ name: "province",
13017
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
13018
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { optional: true, children: "Province / State" }),
13019
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
13020
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
13021
+ ] })
13022
+ }
13023
+ ),
13024
+ /* @__PURE__ */ jsxRuntime.jsx(
13025
+ Form$2.Field,
13026
+ {
13027
+ control: form.control,
13028
+ name: "phone",
13029
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
13030
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { optional: true, children: "Phone" }),
13031
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
13032
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
13033
+ ] })
13034
+ }
13035
+ )
13036
+ ] }) }),
13037
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
13038
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
12943
13039
  /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
12944
13040
  ] }) })
12945
13041
  ]
12946
13042
  }
12947
13043
  ) });
12948
13044
  };
12949
- const GridInput = React.forwardRef(({ className, ...props }, ref) => {
12950
- return /* @__PURE__ */ jsxRuntime.jsx(
12951
- "input",
12952
- {
12953
- ref,
12954
- ...props,
12955
- autoComplete: "off",
12956
- className: ui.clx(
12957
- "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",
12958
- className
12959
- )
12960
- }
12961
- );
12962
- });
12963
- GridInput.displayName = "MetadataForm.GridInput";
12964
- const PlaceholderInner = () => {
12965
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-1 flex-col overflow-hidden", children: [
12966
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-[148ox] w-full rounded-lg" }) }),
12967
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
12968
- /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-7 w-12 rounded-md" }),
12969
- /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-7 w-12 rounded-md" })
12970
- ] }) })
12971
- ] });
12972
- };
12973
- const EDITABLE_TYPES = ["string", "number", "boolean"];
12974
- function getDefaultValues(metadata) {
12975
- if (!metadata || !Object.keys(metadata).length) {
12976
- return [
12977
- {
12978
- key: "",
12979
- value: "",
12980
- disabled: false
12981
- }
12982
- ];
12983
- }
12984
- return Object.entries(metadata).map(([key, value]) => {
12985
- if (!EDITABLE_TYPES.includes(typeof value)) {
12986
- return {
12987
- key,
12988
- value,
12989
- disabled: true
12990
- };
12991
- }
12992
- let stringValue = value;
12993
- if (typeof value !== "string") {
12994
- stringValue = JSON.stringify(value);
12995
- }
12996
- return {
12997
- key,
12998
- value: stringValue,
12999
- original_key: key
13000
- };
13001
- });
13002
- }
13003
- function parseValues(values) {
13004
- const metadata = values.metadata;
13005
- const isEmpty = !metadata.length || metadata.length === 1 && !metadata[0].key && !metadata[0].value;
13006
- if (isEmpty) {
13007
- return null;
13008
- }
13009
- const update = {};
13010
- metadata.forEach((field) => {
13011
- let key = field.key;
13012
- let value = field.value;
13013
- const disabled = field.disabled;
13014
- if (!key || !value) {
13015
- return;
13016
- }
13017
- if (disabled) {
13018
- update[key] = value;
13019
- return;
13020
- }
13021
- key = key.trim();
13022
- value = value.trim();
13023
- if (value === "true") {
13024
- update[key] = true;
13025
- } else if (value === "false") {
13026
- update[key] = false;
13027
- } else {
13028
- const parsedNumber = parseFloat(value);
13029
- if (!isNaN(parsedNumber)) {
13030
- update[key] = parsedNumber;
13031
- } else {
13032
- update[key] = value;
13033
- }
13034
- }
13035
- });
13036
- return update;
13037
- }
13038
- function getHasUneditableRows(metadata) {
13039
- if (!metadata) {
13040
- return false;
13041
- }
13042
- return Object.values(metadata).some(
13043
- (value) => !EDITABLE_TYPES.includes(typeof value)
13044
- );
13045
- }
13045
+ const schema = addressSchema;
13046
13046
  const widgetModule = { widgets: [] };
13047
13047
  const routeModule = {
13048
13048
  routes: [
@@ -13067,30 +13067,30 @@ const routeModule = {
13067
13067
  Component: CustomItems,
13068
13068
  path: "/draft-orders/:id/custom-items"
13069
13069
  },
13070
- {
13071
- Component: Email,
13072
- path: "/draft-orders/:id/email"
13073
- },
13074
- {
13075
- Component: BillingAddress,
13076
- path: "/draft-orders/:id/billing-address"
13077
- },
13078
13070
  {
13079
13071
  Component: Items,
13080
13072
  path: "/draft-orders/:id/items"
13081
13073
  },
13074
+ {
13075
+ Component: Metadata,
13076
+ path: "/draft-orders/:id/metadata"
13077
+ },
13082
13078
  {
13083
13079
  Component: Promotions,
13084
13080
  path: "/draft-orders/:id/promotions"
13085
13081
  },
13086
13082
  {
13087
- Component: Shipping,
13088
- path: "/draft-orders/:id/shipping"
13083
+ Component: Email,
13084
+ path: "/draft-orders/:id/email"
13089
13085
  },
13090
13086
  {
13091
13087
  Component: SalesChannel,
13092
13088
  path: "/draft-orders/:id/sales-channel"
13093
13089
  },
13090
+ {
13091
+ Component: Shipping,
13092
+ path: "/draft-orders/:id/shipping"
13093
+ },
13094
13094
  {
13095
13095
  Component: ShippingAddress,
13096
13096
  path: "/draft-orders/:id/shipping-address"
@@ -13100,8 +13100,8 @@ const routeModule = {
13100
13100
  path: "/draft-orders/:id/transfer-ownership"
13101
13101
  },
13102
13102
  {
13103
- Component: Metadata,
13104
- path: "/draft-orders/:id/metadata"
13103
+ Component: BillingAddress,
13104
+ path: "/draft-orders/:id/billing-address"
13105
13105
  }
13106
13106
  ]
13107
13107
  }