Skip to content

Commit b9597cc

Browse files
authored
Merge pull request #99 from FE9-2/refactor/hook
refactor: useAuth, useUser ๊ฐ ํ›…์„ api ํด๋”์— ๋งž๊ฒŒ ์—ญํ•  ๋ถ„๋ฆฌ ๋ฐ ๋ฆฌํŒฉํ† ๋ง
2 parents bad1128 + c2777d1 commit b9597cc

File tree

24 files changed

+530
-480
lines changed

24 files changed

+530
-480
lines changed

โ€Žsrc/app/(auth)/login/page.tsxโ€Ž

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
"use client";
2-
import { useAuth } from "@/hooks/useAuth";
2+
import { useLogin } from "@/hooks/queries/auth/useLogin";
33
import { type LoginSchema, loginSchema } from "@/schemas/authSchema";
44
import { zodResolver } from "@hookform/resolvers/zod";
55
import Image from "next/image";
66
import Link from "next/link";
77
import { useForm } from "react-hook-form";
88

99
export default function LoginPage() {
10-
const { login, isLoginPending } = useAuth();
10+
const { login, isPending } = useLogin();
1111
const {
1212
register,
1313
handleSubmit,
@@ -57,10 +57,10 @@ export default function LoginPage() {
5757
<div>
5858
<button
5959
type="submit"
60-
disabled={isLoginPending}
60+
disabled={isPending}
6161
className="group relative flex w-full justify-center rounded-lg bg-lime-600 px-4 py-2 text-sm font-medium text-white hover:bg-lime-700 focus:outline-none focus:ring-2 focus:ring-lime-500 focus:ring-offset-2 disabled:bg-lime-300"
6262
>
63-
{isLoginPending ? "๋กœ๊ทธ์ธ ์ค‘..." : "๋กœ๊ทธ์ธ"}
63+
{isPending ? "๋กœ๊ทธ์ธ ์ค‘..." : "๋กœ๊ทธ์ธ"}
6464
</button>
6565
</div>
6666
<div className="flex justify-center space-x-6">

โ€Žsrc/app/(auth)/signup/applicant/page.tsxโ€Ž

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"use client";
22

3-
import { useAuth } from "@/hooks/useAuth";
3+
import { useSignup } from "@/hooks/queries/auth/useSignup";
44
import { type SignupSchema, signupSchema } from "@/schemas/authSchema";
55
import { userRoles } from "@/constants/userRoles";
66
import { zodResolver } from "@hookform/resolvers/zod";
@@ -9,7 +9,7 @@ import { useForm } from "react-hook-form";
99
import Image from "next/image";
1010

1111
export default function ApplicantSignupPage() {
12-
const { signup, isSignupPending } = useAuth();
12+
const { signup, isPending } = useSignup();
1313
const {
1414
register,
1515
handleSubmit,
@@ -100,10 +100,10 @@ export default function ApplicantSignupPage() {
100100
<div>
101101
<button
102102
type="submit"
103-
disabled={isSignupPending}
103+
disabled={isPending}
104104
className="group relative flex w-full justify-center rounded-lg bg-lime-600 px-4 py-2 text-sm font-medium text-white hover:bg-lime-700 focus:outline-none focus:ring-2 focus:ring-lime-500 focus:ring-offset-2 disabled:bg-lime-300"
105105
>
106-
{isSignupPending ? "ํšŒ์›๊ฐ€์ž… ์ค‘..." : "ํšŒ์›๊ฐ€์ž…"}
106+
{isPending ? "ํšŒ์›๊ฐ€์ž… ์ค‘..." : "ํšŒ์›๊ฐ€์ž…"}
107107
</button>
108108
</div>
109109
<div className="flex justify-center space-x-4">

โ€Žsrc/app/(auth)/signup/owner/page.tsxโ€Ž

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"use client";
22

3-
import { useAuth } from "@/hooks/useAuth";
3+
import { useSignup } from "@/hooks/queries/auth/useSignup";
44
import { type SignupSchema, signupSchema } from "@/schemas/authSchema";
55
import { userRoles } from "@/constants/userRoles";
66
import { zodResolver } from "@hookform/resolvers/zod";
@@ -9,7 +9,7 @@ import { useForm } from "react-hook-form";
99
import Image from "next/image";
1010

1111
export default function OwnerSignupPage() {
12-
const { signup, isSignupPending } = useAuth();
12+
const { signup, isPending } = useSignup();
1313
const {
1414
register,
1515
handleSubmit,
@@ -122,10 +122,10 @@ export default function OwnerSignupPage() {
122122
<div>
123123
<button
124124
type="submit"
125-
disabled={isSignupPending}
125+
disabled={isPending}
126126
className="group relative flex w-full justify-center rounded-lg bg-lime-600 px-4 py-2 text-sm font-medium text-white hover:bg-lime-700 focus:outline-none focus:ring-2 focus:ring-lime-500 focus:ring-offset-2 disabled:bg-lime-300"
127127
>
128-
{isSignupPending ? "ํšŒ์›๊ฐ€์ž… ์ค‘..." : "ํšŒ์›๊ฐ€์ž…"}
128+
{isPending ? "ํšŒ์›๊ฐ€์ž… ์ค‘..." : "ํšŒ์›๊ฐ€์ž…"}
129129
</button>
130130
</div>
131131
<div className="flex justify-center space-x-4">

โ€Žsrc/app/(pages)/mypage/components/FilterBar/index.tsxโ€Ž

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@ import Button from "@/app/components/button/default/Button";
66
import KebabDropdown from "@/app/components/button/dropdown/KebabDropdown";
77
import { userRoles } from "@/constants/userRoles";
88
import useModalStore from "@/store/modalStore";
9-
import { useUser } from "@/hooks/useUser";
9+
import { useUser } from "@/hooks/queries/user/me/useUser";
1010

1111
export default function FilterBar() {
1212
const { user, isLoading } = useUser();
1313
const { openModal } = useModalStore();
1414

1515
if (isLoading) {
16-
return <div>Loading...</div>;
16+
return null;
1717
}
1818

1919
if (!user) {

โ€Žsrc/app/(pages)/mypage/components/sections/CommentsSection.tsxโ€Ž

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import React from "react";
44
import { useState } from "react";
5-
import { useUser } from "@/hooks/useUser";
5+
import { useMyComments } from "@/hooks/queries/user/me/useMyComments";
66
import Pagination from "@/app/components/pagination/Pagination";
77
import type { MyCommentType } from "@/types/response/user";
88

@@ -14,7 +14,6 @@ export default function CommentsSection() {
1414
const [currentPage, setCurrentPage] = useState(1);
1515

1616
// ๋‚ด๊ฐ€ ์ž‘์„ฑํ•œ ๋Œ“๊ธ€ ๋ชฉ๋ก ์กฐํšŒ
17-
const { useMyComments } = useUser();
1817
const { data, isLoading, error } = useMyComments({
1918
page: currentPage,
2019
pageSize: COMMENTS_PER_PAGE,

โ€Žsrc/app/(pages)/mypage/components/sections/PostsSection.tsxโ€Ž

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import React, { useEffect } from "react";
44
import { useInView } from "react-intersection-observer";
5-
import { useUser } from "@/hooks/useUser";
5+
import { useMyPosts } from "@/hooks/queries/user/me/useMyPosts";
66
import { useSortStore } from "@/store/sortStore";
77
import type { PostListType } from "@/types/response/post";
88

@@ -21,7 +21,6 @@ export default function PostsSection() {
2121
});
2222

2323
// ๋‚ด๊ฐ€ ์ž‘์„ฑํ•œ ๊ฒŒ์‹œ๊ธ€ ๋ชฉ๋ก ์กฐํšŒ
24-
const { useMyPosts } = useUser();
2524
const { data, isLoading, error, hasNextPage, fetchNextPage, isFetchingNextPage } = useMyPosts({
2625
limit: POSTS_PER_PAGE,
2726
orderBy: orderBy.posts,

โ€Žsrc/app/(pages)/mypage/components/sections/ScrapsSection.tsxโ€Ž

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import React, { useEffect } from "react";
44
import { useInView } from "react-intersection-observer";
5-
import { useUser } from "@/hooks/useUser";
5+
import { useMyScraps } from "@/hooks/queries/user/me/useMyScraps";
66
import { useSortStore } from "@/store/sortStore";
77
import type { FormListType } from "@/types/response/form";
88

@@ -21,7 +21,6 @@ export default function ScrapsSection() {
2121
});
2222

2323
// ๋‚ด๊ฐ€ ์Šคํฌ๋žฉํ•œ ์•Œ๋ฐ”ํผ ๋ชฉ๋ก ์กฐํšŒ
24-
const { useMyScraps } = useUser();
2524
const { data, isLoading, error, hasNextPage, fetchNextPage, isFetchingNextPage } = useMyScraps({
2625
limit: SCRAPS_PER_PAGE,
2726
orderBy: orderBy.scrap,

โ€Žsrc/app/components/layout/Header.tsxโ€Ž

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@ import Image from "next/image";
44
import Link from "next/link";
55
import { usePathname, useRouter } from "next/navigation";
66
import { cn } from "@/lib/tailwindUtil";
7-
import { useAuth } from "@/hooks/useAuth";
7+
import { useLogout } from "@/hooks/queries/auth/useLogout";
88
import { useState } from "react";
99
import { toast } from "react-hot-toast";
10-
import { useUser } from "@/hooks/useUser";
10+
import { useUser } from "@/hooks/queries/user/me/useUser";
1111

1212
export default function Header() {
13-
const { logout } = useAuth();
13+
const { logout } = useLogout();
1414
const { user, isLoading } = useUser();
1515
const pathname = usePathname();
1616
const router = useRouter();

โ€Žsrc/app/components/modal/modals/form/ChangePasswordModal.tsxโ€Ž

Lines changed: 18 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,8 @@ import { passwordSchema } from "@/schemas/commonSchema";
44
import { z } from "zod";
55
import { useForm } from "react-hook-form";
66
import { zodResolver } from "@hookform/resolvers/zod";
7-
import axios from "axios";
8-
import toast from "react-hot-toast";
9-
import { useState } from "react";
10-
import { useAuth } from "@/hooks/useAuth";
7+
import { useLogout } from "@/hooks/queries/auth/useLogout";
8+
import { usePassword } from "@/hooks/queries/user/me/usePassword";
119

1210
interface ChangePasswordModalProps {
1311
isOpen: boolean;
@@ -54,8 +52,8 @@ const defaultFields = [
5452
] as const;
5553

5654
const ChangePasswordModal = ({ isOpen, onClose, className }: ChangePasswordModalProps) => {
57-
const [isSubmitting, setIsSubmitting] = useState(false);
58-
const { logout } = useAuth();
55+
const { mutate: changePassword, isPending } = usePassword();
56+
const { logout } = useLogout();
5957

6058
const {
6159
register,
@@ -75,35 +73,21 @@ const ChangePasswordModal = ({ isOpen, onClose, className }: ChangePasswordModal
7573
if (!isOpen) return null;
7674

7775
const onSubmitHandler = async (data: ChangePasswordFormData) => {
78-
if (isSubmitting) return;
76+
if (isPending) return;
7977

80-
try {
81-
setIsSubmitting(true);
82-
await axios.patch("/api/users/me/password", {
78+
changePassword(
79+
{
8380
currentPassword: data.currentPassword,
8481
newPassword: data.newPassword,
85-
});
86-
87-
reset();
88-
onClose();
89-
// ๋น„๋ฐ€๋ฒˆํ˜ธ ๋ณ€๊ฒฝ ํ›„ ๋กœ๊ทธ์•„์›ƒ ์ฒ˜๋ฆฌ
90-
logout();
91-
toast.success("๋น„๋ฐ€๋ฒˆํ˜ธ๊ฐ€ ๋ณ€๊ฒฝ๋˜์—ˆ์Šต๋‹ˆ๋‹ค!\n๋‹ค์‹œ ๋กœ๊ทธ์ธํ•ด์ฃผ์„ธ์š”.", {
92-
style: {
93-
whiteSpace: "pre-line", // \n์„ ์ค„๋ฐ”๊ฟˆ์œผ๋กœ ์ฒ˜๋ฆฌ
94-
textAlign: "center", // ํ…์ŠคํŠธ ์ค‘์•™ ์ •๋ ฌ
82+
},
83+
{
84+
onSuccess: () => {
85+
reset();
86+
onClose();
87+
logout();
9588
},
96-
});
97-
} catch (error) {
98-
if (axios.isAxiosError(error)) {
99-
const errormessage = error.response?.data?.message || "๋น„๋ฐ€๋ฒˆํ˜ธ ๋ณ€๊ฒฝ์— ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค.";
100-
toast.error(errormessage);
101-
} else {
102-
toast.error("๋น„๋ฐ€๋ฒˆํ˜ธ ๋ณ€๊ฒฝ ์ค‘ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.");
10389
}
104-
} finally {
105-
setIsSubmitting(false);
106-
}
90+
);
10791
};
10892

10993
return (
@@ -124,7 +108,7 @@ const ChangePasswordModal = ({ isOpen, onClose, className }: ChangePasswordModal
124108
type={field.type}
125109
placeholder={field.placeholder}
126110
variant="white"
127-
disabled={isSubmitting}
111+
disabled={isPending}
128112
size="w-[327px] h-[54px] md:w-[640px] md:h-[64px]"
129113
errormessage={errors[field.name]?.message}
130114
/>
@@ -138,17 +122,17 @@ const ChangePasswordModal = ({ isOpen, onClose, className }: ChangePasswordModal
138122
onClose();
139123
reset();
140124
}}
141-
disabled={isSubmitting}
125+
disabled={isPending}
142126
className="text-grayscale-700 flex-1 rounded-md border border-grayscale-300 bg-white px-4 py-2 text-sm font-semibold transition-colors hover:bg-grayscale-50 md:text-base"
143127
>
144128
์ทจ์†Œ
145129
</button>
146130
<button
147131
type="submit"
148-
disabled={isSubmitting}
132+
disabled={isPending}
149133
className="flex-1 rounded-md bg-orange-500 px-4 py-2 text-sm font-semibold text-white transition-colors hover:bg-orange-600 md:text-base"
150134
>
151-
{isSubmitting ? "๋ณ€๊ฒฝ ์ค‘..." : "๋ณ€๊ฒฝํ•˜๊ธฐ"}
135+
{isPending ? "๋ณ€๊ฒฝ ์ค‘..." : "๋ณ€๊ฒฝํ•˜๊ธฐ"}
152136
</button>
153137
</div>
154138
</form>

โ€Žsrc/app/components/modal/modals/form/EditMyProfileModal.tsxโ€Ž

Lines changed: 15 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,7 @@ import { useState, useRef, useEffect } from "react";
55
import Image from "next/image";
66
import { FiUser, FiEdit2 } from "react-icons/fi";
77
import BaseInput from "@/app/components/input/text/BaseInput";
8-
import { useUser } from "@/hooks/useUser";
9-
import axios from "axios";
10-
import toast from "react-hot-toast";
8+
import { useUser } from "@/hooks/queries/user/me/useUser";
119
import { useForm } from "react-hook-form";
1210
import { zodResolver } from "@hookform/resolvers/zod";
1311
import { z } from "zod";
@@ -28,10 +26,9 @@ const editMyProfileSchema = z.object({
2826
type EditMyProfileFormData = z.infer<typeof editMyProfileSchema>;
2927

3028
const EditMyProfileModal = ({ isOpen, onClose, className }: EditMyProfileModalProps) => {
31-
const { user, refetch } = useUser();
29+
const { user, updateProfile, isUpdating } = useUser();
3230
const [selectedFile, setSelectedFile] = useState<File | null>(null);
3331
const [previewUrl, setPreviewUrl] = useState<string>("");
34-
const [isSubmitting, setIsSubmitting] = useState(false);
3532
const fileInputRef = useRef<HTMLInputElement>(null);
3633

3734
const {
@@ -78,58 +75,19 @@ const EditMyProfileModal = ({ isOpen, onClose, className }: EditMyProfileModalPr
7875
};
7976

8077
const onSubmitHandler = async (data: EditMyProfileFormData) => {
81-
if (isSubmitting) return;
78+
if (isUpdating) return;
8279

83-
try {
84-
setIsSubmitting(true);
85-
86-
let imageUrl = user?.imageUrl || "";
87-
88-
if (selectedFile) {
89-
const uploadFormData = new FormData();
90-
uploadFormData.append("image", selectedFile);
91-
92-
const uploadResponse = await axios.post("/api/images/upload", uploadFormData, {
93-
withCredentials: true,
94-
});
95-
96-
if (uploadResponse.status === 201 && uploadResponse.data?.url) {
97-
imageUrl = uploadResponse.data.url;
98-
} else {
99-
throw new Error("์ด๋ฏธ์ง€ ์—…๋กœ๋“œ์— ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค.");
100-
}
101-
}
102-
103-
const updateData = {
80+
const success = await updateProfile(
81+
{
10482
name: data.name,
10583
nickname: data.nickname,
10684
phoneNumber: data.phone,
107-
imageUrl,
108-
};
109-
110-
const updateResponse = await axios.patch("/api/users/me", updateData);
111-
112-
if (updateResponse.status === 200) {
113-
await refetch(); // React Query ์บ์‹œ ๊ฐฑ์‹ 
114-
toast.success("ํ”„๋กœํ•„์ด ์„ฑ๊ณต์ ์œผ๋กœ ์ˆ˜์ •๋˜์—ˆ์Šต๋‹ˆ๋‹ค.");
115-
onClose();
116-
} else {
117-
throw new Error("ํ”„๋กœํ•„ ์—…๋ฐ์ดํŠธ์— ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค.");
118-
}
119-
} catch (error) {
120-
if (axios.isAxiosError(error)) {
121-
const errorMessage = error.response?.data?.message || "ํ”„๋กœํ•„ ์ˆ˜์ •์— ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค.";
122-
console.error("Profile update error:", {
123-
status: error.response?.status,
124-
data: error.response?.data,
125-
});
126-
toast.error(errorMessage);
127-
} else {
128-
console.error("Unexpected error:", error);
129-
toast.error("ํ”„๋กœํ•„ ์ˆ˜์ • ์ค‘ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.");
130-
}
131-
} finally {
132-
setIsSubmitting(false);
85+
},
86+
selectedFile
87+
);
88+
89+
if (success) {
90+
onClose();
13391
}
13492
};
13593

@@ -201,7 +159,7 @@ const EditMyProfileModal = ({ isOpen, onClose, className }: EditMyProfileModalPr
201159
variant="white"
202160
size="w-[327px] h-[54px] md:w-[640px] md:h-[64px]"
203161
wrapperClassName="px-[14px] md:px-[20px]"
204-
disabled={isSubmitting}
162+
disabled={isUpdating}
205163
errormessage={errors[field.name]?.message}
206164
/>
207165
</div>
@@ -213,17 +171,17 @@ const EditMyProfileModal = ({ isOpen, onClose, className }: EditMyProfileModalPr
213171
<button
214172
type="button"
215173
onClick={onClose}
216-
disabled={isSubmitting}
174+
disabled={isUpdating}
217175
className="text-grayscale-700 w-[158px] rounded-md border border-grayscale-300 bg-white px-4 py-2 text-sm font-semibold transition-colors hover:bg-grayscale-100 md:w-[314px] md:text-base"
218176
>
219177
์ทจ์†Œ
220178
</button>
221179
<button
222180
type="submit"
223-
disabled={isSubmitting}
181+
disabled={isUpdating}
224182
className="w-[158px] rounded-md bg-primary-orange-300 px-4 py-2 text-sm font-semibold text-white transition-colors hover:bg-primary-orange-200 md:w-[314px] md:text-base"
225183
>
226-
{isSubmitting ? "์ˆ˜์ • ์ค‘..." : "์ˆ˜์ •ํ•˜๊ธฐ"}
184+
{isUpdating ? "์ˆ˜์ • ์ค‘..." : "์ˆ˜์ •ํ•˜๊ธฐ"}
227185
</button>
228186
</div>
229187
</form>

0 commit comments

Comments
ย (0)