SubscriptionCardActive: passes ?sub= to /connection navigation.
Connection: QR state includes subscriptionId for back-navigation.
ConnectionQR: preserves subscription context on back button.
Dashboard + Subscription: localStorage traffic cache keyed per-subscription
to prevent cooldown bleed between different subscriptions.
- 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
- SubscriptionListCard: always show autopay status (green check / red cross)
for regular tariffs, show auto-charge status for daily tariffs
- Hide autopay for trial subscriptions
- Autopay mutation: invalidate subscriptions-list for instant UI update
- Types: added is_daily, is_daily_paused to SubscriptionListItem
- Daily tariffs renew automatically — no manual renewal CTA needed
- Show "Продление подписки" hint in multi-tariff instead of "Продление и смена тарифа"
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
- SubscriptionListCard: replace status dot with localized status badge,
add traffic progress bar with color coding, use locale-aware date format
- Subscriptions page: apply glass theme colors, improve empty state styling,
add SVG plus icon for buy button, skeleton loader with glass theme
- Subscription detail: invalidate subscriptions-list cache on mutations
- 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
- Add onDelete prop to ColoredItemCombobox with X button per item
- Wire up deleteCategory/deleteTag API calls in AdminNewsCreate
- Auto-clear selection if the deleted item was selected
- Spinner on delete, haptic feedback, i18n aria-label
- ColoredItemCombobox component with search, color swatches, inline creation
- Replace text inputs with combobox dropdowns for category and tag selection
- API methods for categories/tags CRUD
- TypeScript types for NewsCategory, NewsTag
- i18n keys for combobox (ru, en)
- Remove GridBackground and ScanLine animations
- Use simple transparent blur background instead
- Remove negative margins that broke rounded corners on mobile
- Add News item to marketing group in AdminPanel with NewspaperIcon
- Add news nav/panel translations for all 4 locales (ru, en, zh, fa)
- Don't render NewsSection until query confirms articles exist
- Remove skeleton that caused brief flash when news list is empty
- Remove redirect to Telegram bot when email auth disabled + referral code present
(cabinet links should stay on cabinet, bot links should go to bot)
- Remove referral_code from deep link auth (existing users can't get referrals)
- Don't consume referralCode in deep link path — leave it in localStorage for
OIDC/widget auth methods that actually send it to the backend
- Consume campaign slug once into ref to survive retries (codesConsumedRef pattern)
- Update loginWithDeepLink to only accept (token, campaignSlug) — no referralCode
- Update pollDeepLinkToken API to match backend schema change
- Raise portal z-index to z-50 so it covers MobileBottomNav
- Use TG SDK bottom safe area (JS) via CSS variable instead of unreliable env()
- Fix TicketNotificationBell regression: conditional inline style for fullscreen only
- Add bottom safe area padding to detail panel scroll areas
- Extract useHeaderHeight() hook — single source of truth for header
height across AppShell, ReferralNetwork, and TicketNotificationBell
- Portal top offset now computed dynamically from TG safe area insets
instead of hardcoded top-16 (fixes overlap with TG header bar)
- Two-row mobile layout: title + selector on separate rows so dropdown
gets full width on small screens
- Add MOBILE_HEADER_HEIGHT_PX and DESKTOP_HEADER_HEIGHT_PX to constants
- Fix TicketNotificationBell using hardcoded 45px for all platforms
- Кнопка «Подключить устройство» заблокирована при достижении лимита
- Haptic feedback при нажатии на заблокированную кнопку
- Предупреждение «Отключите устройства для подключения новых»
- Убран дублирующийся текст трафика под прогресс-баром (безлимит)
- Replace setInterval with recursive setTimeout to prevent overlapping async polls
- Add cancellation flag in auto-start effect for React Strict Mode double-mount
- Use isAxiosError() instead of unsafe type assertion
- Remove consumeCampaignSlug/consumeReferralCode from loginWithDeepLink (fired on every poll tick, destroying values after first 202)
- Clear previous interval/timeout before starting new deep link auth
- Store expire timeout in ref for cleanup on unmount
- Use server expires_in instead of hardcoded 5 minutes
- Show error message when token expires (not just clear state)
- Add consumeCampaignSlug/consumeReferralCode to loginWithDeepLink
Добавлен fallback через бота когда виджет Telegram не загружается:
- Таймаут 8 сек на загрузку скрипта (OIDC + legacy)
- Автоматический переход на deep link auth
- Polling каждые 2.5 сек до подтверждения в боте
- ConnectedAccounts: таймаут + сообщение при недоступности
- Переводы: ru, en, zh, fa
- Add varsIgnorePattern to no-unused-vars for destructuring patterns
- Fix all react-hooks/exhaustive-deps by adding missing dependencies
- Refactor useAnimatedNumber to use ref instead of stale state closure
- Wrap handleLinkResult in useCallback for stable deps
- Extract OAuth utilities from OAuthCallback.tsx to utils/oauth.ts
- Extract background config utilities to utils/backgroundConfig.ts
- Remove unused catch parameter in GiftSubscription
- Fix stale initData comparison in clearStaleSessionIfNeeded that destroyed
valid refresh tokens on mobile WebView reopens
- Restrict X-Telegram-Init-Data header to auth endpoints only
- Close Mini App on auth retry to force fresh initData from Telegram
- Merge Connection page error/not-configured states for better UX
- Remove unnecessary comments across 40+ files (section dividers,
restating comments, noise catch block comments)
- Configure ESLint allowEmptyCatch to properly handle intentional
empty catch blocks (62 warnings resolved)
- Add is_limited to Subscription type
- Show yellow traffic-exhausted badge on Subscription and AdminUsers pages
- SubscriptionCardExpired: amber theme with warning icon and buy-traffic CTA for limited
- Dashboard: route limited subscriptions to SubscriptionCardExpired
- Subscription page: show additional options (buy traffic) for limited subs
- Use is_limited boolean instead of status string comparison
- Add trafficLimited translations for ru, en, zh, fa
- AdminUserDetail StatusBadge: add limited yellow styling
Icons enlarged to 18px, padding increased. On hover each button
smoothly expands to reveal its label with opacity and max-width
transition (200ms). Uses group/group-hover pattern.
Text labels overflow even at 2xl with Russian + 9 items.
Switch to icon-only mode at all desktop widths. Labels kept
as sr-only for accessibility, title attribute provides tooltips.
Remove horizontal scroll from desktop top nav bar. Items now show
icons only at 1024-1279px with native tooltips, and icons+labels
at 1280px+. All 9 items fit on screen in any language without
scrolling.
PendingGiftCard was linking to /buy/success/:token which uses the landing
API (exact token match). Since gift tokens are now truncated to 12 chars
in API responses, this caused 404s. Route to /gift?tab=activate&code=
which uses the gift API with prefix-based lookup.
- Expired daily tariffs now call purchaseTariff(tariff_id, 1) for 1-day purchase
- Balance check uses daily_price_kopeks for daily tariffs instead of 100 kopeks minimum
- Disabled daily tariffs still use togglePause for resume