Skip to content

Commit 0fd6ce1

Browse files
committed
Refactor: 제출 버튼 기능 수정 및 제출 시 로딩스피너 추가
1 parent 1f41fa3 commit 0fd6ce1

File tree

5 files changed

+96
-76
lines changed

5 files changed

+96
-76
lines changed

components/HeaderMenu.tsx

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,14 @@ import Link from "next/link";
55
import SubmitButton from "./SubMitButton";
66
import { useRouter } from "next/router";
77
import useAuthStore from "@/store/useAuthStore";
8-
import { useEffect, useState } from "react";
8+
import { useState } from "react";
99
import Dropdown from "./Dropdown";
1010

1111
const HeaderMenu = () => {
12-
const { user, checkLogin, isLoggedIn, logout } = useAuthStore();
12+
const { user, logout } = useAuthStore();
1313
const [isOpen, setIsOpen] = useState(false);
1414
const router = useRouter();
1515

16-
useEffect(() => {
17-
checkLogin();
18-
}, [checkLogin]);
19-
2016
const dropdownItems = [
2117
{
2218
label: "마이링크",
@@ -31,7 +27,7 @@ const HeaderMenu = () => {
3127

3228
return (
3329
<>
34-
{!isLoggedIn ? (
30+
{!user ? (
3531
<SubmitButton
3632
onClick={() => {
3733
router.push("/login");

components/LoadingSpinner.tsx

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
1-
import { FadeLoader } from "react-spinners";
1+
import { ClipLoader } from "react-spinners";
22

3-
const LoadingSpinner = ({ text }: { text?: string }) => {
3+
const LoadingSpinner = ({
4+
text,
5+
size = 35,
6+
}: {
7+
text?: string;
8+
size?: number;
9+
}) => {
410
return (
5-
<div className="flex flex-col items-center justify-center h-full">
11+
<div className="flex flex-col items-center justify-center">
612
<p className="md:text-2xl mb-4 sm:text-lg">{text}</p>
7-
<FadeLoader color="#6d6afe" />
13+
<ClipLoader color="#6d6afe" size={size} />
814
</div>
915
);
1016
};

components/SubMitButton.tsx

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import React, { ReactNode, ButtonHTMLAttributes } from "react";
1+
import React, { ReactNode, ButtonHTMLAttributes, useState } from "react";
2+
import LoadingSpinner from "./LoadingSpinner";
23

34
interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
45
children: ReactNode;
@@ -17,8 +18,25 @@ const SubmitButton = ({
1718
color = "positive",
1819
size = "18px",
1920
className = "",
21+
onClick,
22+
disabled,
2023
...props
2124
}: ButtonProps) => {
25+
const [isLoading, setIsLoading] = useState(false);
26+
27+
const handleClick = async (e: React.MouseEvent<HTMLButtonElement>) => {
28+
if (isLoading || disabled) return;
29+
30+
setIsLoading(true);
31+
try {
32+
if (onClick) await onClick(e);
33+
} catch (error) {
34+
console.error("버튼 클릭 중 에러 발생:", error);
35+
} finally {
36+
setIsLoading(false);
37+
}
38+
};
39+
2240
const backgroundStyle =
2341
color === "positive"
2442
? "linear-gradient(90.99deg, #6D6AFE 0.12%, #6AE3FE 101.84%)"
@@ -30,10 +48,20 @@ const SubmitButton = ({
3048
borderRadius: radius,
3149
background: backgroundStyle,
3250
}}
33-
className={`flex justify-center ${width} ${height} ${size} ${className} items-center text-white font-[600] whitespace-nowrap hover:opacity-90`}
51+
className={`flex justify-center items-center ${width} ${height} ${size} ${className} text-white font-[600] whitespace-nowrap hover:opacity-90 ${
52+
isLoading ? "opacity-50 cursor-not-allowed" : ""
53+
}`}
54+
onClick={handleClick}
55+
disabled={isLoading || disabled}
3456
{...props}
3557
>
36-
{children}
58+
{isLoading ? (
59+
<div className="h-full m-4">
60+
<LoadingSpinner size={25} />
61+
</div>
62+
) : (
63+
children
64+
)}
3765
</button>
3866
);
3967
};

pages/index.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@ const sectionImageStyle =
2020

2121
const HomePage = () => {
2222
const router = useRouter();
23-
const { isLoggedIn } = useAuthStore();
23+
const { user } = useAuthStore();
2424

2525
const handleClick = () => {
26-
if (isLoggedIn) {
26+
if (user) {
2727
router.push("/link");
2828
} else {
2929
router.push("/login");

store/useAuthStore.tsx

Lines changed: 50 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { create } from "zustand";
2-
import { persist } from "zustand/middleware";
32
import { User } from "@/types/AuthTypes";
43
import {
54
postSignIn,
@@ -9,11 +8,10 @@ import {
98
} from "@/lib/api/auth";
109
import { getUserInfo } from "@/lib/api/user";
1110
import { proxy } from "@/lib/api/axiosInstanceApi";
11+
import { persist } from "zustand/middleware";
1212

1313
interface AuthStore {
1414
user: User | null;
15-
isLoggedIn: boolean;
16-
checkLogin: () => Promise<void>;
1715
login: (body: signInProps) => Promise<boolean>;
1816
SNSLogin: (
1917
provider: "google" | "kakao",
@@ -22,68 +20,60 @@ interface AuthStore {
2220
logout: () => Promise<void>;
2321
}
2422

25-
const useAuthStore = create<AuthStore>()((set) => ({
26-
user: null,
27-
isLoggedIn: false,
28-
29-
checkLogin: async () => {
30-
try {
31-
const response = await proxy.get("/api/auth/sign-check");
32-
if (response.data.isLoggedIn) {
33-
const userInfo = await getUserInfo();
34-
if (userInfo) {
35-
set({ isLoggedIn: true, user: userInfo });
36-
}
37-
} else {
38-
set({ isLoggedIn: false, user: null });
39-
}
40-
} catch (error) {
41-
console.error("로그인 상태 확인 중 오류 발생", error);
42-
set({ isLoggedIn: false, user: null });
23+
const fetchUserInfo = async (set: any) => {
24+
try {
25+
const userInfo = await getUserInfo();
26+
if (userInfo) {
27+
set({ user: userInfo });
28+
return true;
4329
}
44-
},
30+
} catch (error) {
31+
console.error("사용자 정보 가져오기 에러", error);
32+
}
33+
return false;
34+
};
35+
36+
const useAuthStore = create<AuthStore>()(
37+
persist(
38+
(set) => ({
39+
user: null,
4540

46-
login: async (body) => {
47-
try {
48-
const { email, password } = body;
49-
const response = await postSignIn({ email, password });
50-
if (response) {
51-
const userInfo = await getUserInfo();
52-
if (userInfo) {
53-
set({ isLoggedIn: true, user: userInfo });
54-
return true;
41+
login: async (body) => {
42+
try {
43+
const response = await postSignIn(body);
44+
if (response) {
45+
return await fetchUserInfo(set);
46+
}
47+
} catch (error) {
48+
console.error("로그인 중 에러가 발생했습니다", error);
5549
}
56-
}
57-
} catch (error) {
58-
console.error("로그인 중 에러가 발생했습니다", error);
59-
}
60-
return false;
61-
},
50+
return false;
51+
},
6252

63-
SNSLogin: async (provider, body) => {
64-
try {
65-
const response = await postEasySignIn(provider, body);
66-
if (response) {
67-
const userInfo = await getUserInfo();
68-
if (userInfo) {
69-
set({ isLoggedIn: true, user: userInfo });
70-
return true;
53+
SNSLogin: async (provider, body) => {
54+
try {
55+
const response = await postEasySignIn(provider, body);
56+
if (response) {
57+
return await fetchUserInfo(set);
58+
}
59+
} catch (error) {
60+
console.error("소셜 로그인 중 에러가 발생했습니다.", error);
7161
}
72-
}
73-
} catch (error) {
74-
console.error("소셜 로그인 중 에러가 발생했습니다.", error);
75-
}
76-
return false;
77-
},
62+
return false;
63+
},
7864

79-
logout: async () => {
80-
try {
81-
await proxy.post("/api/auth/sign-out");
82-
set({ user: null, isLoggedIn: false });
83-
} catch (error) {
84-
console.error("로그아웃 중 에러가 발생했습니다.", error);
85-
}
86-
},
87-
}));
65+
logout: async () => {
66+
try {
67+
await proxy.post("/api/auth/sign-out");
68+
set({ user: null });
69+
localStorage.removeItem("token"); // 토큰 삭제
70+
} catch (error) {
71+
console.error("로그아웃 중 에러가 발생했습니다.", error);
72+
}
73+
},
74+
}),
75+
{ name: "auth-storage" }
76+
)
77+
);
8878

8979
export default useAuthStore;

0 commit comments

Comments
 (0)