pricelees ef903cf267 [#22] 프론트엔드 React 전환 및 인증 API 수정 (#23)
<!-- 제목 양식 -->
<!-- [이슈번호] 작업 요약 (예시: [#10] Gitea 템플릿 생성) -->

## 📝 관련 이슈 및 PR

**PR과 관련된 이슈 번호**
- #22

##  작업 내용
<!-- 어떤 작업을 했는지 알려주세요! -->
- 기존 Thymeleaf 기반의 프론트엔드 코드를 React + Typescript 기반으로 마이그레이션
- 프론트엔드 분리에 따른 인증 API 수정 및 회원가입 API 추가

## 🧪 테스트
<!-- 어떤 테스트를 생각했고 진행했는지 알려주세요! -->
- 새로 추가된 API, 변경된 API 테스트 반영

## 📚 참고 자료 및 기타
<!-- 참고한 자료, 또는 논의할 사항이 있다면 알려주세요! -->
프론트엔드 코드는 Gemini CLI가 구현하였고, API 관련 코드(ee21782ef9, frontend/src/api/**) 만 직접 구성

Reviewed-on: #23
Co-authored-by: pricelees <priceelees@gmail.com>
Co-committed-by: pricelees <priceelees@gmail.com>
2025-07-27 03:39:20 +00:00

48 lines
1.8 KiB
TypeScript

import React, { useState } from 'react';
import { useLocation, useNavigate } from 'react-router-dom';
import type { LoginRequest } from '@_api/auth/authTypes';
import { useAuth } from '../context/AuthContext';
const LoginPage: React.FC = () => {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const { login } = useAuth();
const navigate = useNavigate();
const location = useLocation();
const from = location.state?.from?.pathname || '/';
const handleLogin = async () => {
try {
const request: LoginRequest = { email, password };
await login(request);
alert('로그인에 성공했어요!');
navigate(from, { replace: true });
} catch (error: any) {
const message = error.response?.data?.message || '로그인에 실패했어요. 이메일과 비밀번호를 확인해주세요.';
alert(message);
console.error('로그인 실패:', error);
setEmail('');
setPassword('');
}
}
return (
<div className="content-container" style={{ width: '300px' }}>
<h2 className="content-container-title">Login</h2>
<div className="form-group">
<input type="email" className="form-control" placeholder="Email" value={email} onChange={e => setEmail(e.target.value)} />
</div>
<div className="form-group">
<input type="password" className="form-control" placeholder="Password" value={password} onChange={e => setPassword(e.target.value)} />
</div>
<div className="d-flex justify-content-between">
<button className="btn btn-outline-custom" onClick={() => navigate('/signup')}>Sign Up</button>
<button className="btn btn-custom" onClick={handleLogin}>Login</button>
</div>
</div>
);
};
export default LoginPage;