65 lines
2.0 KiB
TypeScript
65 lines
2.0 KiB
TypeScript
import { Box, Button, Container, TextField, Typography, Paper } from '@mui/material'
|
|
import { useState } from 'react'
|
|
import { useNavigate } from 'react-router-dom'
|
|
import api from '../lib/api'
|
|
import { useAuth } from '../contexts/AuthContext' // ✅ useAuth import
|
|
|
|
export default function Login() {
|
|
const [email, setEmail] = useState('')
|
|
const [password, setPassword] = useState('')
|
|
const [error, setError] = useState('')
|
|
const navigate = useNavigate()
|
|
|
|
const { login } = useAuth() // ✅ 전역 login 함수 가져오기
|
|
|
|
const handleLogin = async () => {
|
|
setError('')
|
|
try {
|
|
const res = await api.post('/auth/login', {
|
|
email,
|
|
password,
|
|
})
|
|
|
|
const { access_token } = res.data
|
|
console.log('로그인 성공:', access_token)
|
|
|
|
login(access_token) // ✅ 전역 상태 + localStorage 동시 반영
|
|
navigate('/')
|
|
} catch (err: any) {
|
|
setError('로그인 실패: 이메일 또는 비밀번호가 올바르지 않습니다.')
|
|
console.error(err)
|
|
}
|
|
}
|
|
|
|
return (
|
|
<Container maxWidth="xs">
|
|
<Paper elevation={3} sx={{ p: 4, mt: 8 }}>
|
|
<Typography variant="h5" align="center" gutterBottom>
|
|
로그인
|
|
</Typography>
|
|
|
|
<Box component="form" noValidate sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
|
|
<TextField
|
|
label="이메일"
|
|
type="email"
|
|
fullWidth
|
|
value={email}
|
|
onChange={(e) => setEmail(e.target.value)}
|
|
/>
|
|
<TextField
|
|
label="비밀번호"
|
|
type="password"
|
|
fullWidth
|
|
value={password}
|
|
onChange={(e) => setPassword(e.target.value)}
|
|
/>
|
|
<Button variant="contained" onClick={handleLogin}>
|
|
로그인
|
|
</Button>
|
|
{error && <Typography color="error">{error}</Typography>}
|
|
</Box>
|
|
</Paper>
|
|
</Container>
|
|
)
|
|
}
|