From fd01c0f393491576230aff55275a5ef6d8c2ffb8 Mon Sep 17 00:00:00 2001 From: c0mrade Date: Wed, 25 Mar 2026 11:47:31 +0300 Subject: [PATCH] fix: preserve subscription context in navigation and cache keys 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. --- src/components/dashboard/SubscriptionCardActive.tsx | 2 +- src/pages/Connection.tsx | 3 ++- src/pages/ConnectionQR.tsx | 9 ++++++--- src/pages/Dashboard.tsx | 7 +++++-- src/pages/Subscription.tsx | 9 ++++++--- 5 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/components/dashboard/SubscriptionCardActive.tsx b/src/components/dashboard/SubscriptionCardActive.tsx index 02e2a62..cf2adeb 100644 --- a/src/components/dashboard/SubscriptionCardActive.tsx +++ b/src/components/dashboard/SubscriptionCardActive.tsx @@ -214,7 +214,7 @@ export default function SubscriptionCardActive({ haptic.notification('error'); return; } - navigate('/connection'); + navigate(`/connection?sub=${subscription.id}`); }} className={`mb-2.5 flex w-full items-center gap-3.5 rounded-[14px] p-3.5 text-left transition-shadow duration-300${isAtDeviceLimit ? 'cursor-not-allowed opacity-50' : ''}`} data-onboarding="connect-devices" diff --git a/src/pages/Connection.tsx b/src/pages/Connection.tsx index 0bd6742..d22e5f4 100644 --- a/src/pages/Connection.tsx +++ b/src/pages/Connection.tsx @@ -43,9 +43,10 @@ export default function Connection() { state: { url: appConfig?.subscriptionUrl, hideLink: appConfig?.hideLink ?? false, + subscriptionId: subId, }, }); - }, [navigate, appConfig?.subscriptionUrl, appConfig?.hideLink, isTelegramWebApp]); + }, [navigate, appConfig?.subscriptionUrl, appConfig?.hideLink, isTelegramWebApp, subId]); useEffect(() => { const handleKeyDown = (e: KeyboardEvent) => { diff --git a/src/pages/ConnectionQR.tsx b/src/pages/ConnectionQR.tsx index 5671a2a..f6ae3e4 100644 --- a/src/pages/ConnectionQR.tsx +++ b/src/pages/ConnectionQR.tsx @@ -8,6 +8,7 @@ import { AdminBackButton } from '@/components/admin'; interface ConnectionQRState { url: string; hideLink: boolean; + subscriptionId?: number; } function isValidState(state: unknown): state is ConnectionQRState { @@ -24,12 +25,14 @@ export default function ConnectionQR() { const state = location.state as unknown; const validState = isValidState(state) ? state : null; + const subId = validState?.subscriptionId; + const connectionPath = subId ? `/connection?sub=${subId}` : '/connection'; useEffect(() => { if (!validState) { - navigate('/connection', { replace: true }); + navigate(connectionPath, { replace: true }); } - }, [validState, navigate]); + }, [validState, navigate, connectionPath]); if (!validState) { return null; @@ -38,7 +41,7 @@ export default function ConnectionQR() { return (
- +

{t('subscription.connection.qrTitle')}

diff --git a/src/pages/Dashboard.tsx b/src/pages/Dashboard.tsx index 7cdf4df..33feec3 100644 --- a/src/pages/Dashboard.tsx +++ b/src/pages/Dashboard.tsx @@ -141,7 +141,10 @@ export default function Dashboard() { traffic_used_percent: data.traffic_used_percent, is_unlimited: data.is_unlimited, }); - localStorage.setItem('traffic_refresh_ts', Date.now().toString()); + localStorage.setItem( + `traffic_refresh_ts_${subscription?.id ?? 'default'}`, + Date.now().toString(), + ); if (data.rate_limited && data.retry_after_seconds) { setTrafficRefreshCooldown(data.retry_after_seconds); } else { @@ -176,7 +179,7 @@ export default function Dashboard() { if (hasAutoRefreshed.current) return; hasAutoRefreshed.current = true; - const lastRefresh = localStorage.getItem('traffic_refresh_ts'); + const lastRefresh = localStorage.getItem(`traffic_refresh_ts_${subscription?.id ?? 'default'}`); const now = Date.now(); const cacheMs = API.TRAFFIC_CACHE_MS; diff --git a/src/pages/Subscription.tsx b/src/pages/Subscription.tsx index f51f94b..5129da1 100644 --- a/src/pages/Subscription.tsx +++ b/src/pages/Subscription.tsx @@ -391,7 +391,10 @@ export default function Subscription() { traffic_used_percent: data.traffic_used_percent, is_unlimited: data.is_unlimited, }); - localStorage.setItem('traffic_refresh_ts', Date.now().toString()); + localStorage.setItem( + `traffic_refresh_ts_${subscriptionId ?? 'default'}`, + Date.now().toString(), + ); if (data.rate_limited && data.retry_after_seconds) { setTrafficRefreshCooldown(data.retry_after_seconds); } else { @@ -427,7 +430,7 @@ export default function Subscription() { if (hasAutoRefreshed.current) return; hasAutoRefreshed.current = true; - const lastRefresh = localStorage.getItem('traffic_refresh_ts'); + const lastRefresh = localStorage.getItem(`traffic_refresh_ts_${subscriptionId ?? 'default'}`); const now = Date.now(); const cacheMs = 30 * 1000; @@ -441,7 +444,7 @@ export default function Subscription() { } refreshTrafficMutation.mutate(); - }, [subscription, refreshTrafficMutation]); + }, [subscription, refreshTrafficMutation, subscriptionId]); const copyUrl = () => { if (subscription?.subscription_url) {