- New WebBackButton component: visible on web, hidden in Telegram
(native back button handles navigation there)
- Added to: Subscription detail, SubscriptionPurchase, RenewSubscription
- RenewSubscription: removed max-w-lg, grid layout for period cards
- RenewSubscription: display actual missing amount instead of {{missing}} placeholder
- SubscriptionPurchase: suppress "switch tariff" title in multi-tariff mode
(only renewal exists, no tariff switching)
Renewal flow (per-subscription):
- New /subscriptions/:id/renew page showing only period options for
the specific tariff with balance display and renew button
- PurchaseCTAButton links to /renew in multi-tariff mode
Purchase flow (new tariffs only):
- Hide already purchased tariffs (is_purchased flag from backend)
- Fallback UI when all tariffs are owned
- Types: added is_purchased, all_tariffs_purchased fields
- Remove custom back buttons from Subscription detail and SubscriptionPurchase
pages — native Telegram mini-app back button already handles navigation
- SubscriptionListCard: distinct trial badge with star icon and amber styling,
trial cards get amber border/background for visual differentiation
- SubscriptionPurchase: change "Купить тариф" to "Новый тариф" when adding
a new tariff in multi-subscription mode
- Subscription detail: show tariff name as title in multi-tariff mode
- Add SubscriptionListItem and SubscriptionsListResponse types
- Add getSubscriptions/getSubscriptionById API methods
- Add optional subscriptionId parameter to all 30+ API methods
- Create /subscriptions page with subscription list cards
- Add /subscription/:subscriptionId route for per-subscription management
- Dashboard: show multi-tariff navigation block when user has 2+ subscriptions
- Subscription page: read subscriptionId from URL params, pass to all queries
- SubscriptionPurchase: accept subscriptionId from query params
- SubscriptionCardExpired: pass subscription.id to API calls
- Full backward compatibility: without subscriptionId, works as before
When the purchase-options API call failed (e.g. for email-registered
users), the page rendered only the header with no content. Now shows
an error message with retry button. Also adds a fallback for when
the API returns no available tariffs or periods.
When all periods are removed from a tariff, users saw an empty
purchase form with no way to renew. Now shows a message explaining
the situation and a button to choose a different tariff.
Added staleTime: 0 and refetchOnMount: 'always' to purchase-options
queries in SubscriptionPurchase and Subscription pages to prevent
stale balance_kopeks from causing incorrect insufficient funds display.
- QuickPurchase: публичная страница покупки с выбором тарифа/периода/оплаты
- PurchaseSuccess: статус покупки с поллингом и копированием ссылки
- AdminLandings: управление лендингами (создание, сортировка, удаление)
- AdminLandingEditor: полнофункциональный редактор лендинга
- API-клиент landings.ts для всех эндпоинтов
- Роутинг /buy/:slug и /buy/success/:token
- Локализация ru/en/zh/fa для всех текстов лендинга
- Санитизация HTML/CSS, rate limit защита, DOMPurify
Normal traffic zone now uses configurable accent palette instead of
hardcoded success/green. Added useTrafficZone hook that resolves
mainHex dynamically from theme colors. Replaced emerald/teal classes
with success palette in SuccessNotificationModal. Fixed hardcoded
green hex values in Subscription and SubscriptionPurchase pages.
Reset traffic on tariff switch is an admin-only setting.
Backend handles it via admin settings system (data-driven, no frontend code needed).
Reverted all user-facing toggle UI, API params, types, and translations.
- Add reset_traffic parameter to previewTariffSwitch and switchTariff API calls
- Add reset_traffic_available/reset_traffic_default fields to TariffSwitchPreview type
- Add toggle switch in tariff switch preview modal (shown when backend enables it)
- Initialize toggle from server default (reset_traffic_default)
- Pass reset_traffic flag on switch execution
- Add translations for all 4 locales (ru, en, zh, fa)
Move ~1900 lines of purchase/renewal logic from Subscription.tsx into
a new SubscriptionPurchase.tsx page at /subscription/purchase.
- Create SubscriptionPurchase.tsx with tariffs grid, classic mode wizard,
switch preview modal, and promo handling
- Create PurchaseCTAButton.tsx with animated gradient border, state-aware
colors and context-aware text
- Create subscriptionHelpers.ts with shared utilities
- Add CopyIcon to shared icons module
- Register /subscription/purchase route with lazy loading
- Update SubscriptionCardExpired and PromoOffersSection navigators
- Add CTA translation keys to ru.json and en.json
- Remove all scrollToExtend references