diff --git a/src/apis/auth/index.ts b/src/apis/auth/index.ts index fed079b..cd1591a 100644 --- a/src/apis/auth/index.ts +++ b/src/apis/auth/index.ts @@ -1,27 +1,24 @@ import axiosClientHelper from '@/utils/network/axiosClientHelper'; import { LoginFormData, LoginResponse, loginResponseSchema, PutPasswordFormData } from './types'; -import { isAxiosError } from 'axios'; -import { isError } from 'es-toolkit/compat'; +import { safeResponse } from '@/utils/network/safeResponse'; -export const login = async (loginFormData: LoginFormData): LoginResponse => { - try { - const response = await axiosClientHelper.post('/auth/login', loginFormData); +/** + * login + * https://sp-taskify-api.vercel.app/docs/#/Auth/Login + */ +export const login = async (loginFormData: LoginFormData) => { + const response = await axiosClientHelper.post('/auth/login', loginFormData); + return safeResponse(response.data, loginResponseSchema); +}; - const result = loginResponseSchema.safeParse(response.data); - if (!result.success) { - throw new Error('서버에서 받은 데이터가 예상과 다릅니다.'); - } - return response.data; - } catch (error) { - if (isAxiosError(error)) return error.response?.data; - return { message: isError(error) ? error.message : String(error) }; - } +export const logout = async () => { + await axiosClientHelper.post('/auth/logout'); }; +/** + * password 수정 + * https://sp-taskify-api.vercel.app/docs/#/Auth/ChangePassword + */ export const putPassword = async (putPasswordFormData: PutPasswordFormData) => { await axiosClientHelper.put('/auth/password', putPasswordFormData); }; - -export const logout = async () => { - await axiosClientHelper.post('/auth/logout'); -}; diff --git a/src/apis/auth/queries.tsx b/src/apis/auth/queries.tsx new file mode 100644 index 0000000..6b71bef --- /dev/null +++ b/src/apis/auth/queries.tsx @@ -0,0 +1,31 @@ +import { useMutation, useQueryClient } from '@tanstack/react-query'; +import { login, logout, putPassword } from '.'; +import { LoginFormData, PutPasswordFormData } from './types'; + +export const useLogin = () => { + return useMutation({ + mutationFn: (loginFormData: LoginFormData) => { + return login(loginFormData); + }, + }); +}; + +export const usePutPassword = () => { + return useMutation({ + mutationFn: (putPasswordFormData: PutPasswordFormData) => { + return putPassword(putPasswordFormData); + }, + }); +}; + +export const useLogout = () => { + const queryClient = useQueryClient(); + return useMutation({ + mutationFn: () => { + return logout(); + }, + onSuccess: () => { + queryClient.invalidateQueries(); + }, + }); +}; diff --git a/src/apis/cards/index.ts b/src/apis/cards/index.ts index f613201..0761fab 100644 --- a/src/apis/cards/index.ts +++ b/src/apis/cards/index.ts @@ -1,16 +1,21 @@ import axiosClientHelper from '@/utils/network/axiosClientHelper'; import { Card, CardRequest, cardSchema, CardsResponse, cardsResponseSchema, GetCardsParams } from './types'; import { Column } from '../columns/types'; +import { safeResponse } from '@/utils/network/safeResponse'; -const RESPONSE_INVALID_MESSAGE = '서버에서 받은 데이터가 예상과 다릅니다'; - +/** + * card 생성 + * https://sp-taskify-api.vercel.app/docs/#/Cards/Create + */ export const postCard = async (cardRequest: CardRequest) => { const response = await axiosClientHelper.post('/cards', cardRequest); - const result = cardSchema.safeParse(response.data); - if (!result.success) throw new Error(RESPONSE_INVALID_MESSAGE); - return result.data; + return safeResponse(response.data, cardSchema); }; +/** + * cards 목록 조회 + * https://sp-taskify-api.vercel.app/docs/#/Cards/Find + */ export const getCards = async (params: GetCardsParams) => { const { cursorId, size, columnId } = params; const response = await axiosClientHelper.get('/cards', { @@ -20,32 +25,40 @@ export const getCards = async (params: GetCardsParams) => { ...(cursorId && { cursorId }), }, }); - const result = cardsResponseSchema.safeParse(response.data); - if (!result.success) throw new Error(RESPONSE_INVALID_MESSAGE); - return result.data; + return safeResponse(response.data, cardsResponseSchema); +}; + +/** + * card 상세 조회 + * https://sp-taskify-api.vercel.app/docs/#/Cards/Get + */ +export const getCard = async (cardId: number) => { + const response = await axiosClientHelper.get(`/cards/${cardId}`); + return safeResponse(response.data, cardSchema); }; +/** + * card 수정 + * https://sp-taskify-api.vercel.app/docs/#/Cards/Update + */ export const putCard = async (cardId: number, cardRequest: CardRequest) => { const response = await axiosClientHelper.put(`/cards/${cardId}`, cardRequest); - const result = cardSchema.safeParse(response.data); - if (!result.success) throw new Error(RESPONSE_INVALID_MESSAGE); - return result.data; + return safeResponse(response.data, cardSchema); }; +/** + * card 드래그 이동 + * https://sp-taskify-api.vercel.app/docs/#/Cards/Update + */ export const moveCard = async (cardId: Card['id'], columnId: Column['id']) => { const response = await axiosClientHelper.put(`/cards/${cardId}`, { columnId }); - const result = cardSchema.safeParse(response.data); - if (!result.success) throw new Error(RESPONSE_INVALID_MESSAGE); - return result.data; -}; - -export const getCard = async (cardId: number) => { - const response = await axiosClientHelper.get(`/cards/${cardId}`); - const result = cardSchema.safeParse(response.data); - if (!result.success) throw new Error(RESPONSE_INVALID_MESSAGE); - return result.data; + return safeResponse(response.data, cardSchema); }; +/** + * card 삭제 + * https://sp-taskify-api.vercel.app/docs/#/Cards/Delete + */ export const deleteCard = async (cardId: number) => { await axiosClientHelper.delete(`/cards/${cardId}`); }; diff --git a/src/apis/cards/queries.ts b/src/apis/cards/queries.tsx similarity index 100% rename from src/apis/cards/queries.ts rename to src/apis/cards/queries.tsx diff --git a/src/apis/columns/index.ts b/src/apis/columns/index.ts index f1795db..94a9a59 100644 --- a/src/apis/columns/index.ts +++ b/src/apis/columns/index.ts @@ -1,47 +1,56 @@ import axiosClientHelper from '@/utils/network/axiosClientHelper'; import { CardImageForm, CardImageResponse, cardImageResponseSchema, Column, ColumnForm, columnSchema, ColumnsResponse, columnsResponseSchema, GetColumnsParams } from './types'; +import { safeResponse } from '@/utils/network/safeResponse'; -const RESPONSE_INVALID_MESSAGE = '서버에서 받은 데이터가 예상과 다릅니다'; - +/** + * column 생성 + * https://sp-taskify-api.vercel.app/docs/#/Columns/Create + */ export const postColumn = async (dashboardId: number, columnForm: ColumnForm) => { const response = await axiosClientHelper.post('/columns', { ...columnForm, dashboardId, }); - const result = columnSchema.safeParse(response.data); - if (!result.success) throw new Error(RESPONSE_INVALID_MESSAGE); - return result.data; + return safeResponse(response.data, columnSchema); }; +/** + * columns 목록 조회 + * https://sp-taskify-api.vercel.app/docs/#/Columns/Find + */ export const getColumns = async (params: GetColumnsParams) => { const response = await axiosClientHelper.get('/columns', { params, }); - - const result = columnsResponseSchema.safeParse(response.data); - if (!result.success) throw new Error(RESPONSE_INVALID_MESSAGE); - return result.data; + return safeResponse(response.data, columnsResponseSchema); }; +/** + * column 수정 + * https://sp-taskify-api.vercel.app/docs/#/Columns/Update + */ export const putColumn = async (columnId: number, columnForm: ColumnForm) => { const response = await axiosClientHelper.put(`/columns/${columnId}`, columnForm); - const result = columnSchema.safeParse(response.data); - if (!result.success) throw new Error(RESPONSE_INVALID_MESSAGE); - return result.data; + return safeResponse(response.data, columnSchema); }; +/** + * column 삭제 + * https://sp-taskify-api.vercel.app/docs/#/Columns/Delete + */ export const deleteColumn = async (columnId: number) => { await axiosClientHelper.delete(`/columns/${columnId}`); }; +/** + * card image 생성 + * https://sp-taskify-api.vercel.app/docs/#/Columns/UploadImage + */ export const postCardImage = async (columnId: number, cardImageForm: CardImageForm) => { const response = await axiosClientHelper.post(`/columns/${columnId}/card-image`, cardImageForm, { headers: { 'Content-Type': 'multipart/form-data', }, }); - - const result = cardImageResponseSchema.safeParse(response.data); - if (!result.success) throw new Error(RESPONSE_INVALID_MESSAGE); - return result.data; + return safeResponse(response.data, cardImageResponseSchema); }; diff --git a/src/apis/columns/queries.ts b/src/apis/columns/queries.tsx similarity index 100% rename from src/apis/columns/queries.ts rename to src/apis/columns/queries.tsx diff --git a/src/apis/comments/index.ts b/src/apis/comments/index.ts index 11f6057..725efba 100644 --- a/src/apis/comments/index.ts +++ b/src/apis/comments/index.ts @@ -1,29 +1,38 @@ import axiosClientHelper from '@/utils/network/axiosClientHelper'; import { Comment, CommentForm, commentSchema, CommentsResponse, commentsResponseSchema, GetCommentsParams, PutCommentForm } from './types'; +import { safeResponse } from '@/utils/network/safeResponse'; -const RESPONSE_INVALID_MESSAGE = '서버에서 받은 데이터가 예상과 다릅니다'; - +/** + * comment 생성 + * https://sp-taskify-api.vercel.app/docs/#/Comments/Create + */ export const postComment = async (commentForm: CommentForm) => { const response = await axiosClientHelper.post('/comments', commentForm); - const result = commentSchema.safeParse(response.data); - if (!result.success) throw new Error(RESPONSE_INVALID_MESSAGE); - return result.data; + return safeResponse(response.data, commentSchema); }; +/** + * comments 목록 조회 + * https://sp-taskify-api.vercel.app/docs/#/Columns/Find + */ export const getComments = async (params: GetCommentsParams) => { const response = await axiosClientHelper.get('/comments', { params }); - const result = commentsResponseSchema.safeParse(response.data); - if (!result.success) throw new Error(RESPONSE_INVALID_MESSAGE); - return result.data; + return safeResponse(response.data, commentsResponseSchema); }; +/** + * comment 수정 + * https://sp-taskify-api.vercel.app/docs/#/Columns/Update + */ export const putComment = async (commentId: number, putCommentForm: PutCommentForm) => { const response = await axiosClientHelper.put(`/comments/${commentId}`, putCommentForm); - const result = commentSchema.safeParse(response.data); - if (!result.success) throw new Error(RESPONSE_INVALID_MESSAGE); - return result.data; + return safeResponse(response.data, commentsResponseSchema); }; +/** + * comment 삭제 + * https://sp-taskify-api.vercel.app/docs/#/Columns/Delete + */ export const deleteComment = async (commentId: number) => { await axiosClientHelper.delete(`/comments/${commentId}`); }; diff --git a/src/apis/comments/queries.ts b/src/apis/comments/queries.tsx similarity index 100% rename from src/apis/comments/queries.ts rename to src/apis/comments/queries.tsx diff --git a/src/apis/dashboards/index.ts b/src/apis/dashboards/index.ts index e597640..38a97dc 100644 --- a/src/apis/dashboards/index.ts +++ b/src/apis/dashboards/index.ts @@ -17,6 +17,15 @@ import { } from './types'; import { safeResponse } from '@/utils/network/safeResponse'; +/** + * dashboard 생성 + * https://sp-taskify-api.vercel.app/docs/#/Dashboards/Create + */ +export const createDashboard = async (params: CreateDashboardRequest) => { + const response = await axiosClientHelper.post('/dashboards', params); + return safeResponse(response.data, dashboardSchema); +}; + /** * dashboards 목록 조회 * https://sp-taskify-api.vercel.app/docs/#/Dashboards/Find @@ -31,7 +40,6 @@ export const getDashboards = async (params: GetDashboardsRequest) => { navigationMethod, }, }); - return safeResponse(response.data, dashboardsSchema); }; @@ -41,18 +49,6 @@ export const getDashboards = async (params: GetDashboardsRequest) => { */ export const getDashboardDetails = async (id: Dashboard['id']) => { const response = await axiosClientHelper.get(`/dashboards/${id}`); - - return safeResponse(response.data, dashboardSchema); -}; - -/** - * dashboard 생성 - * https://sp-taskify-api.vercel.app/docs/#/Dashboards/Create - */ - -export const createDashboard = async (params: CreateDashboardRequest) => { - const response = await axiosClientHelper.post('/dashboards', params); - return safeResponse(response.data, dashboardSchema); }; @@ -63,7 +59,6 @@ export const createDashboard = async (params: CreateDashboardRequest) => { export const updateDashboard = async (params: UpdateDashboardRequest) => { const { id, ...reset } = params; const response = await axiosClientHelper.put(`/dashboards/${id}`, reset); - return safeResponse(response.data, dashboardSchema); }; @@ -76,6 +71,16 @@ export const deleteDashboard = async (id: Dashboard['id']) => { return response.data; }; +/** + * dashboard 초대 + * https://sp-taskify-api.vercel.app/docs/#/Dashboards/CreateInvitation + */ +export const inviteDashboard = async (params: InviteDashboardRequest) => { + const { id, email } = params; + const response = await axiosClientHelper.post(`/dashboards/${id}/invitations`, { email }); + return safeResponse(response.data, dashboardInvitationSchema); +}; + /** * dashboard 초대 불러오기 * https://sp-taskify-api.vercel.app/docs/#/Dashboards/GetInvitations @@ -88,27 +93,14 @@ export const getDashboardInvitations = async (params: GetDashboardInvitationsReq size, }, }); - return safeResponse(response.data, dashboardInvitationsSchema); }; -/** - * dashboard 초대 - * https://sp-taskify-api.vercel.app/docs/#/Dashboards/CreateInvitation - */ -export const inviteDashboard = async (params: InviteDashboardRequest) => { - const { id, email } = params; - const response = await axiosClientHelper.post(`/dashboards/${id}/invitations`, { email }); - - return safeResponse(response.data, dashboardInvitationSchema); -}; - /** * dashboard 초대 취소 * https://sp-taskify-api.vercel.app/docs/#/Dashboards/DeleteInvitation */ export const cancelDashboardInvitation = async (params: CancelInviteDashboardRequest) => { const { dashboardId, invitationId } = params; - const response = await axiosClientHelper.delete(`/dashboards/${dashboardId}/invitations/${invitationId}`); - return response.data; + await axiosClientHelper.delete(`/dashboards/${dashboardId}/invitations/${invitationId}`); }; diff --git a/src/apis/dashboards/queries.ts b/src/apis/dashboards/queries.tsx similarity index 100% rename from src/apis/dashboards/queries.ts rename to src/apis/dashboards/queries.tsx diff --git a/src/apis/invitations/index.ts b/src/apis/invitations/index.ts index fab7906..06ab477 100644 --- a/src/apis/invitations/index.ts +++ b/src/apis/invitations/index.ts @@ -16,7 +16,6 @@ export const getMyInvitations = async (params: GetMyInvitationsRequest) => { ...(cursorId && { cursorId }), //cursorId가 있을경우에만(빈값 보내면 오류) }, }); - return safeResponse(response.data, myInvitationsSchema); }; @@ -27,6 +26,5 @@ export const getMyInvitations = async (params: GetMyInvitationsRequest) => { export const respondToInvitation = async (params: RespondToInvitationRequest) => { const { invitationId, inviteAccepted } = params; const response = await axiosClientHelper.put(`/invitations/${invitationId}`, { inviteAccepted }); - return safeResponse(response.data, dashboardInvitationSchema); }; diff --git a/src/apis/invitations/queries.ts b/src/apis/invitations/queries.tsx similarity index 100% rename from src/apis/invitations/queries.ts rename to src/apis/invitations/queries.tsx diff --git a/src/apis/members/index.ts b/src/apis/members/index.ts index 2f75945..8cd1df8 100644 --- a/src/apis/members/index.ts +++ b/src/apis/members/index.ts @@ -15,7 +15,6 @@ export const getMembers = async (params: GetMembersRequest) => { dashboardId, }, }); - return safeResponse(response.data, membersSchema); }; @@ -25,6 +24,5 @@ export const getMembers = async (params: GetMembersRequest) => { */ export const deleteMember = async (params: DeleteMemberRequest) => { const { memberId } = params; - const response = await axiosClientHelper.delete(`/members/${memberId}`); - return response.data; + await axiosClientHelper.delete(`/members/${memberId}`); }; diff --git a/src/apis/members/queries.ts b/src/apis/members/queries.tsx similarity index 100% rename from src/apis/members/queries.ts rename to src/apis/members/queries.tsx diff --git a/src/apis/users/index.ts b/src/apis/users/index.ts index a644404..de73e41 100644 --- a/src/apis/users/index.ts +++ b/src/apis/users/index.ts @@ -1,44 +1,43 @@ import axiosClientHelper from '@/utils/network/axiosClientHelper'; import { CreateProfileImageForm, ProfileImageUrlResponse, profileImageUrlResponseSchema, SignupFormData, SignupResponse, UpdateUserForm, User, userSchema } from './types'; -import { isAxiosError } from 'axios'; -import { isError } from 'es-toolkit/compat'; +import { safeResponse } from '@/utils/network/safeResponse'; -export const signup = async (signupFormData: SignupFormData): SignupResponse => { - try { - const response = await axiosClientHelper.post('/users', signupFormData); - const result = userSchema.safeParse(response.data); - if (!result.success) throw new Error('서버에서 받은 데이터가 예상과 다릅니다.'); - return response.data; - } catch (error) { - if (isAxiosError(error)) return error.response?.data; - return { - message: isError(error) ? error.message : String(error), - }; - } +/** + * signup + * https://sp-taskify-api.vercel.app/docs/#/Users/Create + */ +export const signup = async (signupFormData: SignupFormData) => { + const response = await axiosClientHelper.post('/users', signupFormData); + return safeResponse(response.data, userSchema); }; +/** + * 내 정보 조회 + * https://sp-taskify-api.vercel.app/docs/#/Users/GetMyInfo + */ export const getUser = async () => { const response = await axiosClientHelper.get('/users/me'); - const result = userSchema.safeParse(response.data); - if (!result.success) throw new Error('서버에서 받은 데이터가 예상과 다릅니다.'); - return response.data; + return safeResponse(response.data, userSchema); }; +/** + * 내 정보 수정 + * https://sp-taskify-api.vercel.app/docs/#/Users/UpdateMyInfo + */ export const updateUser = async (updateUserForm: UpdateUserForm) => { const response = await axiosClientHelper.put('/users/me', updateUserForm); - const result = userSchema.safeParse(response.data); - if (!result.success) throw new Error('서버에서 받은 데이터가 예상과 다릅니다.'); - return response.data; + return safeResponse(response.data, userSchema); }; +/** + * 프로필 이미지 업로드 + * https://sp-taskify-api.vercel.app/docs/#/Users/UploadProfileImage + */ export const createProfileImage = async (createProfileImageForm: CreateProfileImageForm) => { const response = await axiosClientHelper.post('/users/me/image', createProfileImageForm, { headers: { 'Content-Type': 'multipart/form-data', }, }); - - const result = profileImageUrlResponseSchema.safeParse(response.data); - if (!result.success) throw new Error('서버에서 받은 데이터가 예상과 다릅니다.'); - return response.data; + return safeResponse(response.data, profileImageUrlResponseSchema); }; diff --git a/src/apis/users/queries.ts b/src/apis/users/queries.ts deleted file mode 100644 index e14c41e..0000000 --- a/src/apis/users/queries.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; -import { getUser, updateUser } from '.'; -import { UpdateUserForm } from './types'; - -export const useGetUser = () => { - return useQuery({ - queryKey: ['user'], - queryFn: () => getUser(), - }); -}; - -export const useUpdateUser = () => { - const queryClient = useQueryClient(); - - return useMutation({ - mutationFn: (params: UpdateUserForm) => { - return updateUser(params); - }, - onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ['user'] }); - }, - }); -}; diff --git a/src/apis/users/queries.tsx b/src/apis/users/queries.tsx new file mode 100644 index 0000000..ceaf384 --- /dev/null +++ b/src/apis/users/queries.tsx @@ -0,0 +1,39 @@ +import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; +import { createProfileImage, getUser, signup, updateUser } from '.'; +import { CreateProfileImageForm, SignupFormData, UpdateUserForm } from './types'; + +export const useGetUser = () => { + return useQuery({ + queryKey: ['user'], + queryFn: () => getUser(), + }); +}; + +export const useUpdateUser = () => { + const queryClient = useQueryClient(); + + return useMutation({ + mutationFn: (params: UpdateUserForm) => { + return updateUser(params); + }, + onSuccess: () => { + queryClient.invalidateQueries({ queryKey: ['user'] }); + }, + }); +}; + +export const useSignup = () => { + return useMutation({ + mutationFn: (signupFormData: SignupFormData) => { + return signup(signupFormData); + }, + }); +}; + +export const useCreateProfileImage = () => { + return useMutation({ + mutationFn: (createProfileImageForm: CreateProfileImageForm) => { + return createProfileImage(createProfileImageForm); + }, + }); +}; diff --git a/src/components/auth/LoginForm.tsx b/src/components/auth/LoginForm.tsx index 2b3dc33..065e301 100644 --- a/src/components/auth/LoginForm.tsx +++ b/src/components/auth/LoginForm.tsx @@ -6,8 +6,9 @@ import Field from '@/components/auth/Field'; import SubmitButton from '@/components/auth/SubmitButton'; import { LOGIN_FORM_PLACEHOLDER } from '@/constants/auth'; import { loginSchema, LoginFormData } from '@/apis/auth/types'; -import { login } from '@/apis/auth'; import useAlert from '@/hooks/useAlert'; +import { useLogin } from '@/apis/auth/queries'; +import { getErrorMessage } from '@/utils/errorMessage'; export default function LoginForm() { const { @@ -24,14 +25,16 @@ export default function LoginForm() { }); const alert = useAlert(); + const { mutateAsync: login } = useLogin(); const onSubmit = async (loginFormData: LoginFormData) => { - const response = await login(loginFormData); - if ('message' in response) { - alert(response.message); - } else { + try { + await login(loginFormData); await alert('로그인이 완료되었습니다!'); window.location.reload(); + } catch (error) { + const message = getErrorMessage(error); + alert(message); } }; diff --git a/src/components/auth/SignupForm.tsx b/src/components/auth/SignupForm.tsx index 5e9c431..77e6938 100644 --- a/src/components/auth/SignupForm.tsx +++ b/src/components/auth/SignupForm.tsx @@ -7,9 +7,10 @@ import SubmitButton from '@/components/auth/SubmitButton'; import Checkbox from './Checkbox'; import { SIGNUP_FORM_PLACEHOLDER } from '@/constants/auth'; import { signupSchema, SignupFormData } from '@/apis/users/types'; -import { signup } from '@/apis/users'; import useAlert from '@/hooks/useAlert'; import { useRouter } from 'next/navigation'; +import { useSignup } from '@/apis/users/queries'; +import { getErrorMessage } from '@/utils/errorMessage'; export default function SignupForm() { const { @@ -31,14 +32,16 @@ export default function SignupForm() { const alert = useAlert(); const router = useRouter(); + const { mutateAsync: signup } = useSignup(); const onSubmit = async (signupFormData: SignupFormData) => { - const response = await signup(signupFormData); - if ('message' in response) { - alert(response.message); - } else { + try { + await signup(signupFormData); await alert('가입이 완료되었습니다!'); router.replace('/login'); + } catch (error) { + const message = getErrorMessage(error); + alert(message); } }; diff --git a/src/components/dashboard-header/Profile.tsx b/src/components/dashboard-header/Profile.tsx index f8a8972..ab11162 100644 --- a/src/components/dashboard-header/Profile.tsx +++ b/src/components/dashboard-header/Profile.tsx @@ -2,24 +2,22 @@ import { useEffect, useRef, useState } from 'react'; import Link from 'next/link'; -import { useQueryClient } from '@tanstack/react-query'; import { motion } from 'motion/react'; import { useGetUser } from '@/apis/users/queries'; import Avatar from '@/components/ui/Avatar/Avatar'; -import axiosClientHelper from '@/utils/network/axiosClientHelper'; import useAlert from '@/hooks/useAlert'; +import { useLogout } from '@/apis/auth/queries'; export default function Profile() { const [isMenuOpen, setIsMenuOpen] = useState(false); const { data, isFetching } = useGetUser(); const alert = useAlert(); const menuRef = useRef(null); - const queryClient = useQueryClient(); + const { mutateAsync: logout } = useLogout(); const handleLogout = async () => { - await axiosClientHelper.post('/auth/logout'); + await logout(); await alert('로그아웃 했습니다.'); - queryClient.invalidateQueries(); window.location.reload(); }; diff --git a/src/components/profile/PasswordEdit.tsx b/src/components/profile/PasswordEdit.tsx index d72db80..0cc05f0 100644 --- a/src/components/profile/PasswordEdit.tsx +++ b/src/components/profile/PasswordEdit.tsx @@ -1,17 +1,14 @@ 'use client'; -import { useRouter } from 'next/navigation'; -import { useQueryClient } from '@tanstack/react-query'; import { useForm } from 'react-hook-form'; import { zodResolver } from '@hookform/resolvers/zod'; -import { isAxiosError } from 'axios'; import { Input } from '@/components/ui/Field/Input'; import { passwordSchema, PutPasswordFormData } from '@/apis/auth/types'; -import { logout, putPassword } from '@/apis/auth'; import useAlert from '@/hooks/useAlert'; import { Card, CardTitle } from '@/components//ui/Card/Card'; import Button from '@/components/ui/Button/Button'; import { getErrorMessage } from '@/utils/errorMessage'; +import { usePutPassword } from '@/apis/auth/queries'; export default function PasswordEdit() { const { @@ -30,8 +27,7 @@ export default function PasswordEdit() { }); const alert = useAlert(); - const router = useRouter(); - const queryClient = useQueryClient(); + const { mutateAsync: putPassword } = usePutPassword(); const onSubmit = async (putPasswordFormData: PutPasswordFormData) => { try { @@ -39,15 +35,8 @@ export default function PasswordEdit() { alert('비밀번호가 변경되었습니다!'); reset(); } catch (error) { - if (isAxiosError(error) && error?.status === 401) { - await alert('세션이 만료되어 로그인 페이지로 이동합니다.'); - await logout(); - queryClient.invalidateQueries(); - router.replace('/login'); - } else { - const message = getErrorMessage(error); - alert(message); - } + const message = getErrorMessage(error); + alert(message); } }; diff --git a/src/components/profile/ProfileEdit.tsx b/src/components/profile/ProfileEdit.tsx index a8e1872..0d57dbd 100644 --- a/src/components/profile/ProfileEdit.tsx +++ b/src/components/profile/ProfileEdit.tsx @@ -5,8 +5,7 @@ import { Controller, useForm } from 'react-hook-form'; import { zodResolver } from '@hookform/resolvers/zod'; import useAlert from '@/hooks/useAlert'; import { UpdateUserForm, updateUserFormSchema, User } from '@/apis/users/types'; -import { useUpdateUser } from '@/apis/users/queries'; -import { createProfileImage } from '@/apis/users'; +import { useCreateProfileImage, useUpdateUser } from '@/apis/users/queries'; import { Input } from '@/components/ui/Field/Input'; import { ImageUpload } from '@/components/ui/Field/ImageUpload'; import Button from '@/components/ui/Button/Button'; @@ -36,6 +35,7 @@ export default function ProfileEdit({ user }: ProfileEditProps) { const router = useRouter(); const alert = useAlert(); const { mutateAsync: update } = useUpdateUser(); + const { mutateAsync: createProfileImage } = useCreateProfileImage(); const resetProfileImage = () => { setValue('profileImageUrl', null, {