Files
OpenFlare/openflare-server/web/features/auth/components/github-oauth-callback.tsx
T
2026-06-06 10:46:40 +08:00

70 lines
2.0 KiB
TypeScript

'use client';
import {useMutation} from '@tanstack/react-query';
import {useRouter, useSearchParams} from 'next/navigation';
import {useEffect, useRef, useState} from 'react';
import {InlineMessage} from '@/components/feedback/inline-message';
import {LoadingState} from '@/components/feedback/loading-state';
import {useAuth} from '@/components/providers/auth-provider';
import {AppCard} from '@/components/ui/app-card';
import {exchangeGitHubCode} from '@/features/auth/api/auth';
export function GitHubOAuthCallback() {
const router = useRouter();
const searchParams = useSearchParams();
const { setUser } = useAuth();
const handledCodeRef = useRef<string | null>(null);
const [prompt, setPrompt] = useState('正在处理 GitHub 授权结果...');
const [message, setMessage] = useState<{
tone: 'danger' | 'success';
text: string;
} | null>(null);
const code = searchParams?.get('code')?.trim() ?? '';
const mutation = useMutation({
mutationFn: exchangeGitHubCode,
onSuccess: (user) => {
setUser(user);
setMessage({ tone: 'success', text: '登录成功,正在跳转...' });
router.replace('/');
},
onError: (error: Error) => {
setPrompt('授权处理失败');
setMessage({
tone: 'danger',
text: error.message || 'GitHub 授权失败,请稍后重试。',
});
},
});
useEffect(() => {
if (!code) {
setPrompt('缺少授权 code');
setMessage({
tone: 'danger',
text: '未收到 GitHub 授权参数,请返回登录页重试。',
});
return;
}
if (handledCodeRef.current === code) {
return;
}
handledCodeRef.current = code;
mutation.mutate(code);
}, [code, mutation]);
return (
<AppCard title="GitHub OAuth 回调" description={prompt}>
<div className="space-y-4">
{mutation.isPending ? <LoadingState /> : null}
{message ? (
<InlineMessage tone={message.tone} message={message.text} />
) : null}
</div>
</AppCard>
);
}