Skip to content

Commit

Permalink
Merge pull request #107 from TEAM-BEAT/refactor/#106/Navigation
Browse files Browse the repository at this point in the history
[Refactor/#106] Navigation 공통 컴포넌트 리팩토링
  • Loading branch information
ocahs9 authored Jul 12, 2024
2 parents 0fb7f04 + dfc89c4 commit 1f00a36
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 100 deletions.
132 changes: 35 additions & 97 deletions src/components/commons/navigation/Navigation.tsx
Original file line number Diff line number Diff line change
@@ -1,154 +1,92 @@
import { NAVIGATION_STATE, NavigationState } from "@constants/navigationState";
import useModal from "@hooks/useModal";
import { useEffect, useState } from "react";
import { useLocation, useNavigate } from "react-router-dom";
import { NAVIGATION_STATE } from "@constants/navigationState";
import { useHeader } from "@hooks/useHeader";
import * as S from "./Navigation.styled";

const Navigation = () => {
const { pathname } = useLocation();
const navigate = useNavigate();
const { openConfirm } = useModal();
const { header } = useHeader();
const { headerStyle, title, subText, leftOnClick, rightOnClick } = header;

const [headerPosition, setHeaderPosition] = useState<NavigationState>();
const [title, setTitle] = useState("");
const [subText, setSubText] = useState("");
// TODO: 전역상태로 관리?
const [isLoggedIn, setIsLoggedIn] = useState(false);

const onClickLogo = () => {
// TODO: 화면 맨 위로 스크롤? 어떤 액션할 지
navigate("/");
};

const onClickMenuBar = () => {
// TODO: 메뉴 연결
console.log("clicked menubar");
};

const onClickBack = () => {
openConfirm({
title: "정말 나가시겠습니까?",
subTitle: "지금 나가실 경우 작성하신 내용이 저장되지 않습니다.",
okText: "작성할게요",
okCallback: () => {
// TODO: 액션 추가
console.log("ok click");
},
noText: "나갈게요",
noCallback: () => {
// TODO: 액션 추가
console.log("no click");
},
});
};

const onClickTest = () => {
console.log("test Click");
};

useEffect(() => {
switch (true) {
case pathname === "/testpage":
setHeaderPosition(NAVIGATION_STATE.ICON_TITLE_ICON);
setTitle("테스트 페이지");
setSubText("삭제");
break;
case pathname === "/":
setHeaderPosition(NAVIGATION_STATE.LOGO_HAMBURGAR);
break;
case pathname === "/register":
// TODO: 상세정보, 미리보기, 완료 따라 position, title 다르게
setHeaderPosition(NAVIGATION_STATE.ICON_TITLE);
break;
case pathname.startsWith("/book"):
// TODO: 상세, 예매하기, 완료 따라 position, title 다르게
setHeaderPosition(NAVIGATION_STATE.ICON_TITLE);
setTitle("공연 예약");
break;
case pathname === "/lookup":
// TODO: 회원, 비회원 로그인 여부에 따라 title 다르게
setHeaderPosition(NAVIGATION_STATE.ICON_TITLE);
break;
case pathname === "/manage":
// TODO: 공연목록, 수정, 삭제 따라 position, title, subTitle 다르게
setHeaderPosition(NAVIGATION_STATE.ICON_TITLE);
break;
case pathname === "/myregisteredshow":
setHeaderPosition(NAVIGATION_STATE.ICON_TITLE);
setTitle("내가 등록한 공연");
break;
default:
setTitle("");
}
}, [pathname]);
//함수 연결은 거의 필수이므로, 경고 콘솔 띄워 디버깅 용이하도록 구성.
if (!leftOnClick) {
//만약 왼쪽 함수를 부여하지 않았다면
console.log("warn: 왼쪽 버튼 미연결");
}
if (!rightOnClick) {
//만약 오른쪽 함수를 부여하지 않았다면
console.log("warn: 오른쪽 버튼 미연결");
}

if (headerPosition === NAVIGATION_STATE.ICON_TITLE) {
if (headerStyle === NAVIGATION_STATE.ICON_TITLE) {
return (
<S.NavigationWrapper>
<S.NavigationLeftButton onClick={onClickBack} />
<S.NavigationLeftButton onClick={leftOnClick} />
<S.NavigationTitle>{title}</S.NavigationTitle>
<S.FragmentDiv />
</S.NavigationWrapper>
);
}

if (headerPosition === NAVIGATION_STATE.TITLE_ICON) {
if (headerStyle === NAVIGATION_STATE.TITLE_ICON) {
return (
<S.NavigationWrapper>
<S.FragmentDiv />
<S.NavigationTitle>{title}</S.NavigationTitle>
<S.NavigationXButton onClick={onClickTest} />
<S.NavigationXButton onClick={rightOnClick} />
</S.NavigationWrapper>
);
}

if (headerPosition === NAVIGATION_STATE.ICON_TITLE_ICON) {
if (headerStyle === NAVIGATION_STATE.ICON_TITLE_ICON) {
return (
<S.NavigationWrapper>
<S.NavigationLeftButton onClick={onClickTest} />
<S.NavigationLeftButton onClick={leftOnClick} />
<S.NavigationTitle>{title}</S.NavigationTitle>
<S.NavigationXButton onClick={onClickTest} />
<S.NavigationXButton onClick={rightOnClick} />
</S.NavigationWrapper>
);
}

if (headerPosition === NAVIGATION_STATE.ICON_TITLE_SUB_TEXT) {
if (headerStyle === NAVIGATION_STATE.ICON_TITLE_SUB_TEXT) {
return (
<S.NavigationWrapper>
<S.NavigationLeftButton onClick={onClickTest} />
<S.NavigationLeftButton onClick={leftOnClick} />
<S.NavigationTitle>{title}</S.NavigationTitle>
<S.SubTextButton onClick={onClickTest}>{subText}</S.SubTextButton>
<S.SubTextButton onClick={rightOnClick}>{subText}</S.SubTextButton>
</S.NavigationWrapper>
);
}

if (headerPosition === NAVIGATION_STATE.ICON) {
if (headerStyle === NAVIGATION_STATE.ICON) {
return (
<S.NavigationWrapper>
<S.FragmentDiv />
<S.NavigationXButton onClick={onClickTest} />
<S.NavigationXButton onClick={rightOnClick} />
</S.NavigationWrapper>
);
}

if (headerPosition === NAVIGATION_STATE.LOGO_HAMBURGAR) {
if (headerStyle === NAVIGATION_STATE.LOGO_HAMBURGAR) {
return (
<S.NavigationWrapper>
<S.Logo onClick={onClickLogo} />
<S.HamburgarButton onClick={onClickMenuBar} />
<S.Logo onClick={leftOnClick} />
<S.HamburgarButton onClick={rightOnClick} />
</S.NavigationWrapper>
);
}

if (headerPosition === NAVIGATION_STATE.ICON_ICON) {
if (headerStyle === NAVIGATION_STATE.ICON_ICON) {
return (
<S.NavigationWrapper>
<S.NavigationLeftButton onClick={onClickTest} />
<S.NavigationXButton onClick={onClickTest} />
<S.NavigationLeftButton onClick={leftOnClick} />
<S.NavigationXButton onClick={rightOnClick} />
</S.NavigationWrapper>
);
}

if (!headerStyle) {
return null;
}

return <></>;
};

Expand Down
9 changes: 9 additions & 0 deletions src/hooks/useHeader.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { headerAtom } from "@stores/header";
import { useAtom } from "jotai";

export const useHeader = () => {
//여기서 header는 header 설정을 위해 필요한 속성들을 담은 객체.
const [header, setHeader] = useAtom(headerAtom);

return { header, setHeader };
};
21 changes: 18 additions & 3 deletions src/pages/MyRegisterdShow/MyRegisterdShow.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,32 @@
import Button from "@components/commons/button/Button";
import { useState } from "react";
import { NAVIGATION_STATE } from "@constants/navigationState";
import { useHeader } from "@hooks/useHeader";
import { useEffect, useState } from "react";
import { useNavigate } from "react-router-dom";
import bannerNarrow from "../../assets/images/banner_narrow.png";
import * as S from "./MyRegisterdShow.styled";
import RegisteredCard from "./components/RegisteredCard";
import { MY_REGISTERED_SHOW, RegisteredObjProps } from "./constants/myRegisterShow";

const MyRegisterdShow = () => {
const { setHeader } = useHeader();
const navigate = useNavigate();

//추후 공연등록하기 주소(채현) 나오면 변경 예정
const handleBtn = () => {
navigate("/");
const handleBackBtn = () => {
navigate(-1);
};

//모든 페이지 컴포넌트는 반드시 헤더 설정하기 + useEffect, NAVIGATION_STATE 사용하기
useEffect(() => {
setHeader({
headerStyle: NAVIGATION_STATE.ICON_TITLE,
title: "내가 등록한 공연",
subText: "메롱",
leftOnClick: handleBackBtn,
});
}, [setHeader]);

//추후 API에서 받아온 걸로 set할 예정
const [showList, setShowList] = useState(MY_REGISTERED_SHOW.data);
const [isNothing, setIsNothing] = useState(false);
Expand Down
21 changes: 21 additions & 0 deletions src/pages/lookup/Lookup.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,25 @@
import { NAVIGATION_STATE } from "@constants/navigationState";
import { useHeader } from "@hooks/useHeader";
import { useEffect } from "react";

const Lookup = () => {
const { setHeader } = useHeader();

const handleLeftBtn = () => {
alert("왼쪽 버튼 클릭!");
};
const handleRightBtn = () => {
alert("오른쪽 버튼 클릭!");
};
useEffect(() => {
setHeader({
headerStyle: NAVIGATION_STATE.ICON_TITLE_ICON,
title: "헤더 테스트!",
subText: "굿",
leftOnClick: handleLeftBtn,
rightOnClick: handleRightBtn,
});
}, [setHeader]);
return <div>Lookup</div>;
};

Expand Down
5 changes: 5 additions & 0 deletions src/stores/header.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { NAVIGATION_STATE } from "@constants/navigationState";
import { HeaderProps } from "@typings/headerType";
import { atom } from "jotai";

export const headerAtom = atom<HeaderProps>({ headerStyle: NAVIGATION_STATE.ICON_TITLE_SUB_TEXT });
9 changes: 9 additions & 0 deletions src/typings/headerType.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { NavigationState } from "@constants/navigationState";

export interface HeaderProps {
headerStyle: NavigationState;
title?: string;
subText?: string;
leftOnClick?: () => void;
rightOnClick?: () => void;
}

0 comments on commit 1f00a36

Please sign in to comment.