Skip to content

Commit

Permalink
feat: 마이페이지 내정보 및 수정 api 연동 (#416)
Browse files Browse the repository at this point in the history
## 1️⃣ 작업 내용 Summary
일반유저 및 자치기구 내정보 api 연동
자치기구 정보수정 api 연동

- resolved #399 

## 2️⃣ 추후 작업할 내용
- 마이페이지 작성글보기 api 연동

## 3️⃣ 체크리스트

- [x] `develop` 브랜치의 최신 코드를 `pull` 받았나요?
  • Loading branch information
naraeng authored and nebulaBdj committed Mar 3, 2025
1 parent 0201095 commit 6037fd5
Show file tree
Hide file tree
Showing 14 changed files with 309 additions and 235 deletions.
Binary file added public/image/mypage/arrow_left.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/image/mypage/arrow_right.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 15 additions & 0 deletions src/apis/getUserProfile.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { getUserProfileResponse } from '@/types/apis/get';
import axios, { AxiosResponse } from 'axios';

export const getUserProfile = async () => {
const accessToken = localStorage.getItem('accessToken');
const response: AxiosResponse<getUserProfileResponse> = await axios({
baseURL: 'http://13.125.101.7:8080',
url: '/users/mypage',
method: 'get',
headers: {
Authorization: `Bearer ${accessToken}`,
},
});
return response.data;
};
22 changes: 22 additions & 0 deletions src/apis/patchUserProfile.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { clientAuth } from './client';
import { patchUserProfileResponse } from '@/types/apis/get';
import { AxiosResponse } from 'axios';

export const patchUserProfile = async (data: {
nickname: string;
currentPassword: string;
newPassword: string;
confirmNewPassword: string;
}) => {
const accessToken = localStorage.getItem('accessToken');
const response: AxiosResponse<patchUserProfileResponse> = await clientAuth({
baseURL: 'http://13.125.101.7:8080',
url: '/users/mypage',
method: 'PATCH',
headers: {
Authorization: `Bearer ${accessToken}`,
},
data,
});
return response.data;
};
2 changes: 1 addition & 1 deletion src/pages/mypage/component/DropdownUserMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ interface DropdownUserMenuProps {

export default function DropdownUserMenu({ selectedMenu, setSelectedMenu, setIsDropdown }: DropdownUserMenuProps) {
return (
<div className="h-36 w-36 rounded-xs border bg-gray-50 px-1 py-1 text-gray-700 shadow-lg sm:text-xs md:text-sm">
<div className="w-36 rounded-xs border bg-gray-50 px-1 py-1 text-gray-700 shadow-lg xs:text-xs sm:text-xs md:text-sm">
<ul>
<li
className={`cursor-pointer px-4 py-3 ${
Expand Down
58 changes: 34 additions & 24 deletions src/pages/mypage/component/UserContainer.tsx
Original file line number Diff line number Diff line change
@@ -1,48 +1,58 @@
import { UserContainerProps } from '../types';
import { useGetUserProfile } from '../profile/hooks/useGetUserProfile';

export default function UserContainer() {
const { data, isLoading, error } = useGetUserProfile();
const userData = data?.data;

if (isLoading) console.log('loading');
if (error) console.log('error : ', error);

export default function UserContainer({ isAssociation, userInfo, associationInfo }: UserContainerProps) {
return (
// props ? api ?
<>
{isAssociation && associationInfo ? (
<div className="mb-16 ml-16 mr-20 mt-16 flex flex-col items-center rounded-lg border-2 border-[#D9D9D9] bg-white p-10 py-8 sm:flex-col">
<img className="mr-8 h-24 w-24" src="/image/mypage/profile_img.png" alt="profile_default_img" />
<div>
<div className="mb-2">
<span className="text-lg font-bold">{associationInfo.nickname}</span>
<div className="w-full px-4">
{userData?.isUnion && userData ? (
<div className="mx-auto mb-10 mt-16 flex flex-row items-center rounded-2xl border-2 border-[#D9D9D9] bg-white px-10 py-8 xs:mx-[20%] xs:flex-col xs:pb-4 sm:mx-[22%] sm:flex-col md:mx-10 md:py-6 lg:mx-10 xl:mx-10 xxl:mx-10">
<img
className="mr-8 h-24 w-24 xs:mb-4 xs:mr-0 xs:h-20 xs:w-20 sm:mr-0 md:mr-6"
src="/image/mypage/profile_img.png"
alt="profile_default_img"
/>
<div className="mb-4">
<div className="mb-2 flex items-center xs:justify-center sm:mt-6 sm:justify-center md:mt-6">
<span className="text-lg font-bold">{userData.nickname}</span>
</div>
<div>
<span>{associationInfo.college}</span>
<span>{associationInfo.department}</span>
<div className="mb-1 text-sm xs:text-xs sm:mb-3 sm:text-xs md:mb-2">
<span>{userData?.memberCode}</span>
{userData?.majorCode ? <span></span> : ''}
<span>{userData?.majorCode}</span>
</div>
</div>
</div>
) : (
<div className="sm:mx-18 m-16 flex flex-row items-center rounded-2xl border-2 border-[#D9D9D9] bg-white px-10 py-8 sm:flex-col md:py-6">
<div className="mx-auto mb-10 mt-16 flex flex-row items-center rounded-2xl border-2 border-[#D9D9D9] bg-white px-10 py-8 xs:mx-[20%] xs:flex-col xs:pb-4 sm:mx-[20%] sm:flex-col md:mx-10 md:py-6 lg:mx-10 xl:mx-10 xxl:mx-10">
<img
className="mr-8 h-24 w-24 sm:mr-0 md:mr-6"
className="mr-8 h-24 w-24 xs:mb-4 xs:mr-0 xs:h-20 xs:w-20 sm:mr-0 md:mr-6"
src="/image/mypage/profile_img.png"
alt="profile_default_img"
/>
<div className="mb-4">
<div className="mb-2 flex items-center sm:mt-6 sm:justify-center md:mt-6">
<span className="text-lg font-bold sm:text-base">{userInfo?.name}</span>
<div className="mb-2 flex items-center xs:justify-center sm:mt-6 sm:justify-center md:mt-6">
<span className="text-lg font-bold xs:text-sm sm:text-base">{userData?.name}</span>
<span className="ml-1 mr-1 text-xl font-light"> | </span>
<span className="text-lg font-bold sm:text-base">{userInfo?.studentId}</span>
<span className="text-lg font-bold xs:m-0 xs:text-sm sm:text-base">{userData?.studentId}</span>
</div>
<div className="mb-1 text-sm sm:mb-3 sm:text-xs md:mb-2">
<span>{userInfo?.college}</span>
<span>{userInfo?.department}</span>
<div className="mb-1 text-sm xs:text-xs sm:mb-3 sm:text-xs md:mb-2">
<span>{userData?.memberCode}</span>
<span>{userData?.majorCode}</span>
<span>재학</span>
</div>
<div className="flex text-sm sm:flex-col sm:items-center sm:text-xs md:flex-col">
{/* <div className="flex text-sm xs:flex-col xs:items-center xs:text-xs sm:flex-col sm:items-center sm:text-xs md:flex-col">
<span>총학생회비 납부</span>
<span className="hidden lg:block xl:block xxl:block"> • </span>
<span>글로벌미디어학부 학생회비 납부</span>
</div>
</div> */}
</div>
</div>
)}
</>
</div>
);
}
19 changes: 11 additions & 8 deletions src/pages/mypage/myPosts/myPostsContent/myPostsContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,18 @@ interface MyPostsPageProps {
}
export function MyPostsContent({ boardCode, postId }: MyPostsPageProps) {
return (
<div className="ml-24 flex h-[92px] w-[1320px] cursor-pointer items-center justify-between border-b-2 border-solid">
<div className="flex items-center gap-[20px]">
<div className="ml-[10px] h-[20px] w-[52px] text-[18px] text-[#2F4BF7]">{postId.toString()}</div>
<div className="text-[18px] font-[500] text-[#374151]">[{boardCode}] 교수님 종강은 언제하시나요..</div>
<div className="mx-16 mt-[14px] flex flex-col border-b-[1px] border-solid border-gray-400 pr-2 text-[14px]">
<div className="flex cursor-pointer flex-row justify-between xs:flex-col xs:items-end">
<div className="flex items-center gap-[20px]">
<div className="ml-[10px] h-[20px] w-[52px] text-[#2F4BF7]">{postId.toString()}</div>
<div className="text-[#374151]">[{boardCode}] 교수님 종강은 언제하시나요..</div>
</div>
<div className="font-[500] text-[#6B7280]">2023/10/02</div>
</div>
<div className="flex flex-col items-end">
<div className="text-[18px] font-[500] text-[#6B7280]">2023/10/02</div>
<div className="flex gap-[6px] text-[18px] font-[500] text-[#2F4BF7]">
<img src={CommentMark} /> 32
<div className="mb-[10px] flex flex-col items-end">
<div className="flex gap-[4px] text-[#2F4BF7]">
<img src={CommentMark} className="mt-[2px] h-[14px] w-[14px]" />
32
</div>
</div>
</div>
Expand Down
73 changes: 30 additions & 43 deletions src/pages/mypage/myPosts/page.tsx
Original file line number Diff line number Diff line change
@@ -1,52 +1,39 @@
import { useState } from 'react';
import UserContainer from '../component/UserContainer';
import { MyPostsContent } from './myPostsContent/myPostsContent';

function MyPostsPage() {
const [searchText, setSearchText] = useState('');

const onClickSearch = () => {
console.log(searchText);
};

return (
<div className="mt-24">
<div className="flex flex-col">
<UserContainer />
<div>
<h1 className="mb-5 ml-72 text-2xl font-bold">마이페이지</h1>
<div className="w-full border-b border-[#E7E7E7]"></div>
<div className="flex flex-row">
<aside className="my-10 w-64 border-r border-gray-300">
<div className="p-10 font-bold">
{/* <h3 className="mb-4 text-lg font-bold text-blue-600">내 정보</h3> */}
<ul>
<li className="mb-2 cursor-pointer text-gray-700 hover:text-blue-600">내 정보</li>
<li className="mb-2 cursor-pointer text-gray-700 hover:text-blue-600">작성 글 보기</li>
<li className="cursor-pointer text-gray-700 hover:text-blue-600">서비스 공지사항</li>
</ul>
</div>
</aside>
<div className="flex-grow">
<div className="mb-16 ml-16 mr-10 mt-16 flex flex-row items-center rounded-lg border-2 border-[#D9D9D9] bg-white p-10">
<img className="mr-8 h-28 w-28" src="/image/mypage/profile_img.png" alt="profile_default_img" />
<div>
<div className="mb-4">
<span className="text-xl font-extrabold">김숭실</span>
<span className="flex-col gap-1 text-xl font-thin"> | </span>
<span className="text-xl font-extrabold">20241234</span>
</div>
<div className="mb-1">
<span>IT대학 • </span>
<span>글로벌미디어학부 • </span>
<span>재학</span>
</div>
<div>
<span>총학생회비 납부 • </span>
<span>글로벌미디어학부 학생회비 납부</span>
</div>
</div>
</div>
<div className="mb-[40px]">
<MyPostsContent boardCode="건의게시판" postId={12345} />
<MyPostsContent boardCode="건의게시판" postId={13213} />
<MyPostsContent boardCode="건의게시판" postId={125} />
<MyPostsContent boardCode="건의게시판" postId={54321} />
<MyPostsContent boardCode="건의게시판" postId={222} />
<MyPostsContent boardCode="건의게시판" postId={5658} />
</div>
</div>
<div className="mx-16 flex items-center border-b-[1px] border-solid border-gray-500 pb-1">
<span className="pl-2">작성 글</span>
<span className="ml-2 text-center font-semibold">45</span>
</div>
<MyPostsContent boardCode="건의게시판" postId={12345} />
<MyPostsContent boardCode="건의게시판" postId={13213} />
<MyPostsContent boardCode="건의게시판" postId={125} />
<MyPostsContent boardCode="건의게시판" postId={54321} />
<MyPostsContent boardCode="건의게시판" postId={222} />
<MyPostsContent boardCode="건의게시판" postId={5658} />
</div>
<div className="my-16 flex justify-center gap-3">
<input
type="text"
onChange={(e) => setSearchText(e.target.value)}
className="w-[40%] rounded-md border border-gray-300 p-3 text-[13px]"
placeholder="원하시는 키워드를 입력하세요"
/>
<button onClick={onClickSearch} className="rounded-md bg-[#2F4BF7] px-7 text-[13px] text-white">
검색
</button>
</div>
</div>
);
Expand Down
15 changes: 10 additions & 5 deletions src/pages/mypage/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { useState } from 'react';
import ProfilePage from './profile/page';
import Sidebar from './component/Sidebar';
import DropdownUserMenu from './component/DropdownUserMenu';
import { ServiceNoticePage } from './service-notice/page';
import MyPostsPage from './myPosts/page';

export default function MyPage() {
const [selectedMenu, setSelectedMenu] = useState('내 정보');
Expand All @@ -13,18 +15,21 @@ export default function MyPage() {
case '내 정보':
return <ProfilePage />;
case '작성 글 보기':
return <ProfilePage />;
return <MyPostsPage />;
case '서비스 공지사항':
return <ProfilePage />;
return <ServiceNoticePage />;
}
};

return (
<div className="mt-24">
<div>
<div className="relative flex sm:justify-center md:ml-52 md:justify-start lg:ml-72 xl:ml-72 xxl:ml-72">
<div className="relative flex xs:justify-center sm:justify-center md:ml-52 md:justify-start lg:ml-72 xl:ml-72 xxl:ml-72">
<h1 className="mb-5 text-2xl font-bold">마이페이지</h1>
<button className="mb-5 ml-3 hidden items-center sm:block" onClick={() => setIsDropdown(!isDropdown)}>
<button
className="mb-5 ml-3 hidden items-center xs:block sm:block"
onClick={() => setIsDropdown(!isDropdown)}
>
<img
src="/image/mypage/arrow_down.png"
alt="arrow down"
Expand All @@ -42,7 +47,7 @@ export default function MyPage() {
)}
</div>
<div className="w-full border-b border-[#E7E7E7]"></div>
<div className="flex flex-row">
<div className="flex md:flex-row lg:flex-row xl:flex-row xxl:flex-row">
<Sidebar selectedMenu={selectedMenu} setSelectedMenu={setSelectedMenu} />
<div className="flex-grow">{renderMenu()}</div>
</div>
Expand Down
11 changes: 11 additions & 0 deletions src/pages/mypage/profile/hooks/useGetUserProfile.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { getUserProfile } from '@/apis/getUserProfile';
import { getUserProfileResponse } from '@/types/apis/get';
import { useQuery, UseQueryResult } from '@tanstack/react-query';
import { AxiosError } from 'axios';

export const useGetUserProfile = (): UseQueryResult<getUserProfileResponse, AxiosError> => {
return useQuery<getUserProfileResponse, AxiosError>({
queryKey: ['get-user-profile'],
queryFn: getUserProfile,
});
};
20 changes: 20 additions & 0 deletions src/pages/mypage/profile/hooks/usePatchUserProfile.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { patchUserProfile } from '@/apis/patchUserProfile';
import { AxiosError } from 'axios';
import { patchUserProfileRequest, patchUserProfileResponse } from '@/types/apis/get';

export const usePatchUserProfile = () => {
const queryClient = useQueryClient();

return useMutation<patchUserProfileResponse, AxiosError, patchUserProfileRequest>({
mutationFn: async (patchData) => {
return await patchUserProfile(patchData);
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['get-user-profile'] });
},
// onError: (error) => {
// console.error('정보 수정 실패:', error.response?.data);
// },
});
};
Loading

0 comments on commit 6037fd5

Please sign in to comment.