페이지를 구성해보니 관리자와 일반 사용자, 둘 다 로그인을 해야지 Navbar가 생긴다는 점을 눈치챘다. 그 사실을 알자마자 회원 가입과 로그인 페이지를 제외한 거의 모든 페이지에 Navbar를 import해서 사용한다면 낭비가 아닐까? 라는 생각이 들었다.
모든 페이지에 Navbar를 render하지 말고 Top바와 Bottom바가 준비되어 있는 Template을 만들고 거기에 들어갈 내용물만 render해보자!
당시 난 리팩토링과 클린코드에 미쳐있던 사람이었고 조금이라도 깔끔할거라고 믿으면 언제나 바로 실행에 옮겼다. 일례로 코드가 2번 정도 중복해서 사용됐다 싶으면 전부 common이라는 폴더에 집어 넣고 다회용으로 만들었는데 이 고민도 저 광기의 흔적이 아닐까 한다. (사실 지금도 이게 나은지 다른게 나은지 잘 모르겠다.)
적어놓고 보니 SPA의 개념을 안다면 모두가 알 만한 내용이다. 이 고민 앞에도 참 많은 고민이 있었지만 기억 속에서 가장 오래된 고민은 이거다. 다음부턴 미래의 나를 위해서라도 전부 다 기록해봐야겠다.
![]() | ![]() |
---|
저 위에 웨이터가 있는 Topbar와 아래 5개의 IconButton으로 이루어져 있는 BottomBar가 오늘의 주인공이다.
막상 남에게 보여주려니 코드가 부끄럽지만 하나하나 설명해보자.
import { Grid } from "@mui/material";
const PaddingGrid = <Grid item sm={1} md={2} />;
const styleForGrid = {
backgroundImage: `url(${BgImg})`,
backgroundSize: "cover",
minHeight: "100vh",
height: "auto",
paddingBottom: "4rem",
}
return (
<Grid container>
<PaddingGrid>
<Grid
item
xs={12}
sm={10}
md={8}
style={styleForGrid}
>
<StickyHeader />
<StickyFooter />
{params?.children}
</Grid>
<PaddingGrid>
</Grid>
);
사용자의 대부분은 모바일로 접속할거란 예상이 있었지만 혹시 모를 데스크탑 사용자를 위해 반응형으로 웹을 꾸렸다.
브라우저가 일정 크기 이상으로 커지면 내용이 없는 빈 Grid가 발생해 양옆을 채워준다. window.innerWidth
에 반응하는 padding이나 margin을 만들어도 좋았겠지만 AI분야에서 협업하던 분이 작성한 코드를 조금만 수정해서 그대로 사용했다.
useEffect(() => {
if (localStorage.getItem("auth") === null) {
localStorage.clear();
navigate("/login");
alert("접속시간이 만료됐습니다.");
}
}, [navigate]);
인증 서버의 RefreshToken이 만료되거나 정상적으로 통신하지 않아 AuthToken이 유효하지 않다면 사용자를 이 세상 밖으로 쫓아내고 싶었다.
하지만 담당 하시던 분이 퇴사(?)를 해버렸고 아쉽게도 기획을 온전히 구현할 수 없었다. 대신에 localStorage나 store, cookie에 저장된 token의 여부를 계속해서 감시했고 혹여나 setMaxAge
로 설정한 시간이 지나 만료되거나 로그아웃, 사용자의 직접적인 쿠키 간섭으로 인해 token 없다면 즉시 로그인을 해지했다.
시간에 쫓기고 쫓겨 만든 이 코드가 부끄럽게 느껴지지만 불과 내가 한 달 전에 짠 코드다. 한 달만에 뒤돌아 봤을 때 부족한 부분이 보인다면 그 만큼 성장한거고, 지금 부끄러움을 느낀만큼 성장할 여지가 많다고 생각하고 더 나아가야겠다.
아마 다음 글은 저 위에 있는 StickyFooter
친구에 관한 설명이지 싶다.