Skip to content

Commit

Permalink
Merge branch 'develop' into feat/#228-suspense
Browse files Browse the repository at this point in the history
  • Loading branch information
joohaem committed Jun 17, 2023
2 parents 7ffc55b + ce9d395 commit 9e6f546
Show file tree
Hide file tree
Showing 14 changed files with 105 additions and 85 deletions.
5 changes: 3 additions & 2 deletions src/@components/@common/Header/HeaderMinVer/index.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import useAuth from "../../../../core/hooks/useAuth";
import { routePaths } from "../../../../core/routes/path";
import { GTM_CLASS_NAME } from "../../../../util/const/gtm";
import St from "./style";

export default function HeaderMinVer() {
const LOGIN_STATE = localStorage.getItem("piickle-token") ? true : false;
const { isLogin } = useAuth();

return (
<St.Header>
{LOGIN_STATE && (
{isLogin && (
<St.Link to={routePaths.BookmarkPage} className={GTM_CLASS_NAME.cardMoveBookmark}>
MY 피클
</St.Link>
Expand Down
6 changes: 4 additions & 2 deletions src/@components/@common/MenuBar/ProfileContainer/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { useNavigate } from "react-router-dom";

import { ImgDefaultProfile } from "../../../../asset/image";
import useAuth from "../../../../core/hooks/useAuth";
import { routePaths } from "../../../../core/routes/path";
import useUserProfile from "../../../MyPage/hooks/useUserProfile";
import DefaultProfileContainer from "./DefaultProfileContainer";
Expand All @@ -13,11 +14,12 @@ export interface ProfileContainerProps {
export default function ProfileContainer(props: ProfileContainerProps) {
const { closeMenuBar } = props;

const { userProfile } = useUserProfile();
const { logout } = useAuth();
const navigate = useNavigate();
const { userProfile } = useUserProfile();

const handleLogout = () => {
localStorage.removeItem("piickle-token");
logout();
navigate(routePaths.Main);
closeMenuBar();
};
Expand Down
7 changes: 4 additions & 3 deletions src/@components/@common/MenuBar/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { IcCloseBtn } from "../../../asset/icon";
import useAuth from "../../../core/hooks/useAuth";
import { routePaths } from "../../../core/routes/path";
import { LocationType } from "../../../types/cardCollection";
import { GTM_CLASS_NAME } from "../../../util/const/gtm";
Expand All @@ -18,7 +19,7 @@ export default function MenuBar(props: MenuBarProps) {
const { closeMenuBar } = props;
const outClickCloserRef = useOutClickCloser(closeMenuBar, true);

const LOGIN_STATE = localStorage.getItem("piickle-token") ? true : false;
const { isLogin } = useAuth();

const { ballotLists } = useBallotLists(true);
const navigateCardCollection = useNavigateCardCollection(LocationType.ALL) as NavigateCardCollectionAllType;
Expand All @@ -36,7 +37,7 @@ export default function MenuBar(props: MenuBarProps) {
<IcCloseBtn />
</St.CloseBtnContainer>
<St.Contents>
{LOGIN_STATE ? (
{isLogin ? (
<ProfileContainer closeMenuBar={closeMenuBar} />
) : (
<DefaultProfileContainer closeMenuBar={closeMenuBar} />
Expand All @@ -60,7 +61,7 @@ export default function MenuBar(props: MenuBarProps) {
<St.Title className={GTM_CLASS_NAME.menuPiickleMe}>Piickle Me</St.Title>
<St.SubTitle className={GTM_CLASS_NAME.menuPiickleMeSub}>진행중인 투표</St.SubTitle>
</St.RecomendWrapper>
{LOGIN_STATE ? (
{isLogin ? (
<St.RecomendWrapper
to={routePaths.BookmarkPage}
className={GTM_CLASS_NAME.menuBookmark}
Expand Down
5 changes: 3 additions & 2 deletions src/@components/CardCollectionPage/hooks/useCardBookmark.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import { useState } from "react";

import { cardCollectionApi } from "../../../core/api/cardCollection";
import useAuth from "../../../core/hooks/useAuth";

const useCardBookmark = (defaultIsBookmarked: boolean, onClickBookmarkBeforeLogin: () => void) => {
const LOGIN_STATE = localStorage.getItem("piickle-token") ? true : false;
const { isLogin } = useAuth();

const [isBookmarked, setIsBookmarked] = useState(defaultIsBookmarked);

const handleClickBookmark = (_id: string) => {
switch (LOGIN_STATE) {
switch (isLogin) {
case true:
setIsBookmarked((prev) => !prev);
cardCollectionApi.addNDeleteBookmark(_id);
Expand Down
27 changes: 13 additions & 14 deletions src/@components/DeletePage/index.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { useRef, useState } from "react";
import { useNavigate } from "react-router-dom";

import { IcEmptyCheckBox, IcFullCheckBox, IcSmallEmptyCheckBox, IcSmallFullCheckBox } from "../../asset/icon";
import { deleteApi } from "../../core/api/delete";
import useAuth from "../../core/hooks/useAuth";
import { routePaths } from "../../core/routes/path";
import { feedBackListsContents } from "../../util/delete/feedBackListsContents";
import Footer from "../@common/Footer";
Expand All @@ -14,7 +14,7 @@ import { St } from "./style";
export default function DeletePage() {
useGTMPage();

const navigate = useNavigate();
const { logout } = useAuth();

const outClickCloserRef = useOutClickCloser(() => {
setIsOpenAlert(false);
Expand All @@ -24,16 +24,6 @@ export default function DeletePage() {
const [isFeedBackItems, setIsFeedBackItems] = useState<boolean[]>([false, false, false, false, false]);
const [isOpenAlert, setIsOpenAlert] = useState(false);
const sendFeedBack = useRef<string[]>([]);

const feedBackLists = feedBackListsContents.map((item, index) => (
<St.FeedBackListsContents key={index}>
<St.OptionalCheckBox type="button" onClick={() => handleChecking(index)}>
{isFeedBackItems[index] ? <IcFullCheckBox /> : <IcEmptyCheckBox />}
</St.OptionalCheckBox>
{item.text}
</St.FeedBackListsContents>
));

const handleChecking = (index: number) => {
setIsFeedBackItems((prevItems) => {
const currentItems = [...prevItems];
Expand All @@ -52,8 +42,7 @@ export default function DeletePage() {
if (item) sendFeedBack.current.push(feedBackListsContents[index].text);
});
deleteAccount();
navigate(routePaths.Main);
localStorage.removeItem("piickle-token");
logout();
} else {
setIsOpenAlert(true);
}
Expand All @@ -62,6 +51,16 @@ export default function DeletePage() {
const deleteAccount = () => {
deleteApi.putDelete(sendFeedBack.current);
};

const feedBackLists = feedBackListsContents.map((item, index) => (
<St.FeedBackListsContents key={index}>
<St.OptionalCheckBox type="button" onClick={() => handleChecking(index)}>
{isFeedBackItems[index] ? <IcFullCheckBox /> : <IcEmptyCheckBox />}
</St.OptionalCheckBox>
{item.text}
</St.FeedBackListsContents>
));

return (
<St.Root>
<SubHeader prevPage={routePaths.MyPage} />
Expand Down
10 changes: 5 additions & 5 deletions src/@components/LoginPage/@hooks/useLoginForm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ import { useRef, useState } from "react";
import { useNavigate } from "react-router-dom";

import { loginApi } from "../../../core/api/login";
import useAuth from "../../../core/hooks/useAuth";
import { routePaths } from "../../../core/routes/path";

export default function useLoginForm() {
const { login } = useAuth();
const navigate = useNavigate();
const inputRefs = useRef<HTMLInputElement[]>([]);
const [errorMessage, setErrorMessage] = useState({ emailError: "", passwordError: "" });
Expand All @@ -19,7 +21,7 @@ export default function useLoginForm() {

try {
const { data } = await loginApi.postLogin(inputRefs.current[0].value, inputRefs.current[1].value);
LoginNGoMain(data.accessToken);
loginWithUserToken(data.accessToken);
} catch (error) {
if (axios.isAxiosError(error)) {
const errorData = error.response?.data;
Expand All @@ -38,7 +40,6 @@ export default function useLoginForm() {
setErrorMessage({ emailError: "", passwordError: "비밀번호가 일치하지 않습니다." });
break;
case 500:
// 서버 내부 오류
navigate(routePaths.Login);
break;
default:
Expand All @@ -48,9 +49,8 @@ export default function useLoginForm() {
}
};

const LoginNGoMain = (accessToken: string) => {
localStorage.setItem("piickle-token", accessToken);
navigate(routePaths.Main);
const loginWithUserToken = (accessToken: string) => {
login(accessToken);
};

return { inputRefs, errorMessage, submitLoginForm };
Expand Down
6 changes: 4 additions & 2 deletions src/@components/MyPage/MySetting/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { useNavigate } from "react-router-dom";

import useAuth from "../../../core/hooks/useAuth";
import { routePaths } from "../../../core/routes/path";
import { St } from "./style";

Expand All @@ -12,12 +13,13 @@ const mySetting = [
];

export default function MySetting() {
const { logout } = useAuth();
const navigate = useNavigate();

const handleClickDetail = (key: string) => {
switch (key) {
case "로그아웃":
localStorage.removeItem("piickle-token");
navigate(routePaths.Main);
logout();
break;
case "회원 탈퇴":
navigate(routePaths.Delete);
Expand Down
23 changes: 11 additions & 12 deletions src/@components/VotePage/VoteContent/BeforeVoteList/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { useState } from "react";

import { IcCheckWithNoBg } from "../../../../asset/icon";
import { voteApi } from "../../../../core/api/vote";
import useAuth from "../../../../core/hooks/useAuth";
import { BallotTopicData } from "../../../../types/ballots";
import { GTM_CLASS_NAME } from "../../../../util/const/gtm";
import useModal from "../../../@common/hooks/useModal";
Expand All @@ -14,12 +15,12 @@ interface BeforeVoteListProps {
}

export default function BeforeVoteList(props: BeforeVoteListProps) {
const LOGIN_STATE = localStorage.getItem("piickle-token") ? true : false;
const { isLogin } = useAuth();
const { ballotTopic, mutateBallotState } = props;

const { isModalOpen: isLoginModalOpen, toggleModal: toggleLoginModal } = useModal();

const [currentIdx, setCurrentIdx] = useState<string>("");
const [currentIdx, setCurrentIdx] = useState("");

const handleClickItem = (key: string) => {
setCurrentIdx((prevIdx) => {
Expand All @@ -29,16 +30,14 @@ export default function BeforeVoteList(props: BeforeVoteListProps) {
};

const handleClickVote = () => {
switch (LOGIN_STATE) {
case true:
if (currentIdx !== "") {
handlePost();
mutateBallotState();
}
break;
case false:
toggleLoginModal();
break;
if (!isLogin) {
toggleLoginModal();
return;
}

if (currentIdx !== "") {
handlePost();
mutateBallotState();
}
};

Expand Down
9 changes: 5 additions & 4 deletions src/Router.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
UserProfilePage,
VotePage,
} from "./@components";
import useAuth from "./core/hooks/useAuth";
import { routePaths } from "./core/routes/path";

export default function Router() {
Expand Down Expand Up @@ -57,10 +58,10 @@ interface PublicRouteProps {
type PrivateRouteProps = Omit<PublicRouteProps, "restricted">;

const PublicRoute = ({ Component, restricted = false }: PublicRouteProps) => {
const isLogined = localStorage.getItem("piickle-token");
return isLogined && restricted ? <MainPage /> : Component;
const { isLogin } = useAuth();
return isLogin && restricted ? <MainPage /> : Component;
};
const PrivateRoute = ({ Component }: PrivateRouteProps) => {
const isLogined = localStorage.getItem("piickle-token");
return isLogined ? Component : <LoginPage />;
const { isLogin } = useAuth();
return isLogin ? Component : <LoginPage />;
};
22 changes: 6 additions & 16 deletions src/core/api/common/axios.ts
Original file line number Diff line number Diff line change
@@ -1,44 +1,34 @@
import axios from "axios";

const real = axios.create({
export const axiosInstance = axios.create({
baseURL: import.meta.env.VITE_BASE_URL,
headers: {
"Content-Type": "application/json",
},
// withCredentials: true,
});

real.interceptors.request.use((config) => {
if (localStorage.getItem("piickle-token") === null) return { ...config };

const headers = {
...config.headers,
"x-auth-token": `Bearer ${localStorage.getItem("piickle-token")}`,
};
return { ...config, headers };
});

export const realReq = {
GET_SWR(path: string) {
return real.get(path);
return axiosInstance.get(path);
},

async GET<T>(path: string, option?: { params: string }) {
const data = await real.get<T>(path, option);
const data = await axiosInstance.get<T>(path, option);
return data.data;
},

async POST<T>(path: string, body: T) {
const data = await real.post(path, body);
const data = await axiosInstance.post(path, body);
return data.data;
},

async PUT<T>(path: string, body: T) {
const data = await real.put(path, body);
const data = await axiosInstance.put(path, body);
return data.data;
},

async PATCH<T>(path: string, body: T) {
await real.patch(path, body);
await axiosInstance.patch(path, body);
},
};
2 changes: 2 additions & 0 deletions src/core/api/common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,5 @@ export const PATH = {
NOTICES: "/notices",
MEDLEY: "/medley",
};

export const USER_TOKEN = "piickle-token";
27 changes: 27 additions & 0 deletions src/core/atom/auth.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { atom } from "recoil";

import { axiosInstance } from "../api/common/axios";
import { USER_TOKEN } from "../api/common/constants";

enum StateType {
USER_TOKEN_ATOM = "usertokenatom",
}

export const userTokenAtom = atom<string | null>({
key: StateType.USER_TOKEN_ATOM,
default: null,
effects: [
({ onSet }) => {
onSet((newToken, _, isReset) => {
if (isReset || newToken === null) {
localStorage.removeItem(USER_TOKEN);
axiosInstance.defaults.headers.common["x-auth-token"] = false;
return;
}

localStorage.setItem(USER_TOKEN, newToken);
axiosInstance.defaults.headers.common["x-auth-token"] = `Bearer ${newToken}`;
});
},
],
});
18 changes: 18 additions & 0 deletions src/core/hooks/useAuth.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { useRecoilState, useResetRecoilState } from "recoil";

import { userTokenAtom } from "../atom/auth";

export default function useAuth() {
const resetUserToken = useResetRecoilState(userTokenAtom);
const [userToken, setUserToken] = useRecoilState(userTokenAtom);

return {
isLogin: !!userToken,
login: (token: string) => {
setUserToken(token);
},
logout: () => {
resetUserToken();
},
};
}
Loading

0 comments on commit 9e6f546

Please sign in to comment.