@medusajs/draft-order 2.11.1-snapshot-20251021080449 → 2.11.1-snapshot-20251021090705

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