o2o-castad-frontend/src/pages/Social/YouTubeOAuthCallback.tsx

91 lines
3.3 KiB
TypeScript

import React, { useEffect, useState } from 'react';
const API_URL = import.meta.env.VITE_API_URL || 'http://40.82.133.44';
const YouTubeOAuthCallback: React.FC = () => {
const [status, setStatus] = useState<'processing' | 'error'>('processing');
const [errorMessage, setErrorMessage] = useState<string>('');
useEffect(() => {
const handleCallback = async () => {
const urlParams = new URLSearchParams(window.location.search);
const code = urlParams.get('code');
const state = urlParams.get('state');
const error = urlParams.get('error');
// OAuth 에러 체크
if (error) {
console.error('[YouTube OAuth] Error from Google:', error);
setStatus('error');
setErrorMessage('Google 인증이 취소되었거나 실패했습니다.');
setTimeout(() => {
window.location.href = '/social/connect/error?platform=youtube&error=' + encodeURIComponent(error);
}, 1500);
return;
}
if (!code) {
console.error('[YouTube OAuth] No code received');
setStatus('error');
setErrorMessage('인증 코드를 받지 못했습니다.');
setTimeout(() => {
window.location.href = '/social/connect/error?platform=youtube&error=no_code';
}, 1500);
return;
}
try {
// 백엔드의 YouTube OAuth 콜백 엔드포인트로 code 전달
const callbackUrl = `${API_URL}/social/oauth/youtube/callback?code=${encodeURIComponent(code)}${state ? `&state=${encodeURIComponent(state)}` : ''}`;
console.log('[YouTube OAuth] Forwarding to backend:', callbackUrl);
// 백엔드로 리다이렉트 (백엔드가 처리 후 /social/connect/success 또는 /social/connect/error로 리다이렉트)
window.location.href = callbackUrl;
} catch (err) {
console.error('[YouTube OAuth] Failed to process callback:', err);
setStatus('error');
setErrorMessage('YouTube 연결 처리 중 오류가 발생했습니다.');
setTimeout(() => {
window.location.href = '/social/connect/error?platform=youtube&error=processing_failed';
}, 1500);
}
};
handleCallback();
}, []);
return (
<div className="social-connect-page">
<div className="social-connect-card">
{status === 'processing' ? (
<>
<div className="social-connect-spinner">
<svg viewBox="0 0 50 50" className="social-spinner-svg">
<circle cx="25" cy="25" r="20" fill="none" strokeWidth="4" />
</svg>
</div>
<h1 className="social-connect-title">YouTube ...</h1>
<p className="social-connect-message"> .</p>
</>
) : (
<>
<div className="social-connect-icon error">
<svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
<circle cx="12" cy="12" r="10" />
<line x1="15" y1="9" x2="9" y2="15" />
<line x1="9" y1="9" x2="15" y2="15" />
</svg>
</div>
<h1 className="social-connect-title"> </h1>
<p className="social-connect-message">{errorMessage}</p>
</>
)}
</div>
</div>
);
};
export default YouTubeOAuthCallback;