import { useState } from 'react'; import { Github, AlertCircle, CheckCircle, Loader, ExternalLink } from 'lucide-react'; import { GitHubService } from '../services/GitHubService'; import { open } from '@tauri-apps/plugin-shell'; import { useLocale } from '../hooks/useLocale'; import '../styles/GitHubAuth.css'; interface GitHubAuthProps { githubService: GitHubService; onSuccess: () => void; } export function GitHubAuth({ githubService, onSuccess }: GitHubAuthProps) { const { t } = useLocale(); const [useOAuth, setUseOAuth] = useState(true); const [githubToken, setGithubToken] = useState(''); const [userCode, setUserCode] = useState(''); const [verificationUri, setVerificationUri] = useState(''); const [authStatus, setAuthStatus] = useState<'idle' | 'pending' | 'authorized' | 'error'>('idle'); const [error, setError] = useState(''); const handleOAuthLogin = async () => { setAuthStatus('pending'); setError(''); try { const deviceCodeResp = await githubService.requestDeviceCode(); setUserCode(deviceCodeResp.user_code); setVerificationUri(deviceCodeResp.verification_uri); await open(deviceCodeResp.verification_uri); await githubService.authenticateWithDeviceFlow( deviceCodeResp.device_code, deviceCodeResp.interval, (status) => { setAuthStatus(status === 'pending' ? 'pending' : status === 'authorized' ? 'authorized' : 'error'); } ); setAuthStatus('authorized'); setTimeout(() => { onSuccess(); }, 1000); } catch (err) { console.error('[GitHubAuth] OAuth failed:', err); setAuthStatus('error'); const errorMessage = err instanceof Error ? err.message : 'OAuth authorization failed'; const fullError = err instanceof Error && err.stack ? `${errorMessage}\n\nDetails: ${err.stack}` : errorMessage; setError(fullError); } }; const handleTokenAuth = async () => { if (!githubToken.trim()) { setError(t('github.enterToken')); return; } try { await githubService.authenticate(githubToken); setError(''); onSuccess(); } catch (err) { console.error('[GitHubAuth] Token auth failed:', err); setError(t('github.authFailedToken')); } }; const copyToClipboard = async (text: string) => { try { await navigator.clipboard.writeText(text); } catch (err) { console.error('Failed to copy:', err); } }; const openCreateTokenPage = async () => { await githubService.openAuthorizationPage(); }; return (
{t('github.githubLogin')}
{t('github.oauthStep1')}
{t('github.oauthStep2')}
{t('github.oauthStep3')}
{error}