import { useEffect, useMemo, useState } from 'react'
import { Link, useLocation, useNavigate, useSearchParams } from 'react-router-dom'
import { Button, Result, Spin, Typography, message } from 'antd'
import { useAuth } from '@/app/providers/auth-context'
import { AuthLayout } from '@/layouts'
import { parseOAuthCallbackHash, sanitizeAuthRedirect } from '@/lib/auth/oauth'
import { getErrorMessage } from '@/lib/errors'
import { exchangeOAuthHandoff } from '@/services/auth'
const { Paragraph } = Typography
export function OAuthCallbackPage() {
const [status, setStatus] = useState<'loading' | 'success' | 'error'>('loading')
const [errorMessage, setErrorMessage] = useState('')
const [searchParams] = useSearchParams()
const location = useLocation()
const navigate = useNavigate()
const { onLoginSuccess } = useAuth()
const redirect = sanitizeAuthRedirect(searchParams.get('redirect'))
const callbackPayload = useMemo(() => parseOAuthCallbackHash(location.hash), [location.hash])
useEffect(() => {
let cancelled = false
const consumeHandoff = async () => {
if (callbackPayload.status === 'error') {
if (!cancelled) {
setStatus('error')
setErrorMessage(callbackPayload.message || '第三方登录失败,请重试')
}
return
}
if (!callbackPayload.code) {
if (!cancelled) {
setStatus('error')
setErrorMessage('缺少OAuth登录交接码,请重新发起登录')
}
return
}
try {
const tokenBundle = await exchangeOAuthHandoff(callbackPayload.code)
await onLoginSuccess(tokenBundle)
if (!cancelled) {
setStatus('success')
message.success('第三方登录成功')
navigate(redirect, { replace: true })
}
} catch (error) {
if (!cancelled) {
setStatus('error')
setErrorMessage(getErrorMessage(error, '第三方登录失败,请重试'))
}
}
}
void consumeHandoff()
return () => {
cancelled = true
}
}, [callbackPayload.code, callbackPayload.message, callbackPayload.status, navigate, onLoginSuccess, redirect])
if (status === 'loading') {
return (
)
}
if (status === 'success') {
return (
)
}
return (
,
]}
/>
)
}