From 1c13695556079c0439e1ff439acdce28b0171b36 Mon Sep 17 00:00:00 2001 From: Leonid Pershin Date: Sun, 19 Jul 2026 05:35:28 +0300 Subject: [PATCH] Enhance PaidUntilBadge component to support pending payment review status - Updated the PaidUntilBadge component to accept a new `pendingReview` prop, indicating if a payment is awaiting admin confirmation. - Modified the rendering logic to display a warning badge when a payment is under review, providing users with a neutral status instead of a negative one. - Updated relevant components in billing and dashboard routes to pass the new `pendingReview` prop based on the active payment request status. - Added internationalization support for new labels related to the pending review status in both English and Russian. --- .../src/features/billing/PaidUntilBadge.tsx | 21 +++++++++++++++++-- frontend/src/routes/billing.tsx | 7 ++++++- frontend/src/routes/dashboard.tsx | 5 ++++- frontend/src/shared/lib/i18n.ts | 4 ++++ 4 files changed, 33 insertions(+), 4 deletions(-) diff --git a/frontend/src/features/billing/PaidUntilBadge.tsx b/frontend/src/features/billing/PaidUntilBadge.tsx index 2684e0b..5779ce5 100644 --- a/frontend/src/features/billing/PaidUntilBadge.tsx +++ b/frontend/src/features/billing/PaidUntilBadge.tsx @@ -6,10 +6,27 @@ const RED_THRESHOLD_DAYS = 3 const YELLOW_THRESHOLD_DAYS = 7 /** Цветовая индикация оплаченного периода: зелёный — обычный запас, жёлтый — ≤7 дней, красный — - * ≤3 дней или уже истекло. Общий компонент для дашборда пользователя и списка пользователей в админке. */ -export function PaidUntilBadge({ paidUntil }: { paidUntil: string | null }) { + * ≤3 дней или уже истекло. Общий компонент для дашборда пользователя и списка пользователей в админке. + * + * `pendingReview` — есть заявка на оплату, ожидающая решения админа (`PaymentRequestStatus.AwaitingConfirmation`): + * конфиги не гасятся, пока админ не решит (см. BillingService), поэтому вместо тревожного "Истекло" + * показываем нейтральный статус — пользователю незачем переживать за то, что от него не зависит. */ +export function PaidUntilBadge({ + paidUntil, + pendingReview, +}: { + paidUntil: string | null + pendingReview?: boolean +}) { const { t } = useTranslation() + if (pendingReview) + return ( + + {t('billing.pendingReviewShort')} + + ) + if (!paidUntil) return {t('billing.neverPaidShort')} const days = getDaysRemaining(paidUntil) diff --git a/frontend/src/routes/billing.tsx b/frontend/src/routes/billing.tsx index cd947db..6451cde 100644 --- a/frontend/src/routes/billing.tsx +++ b/frontend/src/routes/billing.tsx @@ -63,7 +63,12 @@ function BillingContent() { ? t('billing.paidUntil', { date: new Date(data.paidUntil).toLocaleDateString() }) : t('billing.neverPaid')}

- {data.paidUntil && } + {data.paidUntil && ( + + )} diff --git a/frontend/src/routes/dashboard.tsx b/frontend/src/routes/dashboard.tsx index 75b717a..dd93da0 100644 --- a/frontend/src/routes/dashboard.tsx +++ b/frontend/src/routes/dashboard.tsx @@ -45,7 +45,10 @@ function ConfigsList() { {billingStatusQuery.data?.billingEnabled && ( {t('billing.paidUntilLabel')} - + )} diff --git a/frontend/src/shared/lib/i18n.ts b/frontend/src/shared/lib/i18n.ts index 69c5862..0fb722a 100644 --- a/frontend/src/shared/lib/i18n.ts +++ b/frontend/src/shared/lib/i18n.ts @@ -114,6 +114,8 @@ const resources = { daysRemaining: '{{count}} дн.', hoursMinutesRemaining: '{{hours}} ч {{minutes}} мин', minutesRemaining: '{{count}} мин', + pendingReviewShort: 'На проверке', + pendingReviewHint: 'Оплата отправлена на проверку администратору — доступ не будет приостановлен, пока заявка не решена.', newRequest: 'Оформить оплату', period: 'Период', periods: { @@ -638,6 +640,8 @@ const resources = { daysRemaining: '{{count}}d', hoursMinutesRemaining: '{{hours}}h {{minutes}}m', minutesRemaining: '{{count}}m', + pendingReviewShort: 'Under review', + pendingReviewHint: 'Payment sent for admin review — access will not be suspended until the request is decided.', newRequest: 'Set up payment', period: 'Period', periods: {