@medusajs/draft-order 2.21.0 → 2.21.1-preview-20260917150924
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.
- package/.medusa/server/src/admin/index.js +474 -474
- package/.medusa/server/src/admin/index.mjs +474 -474
- package/package.json +18 -18
|
@@ -6168,27 +6168,6 @@ const BillingAddressForm = ({ order }) => {
|
|
|
6168
6168
|
) });
|
|
6169
6169
|
};
|
|
6170
6170
|
const schema$5 = addressSchema;
|
|
6171
|
-
const CustomItems = () => {
|
|
6172
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
|
|
6173
|
-
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Custom Items" }) }) }),
|
|
6174
|
-
/* @__PURE__ */ jsxRuntime.jsx(CustomItemsForm, {})
|
|
6175
|
-
] });
|
|
6176
|
-
};
|
|
6177
|
-
const CustomItemsForm = () => {
|
|
6178
|
-
const form = reactHookForm.useForm({
|
|
6179
|
-
resolver: zod$1.zodResolver(schema$4)
|
|
6180
|
-
});
|
|
6181
|
-
return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(KeyboundForm, { className: "flex flex-1 flex-col", children: [
|
|
6182
|
-
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, {}),
|
|
6183
|
-
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
|
|
6184
|
-
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
|
|
6185
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", children: "Save" })
|
|
6186
|
-
] }) })
|
|
6187
|
-
] }) });
|
|
6188
|
-
};
|
|
6189
|
-
const schema$4 = zod.z.object({
|
|
6190
|
-
email: zod.z.string().email()
|
|
6191
|
-
});
|
|
6192
6171
|
const Email = () => {
|
|
6193
6172
|
const { id } = reactRouterDom.useParams();
|
|
6194
6173
|
const { order, isPending, isError, error } = useOrder(id, {
|
|
@@ -6211,7 +6190,7 @@ const EmailForm = ({ order }) => {
|
|
|
6211
6190
|
defaultValues: {
|
|
6212
6191
|
email: order.email ?? ""
|
|
6213
6192
|
},
|
|
6214
|
-
resolver: zod$1.zodResolver(schema$
|
|
6193
|
+
resolver: zod$1.zodResolver(schema$4)
|
|
6215
6194
|
});
|
|
6216
6195
|
const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
|
|
6217
6196
|
const { handleSuccess } = useRouteModal();
|
|
@@ -6254,7 +6233,7 @@ const EmailForm = ({ order }) => {
|
|
|
6254
6233
|
}
|
|
6255
6234
|
) });
|
|
6256
6235
|
};
|
|
6257
|
-
const schema$
|
|
6236
|
+
const schema$4 = zod.z.object({
|
|
6258
6237
|
email: zod.z.string().email()
|
|
6259
6238
|
});
|
|
6260
6239
|
const NumberInput = React.forwardRef(
|
|
@@ -7276,6 +7255,27 @@ const customItemSchema = zod.z.object({
|
|
|
7276
7255
|
quantity: zod.z.number(),
|
|
7277
7256
|
unit_price: zod.z.union([zod.z.number(), zod.z.string()])
|
|
7278
7257
|
});
|
|
7258
|
+
const CustomItems = () => {
|
|
7259
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
|
|
7260
|
+
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Custom Items" }) }) }),
|
|
7261
|
+
/* @__PURE__ */ jsxRuntime.jsx(CustomItemsForm, {})
|
|
7262
|
+
] });
|
|
7263
|
+
};
|
|
7264
|
+
const CustomItemsForm = () => {
|
|
7265
|
+
const form = reactHookForm.useForm({
|
|
7266
|
+
resolver: zod$1.zodResolver(schema$3)
|
|
7267
|
+
});
|
|
7268
|
+
return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(KeyboundForm, { className: "flex flex-1 flex-col", children: [
|
|
7269
|
+
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, {}),
|
|
7270
|
+
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
|
|
7271
|
+
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
|
|
7272
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", children: "Save" })
|
|
7273
|
+
] }) })
|
|
7274
|
+
] }) });
|
|
7275
|
+
};
|
|
7276
|
+
const schema$3 = zod.z.object({
|
|
7277
|
+
email: zod.z.string().email()
|
|
7278
|
+
});
|
|
7279
7279
|
const InlineTip = React.forwardRef(
|
|
7280
7280
|
({ variant = "tip", label, className, children, ...props }, ref) => {
|
|
7281
7281
|
const labelValue = label || (variant === "warning" ? "Warning" : "Tip");
|
|
@@ -7626,105 +7626,75 @@ function getHasUneditableRows(metadata) {
|
|
|
7626
7626
|
(value) => !EDITABLE_TYPES.includes(typeof value)
|
|
7627
7627
|
);
|
|
7628
7628
|
}
|
|
7629
|
-
const
|
|
7630
|
-
const
|
|
7631
|
-
list: (query2) => [
|
|
7632
|
-
PROMOTION_QUERY_KEY,
|
|
7633
|
-
query2 ? query2 : void 0
|
|
7634
|
-
],
|
|
7635
|
-
detail: (id, query2) => [
|
|
7636
|
-
PROMOTION_QUERY_KEY,
|
|
7637
|
-
id,
|
|
7638
|
-
query2 ? query2 : void 0
|
|
7639
|
-
]
|
|
7640
|
-
};
|
|
7641
|
-
const usePromotions = (query2, options) => {
|
|
7642
|
-
const { data, ...rest } = reactQuery.useQuery({
|
|
7643
|
-
queryKey: promotionsQueryKeys.list(query2),
|
|
7644
|
-
queryFn: async () => sdk.admin.promotion.list(query2),
|
|
7645
|
-
...options
|
|
7646
|
-
});
|
|
7647
|
-
return { ...data, ...rest };
|
|
7648
|
-
};
|
|
7649
|
-
const Promotions = () => {
|
|
7629
|
+
const STACKED_FOCUS_MODAL_ID = "shipping-form";
|
|
7630
|
+
const Shipping = () => {
|
|
7650
7631
|
const { id } = reactRouterDom.useParams();
|
|
7632
|
+
const { order, isPending, isError, error } = useOrder(id, {
|
|
7633
|
+
fields: "+items.*,+items.variant.*,+items.variant.product.*,+items.variant.product.shipping_profile.*,+currency_code"
|
|
7634
|
+
});
|
|
7651
7635
|
const {
|
|
7652
7636
|
order: preview,
|
|
7637
|
+
isPending: isPreviewPending,
|
|
7653
7638
|
isError: isPreviewError,
|
|
7654
7639
|
error: previewError
|
|
7655
|
-
} = useOrderPreview(id
|
|
7640
|
+
} = useOrderPreview(id);
|
|
7656
7641
|
useInitiateOrderEdit({ preview });
|
|
7657
7642
|
const { onCancel } = useCancelOrderEdit({ preview });
|
|
7643
|
+
if (isError) {
|
|
7644
|
+
throw error;
|
|
7645
|
+
}
|
|
7658
7646
|
if (isPreviewError) {
|
|
7659
7647
|
throw previewError;
|
|
7660
7648
|
}
|
|
7661
|
-
const
|
|
7662
|
-
|
|
7663
|
-
|
|
7664
|
-
|
|
7665
|
-
|
|
7649
|
+
const orderHasItems = (order?.items?.length || 0) > 0;
|
|
7650
|
+
const isReady = preview && !isPreviewPending && order && !isPending;
|
|
7651
|
+
return /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal, { onClose: onCancel, children: !orderHasItems ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-full flex-col overflow-hidden ", children: [
|
|
7652
|
+
/* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Header, {}),
|
|
7653
|
+
/* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.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-6 py-16", children: [
|
|
7654
|
+
/* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Shipping" }) }),
|
|
7655
|
+
/* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "This draft order currently has no items. Add items to the order before adding shipping." }) })
|
|
7656
|
+
] }) }) }),
|
|
7657
|
+
/* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Footer, { children: /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }) })
|
|
7658
|
+
] }) : isReady ? /* @__PURE__ */ jsxRuntime.jsx(ShippingForm, { preview, order }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
7659
|
+
/* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Edit Shipping" }) }),
|
|
7660
|
+
/* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Loading data for the draft order, please wait..." }) })
|
|
7661
|
+
] }) });
|
|
7666
7662
|
};
|
|
7667
|
-
const
|
|
7668
|
-
const {
|
|
7663
|
+
const ShippingForm = ({ preview, order }) => {
|
|
7664
|
+
const { setIsOpen } = useStackedModal();
|
|
7669
7665
|
const [isSubmitting, setIsSubmitting] = React.useState(false);
|
|
7670
|
-
const [
|
|
7671
|
-
const
|
|
7672
|
-
const {
|
|
7673
|
-
const promoIds = getPromotionIds(items, shipping_methods);
|
|
7674
|
-
const { promotions, isPending, isError, error } = usePromotions(
|
|
7666
|
+
const [data, setData] = React.useState(null);
|
|
7667
|
+
const appliedShippingOptionIds = preview.shipping_methods?.map((method) => method.shipping_option_id).filter(Boolean);
|
|
7668
|
+
const { shipping_options } = useShippingOptions(
|
|
7675
7669
|
{
|
|
7676
|
-
id:
|
|
7670
|
+
id: appliedShippingOptionIds,
|
|
7671
|
+
fields: "+service_zone.*,+service_zone.fulfillment_set.*,+service_zone.fulfillment_set.location.*"
|
|
7677
7672
|
},
|
|
7678
7673
|
{
|
|
7679
|
-
enabled:
|
|
7674
|
+
enabled: appliedShippingOptionIds.length > 0
|
|
7680
7675
|
}
|
|
7681
7676
|
);
|
|
7682
|
-
const
|
|
7683
|
-
|
|
7684
|
-
|
|
7685
|
-
|
|
7686
|
-
|
|
7687
|
-
|
|
7688
|
-
|
|
7689
|
-
|
|
7690
|
-
|
|
7691
|
-
|
|
7692
|
-
|
|
7693
|
-
return data.promotions.map((promotion) => ({
|
|
7694
|
-
label: promotion.code,
|
|
7695
|
-
value: promotion.code
|
|
7696
|
-
}));
|
|
7697
|
-
}
|
|
7698
|
-
});
|
|
7699
|
-
const add = async (value) => {
|
|
7700
|
-
if (!value) {
|
|
7701
|
-
return;
|
|
7702
|
-
}
|
|
7703
|
-
addPromotions(
|
|
7704
|
-
{
|
|
7705
|
-
promo_codes: [value]
|
|
7706
|
-
},
|
|
7707
|
-
{
|
|
7708
|
-
onError: (e) => {
|
|
7709
|
-
ui.toast.error(e.message);
|
|
7710
|
-
comboboxData.onSearchValueChange("");
|
|
7711
|
-
setComboboxValue("");
|
|
7712
|
-
},
|
|
7713
|
-
onSuccess: () => {
|
|
7714
|
-
comboboxData.onSearchValueChange("");
|
|
7715
|
-
setComboboxValue("");
|
|
7716
|
-
}
|
|
7717
|
-
}
|
|
7718
|
-
);
|
|
7719
|
-
};
|
|
7677
|
+
const uniqueShippingProfiles = React.useMemo(() => {
|
|
7678
|
+
const profiles = /* @__PURE__ */ new Map();
|
|
7679
|
+
getUniqueShippingProfiles(order.items).forEach((profile) => {
|
|
7680
|
+
profiles.set(profile.id, profile);
|
|
7681
|
+
});
|
|
7682
|
+
shipping_options?.forEach((option) => {
|
|
7683
|
+
profiles.set(option.shipping_profile_id, option.shipping_profile);
|
|
7684
|
+
});
|
|
7685
|
+
return Array.from(profiles.values());
|
|
7686
|
+
}, [order.items, shipping_options]);
|
|
7687
|
+
const { handleSuccess } = useRouteModal();
|
|
7720
7688
|
const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
|
|
7721
|
-
const { mutateAsync: requestOrderEdit } =
|
|
7689
|
+
const { mutateAsync: requestOrderEdit } = useDraftOrderRequestEdit(preview.id);
|
|
7690
|
+
const { mutateAsync: removeShippingMethod } = useDraftOrderRemoveShippingMethod(preview.id);
|
|
7691
|
+
const { mutateAsync: removeActionShippingMethod } = useDraftOrderRemoveActionShippingMethod(preview.id);
|
|
7722
7692
|
const onSubmit = async () => {
|
|
7723
7693
|
setIsSubmitting(true);
|
|
7724
7694
|
let requestSucceeded = false;
|
|
7725
7695
|
await requestOrderEdit(void 0, {
|
|
7726
7696
|
onError: (e) => {
|
|
7727
|
-
ui.toast.error(e.message);
|
|
7697
|
+
ui.toast.error(`Failed to request order edit: ${e.message}`);
|
|
7728
7698
|
},
|
|
7729
7699
|
onSuccess: () => {
|
|
7730
7700
|
requestSucceeded = true;
|
|
@@ -7736,7 +7706,7 @@ const PromotionForm = ({ preview }) => {
|
|
|
7736
7706
|
}
|
|
7737
7707
|
await confirmOrderEdit(void 0, {
|
|
7738
7708
|
onError: (e) => {
|
|
7739
|
-
ui.toast.error(e.message);
|
|
7709
|
+
ui.toast.error(`Failed to confirm order edit: ${e.message}`);
|
|
7740
7710
|
},
|
|
7741
7711
|
onSuccess: () => {
|
|
7742
7712
|
handleSuccess();
|
|
@@ -7746,364 +7716,13 @@ const PromotionForm = ({ preview }) => {
|
|
|
7746
7716
|
}
|
|
7747
7717
|
});
|
|
7748
7718
|
};
|
|
7749
|
-
|
|
7750
|
-
|
|
7751
|
-
|
|
7752
|
-
|
|
7753
|
-
|
|
7754
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
|
|
7755
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
|
|
7756
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Label, { size: "small", weight: "plus", htmlFor: "promotion-combobox", children: "Apply promotions" }),
|
|
7757
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Hint, { id: "promotion-combobox-hint", children: "Manage promotions that should be applied to the order." })
|
|
7758
|
-
] }),
|
|
7759
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7760
|
-
Combobox,
|
|
7761
|
-
{
|
|
7762
|
-
id: "promotion-combobox",
|
|
7763
|
-
"aria-describedby": "promotion-combobox-hint",
|
|
7764
|
-
isFetchingNextPage: comboboxData.isFetchingNextPage,
|
|
7765
|
-
fetchNextPage: comboboxData.fetchNextPage,
|
|
7766
|
-
options: comboboxData.options,
|
|
7767
|
-
onSearchValueChange: comboboxData.onSearchValueChange,
|
|
7768
|
-
searchValue: comboboxData.searchValue,
|
|
7769
|
-
disabled: comboboxData.disabled || isAddingPromotions,
|
|
7770
|
-
onChange: add,
|
|
7771
|
-
value: comboboxValue
|
|
7772
|
-
}
|
|
7773
|
-
)
|
|
7774
|
-
] }),
|
|
7775
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
|
|
7776
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-2", children: promotions?.map((promotion) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
7777
|
-
PromotionItem,
|
|
7778
|
-
{
|
|
7779
|
-
promotion,
|
|
7780
|
-
orderId: preview.id,
|
|
7781
|
-
isLoading: isPending
|
|
7782
|
-
},
|
|
7783
|
-
promotion.id
|
|
7784
|
-
)) })
|
|
7785
|
-
] }) }),
|
|
7786
|
-
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
|
|
7787
|
-
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
|
|
7788
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7789
|
-
ui.Button,
|
|
7790
|
-
{
|
|
7791
|
-
size: "small",
|
|
7792
|
-
type: "submit",
|
|
7793
|
-
isLoading: isSubmitting || isAddingPromotions,
|
|
7794
|
-
children: "Save"
|
|
7795
|
-
}
|
|
7796
|
-
)
|
|
7797
|
-
] }) })
|
|
7798
|
-
] });
|
|
7799
|
-
};
|
|
7800
|
-
const PromotionItem = ({
|
|
7801
|
-
promotion,
|
|
7802
|
-
orderId,
|
|
7803
|
-
isLoading
|
|
7804
|
-
}) => {
|
|
7805
|
-
const { mutateAsync: removePromotions, isPending } = useDraftOrderRemovePromotions(orderId);
|
|
7806
|
-
const onRemove = async () => {
|
|
7807
|
-
removePromotions(
|
|
7808
|
-
{
|
|
7809
|
-
promo_codes: [promotion.code]
|
|
7810
|
-
},
|
|
7811
|
-
{
|
|
7812
|
-
onError: (e) => {
|
|
7813
|
-
ui.toast.error(e.message);
|
|
7719
|
+
const onKeydown = React.useCallback(
|
|
7720
|
+
(e) => {
|
|
7721
|
+
if (e.key === "Enter" && (e.ctrlKey || e.metaKey)) {
|
|
7722
|
+
if (data || isSubmitting) {
|
|
7723
|
+
return;
|
|
7814
7724
|
}
|
|
7815
|
-
|
|
7816
|
-
);
|
|
7817
|
-
};
|
|
7818
|
-
const displayValue = getDisplayValue(promotion);
|
|
7819
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
7820
|
-
"div",
|
|
7821
|
-
{
|
|
7822
|
-
className: ui.clx(
|
|
7823
|
-
"bg-ui-bg-component shadow-elevation-card-rest flex items-center justify-between rounded-lg px-3 py-2",
|
|
7824
|
-
{
|
|
7825
|
-
"animate-pulse": isLoading
|
|
7826
|
-
}
|
|
7827
|
-
),
|
|
7828
|
-
children: [
|
|
7829
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
7830
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: promotion.code }),
|
|
7831
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-ui-fg-subtle flex items-center gap-1.5", children: [
|
|
7832
|
-
displayValue && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
7833
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", children: displayValue }),
|
|
7834
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", children: "·" })
|
|
7835
|
-
] }),
|
|
7836
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", className: "capitalize", children: promotion.application_method?.allocation })
|
|
7837
|
-
] })
|
|
7838
|
-
] }),
|
|
7839
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7840
|
-
ui.IconButton,
|
|
7841
|
-
{
|
|
7842
|
-
size: "small",
|
|
7843
|
-
type: "button",
|
|
7844
|
-
variant: "transparent",
|
|
7845
|
-
onClick: onRemove,
|
|
7846
|
-
isLoading: isPending || isLoading,
|
|
7847
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(icons.XMark, {})
|
|
7848
|
-
}
|
|
7849
|
-
)
|
|
7850
|
-
]
|
|
7851
|
-
},
|
|
7852
|
-
promotion.id
|
|
7853
|
-
);
|
|
7854
|
-
};
|
|
7855
|
-
function getDisplayValue(promotion) {
|
|
7856
|
-
const value = promotion.application_method?.value;
|
|
7857
|
-
if (!value) {
|
|
7858
|
-
return null;
|
|
7859
|
-
}
|
|
7860
|
-
if (promotion.application_method?.type === "fixed") {
|
|
7861
|
-
const currency = promotion.application_method?.currency_code;
|
|
7862
|
-
if (!currency) {
|
|
7863
|
-
return null;
|
|
7864
|
-
}
|
|
7865
|
-
return getLocaleAmount(value, currency);
|
|
7866
|
-
} else if (promotion.application_method?.type === "percentage") {
|
|
7867
|
-
return formatPercentage(value);
|
|
7868
|
-
}
|
|
7869
|
-
return null;
|
|
7870
|
-
}
|
|
7871
|
-
const formatter = new Intl.NumberFormat([], {
|
|
7872
|
-
style: "percent",
|
|
7873
|
-
minimumFractionDigits: 2
|
|
7874
|
-
});
|
|
7875
|
-
const formatPercentage = (value, isPercentageValue = false) => {
|
|
7876
|
-
let val = value || 0;
|
|
7877
|
-
if (!isPercentageValue) {
|
|
7878
|
-
val = val / 100;
|
|
7879
|
-
}
|
|
7880
|
-
return formatter.format(val);
|
|
7881
|
-
};
|
|
7882
|
-
function getPromotionIds(items, shippingMethods) {
|
|
7883
|
-
const promotionIds = /* @__PURE__ */ new Set();
|
|
7884
|
-
for (const item of items) {
|
|
7885
|
-
if (item.adjustments) {
|
|
7886
|
-
for (const adjustment of item.adjustments) {
|
|
7887
|
-
if (adjustment.promotion_id) {
|
|
7888
|
-
promotionIds.add(adjustment.promotion_id);
|
|
7889
|
-
}
|
|
7890
|
-
}
|
|
7891
|
-
}
|
|
7892
|
-
}
|
|
7893
|
-
for (const shippingMethod of shippingMethods) {
|
|
7894
|
-
if (shippingMethod.adjustments) {
|
|
7895
|
-
for (const adjustment of shippingMethod.adjustments) {
|
|
7896
|
-
if (adjustment.promotion_id) {
|
|
7897
|
-
promotionIds.add(adjustment.promotion_id);
|
|
7898
|
-
}
|
|
7899
|
-
}
|
|
7900
|
-
}
|
|
7901
|
-
}
|
|
7902
|
-
return Array.from(promotionIds);
|
|
7903
|
-
}
|
|
7904
|
-
const SalesChannel = () => {
|
|
7905
|
-
const { id } = reactRouterDom.useParams();
|
|
7906
|
-
const { draft_order, isPending, isError, error } = useDraftOrder(
|
|
7907
|
-
id,
|
|
7908
|
-
{
|
|
7909
|
-
fields: "+sales_channel_id"
|
|
7910
|
-
},
|
|
7911
|
-
{
|
|
7912
|
-
enabled: !!id
|
|
7913
|
-
}
|
|
7914
|
-
);
|
|
7915
|
-
if (isError) {
|
|
7916
|
-
throw error;
|
|
7917
|
-
}
|
|
7918
|
-
const ISrEADY = !!draft_order && !isPending;
|
|
7919
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
|
|
7920
|
-
/* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Header, { children: [
|
|
7921
|
-
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Sales Channel" }) }),
|
|
7922
|
-
/* @__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" }) })
|
|
7923
|
-
] }),
|
|
7924
|
-
ISrEADY && /* @__PURE__ */ jsxRuntime.jsx(SalesChannelForm, { order: draft_order })
|
|
7925
|
-
] });
|
|
7926
|
-
};
|
|
7927
|
-
const SalesChannelForm = ({ order }) => {
|
|
7928
|
-
const form = reactHookForm.useForm({
|
|
7929
|
-
defaultValues: {
|
|
7930
|
-
sales_channel_id: order.sales_channel_id || ""
|
|
7931
|
-
},
|
|
7932
|
-
resolver: zod$1.zodResolver(schema$2)
|
|
7933
|
-
});
|
|
7934
|
-
const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
|
|
7935
|
-
const { handleSuccess } = useRouteModal();
|
|
7936
|
-
const onSubmit = form.handleSubmit(async (data) => {
|
|
7937
|
-
await mutateAsync(
|
|
7938
|
-
{
|
|
7939
|
-
sales_channel_id: data.sales_channel_id
|
|
7940
|
-
},
|
|
7941
|
-
{
|
|
7942
|
-
onSuccess: () => {
|
|
7943
|
-
ui.toast.success("Sales channel updated");
|
|
7944
|
-
handleSuccess();
|
|
7945
|
-
},
|
|
7946
|
-
onError: (error) => {
|
|
7947
|
-
ui.toast.error(error.message);
|
|
7948
|
-
}
|
|
7949
|
-
}
|
|
7950
|
-
);
|
|
7951
|
-
});
|
|
7952
|
-
return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
7953
|
-
KeyboundForm,
|
|
7954
|
-
{
|
|
7955
|
-
className: "flex flex-1 flex-col overflow-hidden",
|
|
7956
|
-
onSubmit,
|
|
7957
|
-
children: [
|
|
7958
|
-
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsx(SalesChannelField, { control: form.control, order }) }),
|
|
7959
|
-
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
|
|
7960
|
-
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
|
|
7961
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
|
|
7962
|
-
] }) })
|
|
7963
|
-
]
|
|
7964
|
-
}
|
|
7965
|
-
) });
|
|
7966
|
-
};
|
|
7967
|
-
const SalesChannelField = ({ control, order }) => {
|
|
7968
|
-
const salesChannels = useComboboxData({
|
|
7969
|
-
queryFn: async (params) => {
|
|
7970
|
-
return await sdk.admin.salesChannel.list(params);
|
|
7971
|
-
},
|
|
7972
|
-
queryKey: ["sales-channels"],
|
|
7973
|
-
getOptions: (data) => {
|
|
7974
|
-
return data.sales_channels.map((salesChannel) => ({
|
|
7975
|
-
label: salesChannel.name,
|
|
7976
|
-
value: salesChannel.id
|
|
7977
|
-
}));
|
|
7978
|
-
},
|
|
7979
|
-
defaultValue: order.sales_channel_id || void 0
|
|
7980
|
-
});
|
|
7981
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
7982
|
-
Form$2.Field,
|
|
7983
|
-
{
|
|
7984
|
-
control,
|
|
7985
|
-
name: "sales_channel_id",
|
|
7986
|
-
render: ({ field }) => {
|
|
7987
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
|
|
7988
|
-
/* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Sales Channel" }),
|
|
7989
|
-
/* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
7990
|
-
Combobox,
|
|
7991
|
-
{
|
|
7992
|
-
options: salesChannels.options,
|
|
7993
|
-
fetchNextPage: salesChannels.fetchNextPage,
|
|
7994
|
-
isFetchingNextPage: salesChannels.isFetchingNextPage,
|
|
7995
|
-
searchValue: salesChannels.searchValue,
|
|
7996
|
-
onSearchValueChange: salesChannels.onSearchValueChange,
|
|
7997
|
-
placeholder: "Select sales channel",
|
|
7998
|
-
...field
|
|
7999
|
-
}
|
|
8000
|
-
) }),
|
|
8001
|
-
/* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
|
|
8002
|
-
] });
|
|
8003
|
-
}
|
|
8004
|
-
}
|
|
8005
|
-
);
|
|
8006
|
-
};
|
|
8007
|
-
const schema$2 = zod.z.object({
|
|
8008
|
-
sales_channel_id: zod.z.string().min(1)
|
|
8009
|
-
});
|
|
8010
|
-
const STACKED_FOCUS_MODAL_ID = "shipping-form";
|
|
8011
|
-
const Shipping = () => {
|
|
8012
|
-
const { id } = reactRouterDom.useParams();
|
|
8013
|
-
const { order, isPending, isError, error } = useOrder(id, {
|
|
8014
|
-
fields: "+items.*,+items.variant.*,+items.variant.product.*,+items.variant.product.shipping_profile.*,+currency_code"
|
|
8015
|
-
});
|
|
8016
|
-
const {
|
|
8017
|
-
order: preview,
|
|
8018
|
-
isPending: isPreviewPending,
|
|
8019
|
-
isError: isPreviewError,
|
|
8020
|
-
error: previewError
|
|
8021
|
-
} = useOrderPreview(id);
|
|
8022
|
-
useInitiateOrderEdit({ preview });
|
|
8023
|
-
const { onCancel } = useCancelOrderEdit({ preview });
|
|
8024
|
-
if (isError) {
|
|
8025
|
-
throw error;
|
|
8026
|
-
}
|
|
8027
|
-
if (isPreviewError) {
|
|
8028
|
-
throw previewError;
|
|
8029
|
-
}
|
|
8030
|
-
const orderHasItems = (order?.items?.length || 0) > 0;
|
|
8031
|
-
const isReady = preview && !isPreviewPending && order && !isPending;
|
|
8032
|
-
return /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal, { onClose: onCancel, children: !orderHasItems ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-full flex-col overflow-hidden ", children: [
|
|
8033
|
-
/* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Header, {}),
|
|
8034
|
-
/* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.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-6 py-16", children: [
|
|
8035
|
-
/* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Shipping" }) }),
|
|
8036
|
-
/* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "This draft order currently has no items. Add items to the order before adding shipping." }) })
|
|
8037
|
-
] }) }) }),
|
|
8038
|
-
/* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Footer, { children: /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }) })
|
|
8039
|
-
] }) : isReady ? /* @__PURE__ */ jsxRuntime.jsx(ShippingForm, { preview, order }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
8040
|
-
/* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Edit Shipping" }) }),
|
|
8041
|
-
/* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Loading data for the draft order, please wait..." }) })
|
|
8042
|
-
] }) });
|
|
8043
|
-
};
|
|
8044
|
-
const ShippingForm = ({ preview, order }) => {
|
|
8045
|
-
const { setIsOpen } = useStackedModal();
|
|
8046
|
-
const [isSubmitting, setIsSubmitting] = React.useState(false);
|
|
8047
|
-
const [data, setData] = React.useState(null);
|
|
8048
|
-
const appliedShippingOptionIds = preview.shipping_methods?.map((method) => method.shipping_option_id).filter(Boolean);
|
|
8049
|
-
const { shipping_options } = useShippingOptions(
|
|
8050
|
-
{
|
|
8051
|
-
id: appliedShippingOptionIds,
|
|
8052
|
-
fields: "+service_zone.*,+service_zone.fulfillment_set.*,+service_zone.fulfillment_set.location.*"
|
|
8053
|
-
},
|
|
8054
|
-
{
|
|
8055
|
-
enabled: appliedShippingOptionIds.length > 0
|
|
8056
|
-
}
|
|
8057
|
-
);
|
|
8058
|
-
const uniqueShippingProfiles = React.useMemo(() => {
|
|
8059
|
-
const profiles = /* @__PURE__ */ new Map();
|
|
8060
|
-
getUniqueShippingProfiles(order.items).forEach((profile) => {
|
|
8061
|
-
profiles.set(profile.id, profile);
|
|
8062
|
-
});
|
|
8063
|
-
shipping_options?.forEach((option) => {
|
|
8064
|
-
profiles.set(option.shipping_profile_id, option.shipping_profile);
|
|
8065
|
-
});
|
|
8066
|
-
return Array.from(profiles.values());
|
|
8067
|
-
}, [order.items, shipping_options]);
|
|
8068
|
-
const { handleSuccess } = useRouteModal();
|
|
8069
|
-
const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
|
|
8070
|
-
const { mutateAsync: requestOrderEdit } = useDraftOrderRequestEdit(preview.id);
|
|
8071
|
-
const { mutateAsync: removeShippingMethod } = useDraftOrderRemoveShippingMethod(preview.id);
|
|
8072
|
-
const { mutateAsync: removeActionShippingMethod } = useDraftOrderRemoveActionShippingMethod(preview.id);
|
|
8073
|
-
const onSubmit = async () => {
|
|
8074
|
-
setIsSubmitting(true);
|
|
8075
|
-
let requestSucceeded = false;
|
|
8076
|
-
await requestOrderEdit(void 0, {
|
|
8077
|
-
onError: (e) => {
|
|
8078
|
-
ui.toast.error(`Failed to request order edit: ${e.message}`);
|
|
8079
|
-
},
|
|
8080
|
-
onSuccess: () => {
|
|
8081
|
-
requestSucceeded = true;
|
|
8082
|
-
}
|
|
8083
|
-
});
|
|
8084
|
-
if (!requestSucceeded) {
|
|
8085
|
-
setIsSubmitting(false);
|
|
8086
|
-
return;
|
|
8087
|
-
}
|
|
8088
|
-
await confirmOrderEdit(void 0, {
|
|
8089
|
-
onError: (e) => {
|
|
8090
|
-
ui.toast.error(`Failed to confirm order edit: ${e.message}`);
|
|
8091
|
-
},
|
|
8092
|
-
onSuccess: () => {
|
|
8093
|
-
handleSuccess();
|
|
8094
|
-
},
|
|
8095
|
-
onSettled: () => {
|
|
8096
|
-
setIsSubmitting(false);
|
|
8097
|
-
}
|
|
8098
|
-
});
|
|
8099
|
-
};
|
|
8100
|
-
const onKeydown = React.useCallback(
|
|
8101
|
-
(e) => {
|
|
8102
|
-
if (e.key === "Enter" && (e.ctrlKey || e.metaKey)) {
|
|
8103
|
-
if (data || isSubmitting) {
|
|
8104
|
-
return;
|
|
8105
|
-
}
|
|
8106
|
-
onSubmit();
|
|
7725
|
+
onSubmit();
|
|
8107
7726
|
}
|
|
8108
7727
|
},
|
|
8109
7728
|
[data, isSubmitting, onSubmit]
|
|
@@ -8832,7 +8451,7 @@ const ShippingAddressForm = ({ order }) => {
|
|
|
8832
8451
|
postal_code: order.shipping_address?.postal_code ?? "",
|
|
8833
8452
|
phone: order.shipping_address?.phone ?? ""
|
|
8834
8453
|
},
|
|
8835
|
-
resolver: zod$1.zodResolver(schema$
|
|
8454
|
+
resolver: zod$1.zodResolver(schema$2)
|
|
8836
8455
|
});
|
|
8837
8456
|
const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
|
|
8838
8457
|
const { handleSuccess } = useRouteModal();
|
|
@@ -9000,9 +8619,284 @@ const ShippingAddressForm = ({ order }) => {
|
|
|
9000
8619
|
] }) })
|
|
9001
8620
|
]
|
|
9002
8621
|
}
|
|
9003
|
-
) });
|
|
8622
|
+
) });
|
|
8623
|
+
};
|
|
8624
|
+
const schema$2 = addressSchema;
|
|
8625
|
+
const PROMOTION_QUERY_KEY = "promotions";
|
|
8626
|
+
const promotionsQueryKeys = {
|
|
8627
|
+
list: (query2) => [
|
|
8628
|
+
PROMOTION_QUERY_KEY,
|
|
8629
|
+
query2 ? query2 : void 0
|
|
8630
|
+
],
|
|
8631
|
+
detail: (id, query2) => [
|
|
8632
|
+
PROMOTION_QUERY_KEY,
|
|
8633
|
+
id,
|
|
8634
|
+
query2 ? query2 : void 0
|
|
8635
|
+
]
|
|
8636
|
+
};
|
|
8637
|
+
const usePromotions = (query2, options) => {
|
|
8638
|
+
const { data, ...rest } = reactQuery.useQuery({
|
|
8639
|
+
queryKey: promotionsQueryKeys.list(query2),
|
|
8640
|
+
queryFn: async () => sdk.admin.promotion.list(query2),
|
|
8641
|
+
...options
|
|
8642
|
+
});
|
|
8643
|
+
return { ...data, ...rest };
|
|
8644
|
+
};
|
|
8645
|
+
const Promotions = () => {
|
|
8646
|
+
const { id } = reactRouterDom.useParams();
|
|
8647
|
+
const {
|
|
8648
|
+
order: preview,
|
|
8649
|
+
isError: isPreviewError,
|
|
8650
|
+
error: previewError
|
|
8651
|
+
} = useOrderPreview(id, void 0);
|
|
8652
|
+
useInitiateOrderEdit({ preview });
|
|
8653
|
+
const { onCancel } = useCancelOrderEdit({ preview });
|
|
8654
|
+
if (isPreviewError) {
|
|
8655
|
+
throw previewError;
|
|
8656
|
+
}
|
|
8657
|
+
const isReady = !!preview;
|
|
8658
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { onClose: onCancel, children: [
|
|
8659
|
+
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Promotions" }) }) }),
|
|
8660
|
+
isReady && /* @__PURE__ */ jsxRuntime.jsx(PromotionForm, { preview })
|
|
8661
|
+
] });
|
|
8662
|
+
};
|
|
8663
|
+
const PromotionForm = ({ preview }) => {
|
|
8664
|
+
const { items, shipping_methods } = preview;
|
|
8665
|
+
const [isSubmitting, setIsSubmitting] = React.useState(false);
|
|
8666
|
+
const [comboboxValue, setComboboxValue] = React.useState("");
|
|
8667
|
+
const { handleSuccess } = useRouteModal();
|
|
8668
|
+
const { mutateAsync: addPromotions, isPending: isAddingPromotions } = useDraftOrderAddPromotions(preview.id);
|
|
8669
|
+
const promoIds = getPromotionIds(items, shipping_methods);
|
|
8670
|
+
const { promotions, isPending, isError, error } = usePromotions(
|
|
8671
|
+
{
|
|
8672
|
+
id: promoIds
|
|
8673
|
+
},
|
|
8674
|
+
{
|
|
8675
|
+
enabled: !!promoIds.length
|
|
8676
|
+
}
|
|
8677
|
+
);
|
|
8678
|
+
const comboboxData = useComboboxData({
|
|
8679
|
+
queryKey: ["promotions", "combobox", promoIds],
|
|
8680
|
+
queryFn: async (params) => {
|
|
8681
|
+
return await sdk.admin.promotion.list({
|
|
8682
|
+
...params,
|
|
8683
|
+
id: {
|
|
8684
|
+
$nin: promoIds
|
|
8685
|
+
}
|
|
8686
|
+
});
|
|
8687
|
+
},
|
|
8688
|
+
getOptions: (data) => {
|
|
8689
|
+
return data.promotions.map((promotion) => ({
|
|
8690
|
+
label: promotion.code,
|
|
8691
|
+
value: promotion.code
|
|
8692
|
+
}));
|
|
8693
|
+
}
|
|
8694
|
+
});
|
|
8695
|
+
const add = async (value) => {
|
|
8696
|
+
if (!value) {
|
|
8697
|
+
return;
|
|
8698
|
+
}
|
|
8699
|
+
addPromotions(
|
|
8700
|
+
{
|
|
8701
|
+
promo_codes: [value]
|
|
8702
|
+
},
|
|
8703
|
+
{
|
|
8704
|
+
onError: (e) => {
|
|
8705
|
+
ui.toast.error(e.message);
|
|
8706
|
+
comboboxData.onSearchValueChange("");
|
|
8707
|
+
setComboboxValue("");
|
|
8708
|
+
},
|
|
8709
|
+
onSuccess: () => {
|
|
8710
|
+
comboboxData.onSearchValueChange("");
|
|
8711
|
+
setComboboxValue("");
|
|
8712
|
+
}
|
|
8713
|
+
}
|
|
8714
|
+
);
|
|
8715
|
+
};
|
|
8716
|
+
const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
|
|
8717
|
+
const { mutateAsync: requestOrderEdit } = useOrderEditRequest(preview.id);
|
|
8718
|
+
const onSubmit = async () => {
|
|
8719
|
+
setIsSubmitting(true);
|
|
8720
|
+
let requestSucceeded = false;
|
|
8721
|
+
await requestOrderEdit(void 0, {
|
|
8722
|
+
onError: (e) => {
|
|
8723
|
+
ui.toast.error(e.message);
|
|
8724
|
+
},
|
|
8725
|
+
onSuccess: () => {
|
|
8726
|
+
requestSucceeded = true;
|
|
8727
|
+
}
|
|
8728
|
+
});
|
|
8729
|
+
if (!requestSucceeded) {
|
|
8730
|
+
setIsSubmitting(false);
|
|
8731
|
+
return;
|
|
8732
|
+
}
|
|
8733
|
+
await confirmOrderEdit(void 0, {
|
|
8734
|
+
onError: (e) => {
|
|
8735
|
+
ui.toast.error(e.message);
|
|
8736
|
+
},
|
|
8737
|
+
onSuccess: () => {
|
|
8738
|
+
handleSuccess();
|
|
8739
|
+
},
|
|
8740
|
+
onSettled: () => {
|
|
8741
|
+
setIsSubmitting(false);
|
|
8742
|
+
}
|
|
8743
|
+
});
|
|
8744
|
+
};
|
|
8745
|
+
if (isError) {
|
|
8746
|
+
throw error;
|
|
8747
|
+
}
|
|
8748
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(KeyboundForm, { className: "flex flex-1 flex-col", onSubmit, children: [
|
|
8749
|
+
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-4", children: [
|
|
8750
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
|
|
8751
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
|
|
8752
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Label, { size: "small", weight: "plus", htmlFor: "promotion-combobox", children: "Apply promotions" }),
|
|
8753
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Hint, { id: "promotion-combobox-hint", children: "Manage promotions that should be applied to the order." })
|
|
8754
|
+
] }),
|
|
8755
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
8756
|
+
Combobox,
|
|
8757
|
+
{
|
|
8758
|
+
id: "promotion-combobox",
|
|
8759
|
+
"aria-describedby": "promotion-combobox-hint",
|
|
8760
|
+
isFetchingNextPage: comboboxData.isFetchingNextPage,
|
|
8761
|
+
fetchNextPage: comboboxData.fetchNextPage,
|
|
8762
|
+
options: comboboxData.options,
|
|
8763
|
+
onSearchValueChange: comboboxData.onSearchValueChange,
|
|
8764
|
+
searchValue: comboboxData.searchValue,
|
|
8765
|
+
disabled: comboboxData.disabled || isAddingPromotions,
|
|
8766
|
+
onChange: add,
|
|
8767
|
+
value: comboboxValue
|
|
8768
|
+
}
|
|
8769
|
+
)
|
|
8770
|
+
] }),
|
|
8771
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
|
|
8772
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-2", children: promotions?.map((promotion) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
8773
|
+
PromotionItem,
|
|
8774
|
+
{
|
|
8775
|
+
promotion,
|
|
8776
|
+
orderId: preview.id,
|
|
8777
|
+
isLoading: isPending
|
|
8778
|
+
},
|
|
8779
|
+
promotion.id
|
|
8780
|
+
)) })
|
|
8781
|
+
] }) }),
|
|
8782
|
+
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
|
|
8783
|
+
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
|
|
8784
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
8785
|
+
ui.Button,
|
|
8786
|
+
{
|
|
8787
|
+
size: "small",
|
|
8788
|
+
type: "submit",
|
|
8789
|
+
isLoading: isSubmitting || isAddingPromotions,
|
|
8790
|
+
children: "Save"
|
|
8791
|
+
}
|
|
8792
|
+
)
|
|
8793
|
+
] }) })
|
|
8794
|
+
] });
|
|
8795
|
+
};
|
|
8796
|
+
const PromotionItem = ({
|
|
8797
|
+
promotion,
|
|
8798
|
+
orderId,
|
|
8799
|
+
isLoading
|
|
8800
|
+
}) => {
|
|
8801
|
+
const { mutateAsync: removePromotions, isPending } = useDraftOrderRemovePromotions(orderId);
|
|
8802
|
+
const onRemove = async () => {
|
|
8803
|
+
removePromotions(
|
|
8804
|
+
{
|
|
8805
|
+
promo_codes: [promotion.code]
|
|
8806
|
+
},
|
|
8807
|
+
{
|
|
8808
|
+
onError: (e) => {
|
|
8809
|
+
ui.toast.error(e.message);
|
|
8810
|
+
}
|
|
8811
|
+
}
|
|
8812
|
+
);
|
|
8813
|
+
};
|
|
8814
|
+
const displayValue = getDisplayValue(promotion);
|
|
8815
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
8816
|
+
"div",
|
|
8817
|
+
{
|
|
8818
|
+
className: ui.clx(
|
|
8819
|
+
"bg-ui-bg-component shadow-elevation-card-rest flex items-center justify-between rounded-lg px-3 py-2",
|
|
8820
|
+
{
|
|
8821
|
+
"animate-pulse": isLoading
|
|
8822
|
+
}
|
|
8823
|
+
),
|
|
8824
|
+
children: [
|
|
8825
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
8826
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: promotion.code }),
|
|
8827
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-ui-fg-subtle flex items-center gap-1.5", children: [
|
|
8828
|
+
displayValue && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
8829
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", children: displayValue }),
|
|
8830
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", children: "·" })
|
|
8831
|
+
] }),
|
|
8832
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", className: "capitalize", children: promotion.application_method?.allocation })
|
|
8833
|
+
] })
|
|
8834
|
+
] }),
|
|
8835
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
8836
|
+
ui.IconButton,
|
|
8837
|
+
{
|
|
8838
|
+
size: "small",
|
|
8839
|
+
type: "button",
|
|
8840
|
+
variant: "transparent",
|
|
8841
|
+
onClick: onRemove,
|
|
8842
|
+
isLoading: isPending || isLoading,
|
|
8843
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(icons.XMark, {})
|
|
8844
|
+
}
|
|
8845
|
+
)
|
|
8846
|
+
]
|
|
8847
|
+
},
|
|
8848
|
+
promotion.id
|
|
8849
|
+
);
|
|
8850
|
+
};
|
|
8851
|
+
function getDisplayValue(promotion) {
|
|
8852
|
+
const value = promotion.application_method?.value;
|
|
8853
|
+
if (!value) {
|
|
8854
|
+
return null;
|
|
8855
|
+
}
|
|
8856
|
+
if (promotion.application_method?.type === "fixed") {
|
|
8857
|
+
const currency = promotion.application_method?.currency_code;
|
|
8858
|
+
if (!currency) {
|
|
8859
|
+
return null;
|
|
8860
|
+
}
|
|
8861
|
+
return getLocaleAmount(value, currency);
|
|
8862
|
+
} else if (promotion.application_method?.type === "percentage") {
|
|
8863
|
+
return formatPercentage(value);
|
|
8864
|
+
}
|
|
8865
|
+
return null;
|
|
8866
|
+
}
|
|
8867
|
+
const formatter = new Intl.NumberFormat([], {
|
|
8868
|
+
style: "percent",
|
|
8869
|
+
minimumFractionDigits: 2
|
|
8870
|
+
});
|
|
8871
|
+
const formatPercentage = (value, isPercentageValue = false) => {
|
|
8872
|
+
let val = value || 0;
|
|
8873
|
+
if (!isPercentageValue) {
|
|
8874
|
+
val = val / 100;
|
|
8875
|
+
}
|
|
8876
|
+
return formatter.format(val);
|
|
9004
8877
|
};
|
|
9005
|
-
|
|
8878
|
+
function getPromotionIds(items, shippingMethods) {
|
|
8879
|
+
const promotionIds = /* @__PURE__ */ new Set();
|
|
8880
|
+
for (const item of items) {
|
|
8881
|
+
if (item.adjustments) {
|
|
8882
|
+
for (const adjustment of item.adjustments) {
|
|
8883
|
+
if (adjustment.promotion_id) {
|
|
8884
|
+
promotionIds.add(adjustment.promotion_id);
|
|
8885
|
+
}
|
|
8886
|
+
}
|
|
8887
|
+
}
|
|
8888
|
+
}
|
|
8889
|
+
for (const shippingMethod of shippingMethods) {
|
|
8890
|
+
if (shippingMethod.adjustments) {
|
|
8891
|
+
for (const adjustment of shippingMethod.adjustments) {
|
|
8892
|
+
if (adjustment.promotion_id) {
|
|
8893
|
+
promotionIds.add(adjustment.promotion_id);
|
|
8894
|
+
}
|
|
8895
|
+
}
|
|
8896
|
+
}
|
|
8897
|
+
}
|
|
8898
|
+
return Array.from(promotionIds);
|
|
8899
|
+
}
|
|
9006
8900
|
const TransferOwnership = () => {
|
|
9007
8901
|
const { id } = reactRouterDom.useParams();
|
|
9008
8902
|
const { draft_order, isPending, isError, error } = useDraftOrder(id, {
|
|
@@ -9025,7 +8919,7 @@ const TransferOwnershipForm = ({ order }) => {
|
|
|
9025
8919
|
defaultValues: {
|
|
9026
8920
|
customer_id: order.customer_id || ""
|
|
9027
8921
|
},
|
|
9028
|
-
resolver: zod$1.zodResolver(schema)
|
|
8922
|
+
resolver: zod$1.zodResolver(schema$1)
|
|
9029
8923
|
});
|
|
9030
8924
|
const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
|
|
9031
8925
|
const { handleSuccess } = useRouteModal();
|
|
@@ -9475,9 +9369,115 @@ const Illustration = () => {
|
|
|
9475
9369
|
}
|
|
9476
9370
|
);
|
|
9477
9371
|
};
|
|
9478
|
-
const schema = zod.z.object({
|
|
9372
|
+
const schema$1 = zod.z.object({
|
|
9479
9373
|
customer_id: zod.z.string().min(1)
|
|
9480
9374
|
});
|
|
9375
|
+
const SalesChannel = () => {
|
|
9376
|
+
const { id } = reactRouterDom.useParams();
|
|
9377
|
+
const { draft_order, isPending, isError, error } = useDraftOrder(
|
|
9378
|
+
id,
|
|
9379
|
+
{
|
|
9380
|
+
fields: "+sales_channel_id"
|
|
9381
|
+
},
|
|
9382
|
+
{
|
|
9383
|
+
enabled: !!id
|
|
9384
|
+
}
|
|
9385
|
+
);
|
|
9386
|
+
if (isError) {
|
|
9387
|
+
throw error;
|
|
9388
|
+
}
|
|
9389
|
+
const ISrEADY = !!draft_order && !isPending;
|
|
9390
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
|
|
9391
|
+
/* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Header, { children: [
|
|
9392
|
+
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Sales Channel" }) }),
|
|
9393
|
+
/* @__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" }) })
|
|
9394
|
+
] }),
|
|
9395
|
+
ISrEADY && /* @__PURE__ */ jsxRuntime.jsx(SalesChannelForm, { order: draft_order })
|
|
9396
|
+
] });
|
|
9397
|
+
};
|
|
9398
|
+
const SalesChannelForm = ({ order }) => {
|
|
9399
|
+
const form = reactHookForm.useForm({
|
|
9400
|
+
defaultValues: {
|
|
9401
|
+
sales_channel_id: order.sales_channel_id || ""
|
|
9402
|
+
},
|
|
9403
|
+
resolver: zod$1.zodResolver(schema)
|
|
9404
|
+
});
|
|
9405
|
+
const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
|
|
9406
|
+
const { handleSuccess } = useRouteModal();
|
|
9407
|
+
const onSubmit = form.handleSubmit(async (data) => {
|
|
9408
|
+
await mutateAsync(
|
|
9409
|
+
{
|
|
9410
|
+
sales_channel_id: data.sales_channel_id
|
|
9411
|
+
},
|
|
9412
|
+
{
|
|
9413
|
+
onSuccess: () => {
|
|
9414
|
+
ui.toast.success("Sales channel updated");
|
|
9415
|
+
handleSuccess();
|
|
9416
|
+
},
|
|
9417
|
+
onError: (error) => {
|
|
9418
|
+
ui.toast.error(error.message);
|
|
9419
|
+
}
|
|
9420
|
+
}
|
|
9421
|
+
);
|
|
9422
|
+
});
|
|
9423
|
+
return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
9424
|
+
KeyboundForm,
|
|
9425
|
+
{
|
|
9426
|
+
className: "flex flex-1 flex-col overflow-hidden",
|
|
9427
|
+
onSubmit,
|
|
9428
|
+
children: [
|
|
9429
|
+
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsx(SalesChannelField, { control: form.control, order }) }),
|
|
9430
|
+
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
|
|
9431
|
+
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
|
|
9432
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
|
|
9433
|
+
] }) })
|
|
9434
|
+
]
|
|
9435
|
+
}
|
|
9436
|
+
) });
|
|
9437
|
+
};
|
|
9438
|
+
const SalesChannelField = ({ control, order }) => {
|
|
9439
|
+
const salesChannels = useComboboxData({
|
|
9440
|
+
queryFn: async (params) => {
|
|
9441
|
+
return await sdk.admin.salesChannel.list(params);
|
|
9442
|
+
},
|
|
9443
|
+
queryKey: ["sales-channels"],
|
|
9444
|
+
getOptions: (data) => {
|
|
9445
|
+
return data.sales_channels.map((salesChannel) => ({
|
|
9446
|
+
label: salesChannel.name,
|
|
9447
|
+
value: salesChannel.id
|
|
9448
|
+
}));
|
|
9449
|
+
},
|
|
9450
|
+
defaultValue: order.sales_channel_id || void 0
|
|
9451
|
+
});
|
|
9452
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
9453
|
+
Form$2.Field,
|
|
9454
|
+
{
|
|
9455
|
+
control,
|
|
9456
|
+
name: "sales_channel_id",
|
|
9457
|
+
render: ({ field }) => {
|
|
9458
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
|
|
9459
|
+
/* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Sales Channel" }),
|
|
9460
|
+
/* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
9461
|
+
Combobox,
|
|
9462
|
+
{
|
|
9463
|
+
options: salesChannels.options,
|
|
9464
|
+
fetchNextPage: salesChannels.fetchNextPage,
|
|
9465
|
+
isFetchingNextPage: salesChannels.isFetchingNextPage,
|
|
9466
|
+
searchValue: salesChannels.searchValue,
|
|
9467
|
+
onSearchValueChange: salesChannels.onSearchValueChange,
|
|
9468
|
+
placeholder: "Select sales channel",
|
|
9469
|
+
...field
|
|
9470
|
+
}
|
|
9471
|
+
) }),
|
|
9472
|
+
/* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
|
|
9473
|
+
] });
|
|
9474
|
+
}
|
|
9475
|
+
}
|
|
9476
|
+
);
|
|
9477
|
+
};
|
|
9478
|
+
const schema = zod.z.object({
|
|
9479
|
+
sales_channel_id: zod.z.string().min(1)
|
|
9480
|
+
});
|
|
9481
9481
|
const widgetModule = { widgets: [] };
|
|
9482
9482
|
const routeModule = {
|
|
9483
9483
|
routes: [
|
|
@@ -9502,10 +9502,6 @@ const routeModule = {
|
|
|
9502
9502
|
Component: BillingAddress,
|
|
9503
9503
|
path: "/draft-orders/:id/billing-address"
|
|
9504
9504
|
},
|
|
9505
|
-
{
|
|
9506
|
-
Component: CustomItems,
|
|
9507
|
-
path: "/draft-orders/:id/custom-items"
|
|
9508
|
-
},
|
|
9509
9505
|
{
|
|
9510
9506
|
Component: Email,
|
|
9511
9507
|
path: "/draft-orders/:id/email"
|
|
@@ -9515,16 +9511,12 @@ const routeModule = {
|
|
|
9515
9511
|
path: "/draft-orders/:id/items"
|
|
9516
9512
|
},
|
|
9517
9513
|
{
|
|
9518
|
-
Component:
|
|
9519
|
-
path: "/draft-orders/:id/
|
|
9520
|
-
},
|
|
9521
|
-
{
|
|
9522
|
-
Component: Promotions,
|
|
9523
|
-
path: "/draft-orders/:id/promotions"
|
|
9514
|
+
Component: CustomItems,
|
|
9515
|
+
path: "/draft-orders/:id/custom-items"
|
|
9524
9516
|
},
|
|
9525
9517
|
{
|
|
9526
|
-
Component:
|
|
9527
|
-
path: "/draft-orders/:id/
|
|
9518
|
+
Component: Metadata,
|
|
9519
|
+
path: "/draft-orders/:id/metadata"
|
|
9528
9520
|
},
|
|
9529
9521
|
{
|
|
9530
9522
|
Component: Shipping,
|
|
@@ -9534,9 +9526,17 @@ const routeModule = {
|
|
|
9534
9526
|
Component: ShippingAddress,
|
|
9535
9527
|
path: "/draft-orders/:id/shipping-address"
|
|
9536
9528
|
},
|
|
9529
|
+
{
|
|
9530
|
+
Component: Promotions,
|
|
9531
|
+
path: "/draft-orders/:id/promotions"
|
|
9532
|
+
},
|
|
9537
9533
|
{
|
|
9538
9534
|
Component: TransferOwnership,
|
|
9539
9535
|
path: "/draft-orders/:id/transfer-ownership"
|
|
9536
|
+
},
|
|
9537
|
+
{
|
|
9538
|
+
Component: SalesChannel,
|
|
9539
|
+
path: "/draft-orders/:id/sales-channel"
|
|
9540
9540
|
}
|
|
9541
9541
|
]
|
|
9542
9542
|
}
|