@medusajs/draft-order 2.10.3-preview-20250914031450 → 2.10.3-preview-20250914090153

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