o2o-castad-frontend/src/pages/Login/LoginSection.tsx

104 lines
2.7 KiB
TypeScript
Executable File

import React, { useState, useEffect } from 'react';
import { useTranslation } from 'react-i18next';
import { getKakaoLoginUrl, kakaoCallback } from '../../utils/api';
interface LoginSectionProps {
onBack: () => void;
onLogin: () => void;
}
const LoginSection: React.FC<LoginSectionProps> = ({ onBack, onLogin }) => {
const { t } = useTranslation();
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
// 카카오 콜백 처리 (URL에서 code 파라미터 확인)
useEffect(() => {
const urlParams = new URLSearchParams(window.location.search);
const code = urlParams.get('code');
if (code) {
handleKakaoCallback(code);
}
}, []);
const handleKakaoCallback = async (code: string) => {
setIsLoading(true);
setError(null);
try {
await kakaoCallback(code);
// URL에서 code 파라미터 제거
const url = new URL(window.location.href);
url.searchParams.delete('code');
window.history.replaceState({}, document.title, url.pathname);
// 로그인 성공
onLogin();
} catch (err) {
console.error('Kakao callback failed:', err);
setError(t('login.kakaoLoginFailed'));
// URL에서 code 파라미터 제거
const url = new URL(window.location.href);
url.searchParams.delete('code');
window.history.replaceState({}, document.title, url.pathname);
} finally {
setIsLoading(false);
}
};
const handleKakaoLogin = async () => {
setIsLoading(true);
setError(null);
try {
const response = await getKakaoLoginUrl();
// 카카오 로그인 페이지로 리다이렉트
window.location.href = response.auth_url;
} catch (err) {
console.error('Failed to get Kakao login URL:', err);
setError(t('login.loginUrlFailed'));
setIsLoading(false);
}
};
return (
<div className="login-container">
{/* Back Button */}
<button onClick={onBack} className="login-back-btn" disabled={isLoading}>
<img src="/assets/images/icon-back.svg" alt="Back" />
<span>{t('login.back')}</span>
</button>
<div className="login-content">
{/* Logo */}
<div className="login-logo">
<img src="/assets/images/ado2-login-logo.svg" alt="ADO2" />
</div>
{/* Error Message */}
{error && (
<div className="login-error">
{error}
</div>
)}
{/* Kakao Login Button */}
<button
onClick={handleKakaoLogin}
className="btn-kakao"
disabled={isLoading}
>
{isLoading ? t('login.loggingIn') : t('login.kakaoStart')}
</button>
</div>
</div>
);
};
export default LoginSection;