medusa-bonuses-plugin
Version:
medusa-bonuses-plugin is a Medusa plugin that adds bonus program to Medusa ecommerce stores.
457 lines (451 loc) • 23.9 kB
JavaScript
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
import { Plus, Pencil, Trash } from '@medusajs/icons';
import { useState, useEffect } from 'react';
import { Toaster, Heading, Text, Container, Input, Button, toast, Table, Badge, FocusModal } from '@medusajs/ui';
import { useQuery, useQueryClient, useMutation } from '@tanstack/react-query';
import { useMedusa } from 'medusa-react';
const useBonusSettings = () => {
const { client } = useMedusa();
return useQuery({
queryKey: ["bonus-settings"],
queryFn: async () => {
const { data } = await client.admin.custom.get("/admin/bonus/settings");
return data;
}
});
};
const useUpdateBonusSettings = () => {
const queryClient = useQueryClient();
const { client } = useMedusa();
return useMutation({
mutationFn: async (settings) => {
const { data } = await client.admin.custom.post("/admin/bonus/settings", settings);
return data;
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["bonus-settings"] });
}
});
};
const useCustomerBonus = (customerId) => {
const { client } = useMedusa();
return useQuery({
queryKey: ["customer-bonus", customerId],
queryFn: async () => {
const { data } = await client.admin.custom.get(`/admin/customers/${customerId}/bonus`);
return data;
},
enabled: !!customerId
});
};
const useAdjustBonusBalance = (customerId) => {
const queryClient = useQueryClient();
const { client } = useMedusa();
return useMutation({
mutationFn: async ({ amount, reason }) => {
const { data } = await client.admin.custom.post(
`/admin/customers/${customerId}/bonus/adjust`,
{ amount, reason }
);
return data;
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["customer-bonus", customerId] });
}
});
};
const useSetCustomerBonusPercentage = (customerId) => {
const queryClient = useQueryClient();
const { client } = useMedusa();
return useMutation({
mutationFn: async ({
percentage,
ends_at,
metadata
}) => {
const { data } = await client.admin.custom.post(
`/admin/customers/${customerId}/bonus/percentage`,
{ percentage, ends_at, metadata }
);
return data;
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["customer-bonus", customerId] });
}
});
};
const useRemoveCustomerBonusPercentage = (customerId) => {
const queryClient = useQueryClient();
const { client } = useMedusa();
return useMutation({
mutationFn: async () => {
const { data } = await client.admin.custom.delete(
`/admin/customers/${customerId}/bonus/percentage`
);
return data;
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["customer-bonus", customerId] });
}
});
};
const BonusSettingsPage = () => {
var _a, _b, _c;
const [defaultPercentage, setDefaultPercentage] = useState(3);
const [isLoading, setIsLoading] = useState(false);
const { data: settings, refetch } = useBonusSettings();
const updateSettings = useUpdateBonusSettings();
useEffect(() => {
if (settings) {
setDefaultPercentage(settings.default_percentage || 3);
}
}, [settings]);
const handleSave = async () => {
setIsLoading(true);
try {
await updateSettings.mutateAsync({
default_percentage: defaultPercentage
});
toast.success("\u041D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0438 \u0443\u0441\u043F\u0435\u0448\u043D\u043E \u0441\u043E\u0445\u0440\u0430\u043D\u0435\u043D\u044B");
} catch (error) {
toast.error("\u041E\u0448\u0438\u0431\u043A\u0430 \u043F\u0440\u0438 \u0441\u043E\u0445\u0440\u0430\u043D\u0435\u043D\u0438\u0438 \u043D\u0430\u0441\u0442\u0440\u043E\u0435\u043A");
console.error(error);
} finally {
setIsLoading(false);
}
};
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-6 p-6", children: [
/* @__PURE__ */ jsx(Toaster, {}),
/* @__PURE__ */ jsx("div", { className: "flex items-center justify-between", children: /* @__PURE__ */ jsxs("div", { children: [
/* @__PURE__ */ jsx(Heading, { level: "h1", children: "\u041D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0438 \u0431\u043E\u043D\u0443\u0441\u043D\u043E\u0439 \u043F\u0440\u043E\u0433\u0440\u0430\u043C\u043C\u044B" }),
/* @__PURE__ */ jsx(Text, { className: "text-ui-fg-subtle", children: "\u0423\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u0438\u0435 \u0433\u043B\u043E\u0431\u0430\u043B\u044C\u043D\u044B\u043C\u0438 \u043F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u0430\u043C\u0438 \u0431\u043E\u043D\u0443\u0441\u043D\u043E\u0439 \u0441\u0438\u0441\u0442\u0435\u043C\u044B" })
] }) }),
/* @__PURE__ */ jsx(Container, { className: "p-6", children: /* @__PURE__ */ jsxs("div", { className: "space-y-6", children: [
/* @__PURE__ */ jsxs("div", { children: [
/* @__PURE__ */ jsx(Heading, { level: "h2", className: "mb-4", children: "\u041F\u0440\u043E\u0446\u0435\u043D\u0442 \u043D\u0430\u0447\u0438\u0441\u043B\u0435\u043D\u0438\u044F \u0431\u043E\u043D\u0443\u0441\u043E\u0432" }),
/* @__PURE__ */ jsx("div", { className: "grid gap-4", children: /* @__PURE__ */ jsxs("div", { children: [
/* @__PURE__ */ jsx("label", { className: "block text-sm font-medium mb-2", children: "\u041F\u0440\u043E\u0446\u0435\u043D\u0442 \u043F\u043E \u0443\u043C\u043E\u043B\u0447\u0430\u043D\u0438\u044E (%)" }),
/* @__PURE__ */ jsx(
Input,
{
type: "number",
min: "0",
max: "100",
step: "0.1",
value: defaultPercentage,
onChange: (e) => setDefaultPercentage(parseFloat(e.target.value)),
placeholder: "3.0"
}
),
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle mt-1", children: "\u041F\u0440\u043E\u0446\u0435\u043D\u0442 \u043E\u0442 \u0441\u0443\u043C\u043C\u044B \u0437\u0430\u043A\u0430\u0437\u0430, \u043A\u043E\u0442\u043E\u0440\u044B\u0439 \u0431\u0443\u0434\u0435\u0442 \u043D\u0430\u0447\u0438\u0441\u043B\u0435\u043D \u043A\u0430\u043A \u0431\u043E\u043D\u0443\u0441\u044B" })
] }) })
] }),
/* @__PURE__ */ jsx("div", { className: "flex justify-end pt-4 border-t", children: /* @__PURE__ */ jsx(
Button,
{
onClick: handleSave,
disabled: isLoading,
isLoading,
children: "\u0421\u043E\u0445\u0440\u0430\u043D\u0438\u0442\u044C \u043D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0438"
}
) })
] }) }),
/* @__PURE__ */ jsx(Container, { className: "p-6", children: /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
/* @__PURE__ */ jsx(Heading, { level: "h2", children: "\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043A\u0430" }),
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 md:grid-cols-3 gap-4", children: [
/* @__PURE__ */ jsxs("div", { className: "p-4 bg-ui-bg-subtle rounded-lg", children: [
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "\u0410\u043A\u0442\u0438\u0432\u043D\u044B\u0445 \u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u0435\u0439" }),
/* @__PURE__ */ jsx(Text, { size: "large", weight: "plus", children: ((_a = settings == null ? void 0 : settings.stats) == null ? void 0 : _a.active_users) || "\u2014" })
] }),
/* @__PURE__ */ jsxs("div", { className: "p-4 bg-ui-bg-subtle rounded-lg", children: [
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "\u0412\u0441\u0435\u0433\u043E \u043D\u0430\u0447\u0438\u0441\u043B\u0435\u043D\u043E \u0431\u043E\u043D\u0443\u0441\u043E\u0432" }),
/* @__PURE__ */ jsx(Text, { size: "large", weight: "plus", children: ((_b = settings == null ? void 0 : settings.stats) == null ? void 0 : _b.total_earned) || "\u2014" })
] }),
/* @__PURE__ */ jsxs("div", { className: "p-4 bg-ui-bg-subtle rounded-lg", children: [
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "\u041F\u043E\u0442\u0440\u0430\u0447\u0435\u043D\u043E \u0431\u043E\u043D\u0443\u0441\u043E\u0432" }),
/* @__PURE__ */ jsx(Text, { size: "large", weight: "plus", children: ((_c = settings == null ? void 0 : settings.stats) == null ? void 0 : _c.total_spent) || "\u2014" })
] })
] })
] }) })
] });
};
const CustomerBonusWidget = ({ customer }) => {
var _a;
const [isAdjustModalOpen, setIsAdjustModalOpen] = useState(false);
const [isPercentageModalOpen, setIsPercentageModalOpen] = useState(false);
const [adjustAmount, setAdjustAmount] = useState(0);
const [adjustReason, setAdjustReason] = useState("");
const [customPercentage, setCustomPercentage] = useState(0);
const [percentageEndDate, setPercentageEndDate] = useState("");
const { data: bonusData, refetch } = useCustomerBonus(customer.id);
const adjustBalance = useAdjustBonusBalance(customer.id);
const setPercentage = useSetCustomerBonusPercentage(customer.id);
const removePercentage = useRemoveCustomerBonusPercentage(customer.id);
const handleAdjustBalance = async () => {
try {
await adjustBalance.mutateAsync({
amount: adjustAmount,
reason: adjustReason
});
toast.success("\u0411\u0430\u043B\u0430\u043D\u0441 \u0443\u0441\u043F\u0435\u0448\u043D\u043E \u0441\u043A\u043E\u0440\u0440\u0435\u043A\u0442\u0438\u0440\u043E\u0432\u0430\u043D");
setIsAdjustModalOpen(false);
setAdjustAmount(0);
setAdjustReason("");
} catch (error) {
toast.error("\u041E\u0448\u0438\u0431\u043A\u0430 \u043F\u0440\u0438 \u043A\u043E\u0440\u0440\u0435\u043A\u0442\u0438\u0440\u043E\u0432\u043A\u0435 \u0431\u0430\u043B\u0430\u043D\u0441\u0430");
console.error(error);
}
};
const handleSetPercentage = async () => {
try {
await setPercentage.mutateAsync({
percentage: customPercentage,
ends_at: percentageEndDate ? new Date(percentageEndDate) : void 0
});
toast.success("\u041F\u0435\u0440\u0441\u043E\u043D\u0430\u043B\u044C\u043D\u044B\u0439 \u043F\u0440\u043E\u0446\u0435\u043D\u0442 \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u043B\u0435\u043D");
setIsPercentageModalOpen(false);
setCustomPercentage(0);
setPercentageEndDate("");
} catch (error) {
toast.error("\u041E\u0448\u0438\u0431\u043A\u0430 \u043F\u0440\u0438 \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u043A\u0435 \u043F\u0440\u043E\u0446\u0435\u043D\u0442\u0430");
console.error(error);
}
};
const handleRemovePercentage = async () => {
try {
await removePercentage.mutateAsync();
toast.success("\u041F\u0435\u0440\u0441\u043E\u043D\u0430\u043B\u044C\u043D\u044B\u0439 \u043F\u0440\u043E\u0446\u0435\u043D\u0442 \u0443\u0434\u0430\u043B\u0435\u043D");
} catch (error) {
toast.error("\u041E\u0448\u0438\u0431\u043A\u0430 \u043F\u0440\u0438 \u0443\u0434\u0430\u043B\u0435\u043D\u0438\u0438 \u043F\u0440\u043E\u0446\u0435\u043D\u0442\u0430");
console.error(error);
}
};
const formatDate = (date) => {
return new Date(date).toLocaleDateString("ru-RU");
};
const getTransactionTypeLabel = (type) => {
const labels = {
order_earning: "\u041D\u0430\u0447\u0438\u0441\u043B\u0435\u043D\u0438\u0435 \u0437\u0430 \u0437\u0430\u043A\u0430\u0437",
order_spending: "\u0421\u043F\u0438\u0441\u0430\u043D\u0438\u0435 \u043D\u0430 \u0437\u0430\u043A\u0430\u0437",
reservation: "\u0420\u0435\u0437\u0435\u0440\u0432\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u0435",
adjustment: "\u041A\u043E\u0440\u0440\u0435\u043A\u0442\u0438\u0440\u043E\u0432\u043A\u0430",
expiration: "\u0421\u043F\u0438\u0441\u0430\u043D\u0438\u0435 \u043F\u043E \u0438\u0441\u0442\u0435\u0447\u0435\u043D\u0438\u044E"
};
return labels[type] || type;
};
const getTransactionTypeBadgeVariant = (type) => {
const variants = {
order_earning: "green",
order_spending: "red",
reservation: "orange",
adjustment: "blue",
expiration: "red"
};
return variants[type] || "grey";
};
if (!bonusData) {
return /* @__PURE__ */ jsx(Container, { className: "p-6", children: /* @__PURE__ */ jsx(Text, { children: "\u0417\u0430\u0433\u0440\u0443\u0436\u0430\u044E\u0442\u0441\u044F \u0434\u0430\u043D\u043D\u044B\u0435 \u043E \u0431\u043E\u043D\u0443\u0441\u0430\u0445..." }) });
}
return /* @__PURE__ */ jsxs(Fragment, { children: [
/* @__PURE__ */ jsx(Toaster, {}),
/* @__PURE__ */ jsx(Container, { className: "p-6", children: /* @__PURE__ */ jsxs("div", { className: "space-y-6", children: [
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
/* @__PURE__ */ jsx(Heading, { level: "h2", children: "\u0411\u043E\u043D\u0443\u0441\u043D\u0430\u044F \u043F\u0440\u043E\u0433\u0440\u0430\u043C\u043C\u0430" }),
/* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
/* @__PURE__ */ jsxs(
Button,
{
variant: "secondary",
size: "small",
onClick: () => setIsAdjustModalOpen(true),
children: [
/* @__PURE__ */ jsx(Plus, { className: "w-4 h-4" }),
"\u041A\u043E\u0440\u0440\u0435\u043A\u0442\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u0431\u0430\u043B\u0430\u043D\u0441"
]
}
),
/* @__PURE__ */ jsxs(
Button,
{
variant: "secondary",
size: "small",
onClick: () => setIsPercentageModalOpen(true),
children: [
/* @__PURE__ */ jsx(Pencil, { className: "w-4 h-4" }),
"\u041F\u0440\u043E\u0446\u0435\u043D\u0442"
]
}
)
] })
] }),
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 md:grid-cols-3 gap-4", children: [
/* @__PURE__ */ jsxs("div", { className: "p-4 bg-ui-bg-subtle rounded-lg", children: [
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "\u0411\u0430\u043B\u0430\u043D\u0441 \u0431\u043E\u043D\u0443\u0441\u043E\u0432" }),
/* @__PURE__ */ jsx(Text, { size: "large", weight: "plus", children: bonusData.balance })
] }),
/* @__PURE__ */ jsxs("div", { className: "p-4 bg-ui-bg-subtle rounded-lg", children: [
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "\u041F\u0440\u043E\u0446\u0435\u043D\u0442 \u043F\u043E \u0443\u043C\u043E\u043B\u0447\u0430\u043D\u0438\u044E" }),
/* @__PURE__ */ jsxs(Text, { size: "large", weight: "plus", children: [
bonusData.default_bonus_percentage,
"%"
] })
] }),
/* @__PURE__ */ jsxs("div", { className: "p-4 bg-ui-bg-subtle rounded-lg", children: [
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "\u041F\u0435\u0440\u0441\u043E\u043D\u0430\u043B\u044C\u043D\u044B\u0439 \u043F\u0440\u043E\u0446\u0435\u043D\u0442" }),
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
/* @__PURE__ */ jsx(Text, { size: "large", weight: "plus", children: bonusData.custom_percentage ? `${bonusData.custom_percentage.percentage}%` : "\u2014" }),
bonusData.custom_percentage && /* @__PURE__ */ jsx(
Button,
{
variant: "transparent",
size: "small",
onClick: handleRemovePercentage,
children: /* @__PURE__ */ jsx(Trash, { className: "w-4 h-4 text-ui-fg-error" })
}
)
] }),
((_a = bonusData.custom_percentage) == null ? void 0 : _a.ends_at) && /* @__PURE__ */ jsxs(Text, { size: "small", className: "text-ui-fg-subtle", children: [
"\u0434\u043E ",
formatDate(bonusData.custom_percentage.ends_at)
] })
] })
] }),
/* @__PURE__ */ jsxs("div", { children: [
/* @__PURE__ */ jsx(Heading, { level: "h3", className: "mb-4", children: "\u0418\u0441\u0442\u043E\u0440\u0438\u044F \u043E\u043F\u0435\u0440\u0430\u0446\u0438\u0439" }),
bonusData.transactions && bonusData.transactions.length > 0 ? /* @__PURE__ */ jsxs(Table, { children: [
/* @__PURE__ */ jsx(Table.Header, { children: /* @__PURE__ */ jsxs(Table.Row, { children: [
/* @__PURE__ */ jsx(Table.HeaderCell, { children: "\u0414\u0430\u0442\u0430" }),
/* @__PURE__ */ jsx(Table.HeaderCell, { children: "\u0422\u0438\u043F" }),
/* @__PURE__ */ jsx(Table.HeaderCell, { children: "\u0421\u0443\u043C\u043C\u0430" }),
/* @__PURE__ */ jsx(Table.HeaderCell, { children: "\u041E\u043F\u0438\u0441\u0430\u043D\u0438\u0435" })
] }) }),
/* @__PURE__ */ jsx(Table.Body, { children: bonusData.transactions.slice(0, 10).map((transaction, index) => /* @__PURE__ */ jsxs(Table.Row, { children: [
/* @__PURE__ */ jsx(Table.Cell, { children: formatDate(transaction.created_at) }),
/* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(Badge, { color: getTransactionTypeBadgeVariant(transaction.type), children: getTransactionTypeLabel(transaction.type) }) }),
/* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsxs(Text, { className: transaction.amount > 0 ? "text-ui-fg-success" : "text-ui-fg-error", children: [
transaction.amount > 0 ? "+" : "",
transaction.amount
] }) }),
/* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: transaction.note || "\u2014" }) })
] }, index)) })
] }) : /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-subtle", children: "\u041E\u043F\u0435\u0440\u0430\u0446\u0438\u0439 \u043F\u043E\u043A\u0430 \u043D\u0435\u0442" })
] })
] }) }),
/* @__PURE__ */ jsx(FocusModal, { open: isAdjustModalOpen, onOpenChange: setIsAdjustModalOpen, children: /* @__PURE__ */ jsxs(FocusModal.Content, { children: [
/* @__PURE__ */ jsxs(FocusModal.Header, { children: [
/* @__PURE__ */ jsx("div", { className: "flex justify-start", children: /* @__PURE__ */ jsx(Text, { children: "\u041A\u043E\u0440\u0440\u0435\u043A\u0442\u0438\u0440\u043E\u0432\u043A\u0430 \u0431\u0430\u043B\u0430\u043D\u0441\u0430" }) }),
/* @__PURE__ */ jsxs("div", { className: "flex gap-2 justify-end", children: [
/* @__PURE__ */ jsx(
Button,
{
variant: "secondary",
onClick: () => setIsAdjustModalOpen(false),
children: "\u041E\u0442\u043C\u0435\u043D\u0430"
}
),
/* @__PURE__ */ jsx(
Button,
{
onClick: handleAdjustBalance,
disabled: !adjustAmount || !adjustReason.trim(),
children: "\u0421\u043E\u0445\u0440\u0430\u043D\u0438\u0442\u044C"
}
)
] })
] }),
/* @__PURE__ */ jsxs(FocusModal.Body, { className: "space-y-4", children: [
/* @__PURE__ */ jsxs("div", { children: [
/* @__PURE__ */ jsx("label", { className: "block text-sm font-medium mb-2", children: "\u041D\u043E\u0432\u044B\u0439 \u0431\u0430\u043B\u0430\u043D\u0441" }),
/* @__PURE__ */ jsx(
Input,
{
type: "number",
min: "0",
step: "1",
value: adjustAmount,
onChange: (e) => setAdjustAmount(parseFloat(e.target.value)),
placeholder: "\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u043D\u043E\u0432\u0443\u044E \u0441\u0443\u043C\u043C\u0443"
}
)
] }),
/* @__PURE__ */ jsxs("div", { children: [
/* @__PURE__ */ jsx("label", { className: "block text-sm font-medium mb-2", children: "\u041F\u0440\u0438\u0447\u0438\u043D\u0430 \u043A\u043E\u0440\u0440\u0435\u043A\u0442\u0438\u0440\u043E\u0432\u043A\u0438" }),
/* @__PURE__ */ jsx(
Input,
{
value: adjustReason,
onChange: (e) => setAdjustReason(e.target.value),
placeholder: "\u041E\u043F\u0438\u0448\u0438\u0442\u0435 \u043F\u0440\u0438\u0447\u0438\u043D\u0443 \u0438\u0437\u043C\u0435\u043D\u0435\u043D\u0438\u044F"
}
)
] })
] })
] }) }),
/* @__PURE__ */ jsx(FocusModal, { open: isPercentageModalOpen, onOpenChange: setIsPercentageModalOpen, children: /* @__PURE__ */ jsxs(FocusModal.Content, { children: [
/* @__PURE__ */ jsxs(FocusModal.Header, { children: [
/* @__PURE__ */ jsx("div", { className: "flex justify-start", children: /* @__PURE__ */ jsx(Text, { children: "\u041F\u0435\u0440\u0441\u043E\u043D\u0430\u043B\u044C\u043D\u044B\u0439 \u043F\u0440\u043E\u0446\u0435\u043D\u0442 \u0431\u043E\u043D\u0443\u0441\u043E\u0432" }) }),
/* @__PURE__ */ jsxs("div", { className: "flex gap-2 justify-end", children: [
/* @__PURE__ */ jsx(
Button,
{
variant: "secondary",
onClick: () => setIsPercentageModalOpen(false),
children: "\u041E\u0442\u043C\u0435\u043D\u0430"
}
),
/* @__PURE__ */ jsx(
Button,
{
onClick: handleSetPercentage,
disabled: !customPercentage,
children: "\u0423\u0441\u0442\u0430\u043D\u043E\u0432\u0438\u0442\u044C"
}
)
] })
] }),
/* @__PURE__ */ jsxs(FocusModal.Body, { className: "space-y-4", children: [
/* @__PURE__ */ jsxs("div", { children: [
/* @__PURE__ */ jsx("label", { className: "block text-sm font-medium mb-2", children: "\u041F\u0440\u043E\u0446\u0435\u043D\u0442 (%)" }),
/* @__PURE__ */ jsx(
Input,
{
type: "number",
min: "0",
max: "100",
step: "0.1",
value: customPercentage,
onChange: (e) => setCustomPercentage(parseFloat(e.target.value)),
placeholder: "5.0"
}
)
] }),
/* @__PURE__ */ jsxs("div", { children: [
/* @__PURE__ */ jsx("label", { className: "block text-sm font-medium mb-2", children: "\u0414\u0435\u0439\u0441\u0442\u0432\u0443\u0435\u0442 \u0434\u043E (\u043E\u043F\u0446\u0438\u043E\u043D\u0430\u043B\u044C\u043D\u043E)" }),
/* @__PURE__ */ jsx(
Input,
{
type: "date",
value: percentageEndDate,
onChange: (e) => setPercentageEndDate(e.target.value)
}
),
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle mt-1", children: "\u0415\u0441\u043B\u0438 \u043D\u0435 \u0443\u043A\u0430\u0437\u0430\u043D\u043E, \u0434\u0435\u0439\u0441\u0442\u0432\u0443\u0435\u0442 \u0431\u0435\u0441\u0441\u0440\u043E\u0447\u043D\u043E" })
] })
] })
] }) })
] });
};
const config = {
zone: "customer.details.after"
};
const entry = {
identifier: "medusa-bonuses-plugin",
extensions: [
{
Component: BonusSettingsPage,
config: { path: "/settings/bonus", type: "route" }
},
{ Component: CustomerBonusWidget, config: { ...config, type: "widget" } }
],
};
export { entry as default };