feat: renewal btn
This commit is contained in:
@@ -12,6 +12,8 @@ import { DeviceCard } from '../components/DeviceCard';
|
||||
import { Modal } from '../components/Modal';
|
||||
import { SubscriptionQrModal } from '../components/SubscriptionQrModal';
|
||||
import { ClientLinksModal } from '../components/ClientLinksModal';
|
||||
import { formatMoney } from '../lib/format';
|
||||
import { redirectTo } from '../lib/redirect';
|
||||
import type { Device, SubscriptionData, UserInfo } from '../types';
|
||||
|
||||
export function AccountPage() {
|
||||
@@ -27,6 +29,8 @@ export function AccountPage() {
|
||||
const [isQrOpen, setIsQrOpen] = useState(false);
|
||||
const [isReferralQrOpen, setIsReferralQrOpen] = useState(false);
|
||||
const [isClientLinksOpen, setIsClientLinksOpen] = useState(false);
|
||||
const [isRenewalOpen, setIsRenewalOpen] = useState(false);
|
||||
const [isRenewing, setIsRenewing] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isAuthenticated) {
|
||||
@@ -98,18 +102,60 @@ export function AccountPage() {
|
||||
navigate('/', { replace: true });
|
||||
};
|
||||
|
||||
const openPlanWithCurrentConfig = () => {
|
||||
if (!subscription) return;
|
||||
const params = new URLSearchParams();
|
||||
if (subscription.devices) params.set('devices', String(subscription.devices));
|
||||
if (subscription.duration_days) params.set('duration', String(subscription.duration_days));
|
||||
if (subscription.addon_ids.length > 0) params.set('addons', subscription.addon_ids.join(','));
|
||||
navigate(`/plan?${params.toString()}`);
|
||||
};
|
||||
|
||||
const renewCurrentPlan = async () => {
|
||||
if (!subscription?.devices || !subscription.duration_days) {
|
||||
openPlanWithCurrentConfig();
|
||||
return;
|
||||
}
|
||||
setIsRenewing(true);
|
||||
try {
|
||||
const result = await api.checkout({
|
||||
devices: subscription.devices,
|
||||
addons: subscription.addon_ids,
|
||||
duration_days: subscription.duration_days,
|
||||
});
|
||||
if (result.payment_link) {
|
||||
redirectTo(result.payment_link);
|
||||
return;
|
||||
}
|
||||
setIsRenewalOpen(false);
|
||||
showToast(`Заказ ${result.order_id} оформлен. К оплате: ${formatMoney(result.amount_to_pay)}`);
|
||||
} catch (err: unknown) {
|
||||
const message = err instanceof ApiError ? err.message : 'Не удалось оформить продление';
|
||||
showToast(message);
|
||||
} finally {
|
||||
setIsRenewing(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Shell active="account">
|
||||
<section className="account-hero">
|
||||
<Reveal>
|
||||
<div className="kicker">Ваш аккаунт</div>
|
||||
<h1 className="hero-title">{userInfo?.username ?? 'Аккаунт'}</h1>
|
||||
{!loadingMeta ? (
|
||||
<p className="hero-sub">
|
||||
{subscription?.has_subscription && subscription.expires_at
|
||||
? `Подписка до ${new Date(subscription.expires_at).toLocaleDateString('ru-RU')}`
|
||||
: 'Активная подписка отсутствует'}
|
||||
</p>
|
||||
{!loadingMeta ? (
|
||||
<>
|
||||
<p className="hero-sub">
|
||||
{subscription?.has_subscription && subscription.expires_at
|
||||
? `Подписка до ${new Date(subscription.expires_at).toLocaleDateString('ru-RU')}`
|
||||
: 'Активная подписка отсутствует'}
|
||||
</p>
|
||||
{subscription?.has_subscription ? (
|
||||
<button type="button" className="btn btn-primary account-renew" onClick={() => setIsRenewalOpen(true)}>
|
||||
Продлить
|
||||
</button>
|
||||
) : null}
|
||||
</>
|
||||
) : null}
|
||||
</Reveal>
|
||||
</section>
|
||||
@@ -275,6 +321,19 @@ export function AccountPage() {
|
||||
confirmLabel="Удалить"
|
||||
onConfirm={confirmDelete}
|
||||
/>
|
||||
<Modal
|
||||
open={isRenewalOpen}
|
||||
onClose={() => setIsRenewalOpen(false)}
|
||||
kicker="Продление"
|
||||
title="Продлить с текущими параметрами?"
|
||||
body="Мы повторим число устройств, дополнения и срок вашей текущей подписки."
|
||||
confirmLabel={isRenewing ? 'Оформление…' : 'Да, продлить'}
|
||||
cancelLabel="Нет, настроить"
|
||||
confirmClassName="btn-primary"
|
||||
pending={isRenewing}
|
||||
onCancel={openPlanWithCurrentConfig}
|
||||
onConfirm={() => void renewCurrentPlan()}
|
||||
/>
|
||||
<SubscriptionQrModal
|
||||
link={isQrOpen ? subscription?.subscription_link ?? null : null}
|
||||
onClose={() => setIsQrOpen(false)}
|
||||
|
||||
Reference in New Issue
Block a user