기존 지출 내역 리스트에 기능 추가하기
구현 순서
- 회원가입, 로그인 페이지 및 폼의 UI 생성
- jwt 인증서버를 사용한 회원가입, 로그인 기능 추가 및 인증 상태 관리
- 내비게이션 바 생성 및 라우터 설정
- 프로필 수정 페이지 생성 및 프로필 수정 기능 추가
- json-server와 Tanstack Query를 사용해 지출 CRUD 구현
- 이후 디테일한 부분 및 선택 구현 사항 다루기
3. 내비게이션 바 생성 및 라우터 설정
(1) 내비게이션 바 UI 생성
내비게이션 바를 만들어서 홈 화면, 프로필 수정화면으로 이동 및 로그아웃 버튼 추가
src/components/navBar/NavBar.jsx
더보기
<S.Container>
<S.LeftDiv>
<S.NavButton onClick={() => navigate("/")}>Home</S.NavButton>{" "}
<S.NavButton onClick={() => navigate("/mypage")}>내 프로필</S.NavButton>
</S.LeftDiv>
<S.RightDiv>
<S.ProfileDiv>
<S.ProfileImage src={avatar} />
<S.Span>"{nickname}"님 환영합니다!</S.Span>
</S.ProfileDiv>
<S.Button onClick={() => handleLogout()} $color="red">로그아웃</S.Button>
</S.RightDiv>
</S.Container>
src/components/navBar/NavBar.styled.jsx
더보기
import styled from "styled-components";
export const Container = styled.div`
width: 100%;
background-color: white;
height: 40px;
padding: 20px;
border: 5px solid black;
border-radius: 8px;
margin: 0 10px;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-around;
`;
export const LeftDiv = styled.div`
width: 50%;
height: 40px;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-around;
`;
export const RightDiv = styled.div`
width: 50%;
height: 40px;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-around;
`;
export const NavButton = styled.button`
border: none;
background-color: transparent;
font-family: inherit;
font-size: 25px;
cursor: pointer;
`;
export const ProfileDiv = styled.div`
display: flex;
flex-direction: row;
align-items: center;
gap: 10px;
`;
export const ProfileImage = styled.img`
width: 50px;
height: 50px;
border-radius: 25px;
`;
export const Span = styled.span``;
export const Button = styled.button`
border: none;
border-radius: 4px;
background-color: ${props => props.$color || "blue"};
padding: 10px 20px;
width: 20%;
color: white;
font-family: inherit;
font-size: 16px;
cursor: pointer;
&:hover{
filter:brightness(0.8);
}
`;
결과 UI
(2) 라우터 설정
-1. 내비게이션 바는 모든 화면에서 나타나야함
=> DefaultLayout을 생성해 라우트들을 감싸 Outlet을 사용해 모든 페이지에 내비게이션 바 뿌려주기
src/layouts/DefaultLayout.jsx
더보기
const DefalutLayout = () => {
return (
<div id="defalut-layout">
<NavBar />
<Outlet />
</div>
)
}
-2.
로그인 상태에서만 홈화면, 프로필 수정화면, 내비게이션 바가 보여야하고 로그아웃 상태에서 해당 페이지들로 이동하 려고 하면 로그인 페이지로 리다이렉트 시켜주기 &
로그인 페이지, 회원가입 페이지는 로그아웃 상태에서만 이동가능해야하고 로그인 상태에서 해당 페이지들로 이동하 려고 하면 메인페이지로 리다이렉트 시켜주기
=> PrivateRoutes, PublicRoutes를 만들어 따로 관리
src/routes/Router.jsx
더보기
// Redux로 관리하는 로그인 상태에 따라 화면에 보여줄지, 리다이렉트 시킬지 결정
const PrivateRoutes = ({ element: Element, ...rest }) => {
const { isLogin } = useSelector(state => state.auth);
return isLogin ? <Element {...rest} /> : <Navigate to="/login" />
// 로그인 상태라면 보여주고 아니라면 로그인 페이지로 리다이렉트
}
const PublicRoutes = ({ element: Element, ...rest }) => {
const { isLogin } = useSelector(state => state.auth);
return !isLogin ? <Element {...rest} /> : <Navigate to="/" />
// 로그아웃 상태라면 보여주고 아니라면 로그인 페이지로 리다이렉트
}
const Router = () => {
return (
<BrowserRouter>
<Routes>
<Route path='/login' element={<PublicRoutes element={Login} />} />
<Route path='/signup' element={<PublicRoutes element={SignUp} />} />
<Route path='/' element={<PrivateRoutes element={DefalutLayout} />}>
<Route index element={<PrivateRoutes element={Home} />} />
<Route path='/mypage' element={<PrivateRoutes element={MyPage} />} />
<Route path='/detail/:postId' element={<PrivateRoutes element={Details} />} />
</Route>
</Routes>
</BrowserRouter>
)
}
export default Router
(3) 내비게이션 바 기능 추가
더보기
const NavBar = () => {
const navigate = useNavigate();
const dispatch = useDispatch();
// 로그인 상태와 유저 정보를 store에서 불러오기
const { isLogin } = useSelector(state => state.auth);
const { userInfo } = useSelector(state => state.auth);
const nickname = userInfo?.nickname;
const avatar = userInfo?.avatar;
// 로그아웃 버튼 클릭시
const handleLogout = () => {
const isLogout = confirm("정말 로그아웃 하시겠습니까?");
if (isLogout) {
dispatch(logout());
navigate("/login");
}
};
// 로그인 상태가 변할 때 마다 서버에 유저정보를 요청해 담거나 비워줌
useEffect(() => {
const fetchUserInfo = async () => {
try {
const response = await authApi.get("/user");
dispatch(setUserInfo(response.data));
} catch (error) {
console.error("Failed to fetch user info:", error);
}
};
fetchUserInfo();
}, [isLogin])
결과 - 로그인 상태
1. 내비게이션 바를 이용해 페이지 이동
2. 리다이렉트
결과 - 로그아웃 상태
리다이렉트
'지출 내역 APP (개인 프로젝트)' 카테고리의 다른 글
지출 내역 리스트 기능 추가하기 : 5 - 1 (1) | 2024.06.13 |
---|---|
지출 내역 리스트 기능 추가하기 : 4 (0) | 2024.06.13 |
지출 내역 리스트 기능 추가하기 : 2 (0) | 2024.06.13 |
지출 내역 리스트 기능 추가하기 : 1 (0) | 2024.06.12 |
개인 프로젝트(React) : 지출 내역 리스트 -10 마무리 (0) | 2024.05.30 |