From 5dce7ec01a5b690e0742da8ff6b17bc05dc1e7ca Mon Sep 17 00:00:00 2001 From: naraeng Date: Sun, 2 Mar 2025 16:17:14 +0900 Subject: [PATCH] Feat: search user posts (#399) --- src/apis/getUserPostSearch.ts | 0 src/apis/getUserPosts.ts | 3 +- src/apis/getUserPostsSearch.ts | 11 + src/apis/getUserProfile.ts | 3 +- .../mypage/component/DropdownUserMenu.tsx | 2 +- .../myPosts/hooks/useGetSearchUserPosts.ts | 0 .../mypage/myPosts/hooks/useGetUserPosts.ts | 1 - .../myPosts/hooks/useSearchUserPosts.ts | 25 ++ src/pages/mypage/myPosts/page.tsx | 12 +- src/pages/mypage/page.tsx | 2 +- src/pages/mypage/profile/page.tsx | 246 +++++++++--------- 11 files changed, 171 insertions(+), 134 deletions(-) delete mode 100644 src/apis/getUserPostSearch.ts create mode 100644 src/apis/getUserPostsSearch.ts delete mode 100644 src/pages/mypage/myPosts/hooks/useGetSearchUserPosts.ts create mode 100644 src/pages/mypage/myPosts/hooks/useSearchUserPosts.ts diff --git a/src/apis/getUserPostSearch.ts b/src/apis/getUserPostSearch.ts deleted file mode 100644 index e69de29b..00000000 diff --git a/src/apis/getUserPosts.ts b/src/apis/getUserPosts.ts index b1253694..9819692e 100644 --- a/src/apis/getUserPosts.ts +++ b/src/apis/getUserPosts.ts @@ -1,10 +1,9 @@ import { GetUserPostsResponse } from '@/types/apis/get'; import { AxiosResponse } from 'axios'; -import { clientAuth } from './client'; +import { clientAuth } from '@/apis/client.ts'; export const getUserPosts = async (page: number, take: number) => { const response: AxiosResponse = await clientAuth({ - baseURL: import.meta.env.VITE_API_URL, url: `board/mypost?page=${page}&take=${take}`, method: 'get', }); diff --git a/src/apis/getUserPostsSearch.ts b/src/apis/getUserPostsSearch.ts new file mode 100644 index 00000000..b6833a3c --- /dev/null +++ b/src/apis/getUserPostsSearch.ts @@ -0,0 +1,11 @@ +import { GetUserPostsResponse } from '@/types/apis/get'; +import { AxiosResponse } from 'axios'; +import { clientAuth } from './client.ts'; + +export const getUserPostsSearch = async (page: number, take: number, q: string) => { + const response: AxiosResponse = await clientAuth({ + url: `board/mypost/search?page=${page}&take=${take}&q=${q}`, + method: 'get', + }); + return response.data; +}; diff --git a/src/apis/getUserProfile.ts b/src/apis/getUserProfile.ts index ed68079e..297c3664 100644 --- a/src/apis/getUserProfile.ts +++ b/src/apis/getUserProfile.ts @@ -1,10 +1,9 @@ import { GetUserProfileResponse } from '@/types/apis/get'; import { AxiosResponse } from 'axios'; -import { clientAuth } from './client'; +import { clientAuth } from './client.ts'; export const getUserProfile = async () => { const response: AxiosResponse = await clientAuth({ - baseURL: 'http://13.125.101.7:8080', url: '/users/mypage', method: 'get', }); diff --git a/src/pages/mypage/component/DropdownUserMenu.tsx b/src/pages/mypage/component/DropdownUserMenu.tsx index 9a07d4da..c39fad3a 100644 --- a/src/pages/mypage/component/DropdownUserMenu.tsx +++ b/src/pages/mypage/component/DropdownUserMenu.tsx @@ -6,7 +6,7 @@ interface DropdownUserMenuProps { export default function DropdownUserMenu({ selectedMenu, setSelectedMenu, setIsDropdown }: DropdownUserMenuProps) { return ( -
+
  • => { return useQuery({ queryKey: ['get-user-posts', page, take], - // queryFn: () => getUserPosts(page, take), queryFn: async () => { try { return await getUserPosts(page, take); diff --git a/src/pages/mypage/myPosts/hooks/useSearchUserPosts.ts b/src/pages/mypage/myPosts/hooks/useSearchUserPosts.ts new file mode 100644 index 00000000..686e7b49 --- /dev/null +++ b/src/pages/mypage/myPosts/hooks/useSearchUserPosts.ts @@ -0,0 +1,25 @@ +import { getUserPostsSearch } from '@/apis/getUserPostsSearch'; +import { GetUserPostsResponse } from '@/types/apis/get'; +import { useQuery, UseQueryResult } from '@tanstack/react-query'; +import axios, { AxiosError } from 'axios'; + +export const useSearchUserPosts = ( + page: number, + take: number, + q: string +): UseQueryResult => { + return useQuery({ + queryKey: ['get-user-posts', page, take, q], + queryFn: async () => { + try { + return await getUserPostsSearch(page, take, q); + } catch (error) { + console.error('API Error:', error); + if (axios.isAxiosError(error)) { + console.error('Error response:', error.response?.data); + } + throw error; + } + }, + }); +}; diff --git a/src/pages/mypage/myPosts/page.tsx b/src/pages/mypage/myPosts/page.tsx index 3621c2be..27628148 100644 --- a/src/pages/mypage/myPosts/page.tsx +++ b/src/pages/mypage/myPosts/page.tsx @@ -4,17 +4,27 @@ import { MyPostsContent } from './myPostsContent/myPostsContent'; import { useGetUserPosts } from './hooks/useGetUserPosts'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; +import { useSearchUserPosts } from './hooks/useSearchUserPosts'; function MyPostsPage() { const [page, setPage] = useState(0); const [take] = useState(6); const [searchText, setSearchText] = useState(''); + const [query, setQuery] = useState(''); + + const userPostsData = useGetUserPosts(page, take); + const searchData = useSearchUserPosts(page, take, query); + + const data = query ? searchData.data : userPostsData.data; + const isLoading = query ? searchData.isLoading : userPostsData.isLoading; + const error = query ? searchData.error : userPostsData.error; - const { data, isLoading, error } = useGetUserPosts(page, take); const totalPages = data?.data?.pageInfo?.totalPages ?? 1; const onClickSearch = () => { console.log(searchText); + setPage(0); + setQuery(searchText); }; const handlePageClick = (pageNumber: number) => { diff --git a/src/pages/mypage/page.tsx b/src/pages/mypage/page.tsx index 8e523342..ef02e476 100644 --- a/src/pages/mypage/page.tsx +++ b/src/pages/mypage/page.tsx @@ -34,7 +34,7 @@ export default function MyPage() { {isDropdown && ( -
    +
    { - if (userData?.nickname) setNickname(userData.nickname); - }, [userData, isEditing]); + if (userData?.nickname) { + setValue('nickname', userData.nickname); + } + }, [userData, isEditing, setValue]); const mutation = usePatchUserProfile(); - const handleInputChange = (e: { target: { name: string; value: string } }) => { - const { name, value } = e.target; - if (name === 'nickname') { - setNickname(value); - console.log(nickname); - } else if (name === 'currentPassword') { - setCurrentPassword(value); - console.log(currentPassword); - } else if (name === 'newPassword') { - setNewPassword(value); - console.log(newPassword); - } else if (name === 'confirmPassword') { - setConfirmPassword(value); - console.log(confirmPassword); - } - }; - - const handleSubmit = () => { - if (newPassword !== confirmPassword) { - setPasswordError('비밀번호가 일치하지 않습니다'); + const onSubmit = (formData: PatchUserProfileRequest) => { + if (formData.newPassword !== formData.confirmNewPassword) { + alert('비밀번호가 일치하지 않습니다.'); return; } + mutation.mutate( { - nickname, - currentPassword, - newPassword, - confirmNewPassword: confirmPassword, + nickname: formData.nickname, + currentPassword: formData.currentPassword, + newPassword: formData.newPassword, + confirmNewPassword: formData.confirmNewPassword, }, { onSuccess: () => { @@ -69,13 +62,19 @@ export default function ProfilePage() { }, } ); - // 변경 후 초기화 - setNewPassword(''); - setConfirmPassword(''); - setPasswordError(''); - setIsEditing(false); + reset(); }; + if (isLoading) { + console.log('loading'); + return null; + } + + if (error || !userData) { + console.log('error : ', error); + return null; + } + return (
    {userData?.isUnion ? ( @@ -83,67 +82,87 @@ export default function ProfilePage() {
    {isEditing ? ( -
    -

    기본정보

    -
    - 단위명 - - - 닉네임 - -
    -

    비밀번호 변경

    -
    - 기존 비밀번호 - - - 새 비밀번호 - - - 비밀번호 확인 - - {passwordError && {passwordError}} -
    -
    - - +
    +
    +

    기본정보

    +
    + 단위명 + + + 닉네임 + +
    +

    비밀번호 변경

    +
    + 기존 비밀번호 +
    + + {errors.currentPassword && ( + + {errors.currentPassword.message} + + )} +
    + + 새 비밀번호 +
    + + {errors.newPassword && ( + + {errors.newPassword.message} + + )} +
    + + 비밀번호 확인 +
    + value === watch('newPassword') || '비밀번호가 일치하지 않습니다.', + })} + className="w-56 rounded-sm border border-gray-300 px-3 py-1 xs:w-40 sm:w-40" + /> + {errors.confirmNewPassword && ( + + {errors.confirmNewPassword.message} + + )} +
    +
    +
    + + +
    -
    + ) : (

    기본정보

    @@ -189,31 +208,6 @@ export default function ProfilePage() {
    )} - {/*
    - {isEditing ? ( - <> - - - - ) : ( - - )} -
    */}
    ); }