@medusajs/draft-order 2.11.0-preview-20251016000321 → 2.11.0-preview-20251016060156

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -9573,27 +9573,6 @@ const ID = () => {
9573
9573
  /* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Outlet, {})
9574
9574
  ] });
9575
9575
  };
9576
- const CustomItems = () => {
9577
- return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
9578
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Custom Items" }) }) }),
9579
- /* @__PURE__ */ jsxRuntime.jsx(CustomItemsForm, {})
9580
- ] });
9581
- };
9582
- const CustomItemsForm = () => {
9583
- const form = reactHookForm.useForm({
9584
- resolver: zod.zodResolver(schema$5)
9585
- });
9586
- return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(KeyboundForm, { className: "flex flex-1 flex-col", children: [
9587
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, {}),
9588
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
9589
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
9590
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", children: "Save" })
9591
- ] }) })
9592
- ] }) });
9593
- };
9594
- const schema$5 = objectType({
9595
- email: stringType().email()
9596
- });
9597
9576
  const BillingAddress = () => {
9598
9577
  const { id } = reactRouterDom.useParams();
9599
9578
  const { order, isPending, isError, error } = useOrder(id, {
@@ -9626,7 +9605,7 @@ const BillingAddressForm = ({ order }) => {
9626
9605
  postal_code: ((_i = order.billing_address) == null ? void 0 : _i.postal_code) ?? "",
9627
9606
  phone: ((_j = order.billing_address) == null ? void 0 : _j.phone) ?? ""
9628
9607
  },
9629
- resolver: zod.zodResolver(schema$4)
9608
+ resolver: zod.zodResolver(schema$5)
9630
9609
  });
9631
9610
  const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
9632
9611
  const { handleSuccess } = useRouteModal();
@@ -9783,7 +9762,7 @@ const BillingAddressForm = ({ order }) => {
9783
9762
  }
9784
9763
  ) });
9785
9764
  };
9786
- const schema$4 = addressSchema;
9765
+ const schema$5 = addressSchema;
9787
9766
  const Email = () => {
9788
9767
  const { id } = reactRouterDom.useParams();
9789
9768
  const { order, isPending, isError, error } = useOrder(id, {
@@ -9806,7 +9785,7 @@ const EmailForm = ({ order }) => {
9806
9785
  defaultValues: {
9807
9786
  email: order.email ?? ""
9808
9787
  },
9809
- resolver: zod.zodResolver(schema$3)
9788
+ resolver: zod.zodResolver(schema$4)
9810
9789
  });
9811
9790
  const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
9812
9791
  const { handleSuccess } = useRouteModal();
@@ -9849,115 +9828,459 @@ const EmailForm = ({ order }) => {
9849
9828
  }
9850
9829
  ) });
9851
9830
  };
9831
+ const schema$4 = objectType({
9832
+ email: stringType().email()
9833
+ });
9834
+ const CustomItems = () => {
9835
+ return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
9836
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Custom Items" }) }) }),
9837
+ /* @__PURE__ */ jsxRuntime.jsx(CustomItemsForm, {})
9838
+ ] });
9839
+ };
9840
+ const CustomItemsForm = () => {
9841
+ const form = reactHookForm.useForm({
9842
+ resolver: zod.zodResolver(schema$3)
9843
+ });
9844
+ return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(KeyboundForm, { className: "flex flex-1 flex-col", children: [
9845
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, {}),
9846
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
9847
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
9848
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", children: "Save" })
9849
+ ] }) })
9850
+ ] }) });
9851
+ };
9852
9852
  const schema$3 = objectType({
9853
9853
  email: stringType().email()
9854
9854
  });
9855
- const InlineTip = React.forwardRef(
9856
- ({ variant = "tip", label, className, children, ...props }, ref) => {
9857
- const labelValue = label || (variant === "warning" ? "Warning" : "Tip");
9858
- return /* @__PURE__ */ jsxRuntime.jsxs(
9859
- "div",
9860
- {
9861
- ref,
9862
- className: ui.clx(
9863
- "bg-ui-bg-component txt-small text-ui-fg-subtle grid grid-cols-[4px_1fr] items-start gap-3 rounded-lg border p-3",
9864
- className
9865
- ),
9866
- ...props,
9867
- children: [
9868
- /* @__PURE__ */ jsxRuntime.jsx(
9869
- "div",
9870
- {
9871
- role: "presentation",
9872
- className: ui.clx("w-4px bg-ui-tag-neutral-icon h-full rounded-full", {
9873
- "bg-ui-tag-orange-icon": variant === "warning"
9874
- })
9875
- }
9876
- ),
9877
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-pretty", children: [
9878
- /* @__PURE__ */ jsxRuntime.jsxs("strong", { className: "txt-small-plus text-ui-fg-base", children: [
9879
- labelValue,
9880
- ":"
9881
- ] }),
9882
- " ",
9883
- children
9884
- ] })
9885
- ]
9855
+ const PROMOTION_QUERY_KEY = "promotions";
9856
+ const promotionsQueryKeys = {
9857
+ list: (query2) => [
9858
+ PROMOTION_QUERY_KEY,
9859
+ query2 ? query2 : void 0
9860
+ ],
9861
+ detail: (id, query2) => [
9862
+ PROMOTION_QUERY_KEY,
9863
+ id,
9864
+ query2 ? query2 : void 0
9865
+ ]
9866
+ };
9867
+ const usePromotions = (query2, options) => {
9868
+ const { data, ...rest } = reactQuery.useQuery({
9869
+ queryKey: promotionsQueryKeys.list(query2),
9870
+ queryFn: async () => sdk.admin.promotion.list(query2),
9871
+ ...options
9872
+ });
9873
+ return { ...data, ...rest };
9874
+ };
9875
+ const useCancelOrderEdit = ({ preview }) => {
9876
+ const { mutateAsync: cancelOrderEdit } = useDraftOrderCancelEdit(preview == null ? void 0 : preview.id);
9877
+ const onCancel = React.useCallback(async () => {
9878
+ if (!preview) {
9879
+ return true;
9880
+ }
9881
+ let res = false;
9882
+ await cancelOrderEdit(void 0, {
9883
+ onError: (e) => {
9884
+ ui.toast.error(e.message);
9885
+ },
9886
+ onSuccess: () => {
9887
+ res = true;
9886
9888
  }
9887
- );
9888
- }
9889
- );
9890
- InlineTip.displayName = "InlineTip";
9891
- const MetadataFieldSchema = objectType({
9892
- key: stringType(),
9893
- disabled: booleanType().optional(),
9894
- value: anyType()
9895
- });
9896
- const MetadataSchema = objectType({
9897
- metadata: arrayType(MetadataFieldSchema)
9898
- });
9899
- const Metadata = () => {
9889
+ });
9890
+ return res;
9891
+ }, [preview, cancelOrderEdit]);
9892
+ return { onCancel };
9893
+ };
9894
+ let IS_REQUEST_RUNNING = false;
9895
+ const useInitiateOrderEdit = ({
9896
+ preview
9897
+ }) => {
9898
+ const navigate = reactRouterDom.useNavigate();
9899
+ const { mutateAsync } = useDraftOrderBeginEdit(preview == null ? void 0 : preview.id);
9900
+ React.useEffect(() => {
9901
+ async function run() {
9902
+ if (IS_REQUEST_RUNNING || !preview) {
9903
+ return;
9904
+ }
9905
+ if (preview.order_change) {
9906
+ return;
9907
+ }
9908
+ IS_REQUEST_RUNNING = true;
9909
+ await mutateAsync(void 0, {
9910
+ onError: (e) => {
9911
+ ui.toast.error(e.message);
9912
+ navigate(`/draft-orders/${preview.id}`, { replace: true });
9913
+ return;
9914
+ }
9915
+ });
9916
+ IS_REQUEST_RUNNING = false;
9917
+ }
9918
+ run();
9919
+ }, [preview, navigate, mutateAsync]);
9920
+ };
9921
+ const Promotions = () => {
9900
9922
  const { id } = reactRouterDom.useParams();
9901
- const { order, isPending, isError, error } = useOrder(id, {
9902
- fields: "metadata"
9903
- });
9904
- if (isError) {
9905
- throw error;
9923
+ const {
9924
+ order: preview,
9925
+ isError: isPreviewError,
9926
+ error: previewError
9927
+ } = useOrderPreview(id, void 0);
9928
+ useInitiateOrderEdit({ preview });
9929
+ const { onCancel } = useCancelOrderEdit({ preview });
9930
+ if (isPreviewError) {
9931
+ throw previewError;
9906
9932
  }
9907
- const isReady = !isPending && !!order;
9908
- return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
9909
- /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Header, { children: [
9910
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Metadata" }) }),
9911
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Add metadata to the draft order." }) })
9912
- ] }),
9913
- !isReady ? /* @__PURE__ */ jsxRuntime.jsx(PlaceholderInner, {}) : /* @__PURE__ */ jsxRuntime.jsx(MetadataForm, { orderId: id, metadata: order == null ? void 0 : order.metadata })
9933
+ const isReady = !!preview;
9934
+ return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { onClose: onCancel, children: [
9935
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Promotions" }) }) }),
9936
+ isReady && /* @__PURE__ */ jsxRuntime.jsx(PromotionForm, { preview })
9914
9937
  ] });
9915
9938
  };
9916
- const METADATA_KEY_LABEL_ID = "metadata-form-key-label";
9917
- const METADATA_VALUE_LABEL_ID = "metadata-form-value-label";
9918
- const MetadataForm = ({ orderId, metadata }) => {
9939
+ const PromotionForm = ({ preview }) => {
9940
+ const { items, shipping_methods } = preview;
9941
+ const [isSubmitting, setIsSubmitting] = React.useState(false);
9942
+ const [comboboxValue, setComboboxValue] = React.useState("");
9919
9943
  const { handleSuccess } = useRouteModal();
9920
- const hasUneditableRows = getHasUneditableRows(metadata);
9921
- const { mutateAsync, isPending } = useUpdateDraftOrder(orderId);
9922
- const form = reactHookForm.useForm({
9923
- defaultValues: {
9924
- metadata: getDefaultValues(metadata)
9944
+ const { mutateAsync: addPromotions, isPending: isAddingPromotions } = useDraftOrderAddPromotions(preview.id);
9945
+ const promoIds = getPromotionIds(items, shipping_methods);
9946
+ const { promotions, isPending, isError, error } = usePromotions(
9947
+ {
9948
+ id: promoIds
9925
9949
  },
9926
- resolver: zod.zodResolver(MetadataSchema)
9950
+ {
9951
+ enabled: !!promoIds.length
9952
+ }
9953
+ );
9954
+ const comboboxData = useComboboxData({
9955
+ queryKey: ["promotions", "combobox", promoIds],
9956
+ queryFn: async (params) => {
9957
+ return await sdk.admin.promotion.list({
9958
+ ...params,
9959
+ id: {
9960
+ $nin: promoIds
9961
+ }
9962
+ });
9963
+ },
9964
+ getOptions: (data) => {
9965
+ return data.promotions.map((promotion) => ({
9966
+ label: promotion.code,
9967
+ value: promotion.code
9968
+ }));
9969
+ }
9927
9970
  });
9928
- const handleSubmit = form.handleSubmit(async (data) => {
9929
- const parsedData = parseValues(data);
9930
- await mutateAsync(
9971
+ const add = async (value) => {
9972
+ if (!value) {
9973
+ return;
9974
+ }
9975
+ addPromotions(
9931
9976
  {
9932
- metadata: parsedData
9977
+ promo_codes: [value]
9933
9978
  },
9934
9979
  {
9935
- onSuccess: () => {
9936
- ui.toast.success("Metadata updated");
9937
- handleSuccess();
9980
+ onError: (e) => {
9981
+ ui.toast.error(e.message);
9982
+ comboboxData.onSearchValueChange("");
9983
+ setComboboxValue("");
9938
9984
  },
9939
- onError: (error) => {
9940
- ui.toast.error(error.message);
9985
+ onSuccess: () => {
9986
+ comboboxData.onSearchValueChange("");
9987
+ setComboboxValue("");
9941
9988
  }
9942
9989
  }
9943
9990
  );
9944
- });
9945
- const { fields, insert, remove } = reactHookForm.useFieldArray({
9946
- control: form.control,
9947
- name: "metadata"
9948
- });
9949
- function deleteRow(index) {
9950
- remove(index);
9951
- if (fields.length === 1) {
9952
- insert(0, {
9953
- key: "",
9954
- value: "",
9955
- disabled: false
9956
- });
9957
- }
9958
- }
9959
- function insertRow(index, position) {
9960
- insert(index + (position === "above" ? 0 : 1), {
9991
+ };
9992
+ const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
9993
+ const { mutateAsync: requestOrderEdit } = useOrderEditRequest(preview.id);
9994
+ const onSubmit = async () => {
9995
+ setIsSubmitting(true);
9996
+ let requestSucceeded = false;
9997
+ await requestOrderEdit(void 0, {
9998
+ onError: (e) => {
9999
+ ui.toast.error(e.message);
10000
+ },
10001
+ onSuccess: () => {
10002
+ requestSucceeded = true;
10003
+ }
10004
+ });
10005
+ if (!requestSucceeded) {
10006
+ setIsSubmitting(false);
10007
+ return;
10008
+ }
10009
+ await confirmOrderEdit(void 0, {
10010
+ onError: (e) => {
10011
+ ui.toast.error(e.message);
10012
+ },
10013
+ onSuccess: () => {
10014
+ handleSuccess();
10015
+ },
10016
+ onSettled: () => {
10017
+ setIsSubmitting(false);
10018
+ }
10019
+ });
10020
+ };
10021
+ if (isError) {
10022
+ throw error;
10023
+ }
10024
+ return /* @__PURE__ */ jsxRuntime.jsxs(KeyboundForm, { className: "flex flex-1 flex-col", onSubmit, children: [
10025
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-4", children: [
10026
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
10027
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
10028
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Label, { size: "small", weight: "plus", htmlFor: "promotion-combobox", children: "Apply promotions" }),
10029
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Hint, { id: "promotion-combobox-hint", children: "Manage promotions that should be applied to the order." })
10030
+ ] }),
10031
+ /* @__PURE__ */ jsxRuntime.jsx(
10032
+ Combobox,
10033
+ {
10034
+ id: "promotion-combobox",
10035
+ "aria-describedby": "promotion-combobox-hint",
10036
+ isFetchingNextPage: comboboxData.isFetchingNextPage,
10037
+ fetchNextPage: comboboxData.fetchNextPage,
10038
+ options: comboboxData.options,
10039
+ onSearchValueChange: comboboxData.onSearchValueChange,
10040
+ searchValue: comboboxData.searchValue,
10041
+ disabled: comboboxData.disabled || isAddingPromotions,
10042
+ onChange: add,
10043
+ value: comboboxValue
10044
+ }
10045
+ )
10046
+ ] }),
10047
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
10048
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-2", children: promotions == null ? void 0 : promotions.map((promotion) => /* @__PURE__ */ jsxRuntime.jsx(
10049
+ PromotionItem,
10050
+ {
10051
+ promotion,
10052
+ orderId: preview.id,
10053
+ isLoading: isPending
10054
+ },
10055
+ promotion.id
10056
+ )) })
10057
+ ] }) }),
10058
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
10059
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
10060
+ /* @__PURE__ */ jsxRuntime.jsx(
10061
+ ui.Button,
10062
+ {
10063
+ size: "small",
10064
+ type: "submit",
10065
+ isLoading: isSubmitting || isAddingPromotions,
10066
+ children: "Save"
10067
+ }
10068
+ )
10069
+ ] }) })
10070
+ ] });
10071
+ };
10072
+ const PromotionItem = ({
10073
+ promotion,
10074
+ orderId,
10075
+ isLoading
10076
+ }) => {
10077
+ var _a;
10078
+ const { mutateAsync: removePromotions, isPending } = useDraftOrderRemovePromotions(orderId);
10079
+ const onRemove = async () => {
10080
+ removePromotions(
10081
+ {
10082
+ promo_codes: [promotion.code]
10083
+ },
10084
+ {
10085
+ onError: (e) => {
10086
+ ui.toast.error(e.message);
10087
+ }
10088
+ }
10089
+ );
10090
+ };
10091
+ const displayValue = getDisplayValue(promotion);
10092
+ return /* @__PURE__ */ jsxRuntime.jsxs(
10093
+ "div",
10094
+ {
10095
+ className: ui.clx(
10096
+ "bg-ui-bg-component shadow-elevation-card-rest flex items-center justify-between rounded-lg px-3 py-2",
10097
+ {
10098
+ "animate-pulse": isLoading
10099
+ }
10100
+ ),
10101
+ children: [
10102
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10103
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: promotion.code }),
10104
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-ui-fg-subtle flex items-center gap-1.5", children: [
10105
+ displayValue && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
10106
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", children: displayValue }),
10107
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", children: "·" })
10108
+ ] }),
10109
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", className: "capitalize", children: (_a = promotion.application_method) == null ? void 0 : _a.allocation })
10110
+ ] })
10111
+ ] }),
10112
+ /* @__PURE__ */ jsxRuntime.jsx(
10113
+ ui.IconButton,
10114
+ {
10115
+ size: "small",
10116
+ type: "button",
10117
+ variant: "transparent",
10118
+ onClick: onRemove,
10119
+ isLoading: isPending || isLoading,
10120
+ children: /* @__PURE__ */ jsxRuntime.jsx(icons.XMark, {})
10121
+ }
10122
+ )
10123
+ ]
10124
+ },
10125
+ promotion.id
10126
+ );
10127
+ };
10128
+ function getDisplayValue(promotion) {
10129
+ var _a, _b, _c, _d;
10130
+ const value = (_a = promotion.application_method) == null ? void 0 : _a.value;
10131
+ if (!value) {
10132
+ return null;
10133
+ }
10134
+ if (((_b = promotion.application_method) == null ? void 0 : _b.type) === "fixed") {
10135
+ const currency = (_c = promotion.application_method) == null ? void 0 : _c.currency_code;
10136
+ if (!currency) {
10137
+ return null;
10138
+ }
10139
+ return getLocaleAmount(value, currency);
10140
+ } else if (((_d = promotion.application_method) == null ? void 0 : _d.type) === "percentage") {
10141
+ return formatPercentage(value);
10142
+ }
10143
+ return null;
10144
+ }
10145
+ const formatter = new Intl.NumberFormat([], {
10146
+ style: "percent",
10147
+ minimumFractionDigits: 2
10148
+ });
10149
+ const formatPercentage = (value, isPercentageValue = false) => {
10150
+ let val = value || 0;
10151
+ if (!isPercentageValue) {
10152
+ val = val / 100;
10153
+ }
10154
+ return formatter.format(val);
10155
+ };
10156
+ function getPromotionIds(items, shippingMethods) {
10157
+ const promotionIds = /* @__PURE__ */ new Set();
10158
+ for (const item of items) {
10159
+ if (item.adjustments) {
10160
+ for (const adjustment of item.adjustments) {
10161
+ if (adjustment.promotion_id) {
10162
+ promotionIds.add(adjustment.promotion_id);
10163
+ }
10164
+ }
10165
+ }
10166
+ }
10167
+ for (const shippingMethod of shippingMethods) {
10168
+ if (shippingMethod.adjustments) {
10169
+ for (const adjustment of shippingMethod.adjustments) {
10170
+ if (adjustment.promotion_id) {
10171
+ promotionIds.add(adjustment.promotion_id);
10172
+ }
10173
+ }
10174
+ }
10175
+ }
10176
+ return Array.from(promotionIds);
10177
+ }
10178
+ const InlineTip = React.forwardRef(
10179
+ ({ variant = "tip", label, className, children, ...props }, ref) => {
10180
+ const labelValue = label || (variant === "warning" ? "Warning" : "Tip");
10181
+ return /* @__PURE__ */ jsxRuntime.jsxs(
10182
+ "div",
10183
+ {
10184
+ ref,
10185
+ className: ui.clx(
10186
+ "bg-ui-bg-component txt-small text-ui-fg-subtle grid grid-cols-[4px_1fr] items-start gap-3 rounded-lg border p-3",
10187
+ className
10188
+ ),
10189
+ ...props,
10190
+ children: [
10191
+ /* @__PURE__ */ jsxRuntime.jsx(
10192
+ "div",
10193
+ {
10194
+ role: "presentation",
10195
+ className: ui.clx("w-4px bg-ui-tag-neutral-icon h-full rounded-full", {
10196
+ "bg-ui-tag-orange-icon": variant === "warning"
10197
+ })
10198
+ }
10199
+ ),
10200
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-pretty", children: [
10201
+ /* @__PURE__ */ jsxRuntime.jsxs("strong", { className: "txt-small-plus text-ui-fg-base", children: [
10202
+ labelValue,
10203
+ ":"
10204
+ ] }),
10205
+ " ",
10206
+ children
10207
+ ] })
10208
+ ]
10209
+ }
10210
+ );
10211
+ }
10212
+ );
10213
+ InlineTip.displayName = "InlineTip";
10214
+ const MetadataFieldSchema = objectType({
10215
+ key: stringType(),
10216
+ disabled: booleanType().optional(),
10217
+ value: anyType()
10218
+ });
10219
+ const MetadataSchema = objectType({
10220
+ metadata: arrayType(MetadataFieldSchema)
10221
+ });
10222
+ const Metadata = () => {
10223
+ const { id } = reactRouterDom.useParams();
10224
+ const { order, isPending, isError, error } = useOrder(id, {
10225
+ fields: "metadata"
10226
+ });
10227
+ if (isError) {
10228
+ throw error;
10229
+ }
10230
+ const isReady = !isPending && !!order;
10231
+ return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
10232
+ /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Header, { children: [
10233
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Metadata" }) }),
10234
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Add metadata to the draft order." }) })
10235
+ ] }),
10236
+ !isReady ? /* @__PURE__ */ jsxRuntime.jsx(PlaceholderInner, {}) : /* @__PURE__ */ jsxRuntime.jsx(MetadataForm, { orderId: id, metadata: order == null ? void 0 : order.metadata })
10237
+ ] });
10238
+ };
10239
+ const METADATA_KEY_LABEL_ID = "metadata-form-key-label";
10240
+ const METADATA_VALUE_LABEL_ID = "metadata-form-value-label";
10241
+ const MetadataForm = ({ orderId, metadata }) => {
10242
+ const { handleSuccess } = useRouteModal();
10243
+ const hasUneditableRows = getHasUneditableRows(metadata);
10244
+ const { mutateAsync, isPending } = useUpdateDraftOrder(orderId);
10245
+ const form = reactHookForm.useForm({
10246
+ defaultValues: {
10247
+ metadata: getDefaultValues(metadata)
10248
+ },
10249
+ resolver: zod.zodResolver(MetadataSchema)
10250
+ });
10251
+ const handleSubmit = form.handleSubmit(async (data) => {
10252
+ const parsedData = parseValues(data);
10253
+ await mutateAsync(
10254
+ {
10255
+ metadata: parsedData
10256
+ },
10257
+ {
10258
+ onSuccess: () => {
10259
+ ui.toast.success("Metadata updated");
10260
+ handleSuccess();
10261
+ },
10262
+ onError: (error) => {
10263
+ ui.toast.error(error.message);
10264
+ }
10265
+ }
10266
+ );
10267
+ });
10268
+ const { fields, insert, remove } = reactHookForm.useFieldArray({
10269
+ control: form.control,
10270
+ name: "metadata"
10271
+ });
10272
+ function deleteRow(index) {
10273
+ remove(index);
10274
+ if (fields.length === 1) {
10275
+ insert(0, {
10276
+ key: "",
10277
+ value: "",
10278
+ disabled: false
10279
+ });
10280
+ }
10281
+ }
10282
+ function insertRow(index, position) {
10283
+ insert(index + (position === "above" ? 0 : 1), {
9961
10284
  key: "",
9962
10285
  value: "",
9963
10286
  disabled: false
@@ -10327,52 +10650,6 @@ const useProductVariants = (query2, options) => {
10327
10650
  });
10328
10651
  return { ...data, ...rest };
10329
10652
  };
10330
- const useCancelOrderEdit = ({ preview }) => {
10331
- const { mutateAsync: cancelOrderEdit } = useDraftOrderCancelEdit(preview == null ? void 0 : preview.id);
10332
- const onCancel = React.useCallback(async () => {
10333
- if (!preview) {
10334
- return true;
10335
- }
10336
- let res = false;
10337
- await cancelOrderEdit(void 0, {
10338
- onError: (e) => {
10339
- ui.toast.error(e.message);
10340
- },
10341
- onSuccess: () => {
10342
- res = true;
10343
- }
10344
- });
10345
- return res;
10346
- }, [preview, cancelOrderEdit]);
10347
- return { onCancel };
10348
- };
10349
- let IS_REQUEST_RUNNING = false;
10350
- const useInitiateOrderEdit = ({
10351
- preview
10352
- }) => {
10353
- const navigate = reactRouterDom.useNavigate();
10354
- const { mutateAsync } = useDraftOrderBeginEdit(preview == null ? void 0 : preview.id);
10355
- React.useEffect(() => {
10356
- async function run() {
10357
- if (IS_REQUEST_RUNNING || !preview) {
10358
- return;
10359
- }
10360
- if (preview.order_change) {
10361
- return;
10362
- }
10363
- IS_REQUEST_RUNNING = true;
10364
- await mutateAsync(void 0, {
10365
- onError: (e) => {
10366
- ui.toast.error(e.message);
10367
- navigate(`/draft-orders/${preview.id}`, { replace: true });
10368
- return;
10369
- }
10370
- });
10371
- IS_REQUEST_RUNNING = false;
10372
- }
10373
- run();
10374
- }, [preview, navigate, mutateAsync]);
10375
- };
10376
10653
  function convertNumber(value) {
10377
10654
  return typeof value === "string" ? Number(value.replace(",", ".")) : value;
10378
10655
  }
@@ -10620,155 +10897,7 @@ const VariantItem = ({ item, preview, currencyCode }) => {
10620
10897
  const { mutateAsync: updateOriginalItem, isPending: isUpdatingOriginalItem } = useDraftOrderUpdateItem(preview.id);
10621
10898
  const isPending = isUpdatingActionItem || isUpdatingOriginalItem;
10622
10899
  const onSubmit = form.handleSubmit(async (data) => {
10623
- if (convertNumber(data.unit_price) === item.unit_price && data.quantity === item.quantity) {
10624
- setEditing(false);
10625
- return;
10626
- }
10627
- if (!actionId) {
10628
- await updateOriginalItem(
10629
- {
10630
- item_id: item.id,
10631
- quantity: data.quantity,
10632
- unit_price: convertNumber(data.unit_price)
10633
- },
10634
- {
10635
- onSuccess: () => {
10636
- setEditing(false);
10637
- },
10638
- onError: (e) => {
10639
- ui.toast.error(e.message);
10640
- }
10641
- }
10642
- );
10643
- return;
10644
- }
10645
- await updateActionItem(
10646
- {
10647
- action_id: actionId,
10648
- quantity: data.quantity,
10649
- unit_price: convertNumber(data.unit_price)
10650
- },
10651
- {
10652
- onSuccess: () => {
10653
- setEditing(false);
10654
- },
10655
- onError: (e) => {
10656
- ui.toast.error(e.message);
10657
- }
10658
- }
10659
- );
10660
- });
10661
- 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: [
10662
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full items-center gap-x-3", children: [
10663
- /* @__PURE__ */ jsxRuntime.jsx(
10664
- Thumbnail,
10665
- {
10666
- thumbnail: item.thumbnail,
10667
- alt: item.product_title ?? void 0
10668
- }
10669
- ),
10670
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
10671
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-1", children: [
10672
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: item.product_title }),
10673
- /* @__PURE__ */ jsxRuntime.jsxs(
10674
- ui.Text,
10675
- {
10676
- size: "small",
10677
- leading: "compact",
10678
- className: "text-ui-fg-subtle",
10679
- children: [
10680
- "(",
10681
- item.variant_title,
10682
- ")"
10683
- ]
10684
- }
10685
- )
10686
- ] }),
10687
- /* @__PURE__ */ jsxRuntime.jsx(
10688
- ui.Text,
10689
- {
10690
- size: "small",
10691
- leading: "compact",
10692
- className: "text-ui-fg-subtle",
10693
- children: item.variant_sku
10694
- }
10695
- )
10696
- ] })
10697
- ] }),
10698
- editing ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(
10699
- Form$2.Field,
10700
- {
10701
- control: form.control,
10702
- name: "quantity",
10703
- render: ({ field }) => {
10704
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(NumberInput, { ...field }) }) });
10705
- }
10706
- }
10707
- ) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: item.quantity }) }),
10708
- editing ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(
10709
- Form$2.Field,
10710
- {
10711
- control: form.control,
10712
- name: "unit_price",
10713
- render: ({ field: { onChange, ...field } }) => {
10714
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
10715
- ui.CurrencyInput,
10716
- {
10717
- ...field,
10718
- symbol: getNativeSymbol(currencyCode),
10719
- code: currencyCode,
10720
- onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value)
10721
- }
10722
- ) }) });
10723
- }
10724
- }
10725
- ) }) : /* @__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) }) }),
10726
- /* @__PURE__ */ jsxRuntime.jsx(
10727
- ui.IconButton,
10728
- {
10729
- type: "button",
10730
- size: "small",
10731
- onClick: editing ? onSubmit : () => {
10732
- setEditing(true);
10733
- },
10734
- disabled: isPending,
10735
- children: editing ? /* @__PURE__ */ jsxRuntime.jsx(icons.Check, {}) : /* @__PURE__ */ jsxRuntime.jsx(icons.PencilSquare, {})
10736
- }
10737
- )
10738
- ] }) }) });
10739
- };
10740
- const variantItemSchema = objectType({
10741
- quantity: numberType(),
10742
- unit_price: unionType([numberType(), stringType()])
10743
- });
10744
- const CustomItem = ({ item, preview, currencyCode }) => {
10745
- const [editing, setEditing] = React.useState(false);
10746
- const { quantity, unit_price, title } = item;
10747
- const form = reactHookForm.useForm({
10748
- defaultValues: {
10749
- title,
10750
- quantity,
10751
- unit_price
10752
- },
10753
- resolver: zod.zodResolver(customItemSchema)
10754
- });
10755
- React.useEffect(() => {
10756
- form.reset({
10757
- title,
10758
- quantity,
10759
- unit_price
10760
- });
10761
- }, [form, title, quantity, unit_price]);
10762
- const actionId = React.useMemo(() => {
10763
- var _a, _b;
10764
- return (_b = (_a = item.actions) == null ? void 0 : _a.find((a) => a.action === "ITEM_ADD")) == null ? void 0 : _b.id;
10765
- }, [item]);
10766
- const { mutateAsync: updateActionItem, isPending: isUpdatingActionItem } = useDraftOrderUpdateActionItem(preview.id);
10767
- const { mutateAsync: removeActionItem, isPending: isRemovingActionItem } = useDraftOrderRemoveActionItem(preview.id);
10768
- const { mutateAsync: updateOriginalItem, isPending: isUpdatingOriginalItem } = useDraftOrderUpdateItem(preview.id);
10769
- const isPending = isUpdatingActionItem || isUpdatingOriginalItem;
10770
- const onSubmit = form.handleSubmit(async (data) => {
10771
- if (convertNumber(data.unit_price) === item.unit_price && data.quantity === item.quantity && data.title === item.title) {
10900
+ if (convertNumber(data.unit_price) === item.unit_price && data.quantity === item.quantity) {
10772
10901
  setEditing(false);
10773
10902
  return;
10774
10903
  }
@@ -10790,17 +10919,6 @@ const CustomItem = ({ item, preview, currencyCode }) => {
10790
10919
  );
10791
10920
  return;
10792
10921
  }
10793
- if (data.quantity === 0) {
10794
- await removeActionItem(actionId, {
10795
- onSuccess: () => {
10796
- setEditing(false);
10797
- },
10798
- onError: (e) => {
10799
- ui.toast.error(e.message);
10800
- }
10801
- });
10802
- return;
10803
- }
10804
10922
  await updateActionItem(
10805
10923
  {
10806
10924
  action_id: actionId,
@@ -10818,276 +10936,157 @@ const CustomItem = ({ item, preview, currencyCode }) => {
10818
10936
  );
10819
10937
  });
10820
10938
  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: [
10821
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-3", children: [
10939
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full items-center gap-x-3", children: [
10822
10940
  /* @__PURE__ */ jsxRuntime.jsx(
10823
10941
  Thumbnail,
10824
10942
  {
10825
10943
  thumbnail: item.thumbnail,
10826
- alt: item.title ?? void 0
10944
+ alt: item.product_title ?? void 0
10827
10945
  }
10828
10946
  ),
10829
- editing ? /* @__PURE__ */ jsxRuntime.jsx(
10830
- Form$2.Field,
10831
- {
10832
- control: form.control,
10833
- name: "title",
10834
- render: ({ field }) => {
10835
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }) });
10836
- }
10837
- }
10838
- ) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: item.title })
10839
- ] }),
10840
- editing ? /* @__PURE__ */ jsxRuntime.jsx(
10841
- Form$2.Field,
10842
- {
10843
- control: form.control,
10844
- name: "quantity",
10845
- render: ({ field }) => {
10846
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(NumberInput, { ...field }) }) });
10847
- }
10848
- }
10849
- ) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: item.quantity }),
10850
- editing ? /* @__PURE__ */ jsxRuntime.jsx(
10851
- Form$2.Field,
10852
- {
10853
- control: form.control,
10854
- name: "unit_price",
10855
- render: ({ field: { onChange, ...field } }) => {
10856
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
10857
- ui.CurrencyInput,
10947
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
10948
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-1", children: [
10949
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: item.product_title }),
10950
+ /* @__PURE__ */ jsxRuntime.jsxs(
10951
+ ui.Text,
10858
10952
  {
10859
- ...field,
10860
- symbol: getNativeSymbol(currencyCode),
10861
- code: currencyCode,
10862
- onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value)
10953
+ size: "small",
10954
+ leading: "compact",
10955
+ className: "text-ui-fg-subtle",
10956
+ children: [
10957
+ "(",
10958
+ item.variant_title,
10959
+ ")"
10960
+ ]
10863
10961
  }
10864
- ) }) });
10865
- }
10866
- }
10867
- ) : /* @__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) }) }),
10868
- /* @__PURE__ */ jsxRuntime.jsx(
10869
- ui.IconButton,
10870
- {
10871
- type: "button",
10872
- size: "small",
10873
- onClick: editing ? onSubmit : () => {
10874
- setEditing(true);
10875
- },
10876
- disabled: isPending,
10877
- children: editing ? /* @__PURE__ */ jsxRuntime.jsx(icons.Check, {}) : /* @__PURE__ */ jsxRuntime.jsx(icons.PencilSquare, {})
10878
- }
10879
- )
10880
- ] }) }) });
10881
- };
10882
- const StackedModalTrigger$1 = ({
10883
- type,
10884
- setModalContent
10885
- }) => {
10886
- const { setIsOpen } = useStackedModal();
10887
- const onClick = React.useCallback(() => {
10888
- setModalContent(type);
10889
- setIsOpen(STACKED_MODAL_ID, true);
10890
- }, [setModalContent, setIsOpen, type]);
10891
- 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" }) });
10892
- };
10893
- const VARIANT_PREFIX = "items";
10894
- const LIMIT = 50;
10895
- const ExistingItemsForm = ({ orderId, items }) => {
10896
- const { setIsOpen } = useStackedModal();
10897
- const [rowSelection, setRowSelection] = React.useState(
10898
- items.reduce((acc, item) => {
10899
- acc[item.variant_id] = true;
10900
- return acc;
10901
- }, {})
10902
- );
10903
- React.useEffect(() => {
10904
- setRowSelection(
10905
- items.reduce((acc, item) => {
10906
- if (item.variant_id) {
10907
- acc[item.variant_id] = true;
10908
- }
10909
- return acc;
10910
- }, {})
10911
- );
10912
- }, [items]);
10913
- const { q, order, offset } = useQueryParams(
10914
- ["q", "order", "offset"],
10915
- VARIANT_PREFIX
10916
- );
10917
- const { variants, count, isPending, isError, error } = useProductVariants(
10918
- {
10919
- q,
10920
- order,
10921
- offset: offset ? parseInt(offset) : void 0,
10922
- limit: LIMIT
10923
- },
10924
- {
10925
- placeholderData: reactQuery.keepPreviousData
10926
- }
10927
- );
10928
- const columns = useColumns();
10929
- const { mutateAsync } = useDraftOrderAddItems(orderId);
10930
- const onSubmit = async () => {
10931
- const ids = Object.keys(rowSelection).filter(
10932
- (id) => !items.find((i) => i.variant_id === id)
10933
- );
10934
- await mutateAsync(
10935
- {
10936
- items: ids.map((id) => ({
10937
- variant_id: id,
10938
- quantity: 1
10939
- }))
10940
- },
10941
- {
10942
- onSuccess: () => {
10943
- setRowSelection({});
10944
- setIsOpen(STACKED_MODAL_ID, false);
10945
- },
10946
- onError: (e) => {
10947
- ui.toast.error(e.message);
10948
- }
10949
- }
10950
- );
10951
- };
10952
- if (isError) {
10953
- throw error;
10954
- }
10955
- return /* @__PURE__ */ jsxRuntime.jsxs(
10956
- StackedFocusModal.Content,
10957
- {
10958
- onOpenAutoFocus: (e) => {
10959
- e.preventDefault();
10960
- const searchInput = document.querySelector(
10961
- "[data-modal-id='modal-search-input']"
10962
- );
10963
- if (searchInput) {
10964
- searchInput.focus();
10965
- }
10966
- },
10967
- children: [
10968
- /* @__PURE__ */ jsxRuntime.jsxs(StackedFocusModal.Header, { children: [
10969
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Product Variants" }) }),
10970
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Choose product variants to add to the order." }) })
10962
+ )
10971
10963
  ] }),
10972
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Body, { className: "flex-1 overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(
10973
- DataTable,
10964
+ /* @__PURE__ */ jsxRuntime.jsx(
10965
+ ui.Text,
10974
10966
  {
10975
- data: variants,
10976
- columns,
10977
- isLoading: isPending,
10978
- getRowId: (row) => row.id,
10979
- rowCount: count,
10980
- prefix: VARIANT_PREFIX,
10981
- layout: "fill",
10982
- rowSelection: {
10983
- state: rowSelection,
10984
- onRowSelectionChange: setRowSelection,
10985
- enableRowSelection: (row) => {
10986
- return !items.find((i) => i.variant_id === row.original.id);
10987
- }
10988
- },
10989
- autoFocusSearch: true
10990
- }
10991
- ) }),
10992
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
10993
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
10994
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "button", onClick: onSubmit, children: "Update items" })
10995
- ] }) })
10996
- ]
10997
- }
10998
- );
10999
- };
11000
- const columnHelper = ui.createDataTableColumnHelper();
11001
- const useColumns = () => {
11002
- return React.useMemo(() => {
11003
- return [
11004
- columnHelper.select(),
11005
- columnHelper.accessor("product.title", {
11006
- header: "Product",
11007
- cell: ({ row }) => {
11008
- var _a, _b, _c;
11009
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-2", children: [
11010
- /* @__PURE__ */ jsxRuntime.jsx(
11011
- Thumbnail,
11012
- {
11013
- thumbnail: (_a = row.original.product) == null ? void 0 : _a.thumbnail,
11014
- alt: (_b = row.original.product) == null ? void 0 : _b.title
11015
- }
11016
- ),
11017
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: (_c = row.original.product) == null ? void 0 : _c.title })
11018
- ] });
11019
- },
11020
- enableSorting: true
11021
- }),
11022
- columnHelper.accessor("title", {
11023
- header: "Variant",
11024
- enableSorting: true
11025
- }),
11026
- columnHelper.accessor("sku", {
11027
- header: "SKU",
11028
- cell: ({ getValue }) => {
11029
- return getValue() ?? "-";
11030
- },
11031
- enableSorting: true
11032
- }),
11033
- columnHelper.accessor("updated_at", {
11034
- header: "Updated",
11035
- cell: ({ getValue }) => {
11036
- return /* @__PURE__ */ jsxRuntime.jsx(
11037
- ui.Tooltip,
11038
- {
11039
- content: getFullDate({ date: getValue(), includeTime: true }),
11040
- children: /* @__PURE__ */ jsxRuntime.jsx("span", { children: getFullDate({ date: getValue() }) })
11041
- }
11042
- );
11043
- },
11044
- enableSorting: true,
11045
- sortAscLabel: "Oldest first",
11046
- sortDescLabel: "Newest first"
11047
- }),
11048
- columnHelper.accessor("created_at", {
11049
- header: "Created",
11050
- cell: ({ getValue }) => {
11051
- return /* @__PURE__ */ jsxRuntime.jsx(
11052
- ui.Tooltip,
10967
+ size: "small",
10968
+ leading: "compact",
10969
+ className: "text-ui-fg-subtle",
10970
+ children: item.variant_sku
10971
+ }
10972
+ )
10973
+ ] })
10974
+ ] }),
10975
+ editing ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(
10976
+ Form$2.Field,
10977
+ {
10978
+ control: form.control,
10979
+ name: "quantity",
10980
+ render: ({ field }) => {
10981
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(NumberInput, { ...field }) }) });
10982
+ }
10983
+ }
10984
+ ) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: item.quantity }) }),
10985
+ editing ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(
10986
+ Form$2.Field,
10987
+ {
10988
+ control: form.control,
10989
+ name: "unit_price",
10990
+ render: ({ field: { onChange, ...field } }) => {
10991
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
10992
+ ui.CurrencyInput,
11053
10993
  {
11054
- content: getFullDate({ date: getValue(), includeTime: true }),
11055
- children: /* @__PURE__ */ jsxRuntime.jsx("span", { children: getFullDate({ date: getValue() }) })
10994
+ ...field,
10995
+ symbol: getNativeSymbol(currencyCode),
10996
+ code: currencyCode,
10997
+ onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value)
11056
10998
  }
11057
- );
10999
+ ) }) });
11000
+ }
11001
+ }
11002
+ ) }) : /* @__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) }) }),
11003
+ /* @__PURE__ */ jsxRuntime.jsx(
11004
+ ui.IconButton,
11005
+ {
11006
+ type: "button",
11007
+ size: "small",
11008
+ onClick: editing ? onSubmit : () => {
11009
+ setEditing(true);
11058
11010
  },
11059
- enableSorting: true,
11060
- sortAscLabel: "Oldest first",
11061
- sortDescLabel: "Newest first"
11062
- })
11063
- ];
11064
- }, []);
11011
+ disabled: isPending,
11012
+ children: editing ? /* @__PURE__ */ jsxRuntime.jsx(icons.Check, {}) : /* @__PURE__ */ jsxRuntime.jsx(icons.PencilSquare, {})
11013
+ }
11014
+ )
11015
+ ] }) }) });
11065
11016
  };
11066
- const CustomItemForm = ({ orderId, currencyCode }) => {
11067
- const { setIsOpen } = useStackedModal();
11068
- const { mutateAsync: addItems } = useDraftOrderAddItems(orderId);
11017
+ const variantItemSchema = objectType({
11018
+ quantity: numberType(),
11019
+ unit_price: unionType([numberType(), stringType()])
11020
+ });
11021
+ const CustomItem = ({ item, preview, currencyCode }) => {
11022
+ const [editing, setEditing] = React.useState(false);
11023
+ const { quantity, unit_price, title } = item;
11069
11024
  const form = reactHookForm.useForm({
11070
11025
  defaultValues: {
11071
- title: "",
11072
- quantity: 1,
11073
- unit_price: ""
11026
+ title,
11027
+ quantity,
11028
+ unit_price
11074
11029
  },
11075
11030
  resolver: zod.zodResolver(customItemSchema)
11076
11031
  });
11032
+ React.useEffect(() => {
11033
+ form.reset({
11034
+ title,
11035
+ quantity,
11036
+ unit_price
11037
+ });
11038
+ }, [form, title, quantity, unit_price]);
11039
+ const actionId = React.useMemo(() => {
11040
+ var _a, _b;
11041
+ return (_b = (_a = item.actions) == null ? void 0 : _a.find((a) => a.action === "ITEM_ADD")) == null ? void 0 : _b.id;
11042
+ }, [item]);
11043
+ const { mutateAsync: updateActionItem, isPending: isUpdatingActionItem } = useDraftOrderUpdateActionItem(preview.id);
11044
+ const { mutateAsync: removeActionItem, isPending: isRemovingActionItem } = useDraftOrderRemoveActionItem(preview.id);
11045
+ const { mutateAsync: updateOriginalItem, isPending: isUpdatingOriginalItem } = useDraftOrderUpdateItem(preview.id);
11046
+ const isPending = isUpdatingActionItem || isUpdatingOriginalItem;
11077
11047
  const onSubmit = form.handleSubmit(async (data) => {
11078
- await addItems(
11079
- {
11080
- items: [
11081
- {
11082
- title: data.title,
11083
- quantity: data.quantity,
11084
- unit_price: convertNumber(data.unit_price)
11048
+ if (convertNumber(data.unit_price) === item.unit_price && data.quantity === item.quantity && data.title === item.title) {
11049
+ setEditing(false);
11050
+ return;
11051
+ }
11052
+ if (!actionId) {
11053
+ await updateOriginalItem(
11054
+ {
11055
+ item_id: item.id,
11056
+ quantity: data.quantity,
11057
+ unit_price: convertNumber(data.unit_price)
11058
+ },
11059
+ {
11060
+ onSuccess: () => {
11061
+ setEditing(false);
11062
+ },
11063
+ onError: (e) => {
11064
+ ui.toast.error(e.message);
11085
11065
  }
11086
- ]
11066
+ }
11067
+ );
11068
+ return;
11069
+ }
11070
+ if (data.quantity === 0) {
11071
+ await removeActionItem(actionId, {
11072
+ onSuccess: () => {
11073
+ setEditing(false);
11074
+ },
11075
+ onError: (e) => {
11076
+ ui.toast.error(e.message);
11077
+ }
11078
+ });
11079
+ return;
11080
+ }
11081
+ await updateActionItem(
11082
+ {
11083
+ action_id: actionId,
11084
+ quantity: data.quantity,
11085
+ unit_price: convertNumber(data.unit_price)
11087
11086
  },
11088
11087
  {
11089
11088
  onSuccess: () => {
11090
- setIsOpen(STACKED_MODAL_ID, false);
11089
+ setEditing(false);
11091
11090
  },
11092
11091
  onError: (e) => {
11093
11092
  ui.toast.error(e.message);
@@ -11095,364 +11094,365 @@ const CustomItemForm = ({ orderId, currencyCode }) => {
11095
11094
  }
11096
11095
  );
11097
11096
  });
11098
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2, { ...form, children: /* @__PURE__ */ jsxRuntime.jsx(KeyboundForm, { onSubmit, children: /* @__PURE__ */ jsxRuntime.jsxs(StackedFocusModal.Content, { children: [
11099
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Header, {}),
11100
- /* @__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: [
11101
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
11102
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Add custom item" }) }),
11103
- /* @__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." }) })
11104
- ] }),
11105
- /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
11097
+ 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: [
11098
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-3", children: [
11106
11099
  /* @__PURE__ */ jsxRuntime.jsx(
11107
- Form$2.Field,
11100
+ Thumbnail,
11108
11101
  {
11109
- control: form.control,
11110
- name: "title",
11111
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
11112
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
11113
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Title" }),
11114
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Enter the title of the item" })
11115
- ] }),
11116
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
11117
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
11118
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
11119
- ] })
11120
- ] }) })
11102
+ thumbnail: item.thumbnail,
11103
+ alt: item.title ?? void 0
11121
11104
  }
11122
11105
  ),
11123
- /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
11124
- /* @__PURE__ */ jsxRuntime.jsx(
11106
+ editing ? /* @__PURE__ */ jsxRuntime.jsx(
11125
11107
  Form$2.Field,
11126
11108
  {
11127
11109
  control: form.control,
11128
- name: "unit_price",
11129
- render: ({ field: { onChange, ...field } }) => /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
11130
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
11131
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Unit price" }),
11132
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Enter the unit price of the item" })
11133
- ] }),
11134
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
11135
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
11136
- ui.CurrencyInput,
11137
- {
11138
- symbol: getNativeSymbol(currencyCode),
11139
- code: currencyCode,
11140
- onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value),
11141
- ...field
11142
- }
11143
- ) }),
11144
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
11145
- ] })
11146
- ] }) })
11110
+ name: "title",
11111
+ render: ({ field }) => {
11112
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }) });
11113
+ }
11147
11114
  }
11148
- ),
11149
- /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
11150
- /* @__PURE__ */ jsxRuntime.jsx(
11151
- Form$2.Field,
11152
- {
11153
- control: form.control,
11154
- name: "quantity",
11155
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
11156
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
11157
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Quantity" }),
11158
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Enter the quantity of the item" })
11159
- ] }),
11160
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full flex-1", children: [
11161
- /* @__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" }) }) }),
11162
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
11163
- ] })
11164
- ] }) })
11115
+ ) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: item.title })
11116
+ ] }),
11117
+ editing ? /* @__PURE__ */ jsxRuntime.jsx(
11118
+ Form$2.Field,
11119
+ {
11120
+ control: form.control,
11121
+ name: "quantity",
11122
+ render: ({ field }) => {
11123
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(NumberInput, { ...field }) }) });
11165
11124
  }
11166
- )
11167
- ] }) }) }),
11168
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
11169
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
11170
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "button", onClick: onSubmit, children: "Add item" })
11171
- ] }) })
11172
- ] }) }) });
11173
- };
11174
- const customItemSchema = objectType({
11175
- title: stringType().min(1),
11176
- quantity: numberType(),
11177
- unit_price: unionType([numberType(), stringType()])
11178
- });
11179
- const PROMOTION_QUERY_KEY = "promotions";
11180
- const promotionsQueryKeys = {
11181
- list: (query2) => [
11182
- PROMOTION_QUERY_KEY,
11183
- query2 ? query2 : void 0
11184
- ],
11185
- detail: (id, query2) => [
11186
- PROMOTION_QUERY_KEY,
11187
- id,
11188
- query2 ? query2 : void 0
11189
- ]
11190
- };
11191
- const usePromotions = (query2, options) => {
11192
- const { data, ...rest } = reactQuery.useQuery({
11193
- queryKey: promotionsQueryKeys.list(query2),
11194
- queryFn: async () => sdk.admin.promotion.list(query2),
11195
- ...options
11196
- });
11197
- return { ...data, ...rest };
11125
+ }
11126
+ ) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: item.quantity }),
11127
+ editing ? /* @__PURE__ */ jsxRuntime.jsx(
11128
+ Form$2.Field,
11129
+ {
11130
+ control: form.control,
11131
+ name: "unit_price",
11132
+ render: ({ field: { onChange, ...field } }) => {
11133
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
11134
+ ui.CurrencyInput,
11135
+ {
11136
+ ...field,
11137
+ symbol: getNativeSymbol(currencyCode),
11138
+ code: currencyCode,
11139
+ onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value)
11140
+ }
11141
+ ) }) });
11142
+ }
11143
+ }
11144
+ ) : /* @__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) }) }),
11145
+ /* @__PURE__ */ jsxRuntime.jsx(
11146
+ ui.IconButton,
11147
+ {
11148
+ type: "button",
11149
+ size: "small",
11150
+ onClick: editing ? onSubmit : () => {
11151
+ setEditing(true);
11152
+ },
11153
+ disabled: isPending,
11154
+ children: editing ? /* @__PURE__ */ jsxRuntime.jsx(icons.Check, {}) : /* @__PURE__ */ jsxRuntime.jsx(icons.PencilSquare, {})
11155
+ }
11156
+ )
11157
+ ] }) }) });
11198
11158
  };
11199
- const Promotions = () => {
11200
- const { id } = reactRouterDom.useParams();
11201
- const {
11202
- order: preview,
11203
- isError: isPreviewError,
11204
- error: previewError
11205
- } = useOrderPreview(id, void 0);
11206
- useInitiateOrderEdit({ preview });
11207
- const { onCancel } = useCancelOrderEdit({ preview });
11208
- if (isPreviewError) {
11209
- throw previewError;
11210
- }
11211
- const isReady = !!preview;
11212
- return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { onClose: onCancel, children: [
11213
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Promotions" }) }) }),
11214
- isReady && /* @__PURE__ */ jsxRuntime.jsx(PromotionForm, { preview })
11215
- ] });
11159
+ const StackedModalTrigger$1 = ({
11160
+ type,
11161
+ setModalContent
11162
+ }) => {
11163
+ const { setIsOpen } = useStackedModal();
11164
+ const onClick = React.useCallback(() => {
11165
+ setModalContent(type);
11166
+ setIsOpen(STACKED_MODAL_ID, true);
11167
+ }, [setModalContent, setIsOpen, type]);
11168
+ 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" }) });
11216
11169
  };
11217
- const PromotionForm = ({ preview }) => {
11218
- const { items, shipping_methods } = preview;
11219
- const [isSubmitting, setIsSubmitting] = React.useState(false);
11220
- const [comboboxValue, setComboboxValue] = React.useState("");
11221
- const { handleSuccess } = useRouteModal();
11222
- const { mutateAsync: addPromotions, isPending: isAddingPromotions } = useDraftOrderAddPromotions(preview.id);
11223
- const promoIds = getPromotionIds(items, shipping_methods);
11224
- const { promotions, isPending, isError, error } = usePromotions(
11170
+ const VARIANT_PREFIX = "items";
11171
+ const LIMIT = 50;
11172
+ const ExistingItemsForm = ({ orderId, items }) => {
11173
+ const { setIsOpen } = useStackedModal();
11174
+ const [rowSelection, setRowSelection] = React.useState(
11175
+ items.reduce((acc, item) => {
11176
+ acc[item.variant_id] = true;
11177
+ return acc;
11178
+ }, {})
11179
+ );
11180
+ React.useEffect(() => {
11181
+ setRowSelection(
11182
+ items.reduce((acc, item) => {
11183
+ if (item.variant_id) {
11184
+ acc[item.variant_id] = true;
11185
+ }
11186
+ return acc;
11187
+ }, {})
11188
+ );
11189
+ }, [items]);
11190
+ const { q, order, offset } = useQueryParams(
11191
+ ["q", "order", "offset"],
11192
+ VARIANT_PREFIX
11193
+ );
11194
+ const { variants, count, isPending, isError, error } = useProductVariants(
11225
11195
  {
11226
- id: promoIds
11196
+ q,
11197
+ order,
11198
+ offset: offset ? parseInt(offset) : void 0,
11199
+ limit: LIMIT
11227
11200
  },
11228
11201
  {
11229
- enabled: !!promoIds.length
11202
+ placeholderData: reactQuery.keepPreviousData
11230
11203
  }
11231
11204
  );
11232
- const comboboxData = useComboboxData({
11233
- queryKey: ["promotions", "combobox", promoIds],
11234
- queryFn: async (params) => {
11235
- return await sdk.admin.promotion.list({
11236
- ...params,
11237
- id: {
11238
- $nin: promoIds
11239
- }
11240
- });
11241
- },
11242
- getOptions: (data) => {
11243
- return data.promotions.map((promotion) => ({
11244
- label: promotion.code,
11245
- value: promotion.code
11246
- }));
11247
- }
11248
- });
11249
- const add = async (value) => {
11250
- if (!value) {
11251
- return;
11252
- }
11253
- addPromotions(
11205
+ const columns = useColumns();
11206
+ const { mutateAsync } = useDraftOrderAddItems(orderId);
11207
+ const onSubmit = async () => {
11208
+ const ids = Object.keys(rowSelection).filter(
11209
+ (id) => !items.find((i) => i.variant_id === id)
11210
+ );
11211
+ await mutateAsync(
11254
11212
  {
11255
- promo_codes: [value]
11213
+ items: ids.map((id) => ({
11214
+ variant_id: id,
11215
+ quantity: 1
11216
+ }))
11256
11217
  },
11257
11218
  {
11219
+ onSuccess: () => {
11220
+ setRowSelection({});
11221
+ setIsOpen(STACKED_MODAL_ID, false);
11222
+ },
11258
11223
  onError: (e) => {
11259
11224
  ui.toast.error(e.message);
11260
- comboboxData.onSearchValueChange("");
11261
- setComboboxValue("");
11262
- },
11263
- onSuccess: () => {
11264
- comboboxData.onSearchValueChange("");
11265
- setComboboxValue("");
11266
11225
  }
11267
11226
  }
11268
11227
  );
11269
11228
  };
11270
- const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
11271
- const { mutateAsync: requestOrderEdit } = useOrderEditRequest(preview.id);
11272
- const onSubmit = async () => {
11273
- setIsSubmitting(true);
11274
- let requestSucceeded = false;
11275
- await requestOrderEdit(void 0, {
11276
- onError: (e) => {
11277
- ui.toast.error(e.message);
11278
- },
11279
- onSuccess: () => {
11280
- requestSucceeded = true;
11281
- }
11282
- });
11283
- if (!requestSucceeded) {
11284
- setIsSubmitting(false);
11285
- return;
11286
- }
11287
- await confirmOrderEdit(void 0, {
11288
- onError: (e) => {
11289
- ui.toast.error(e.message);
11290
- },
11291
- onSuccess: () => {
11292
- handleSuccess();
11293
- },
11294
- onSettled: () => {
11295
- setIsSubmitting(false);
11296
- }
11297
- });
11298
- };
11299
11229
  if (isError) {
11300
11230
  throw error;
11301
11231
  }
11302
- return /* @__PURE__ */ jsxRuntime.jsxs(KeyboundForm, { className: "flex flex-1 flex-col", onSubmit, children: [
11303
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-4", children: [
11304
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
11305
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
11306
- /* @__PURE__ */ jsxRuntime.jsx(ui.Label, { size: "small", weight: "plus", htmlFor: "promotion-combobox", children: "Apply promotions" }),
11307
- /* @__PURE__ */ jsxRuntime.jsx(ui.Hint, { id: "promotion-combobox-hint", children: "Manage promotions that should be applied to the order." })
11232
+ return /* @__PURE__ */ jsxRuntime.jsxs(
11233
+ StackedFocusModal.Content,
11234
+ {
11235
+ onOpenAutoFocus: (e) => {
11236
+ e.preventDefault();
11237
+ const searchInput = document.querySelector(
11238
+ "[data-modal-id='modal-search-input']"
11239
+ );
11240
+ if (searchInput) {
11241
+ searchInput.focus();
11242
+ }
11243
+ },
11244
+ children: [
11245
+ /* @__PURE__ */ jsxRuntime.jsxs(StackedFocusModal.Header, { children: [
11246
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Product Variants" }) }),
11247
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Choose product variants to add to the order." }) })
11308
11248
  ] }),
11309
- /* @__PURE__ */ jsxRuntime.jsx(
11310
- Combobox,
11249
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Body, { className: "flex-1 overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(
11250
+ DataTable,
11311
11251
  {
11312
- id: "promotion-combobox",
11313
- "aria-describedby": "promotion-combobox-hint",
11314
- isFetchingNextPage: comboboxData.isFetchingNextPage,
11315
- fetchNextPage: comboboxData.fetchNextPage,
11316
- options: comboboxData.options,
11317
- onSearchValueChange: comboboxData.onSearchValueChange,
11318
- searchValue: comboboxData.searchValue,
11319
- disabled: comboboxData.disabled || isAddingPromotions,
11320
- onChange: add,
11321
- value: comboboxValue
11252
+ data: variants,
11253
+ columns,
11254
+ isLoading: isPending,
11255
+ getRowId: (row) => row.id,
11256
+ rowCount: count,
11257
+ prefix: VARIANT_PREFIX,
11258
+ layout: "fill",
11259
+ rowSelection: {
11260
+ state: rowSelection,
11261
+ onRowSelectionChange: setRowSelection,
11262
+ enableRowSelection: (row) => {
11263
+ return !items.find((i) => i.variant_id === row.original.id);
11264
+ }
11265
+ },
11266
+ autoFocusSearch: true
11322
11267
  }
11323
- )
11324
- ] }),
11325
- /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
11326
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-2", children: promotions == null ? void 0 : promotions.map((promotion) => /* @__PURE__ */ jsxRuntime.jsx(
11327
- PromotionItem,
11328
- {
11329
- promotion,
11330
- orderId: preview.id,
11331
- isLoading: isPending
11268
+ ) }),
11269
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
11270
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
11271
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "button", onClick: onSubmit, children: "Update items" })
11272
+ ] }) })
11273
+ ]
11274
+ }
11275
+ );
11276
+ };
11277
+ const columnHelper = ui.createDataTableColumnHelper();
11278
+ const useColumns = () => {
11279
+ return React.useMemo(() => {
11280
+ return [
11281
+ columnHelper.select(),
11282
+ columnHelper.accessor("product.title", {
11283
+ header: "Product",
11284
+ cell: ({ row }) => {
11285
+ var _a, _b, _c;
11286
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-2", children: [
11287
+ /* @__PURE__ */ jsxRuntime.jsx(
11288
+ Thumbnail,
11289
+ {
11290
+ thumbnail: (_a = row.original.product) == null ? void 0 : _a.thumbnail,
11291
+ alt: (_b = row.original.product) == null ? void 0 : _b.title
11292
+ }
11293
+ ),
11294
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: (_c = row.original.product) == null ? void 0 : _c.title })
11295
+ ] });
11296
+ },
11297
+ enableSorting: true
11298
+ }),
11299
+ columnHelper.accessor("title", {
11300
+ header: "Variant",
11301
+ enableSorting: true
11302
+ }),
11303
+ columnHelper.accessor("sku", {
11304
+ header: "SKU",
11305
+ cell: ({ getValue }) => {
11306
+ return getValue() ?? "-";
11307
+ },
11308
+ enableSorting: true
11309
+ }),
11310
+ columnHelper.accessor("updated_at", {
11311
+ header: "Updated",
11312
+ cell: ({ getValue }) => {
11313
+ return /* @__PURE__ */ jsxRuntime.jsx(
11314
+ ui.Tooltip,
11315
+ {
11316
+ content: getFullDate({ date: getValue(), includeTime: true }),
11317
+ children: /* @__PURE__ */ jsxRuntime.jsx("span", { children: getFullDate({ date: getValue() }) })
11318
+ }
11319
+ );
11332
11320
  },
11333
- promotion.id
11334
- )) })
11335
- ] }) }),
11336
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
11337
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
11338
- /* @__PURE__ */ jsxRuntime.jsx(
11339
- ui.Button,
11340
- {
11341
- size: "small",
11342
- type: "submit",
11343
- isLoading: isSubmitting || isAddingPromotions,
11344
- children: "Save"
11345
- }
11346
- )
11347
- ] }) })
11348
- ] });
11321
+ enableSorting: true,
11322
+ sortAscLabel: "Oldest first",
11323
+ sortDescLabel: "Newest first"
11324
+ }),
11325
+ columnHelper.accessor("created_at", {
11326
+ header: "Created",
11327
+ cell: ({ getValue }) => {
11328
+ return /* @__PURE__ */ jsxRuntime.jsx(
11329
+ ui.Tooltip,
11330
+ {
11331
+ content: getFullDate({ date: getValue(), includeTime: true }),
11332
+ children: /* @__PURE__ */ jsxRuntime.jsx("span", { children: getFullDate({ date: getValue() }) })
11333
+ }
11334
+ );
11335
+ },
11336
+ enableSorting: true,
11337
+ sortAscLabel: "Oldest first",
11338
+ sortDescLabel: "Newest first"
11339
+ })
11340
+ ];
11341
+ }, []);
11349
11342
  };
11350
- const PromotionItem = ({
11351
- promotion,
11352
- orderId,
11353
- isLoading
11354
- }) => {
11355
- var _a;
11356
- const { mutateAsync: removePromotions, isPending } = useDraftOrderRemovePromotions(orderId);
11357
- const onRemove = async () => {
11358
- removePromotions(
11343
+ const CustomItemForm = ({ orderId, currencyCode }) => {
11344
+ const { setIsOpen } = useStackedModal();
11345
+ const { mutateAsync: addItems } = useDraftOrderAddItems(orderId);
11346
+ const form = reactHookForm.useForm({
11347
+ defaultValues: {
11348
+ title: "",
11349
+ quantity: 1,
11350
+ unit_price: ""
11351
+ },
11352
+ resolver: zod.zodResolver(customItemSchema)
11353
+ });
11354
+ const onSubmit = form.handleSubmit(async (data) => {
11355
+ await addItems(
11359
11356
  {
11360
- promo_codes: [promotion.code]
11357
+ items: [
11358
+ {
11359
+ title: data.title,
11360
+ quantity: data.quantity,
11361
+ unit_price: convertNumber(data.unit_price)
11362
+ }
11363
+ ]
11361
11364
  },
11362
11365
  {
11366
+ onSuccess: () => {
11367
+ setIsOpen(STACKED_MODAL_ID, false);
11368
+ },
11363
11369
  onError: (e) => {
11364
11370
  ui.toast.error(e.message);
11365
11371
  }
11366
11372
  }
11367
11373
  );
11368
- };
11369
- const displayValue = getDisplayValue(promotion);
11370
- return /* @__PURE__ */ jsxRuntime.jsxs(
11371
- "div",
11372
- {
11373
- className: ui.clx(
11374
- "bg-ui-bg-component shadow-elevation-card-rest flex items-center justify-between rounded-lg px-3 py-2",
11374
+ });
11375
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2, { ...form, children: /* @__PURE__ */ jsxRuntime.jsx(KeyboundForm, { onSubmit, children: /* @__PURE__ */ jsxRuntime.jsxs(StackedFocusModal.Content, { children: [
11376
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Header, {}),
11377
+ /* @__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: [
11378
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
11379
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Add custom item" }) }),
11380
+ /* @__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." }) })
11381
+ ] }),
11382
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
11383
+ /* @__PURE__ */ jsxRuntime.jsx(
11384
+ Form$2.Field,
11375
11385
  {
11376
- "animate-pulse": isLoading
11386
+ control: form.control,
11387
+ name: "title",
11388
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
11389
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
11390
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Title" }),
11391
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Enter the title of the item" })
11392
+ ] }),
11393
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
11394
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
11395
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
11396
+ ] })
11397
+ ] }) })
11377
11398
  }
11378
11399
  ),
11379
- children: [
11380
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
11381
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: promotion.code }),
11382
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-ui-fg-subtle flex items-center gap-1.5", children: [
11383
- displayValue && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
11384
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", children: displayValue }),
11385
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", children: "·" })
11400
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
11401
+ /* @__PURE__ */ jsxRuntime.jsx(
11402
+ Form$2.Field,
11403
+ {
11404
+ control: form.control,
11405
+ name: "unit_price",
11406
+ render: ({ field: { onChange, ...field } }) => /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
11407
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
11408
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Unit price" }),
11409
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Enter the unit price of the item" })
11386
11410
  ] }),
11387
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", className: "capitalize", children: (_a = promotion.application_method) == null ? void 0 : _a.allocation })
11388
- ] })
11389
- ] }),
11390
- /* @__PURE__ */ jsxRuntime.jsx(
11391
- ui.IconButton,
11392
- {
11393
- size: "small",
11394
- type: "button",
11395
- variant: "transparent",
11396
- onClick: onRemove,
11397
- isLoading: isPending || isLoading,
11398
- children: /* @__PURE__ */ jsxRuntime.jsx(icons.XMark, {})
11399
- }
11400
- )
11401
- ]
11402
- },
11403
- promotion.id
11404
- );
11405
- };
11406
- function getDisplayValue(promotion) {
11407
- var _a, _b, _c, _d;
11408
- const value = (_a = promotion.application_method) == null ? void 0 : _a.value;
11409
- if (!value) {
11410
- return null;
11411
- }
11412
- if (((_b = promotion.application_method) == null ? void 0 : _b.type) === "fixed") {
11413
- const currency = (_c = promotion.application_method) == null ? void 0 : _c.currency_code;
11414
- if (!currency) {
11415
- return null;
11416
- }
11417
- return getLocaleAmount(value, currency);
11418
- } else if (((_d = promotion.application_method) == null ? void 0 : _d.type) === "percentage") {
11419
- return formatPercentage(value);
11420
- }
11421
- return null;
11422
- }
11423
- const formatter = new Intl.NumberFormat([], {
11424
- style: "percent",
11425
- minimumFractionDigits: 2
11426
- });
11427
- const formatPercentage = (value, isPercentageValue = false) => {
11428
- let val = value || 0;
11429
- if (!isPercentageValue) {
11430
- val = val / 100;
11431
- }
11432
- return formatter.format(val);
11433
- };
11434
- function getPromotionIds(items, shippingMethods) {
11435
- const promotionIds = /* @__PURE__ */ new Set();
11436
- for (const item of items) {
11437
- if (item.adjustments) {
11438
- for (const adjustment of item.adjustments) {
11439
- if (adjustment.promotion_id) {
11440
- promotionIds.add(adjustment.promotion_id);
11411
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
11412
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
11413
+ ui.CurrencyInput,
11414
+ {
11415
+ symbol: getNativeSymbol(currencyCode),
11416
+ code: currencyCode,
11417
+ onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value),
11418
+ ...field
11419
+ }
11420
+ ) }),
11421
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
11422
+ ] })
11423
+ ] }) })
11441
11424
  }
11442
- }
11443
- }
11444
- }
11445
- for (const shippingMethod of shippingMethods) {
11446
- if (shippingMethod.adjustments) {
11447
- for (const adjustment of shippingMethod.adjustments) {
11448
- if (adjustment.promotion_id) {
11449
- promotionIds.add(adjustment.promotion_id);
11425
+ ),
11426
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
11427
+ /* @__PURE__ */ jsxRuntime.jsx(
11428
+ Form$2.Field,
11429
+ {
11430
+ control: form.control,
11431
+ name: "quantity",
11432
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
11433
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
11434
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Quantity" }),
11435
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Enter the quantity of the item" })
11436
+ ] }),
11437
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full flex-1", children: [
11438
+ /* @__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" }) }) }),
11439
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
11440
+ ] })
11441
+ ] }) })
11450
11442
  }
11451
- }
11452
- }
11453
- }
11454
- return Array.from(promotionIds);
11455
- }
11443
+ )
11444
+ ] }) }) }),
11445
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
11446
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
11447
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "button", onClick: onSubmit, children: "Add item" })
11448
+ ] }) })
11449
+ ] }) }) });
11450
+ };
11451
+ const customItemSchema = objectType({
11452
+ title: stringType().min(1),
11453
+ quantity: numberType(),
11454
+ unit_price: unionType([numberType(), stringType()])
11455
+ });
11456
11456
  const SalesChannel = () => {
11457
11457
  const { id } = reactRouterDom.useParams();
11458
11458
  const { draft_order, isPending, isError, error } = useDraftOrder(
@@ -13065,10 +13065,6 @@ const routeModule = {
13065
13065
  handle,
13066
13066
  loader,
13067
13067
  children: [
13068
- {
13069
- Component: CustomItems,
13070
- path: "/draft-orders/:id/custom-items"
13071
- },
13072
13068
  {
13073
13069
  Component: BillingAddress,
13074
13070
  path: "/draft-orders/:id/billing-address"
@@ -13077,6 +13073,14 @@ const routeModule = {
13077
13073
  Component: Email,
13078
13074
  path: "/draft-orders/:id/email"
13079
13075
  },
13076
+ {
13077
+ Component: CustomItems,
13078
+ path: "/draft-orders/:id/custom-items"
13079
+ },
13080
+ {
13081
+ Component: Promotions,
13082
+ path: "/draft-orders/:id/promotions"
13083
+ },
13080
13084
  {
13081
13085
  Component: Metadata,
13082
13086
  path: "/draft-orders/:id/metadata"
@@ -13085,10 +13089,6 @@ const routeModule = {
13085
13089
  Component: Items,
13086
13090
  path: "/draft-orders/:id/items"
13087
13091
  },
13088
- {
13089
- Component: Promotions,
13090
- path: "/draft-orders/:id/promotions"
13091
- },
13092
13092
  {
13093
13093
  Component: SalesChannel,
13094
13094
  path: "/draft-orders/:id/sales-channel"