From 39bfef58d0db9ebbe2bd27d4e7f327f02932b81b Mon Sep 17 00:00:00 2001 From: c0mrade Date: Wed, 3 Jun 2026 11:07:45 +0300 Subject: [PATCH] =?UTF-8?q?fix(subscriptions):=20=C2=AB+=20=D0=9A=D1=83?= =?UTF-8?q?=D0=BF=D0=B8=D1=82=D1=8C=20=D0=B5=D1=89=D1=91=C2=BB=20=D1=82?= =?UTF-8?q?=D0=BE=D0=BB=D1=8C=D0=BA=D0=BE=20=D0=BF=D1=80=D0=B8=20=D0=BF?= =?UTF-8?q?=D0=BB=D0=B0=D1=82=D0=BD=D0=BE=D0=B9=20=D0=BF=D0=BE=D0=B4=D0=BF?= =?UTF-8?q?=D0=B8=D1=81=D0=BA=D0=B5,=20=D1=8F=D0=B2=D0=BD=D1=8B=D0=B9=20CT?= =?UTF-8?q?A=20=D0=BF=D0=BE=D0=BA=D1=83=D0=BF=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit В мульти-тарифе кнопка «+ Купить ещё подписку» висела всегда, когда есть хоть какая-то подписка — даже если это только триал или всё истёкшее. Теперь она показывается только при наличии НАСТОЯЩЕЙ платной активной подписки (hasActivePaid: не триал + status active/limited). А «Посмотреть тарифы и купить подписку» из тусклой (пунктир + opacity-60, спрятана в триал-блоке) стала ЯВНОЙ primary-кнопкой (solid accent) и показывается, когда платной активной подписки ещё нет (триал/истёкшие/ новый юзер) — мы продаём подписки, путь к покупке должен быть очевиден. Затронуты Dashboard и Subscriptions. Добавлен ключ subscriptions.browsePlans (раньше рендерился только inline-фолбэк) в 4 локали. --- src/locales/en.json | 1 + src/locales/fa.json | 1 + src/locales/ru.json | 1 + src/locales/zh.json | 1 + src/pages/Dashboard.tsx | 32 +++++++++++++++++++++++++------- src/pages/Subscriptions.tsx | 25 ++++++++++++++++++++++--- 6 files changed, 51 insertions(+), 10 deletions(-) diff --git a/src/locales/en.json b/src/locales/en.json index 41c7c93..81f4f61 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -5103,6 +5103,7 @@ "subscriptions": { "buy": "Buy subscription", "buyAnother": "Buy another subscription", + "browsePlans": "View plans and subscribe", "empty": "You have no subscriptions yet", "emptyDesc": "Choose a tariff to get started", "title": "My subscriptions" diff --git a/src/locales/fa.json b/src/locales/fa.json index 00ef8c1..c471622 100644 --- a/src/locales/fa.json +++ b/src/locales/fa.json @@ -4737,6 +4737,7 @@ "subscriptions": { "buy": "خرید اشتراک", "buyAnother": "خرید اشتراک دیگر", + "browsePlans": "مشاهده تعرفه‌ها و خرید اشتراک", "empty": "هنوز اشتراکی ندارید", "emptyDesc": "برای شروع تعرفه‌ای انتخاب کنید", "title": "اشتراک‌های من" diff --git a/src/locales/ru.json b/src/locales/ru.json index d7bd867..3fefdf8 100644 --- a/src/locales/ru.json +++ b/src/locales/ru.json @@ -5665,6 +5665,7 @@ "subscriptions": { "buy": "Купить подписку", "buyAnother": "Купить ещё подписку", + "browsePlans": "Посмотреть тарифы и купить подписку", "empty": "У вас пока нет подписок", "emptyDesc": "Выберите тариф, чтобы начать пользоваться сервисом", "title": "Мои подписки" diff --git a/src/locales/zh.json b/src/locales/zh.json index 9143769..8e59695 100644 --- a/src/locales/zh.json +++ b/src/locales/zh.json @@ -4736,6 +4736,7 @@ "subscriptions": { "buy": "购买订阅", "buyAnother": "再购买一个订阅", + "browsePlans": "查看套餐并订阅", "empty": "您还没有订阅", "emptyDesc": "选择套餐以开始使用", "title": "我的订阅" diff --git a/src/pages/Dashboard.tsx b/src/pages/Dashboard.tsx index 18db455..c5c87ed 100644 --- a/src/pages/Dashboard.tsx +++ b/src/pages/Dashboard.tsx @@ -198,6 +198,12 @@ export default function Dashboard() { ? multiSubData !== undefined && (multiSubData.subscriptions?.length ?? 0) === 0 : subscriptionResponse?.has_subscription === false && !subLoading; + // Есть ли НАСТОЯЩАЯ (платная, не триал) живая подписка — от этого зависит CTA: + // «+ Купить ещё» только при наличии платной; иначе явная «Посмотреть тарифы». + const hasActivePaid = (multiSubData?.subscriptions ?? []).some( + (s) => !s.is_trial && (s.status === 'active' || s.status === 'limited'), + ); + // Show onboarding for new users after data loads useEffect(() => { if (!isOnboardingCompleted && !subLoading && !refLoading && !blockingType) { @@ -299,12 +305,23 @@ export default function Dashboard() { {t('dashboard.showAll', 'Показать все')} ({multiSubData.subscriptions.length}) )} - - + {t('subscriptions.buyAnother', 'Купить ещё тариф')} - + {hasActivePaid ? ( + + +{' '} + {t('subscriptions.buyAnother', 'Купить ещё тариф')} + + ) : ( + + +{' '} + {t('subscriptions.browsePlans', 'Посмотреть тарифы и купить подписку')} + + )} )} @@ -360,8 +377,9 @@ export default function Dashboard() { (вход по умолчанию) юзер оставался заперт (Telegram-баг #605056/#605063). */} + +{' '} {t('subscriptions.browsePlans', 'Посмотреть тарифы и купить подписку')} diff --git a/src/pages/Subscriptions.tsx b/src/pages/Subscriptions.tsx index 67b64e8..03d33b4 100644 --- a/src/pages/Subscriptions.tsx +++ b/src/pages/Subscriptions.tsx @@ -62,6 +62,12 @@ export default function Subscriptions() { const subscriptions = data?.subscriptions ?? []; const isMultiTariff = data?.multi_tariff_enabled ?? false; const hasNoSubscriptions = !isLoading && subscriptions.length === 0; + // Есть ли хотя бы одна НАСТОЯЩАЯ (платная, не триал) живая подписка. От этого + // зависит CTA: «+ Купить ещё» — только если уже есть платная; иначе показываем + // явную «Посмотреть тарифы и купить подписку» (триал/истёкшие — это ещё не покупка). + const hasActivePaid = subscriptions.some( + (s) => !s.is_trial && (s.status === 'active' || s.status === 'limited'), + ); // Если у юзера нет подписок — проверяем доступность триала, иначе // (в multi-tariff) ему вообще негде увидеть оффер. @@ -107,7 +113,8 @@ export default function Subscriptions() {

{t('subscriptions.title', 'Мои подписки')}

- {!isLoading && subscriptions.length > 0 && ( + {/* «+ Купить ещё» — только если уже есть платная активная подписка */} + {!isLoading && hasActivePaid && ( + )} + {/* Loading */} {isLoading && (
@@ -152,9 +171,9 @@ export default function Subscriptions() { (Telegram-баг #605056/#605063). */}