OVERVIEW
src/pages/Login.jsx
기본적으로 Join.jsx를 복사하여 수정했다.
import {
Alert,
Avatar,
Box,
Container,
Grid,
TextField,
Typography,
} from '@mui/material'
import TagIcon from '@mui/icons-material/Tag'
import React, { useEffect, useState } from 'react'
import { LoadingButton } from '@mui/lab'
import { Link } from 'react-router-dom'
import '../firebase'
import { getAuth, signInWithEmailAndPassword } from 'firebase/auth'
export default function Login() {
// 에러 상태
const [error, setError] = useState('')
// 로딩 상태
const [loading, setLoading] = useState(false)
// 로그인 버튼 클릭 시
const handleSubmit = event => {
event.preventDefault()
const data = new FormData(event.currentTarget) // 데이터 생성
const email = data.get('email') // 이메일
const password = data.get('password') // 패스워드
// 비어있는 칸 방어
if (!email || !password) {
setError('모든 항목을 입력해주세요.')
return
}
// 로그인
loginUser(email, password)
}
// 로그인 기능 (firebass)
const loginUser = async (email, password) => {
setLoading(true)
try {
await signInWithEmailAndPassword(getAuth(), email, password)
} catch (e) {
setError(e.message)
setLoading(false)
}
}
// 경고 메시지 3초 후 사라지게 작동
useEffect(() => {
if (!error) return
setTimeout(() => {
setError('')
}, 3000)
}, [error])
return (
<Container component="main" maxWidth="xs">
<Box
sx={{
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
height: '100vh',
}}
>
<Avatar sx={{ m: 1, bgcolor: 'secondary.main' }}>
<TagIcon />
</Avatar>
<Typography component="h1" variant="h5">
로그인
</Typography>
<Box component="form" noValidate onSubmit={handleSubmit} sx={{ mt: 3 }}>
<TextField
margin="normal"
required
fullWidth
label="이메일 주소"
name="email"
autoComplete="off"
autoFocus
/>
<TextField
margin="normal"
required
fullWidth
label="비밀번호"
name="password"
type="password"
/>
{error ? (
<Alert sx={{ mt: 3 }} severity="error">
{error}
</Alert>
) : null}
<LoadingButton
type="submit"
fullWidth
variant="contained"
color="secondary"
sx={{ mt: 3, mb: 2 }}
loading={loading}
>
로그인
</LoadingButton>
<Grid container justifyContent="flex-end">
<Grid item>
<Link
to="/join"
style={{ textDecoration: 'none', color: 'blue' }}
>
계정이 없나요? 회원가입으로 이동
</Link>
</Grid>
</Grid>
</Box>
</Box>
</Container>
)
}a
App.js에서 루트를 수정해준다.
import { Navigate, Route, Routes } from 'react-router-dom'
import './App.css'
import Join from './pages/Join'
import Login from './pages/Login'
import { useEffect } from 'react'
import { getAuth, onAuthStateChanged } from 'firebase/auth'
import { useDispatch, useSelector } from 'react-redux'
import { clearUser, setUser } from './store/userReducer'
import Main from './pages/Main'
import { CircularProgress, Stack } from '@mui/material'
function App() {
const dispatch = useDispatch()
// useSelector를 사용하여 현재 로그인된 사용자 정보 가져오기
const { isLoading, currentUser } = useSelector(state => state.user)
console.log(currentUser)
useEffect(() => {
const unsubscribe = onAuthStateChanged(getAuth(), user => {
if (!!user) {
dispatch(setUser(user))
} else {
dispatch(clearUser())
}
})
return () => unsubscribe()
}, [dispatch])
if (isLoading) {
return (
<Stack alignItems="center" justifyContent="center" height="100vh">
<CircularProgress color="secondary" size={150} />
</Stack>
)
}
return (
<>
<Routes>
<Route
path="/"
element={currentUser ? <Main /> : <Navigate to="/login" />} // 로그인 유저가 있을경우 메인, 없을경우 로그인 페이지로
/>
<Route
path="/login"
element={currentUser ? <Navigate to="/" /> : <Login />} // 로그인 유저가 있을 경우 메인, 없을경우 로그인
/>
<Route
path="/join"
element={currentUser ? <Navigate to="/" /> : <Join />} //로그인 유저가 있을 경우 메인으로
/>
</Routes>
</>
)
}
export default App