Skip to content

Commit

Permalink
Merge pull request #52 from team-pofo/feature/#49/mypage
Browse files Browse the repository at this point in the history
Feature/#49/mypage
  • Loading branch information
kevinmj12 authored Jan 16, 2025
2 parents e01d17c + 3d6bcbc commit a6d16b8
Show file tree
Hide file tree
Showing 13 changed files with 102 additions and 40 deletions.
5 changes: 2 additions & 3 deletions src/components/LoginModal/LoginModel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -163,16 +163,15 @@ const Modal: React.FC<ModalProps> = ({
const response = await login(email, password);
console.log("response");
console.log(response);
const token = response.data.accessToken;
// const token = response.data.accessToken;
if (response.success) {
setAccessToken(response.data.accessToken);

try {
const response = await getUserInfo();
if (response.success) {
setLoginState(token, response.data);
setLoginState(response.data);
}
console.log(response);
} catch {
console.log("error");
}
Expand Down
8 changes: 6 additions & 2 deletions src/components/Mypage/MyProjects/MyProjects.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@ import { useSearchProject } from "@/stores/searchProjectStore";
import { useQuery } from "@apollo/client";
import { useEffect, useRef, useState } from "react";
import MypageProjectCard from "@/components/ProjectCard/Mypage/MypageProjectCard";
import { useAuthStore } from "@/stores/authStore";
import * as Styles from "./styles";

export default function MyProjectComponents() {
const { page, hasNext, projects, setPage, setHasNext, setProjects, reset } =
useSearchProject();
const { user } = useAuthStore();

const SIZE = 5;
const [isLoading, setIsLoading] = useState(true);
Expand All @@ -19,6 +22,7 @@ export default function MyProjectComponents() {
title: "",
stackNames: [],
categories: [],
authorName: user?.username,
},
});

Expand Down Expand Up @@ -85,7 +89,7 @@ export default function MyProjectComponents() {
};

return (
<div>
<Styles.MypageMyProjectsContainer>
{!isLoading && projects.length === 0 ? (
<p style={{ marginTop: "20px", fontSize: "20px" }}>
등록한 프로젝트가 없습니다.
Expand All @@ -111,6 +115,6 @@ export default function MyProjectComponents() {
/>
</div>
)}
</div>
</Styles.MypageMyProjectsContainer>
);
}
10 changes: 10 additions & 0 deletions src/components/Mypage/MyProjects/styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import styled from "@emotion/styled";

export const MypageMyProjectsContainer = styled.div`
/* -ms-overflow-style: none; */
/* &::-webkit-scrollbar {
display: none;
} */
/* overflow: hidden; */
/* overflow-y: scroll; */
`;
10 changes: 8 additions & 2 deletions src/components/Mypage/MypageLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ function MypageMyInfo() {
height={200}
style={{ borderRadius: "50%" }}
/>
<Styles.MypageNickname>{user?.data?.username}</Styles.MypageNickname>
<Styles.MypageEmail>{user?.data?.email}</Styles.MypageEmail>
<Styles.MypageNickname>{user?.username}</Styles.MypageNickname>
<Styles.MypageEmail>{user?.email}</Styles.MypageEmail>
</Styles.MypageMyinfo>
);
}
Expand Down Expand Up @@ -72,6 +72,12 @@ type MypageLayoutProps = {
};

export default function MypageLayout({ children }: MypageLayoutProps) {
const { isLoggedIn } = useAuthStore();

if (!isLoggedIn) {
return null;
}

return (
<Styles.MypageContainer>
<Styles.MypageSidebarContainer>
Expand Down
40 changes: 23 additions & 17 deletions src/components/Navigation/Navigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,23 +21,27 @@ import { Popover, PopoverContent, PopoverTrigger } from "../ui/popover";

import { Button } from "../ui/button";
import Link from "next/link";
import { PopoverClose } from "@radix-ui/react-popover";

const Navigation: React.FC = () => {
const [isModalOpen, setIsModalOpen] = useState(false);
const [isMenuOpen, setIsMenuOpen] = useState(false);
const [initialStep, setInitialStep] = useState<
"main" | "signup" | "emailLogin" | "emailSignup"
>("main");
const [isAuthLoading, setIsAuthLoading] = useState(true); // 로그인 관련 로딩 상태
// const [isAuthLoading, setIsAuthLoading] = useState(true); // 로그인 관련 로딩 상태
const {
isLoggedIn,
isAuthLoading,
setAccessToken,
login,
logout: clearAuthState,
setIsAuthLoading,
} = useAuthStore();

// 자동 로그인 처리
useEffect(() => {
setIsAuthLoading(true);
const autoLogin = async () => {
try {
const refreshResponse = await reIssue();
Expand All @@ -48,7 +52,7 @@ const Navigation: React.FC = () => {
setAccessToken(newAccessToken);
apiClient.defaults.headers.common.Authorization = `Bearer ${newAccessToken}`;
const userInfo = await getUserInfo();
login(newAccessToken, userInfo);
login(userInfo.data);
}
} catch (error) {
console.error("자동 로그인 실패:", error);
Expand All @@ -59,7 +63,7 @@ const Navigation: React.FC = () => {
};

autoLogin();
}, []);
}, [clearAuthState, login, setAccessToken]);

const handleLogout = async () => {
try {
Expand Down Expand Up @@ -143,20 +147,22 @@ const Navigation: React.FC = () => {
</PopoverTrigger>
<PopoverContent>
<Link href="/mypage">
<Button
variant="ghost"
className="w-full justify-start"
onClick={() => {}}
>
<Image
style={{ cursor: "pointer", marginRight: "8px" }}
src={"/icons/user_2.svg"}
width={18}
height={18}
alt="mypage"
/>
내 정보
</Button>
<PopoverClose>
<Button
variant="ghost"
className="w-full justify-start"
onClick={() => {}}
>
<Image
style={{ cursor: "pointer", marginRight: "8px" }}
src={"/icons/user_2.svg"}
width={18}
height={18}
alt="mypage"
/>
내 정보
</Button>
</PopoverClose>
</Link>
<Button variant="ghost" className="w-full justify-start">
<Image
Expand Down
2 changes: 1 addition & 1 deletion src/components/Project/Project.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ function ProjectLikeShare({ project }: IProjectProps) {
<button>
<FaShare style={{ width: "26px", height: "26px" }} />
</button>
{user?.data?.email === project.authorName ? (
{user?.email === project.authorName ? (
<Link style={{ width: "100%" }} href={`/project/edit/${project.id}`}>
<FaEdit style={{ width: "26px", height: "26px" }} />
</Link>
Expand Down
11 changes: 3 additions & 8 deletions src/lib/interface/iUser.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
export interface IUserData {
export interface IUser {
id: number;
username: string;
email: string;
username: string;
role: string;
// avatarUrl: string | null;
}

export interface IUser {
success: boolean;
data: IUserData | null;
avatarUrl: string | null;
}
24 changes: 24 additions & 0 deletions src/pages/_app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,33 @@ import type { AppProps } from "next/app";
import localFont from "next/font/local";
import { ApolloProvider } from "@apollo/client";
import client from "@/lib/apolloClient";
import { useAuthStore } from "@/stores/authStore";
import { useRouter } from "next/router";
import { useEffect, useRef } from "react";
const myFont = localFont({ src: "../fonts/PretendardVariable.woff2" });

export default function App({ Component, pageProps }: AppProps) {
const { isLoggedIn, isAuthLoading } = useAuthStore();
const router = useRouter();
const hasAlerted = useRef(false);

useEffect(() => {
const protectedRoutes = ["/mypage"];
const isProtectedRoute = protectedRoutes.some((route) =>
router.pathname.startsWith(route),
);

if (isProtectedRoute && !isAuthLoading) {
if (!isLoggedIn) {
if (!hasAlerted.current) {
hasAlerted.current = true;
alert("로그인이 필요합니다");
router.replace("/");
}
}
}
}, [isLoggedIn, isAuthLoading, router]);

return (
<div className={myFont.className}>
<Layout>
Expand Down
2 changes: 1 addition & 1 deletion src/pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export default function Home() {
resetType();
}, [resetStack, resetType]);

const SIZE = 5;
const SIZE = 36;

const observerRef = useRef<HTMLDivElement>(null);
const { data, loading, fetchMore, refetch } = useQuery(SEARCH_PROJECT, {
Expand Down
1 change: 0 additions & 1 deletion src/pages/mypage/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ export default function Mypage() {
useEffect(() => {
if (isLoggedIn) {
router.replace("/mypage/myprojects");
console.log(isLoggedIn);
}
}, [isLoggedIn, router]);

Expand Down
16 changes: 13 additions & 3 deletions src/pages/mypage/myprojects.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,24 @@ import React from "react";
import MypageLayout from "@/components/Mypage/MypageLayout";
import MyProjectComponents from "@/components/Mypage/MyProjects/MyProjects";
import { useAuthStore } from "@/stores/authStore";
import { css, Global } from "@emotion/react";

const MyProjects: React.FC = () => {
const { isLoggedIn } = useAuthStore();
if (isLoggedIn) {
return (
<MypageLayout>
<MyProjectComponents />
</MypageLayout>
<div>
<Global
styles={css`
&::-webkit-scrollbar {
display: none;
}
`}
/>
<MypageLayout>
<MyProjectComponents />
</MypageLayout>
</div>
);
} else {
return null;
Expand Down
2 changes: 2 additions & 0 deletions src/services/gql/searchProject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export const SEARCH_PROJECT = gql`
$title: String
$stackNames: [String]
$categories: [ProjectCategory]
$authorName: String
) {
searchProject(
projectSearchRequest: {
Expand All @@ -15,6 +16,7 @@ export const SEARCH_PROJECT = gql`
title: $title
stackNames: $stackNames
categories: $categories
authorName: $authorName
}
) {
count
Expand Down
11 changes: 9 additions & 2 deletions src/stores/authStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ interface AuthState {
isLoggedIn: boolean;
accessToken: string | null;
user: IUser | null;
login: (token: string, user: IUser) => void;
isAuthLoading: boolean;
setIsAuthLoading: (loading: boolean) => void;
login: (user: IUser) => void;
logout: () => void;
setAccessToken: (accessToken: string) => void;
}
Expand All @@ -14,8 +16,13 @@ export const useAuthStore = create<AuthState>((set) => ({
isLoggedIn: false,
accessToken: null,
user: null,
isAuthLoading: true,

login: (token, user) => {
setIsAuthLoading: (loading: boolean) => {
set({ isAuthLoading: loading });
},

login: (user: IUser) => {
set({ isLoggedIn: true, user: user });
},

Expand Down

0 comments on commit a6d16b8

Please sign in to comment.