mirror of
https://github.com/chillpadclub/bedolaga-cabinet.git
synced 2026-07-28 09:33:46 +00:00
Add files via upload
This commit is contained in:
@@ -301,18 +301,20 @@ export default function Subscription() {
|
|||||||
// Auto-scroll to switch tariff modal when it appears
|
// Auto-scroll to switch tariff modal when it appears
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (switchTariffId && switchModalRef.current) {
|
if (switchTariffId && switchModalRef.current) {
|
||||||
setTimeout(() => {
|
const timer = setTimeout(() => {
|
||||||
switchModalRef.current?.scrollIntoView({ behavior: 'smooth', block: 'center' })
|
switchModalRef.current?.scrollIntoView({ behavior: 'smooth', block: 'center' })
|
||||||
}, 100)
|
}, 100)
|
||||||
|
return () => clearTimeout(timer)
|
||||||
}
|
}
|
||||||
}, [switchTariffId])
|
}, [switchTariffId])
|
||||||
|
|
||||||
// Auto-scroll to tariff purchase form when it appears
|
// Auto-scroll to tariff purchase form when it appears
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (showTariffPurchase && tariffPurchaseRef.current) {
|
if (showTariffPurchase && tariffPurchaseRef.current) {
|
||||||
setTimeout(() => {
|
const timer = setTimeout(() => {
|
||||||
tariffPurchaseRef.current?.scrollIntoView({ behavior: 'smooth', block: 'center' })
|
tariffPurchaseRef.current?.scrollIntoView({ behavior: 'smooth', block: 'center' })
|
||||||
}, 100)
|
}, 100)
|
||||||
|
return () => clearTimeout(timer)
|
||||||
}
|
}
|
||||||
}, [showTariffPurchase])
|
}, [showTariffPurchase])
|
||||||
|
|
||||||
@@ -320,11 +322,12 @@ export default function Subscription() {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const state = location.state as { scrollToExtend?: boolean } | null
|
const state = location.state as { scrollToExtend?: boolean } | null
|
||||||
if (state?.scrollToExtend && tariffsCardRef.current) {
|
if (state?.scrollToExtend && tariffsCardRef.current) {
|
||||||
setTimeout(() => {
|
const timer = setTimeout(() => {
|
||||||
tariffsCardRef.current?.scrollIntoView({ behavior: 'smooth', block: 'center' })
|
tariffsCardRef.current?.scrollIntoView({ behavior: 'smooth', block: 'center' })
|
||||||
}, 300)
|
}, 300)
|
||||||
// Clear the state to prevent re-scrolling on subsequent renders
|
// Clear the state to prevent re-scrolling on subsequent renders
|
||||||
window.history.replaceState({}, document.title)
|
window.history.replaceState({}, document.title)
|
||||||
|
return () => clearTimeout(timer)
|
||||||
}
|
}
|
||||||
}, [location.state])
|
}, [location.state])
|
||||||
|
|
||||||
|
|||||||
@@ -32,19 +32,27 @@ export default function TelegramCallback() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Parse and validate numeric fields
|
||||||
|
const parsedId = parseInt(id, 10)
|
||||||
|
const parsedAuthDate = parseInt(authDate, 10)
|
||||||
|
|
||||||
|
if (Number.isNaN(parsedId) || Number.isNaN(parsedAuthDate)) {
|
||||||
|
setError(t('auth.telegramRequired'))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await loginWithTelegramWidget({
|
await loginWithTelegramWidget({
|
||||||
id: parseInt(id, 10),
|
id: parsedId,
|
||||||
first_name: firstName,
|
first_name: firstName,
|
||||||
last_name: lastName || undefined,
|
last_name: lastName || undefined,
|
||||||
username: username || undefined,
|
username: username || undefined,
|
||||||
photo_url: photoUrl || undefined,
|
photo_url: photoUrl || undefined,
|
||||||
auth_date: parseInt(authDate, 10),
|
auth_date: parsedAuthDate,
|
||||||
hash: hash,
|
hash: hash,
|
||||||
})
|
})
|
||||||
navigate('/')
|
navigate('/')
|
||||||
} catch (err: unknown) {
|
} catch (err: unknown) {
|
||||||
console.error('Telegram auth error:', err)
|
|
||||||
const error = err as { response?: { data?: { detail?: string } } }
|
const error = err as { response?: { data?: { detail?: string } } }
|
||||||
setError(error.response?.data?.detail || t('common.error'))
|
setError(error.response?.data?.detail || t('common.error'))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,9 @@ const getSafeRedirectUrl = (url: string | null): string => {
|
|||||||
return url
|
return url
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const MAX_RETRY_ATTEMPTS = 3
|
||||||
|
const RETRY_COUNT_KEY = 'telegram_redirect_retry_count'
|
||||||
|
|
||||||
export default function TelegramRedirect() {
|
export default function TelegramRedirect() {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const navigate = useNavigate()
|
const navigate = useNavigate()
|
||||||
@@ -32,6 +35,10 @@ export default function TelegramRedirect() {
|
|||||||
const { loginWithTelegram, isAuthenticated, isLoading: authLoading } = useAuthStore()
|
const { loginWithTelegram, isAuthenticated, isLoading: authLoading } = useAuthStore()
|
||||||
const [status, setStatus] = useState<'loading' | 'success' | 'error' | 'not-telegram'>('loading')
|
const [status, setStatus] = useState<'loading' | 'success' | 'error' | 'not-telegram'>('loading')
|
||||||
const [errorMessage, setErrorMessage] = useState('')
|
const [errorMessage, setErrorMessage] = useState('')
|
||||||
|
const [retryCount, setRetryCount] = useState(() => {
|
||||||
|
const stored = sessionStorage.getItem(RETRY_COUNT_KEY)
|
||||||
|
return stored ? parseInt(stored, 10) : 0
|
||||||
|
})
|
||||||
|
|
||||||
// Get branding for nice display
|
// Get branding for nice display
|
||||||
const { data: branding } = useQuery({
|
const { data: branding } = useQuery({
|
||||||
@@ -96,13 +103,28 @@ export default function TelegramRedirect() {
|
|||||||
setTimeout(initTelegram, 300)
|
setTimeout(initTelegram, 300)
|
||||||
}, [loginWithTelegram, navigate, isAuthenticated, authLoading, redirectTo, t])
|
}, [loginWithTelegram, navigate, isAuthenticated, authLoading, redirectTo, t])
|
||||||
|
|
||||||
// Handle retry
|
// Handle retry with limit to prevent infinite loops
|
||||||
const handleRetry = () => {
|
const handleRetry = () => {
|
||||||
|
if (retryCount >= MAX_RETRY_ATTEMPTS) {
|
||||||
|
setErrorMessage('Превышено количество попыток. Попробуйте позже.')
|
||||||
|
sessionStorage.removeItem(RETRY_COUNT_KEY)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const newCount = retryCount + 1
|
||||||
|
setRetryCount(newCount)
|
||||||
|
sessionStorage.setItem(RETRY_COUNT_KEY, String(newCount))
|
||||||
setStatus('loading')
|
setStatus('loading')
|
||||||
setErrorMessage('')
|
setErrorMessage('')
|
||||||
window.location.reload()
|
window.location.reload()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Clear retry count on successful auth
|
||||||
|
useEffect(() => {
|
||||||
|
if (status === 'success') {
|
||||||
|
sessionStorage.removeItem(RETRY_COUNT_KEY)
|
||||||
|
}
|
||||||
|
}, [status])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="min-h-screen flex items-center justify-center p-4">
|
<div className="min-h-screen flex items-center justify-center p-4">
|
||||||
{/* Background */}
|
{/* Background */}
|
||||||
|
|||||||
Reference in New Issue
Block a user