fix(cabinet): Lava top-up return route + Telegram-unavailable card overflow

- Lava returns to a path-based result URL (/balance/top-up/result/:method) because Lava
  Business rejects query strings in success/fail URLs. Add the route and read the method
  from the path param as a fallback (alongside ?method=) so external-browser redirects
  still poll the right payment. Pairs with the backend fix.
- ConnectedAccounts: the "Привязка Telegram временно недоступна" message overflowed the
  card (it sat in the non-shrinking action column and never wrapped). Constrain its width
  and wrap it (max-w + break-words) so it stays inside the card. Verified by rendering.

Both reported in the Bedolaga bug topic.
This commit is contained in:
c0mrade
2026-06-10 16:44:46 +03:00
parent 16fad9f4fe
commit d7f7bc7c17
3 changed files with 23 additions and 6 deletions

View File

@@ -408,6 +408,18 @@ function App() {
</ProtectedRoute>
}
/>
{/* Path-based method variant: some providers (Lava) reject return URLs that carry a
query string, so the method is encoded in the path instead of ?method=. */}
<Route
path="/balance/top-up/result/:method"
element={
<ProtectedRoute withLayout={false}>
<LazyPage>
<TopUpResult />
</LazyPage>
</ProtectedRoute>
}
/>
<Route
path="/balance/top-up/:methodId"
element={

View File

@@ -240,13 +240,15 @@ function TelegramLinkWidget() {
// Script failed to load - show unavailable message with bot link
if (scriptFailed) {
return (
<div className="flex flex-col items-center gap-1.5">
<p className="text-xs text-dark-400">{t('profile.accounts.telegramLinkUnavailable')}</p>
<div className="flex max-w-[200px] flex-col items-center gap-1.5">
<p className="break-words text-center text-xs text-dark-400">
{t('profile.accounts.telegramLinkUnavailable')}
</p>
<a
href={`https://t.me/${botUsername}`}
target="_blank"
rel="noopener noreferrer"
className="text-sm text-accent-400 transition-colors hover:text-accent-300"
className="break-all text-sm text-accent-400 transition-colors hover:text-accent-300"
>
@{botUsername}
</a>

View File

@@ -1,5 +1,5 @@
import { useState, useCallback, useRef, useEffect } from 'react';
import { useNavigate, useSearchParams } from 'react-router';
import { useNavigate, useParams, useSearchParams } from 'react-router';
import { useQuery, useQueryClient } from '@tanstack/react-query';
import { useTranslation } from 'react-i18next';
import { motion } from 'framer-motion';
@@ -194,8 +194,11 @@ export default function TopUpResult() {
// Load saved payment info from sessionStorage (once on mount)
const [pendingInfo] = useState(() => loadTopUpPendingInfo());
// Fallback: read method from query params (for external browser redirects where sessionStorage is unavailable)
const methodFromUrl = searchParams.get('method');
// Fallback: read method for external-browser redirects where sessionStorage is unavailable.
// Providers that reject query strings (Lava) return to /balance/top-up/result/<method>, so
// accept the method from the path param too, not just ?method=.
const { method: methodFromPath } = useParams<{ method?: string }>();
const methodFromUrl = searchParams.get('method') || methodFromPath || null;
// Detect if user arrived via redirect with success param (no polling needed)
const redirectStatus = searchParams.get('status') || searchParams.get('payment');