Skip to content

Commit

Permalink
feat #18 Profile 수정페이지 disable 수정
Browse files Browse the repository at this point in the history
  • Loading branch information
lee7198 committed Jan 26, 2024
1 parent fb3ef87 commit a2e9185
Show file tree
Hide file tree
Showing 9 changed files with 79 additions and 30 deletions.
2 changes: 1 addition & 1 deletion src/Router.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import Auth from './pages/Auth';
import InitAccessRights from './pages/Auth/components/Init/components/initAccessRights';
import Submitted from './pages/Goods/components/Submitted';
import Profile from './pages/Mypage/components/Profile';
import Edit from './pages/Mypage/components/Edit';
import Edit from './pages/Mypage/components/EditProfile';

export default function Router() {
// recoil state로 access roles 관리
Expand Down
5 changes: 3 additions & 2 deletions src/api/mypage.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { MemberInfoDto } from '@src/types/user';
import jigumeAxios from './axios';

const getProfile = async () => {
const getProfile = async (): Promise<MemberInfoDto> => {
const response = await jigumeAxios.get('/api/member/profile');

return response;
return response.data;
};

export default getProfile;
14 changes: 11 additions & 3 deletions src/api/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,9 +96,17 @@ export const updateProfile = async (param: NewProfileType) => {
const formData = new FormData();
formData.append('UpdateMemberInfoDto', blobData);

const response = await jigumeAxios.post('/api/member/info', {
data: formData,
});
const response = await jigumeAxios.post(
'/api/member/info',
{
data: formData,
},
{
headers: {
'Content-Type': 'multipart/form-data',
},
}
);
console.log(response);

return response;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,21 @@ import { handleTextFieldColor, validNickname } from '../../../utils';
import CircularProgress from '../../Auth/components/Init/components/circularProgress';
import { MyPageContextType, NewProfileType } from '../index.d';

export default function Edit() {
const { setTitle } = useOutletContext<MyPageContextType>();
export default function EditProfile() {
const { setProfileHeader, profile } = useOutletContext<MyPageContextType>();
const [valid, setValid] = useState(false);
const [newProfile, setNewProfile] = useState<NewProfileType>({
nickname: '',
image: undefined,
});
const [isChanged, setIsChanged] = useState({
image: false,
nickname: false,
});

const handleNickname = (text: string) => {
setIsChanged((prev) => ({ ...prev, nickname: true }));

setValid(validNickname(text));
setNewProfile((prev) => ({ ...prev, nickname: text }));
};
Expand All @@ -39,7 +45,11 @@ export default function Edit() {
};

useEffect(() => {
setTitle('');
// 수정 페이지 헤더 조정
setProfileHeader((prev) => ({
title: '',
isAlert: false,
}));
}, []);

const {
Expand Down Expand Up @@ -69,13 +79,16 @@ export default function Edit() {
className="hidden"
id="image"
onChange={(e) => {
if (e.target.files) encodeFileToBase64(e.target.files[0]);
if (e.target.files) {
encodeFileToBase64(e.target.files[0]);
setIsChanged((prev) => ({ ...prev, image: true }));
}
}}
/>
<div className="relative aspect-square size-32">
<img
className="size-full rounded-full object-cover"
src={newProfile.image}
className="size-full rounded-full bg-zinc-200 object-cover text-[0]"
src={profile?.profileImageUrl || newProfile.image}
alt="프로필 이미지"
/>
<img
Expand Down Expand Up @@ -129,7 +142,7 @@ export default function Edit() {
<NextButton
content="수정하기"
onClick={update}
isDisabled={!(newProfile.nickname.length > 1) && !valid}
isDisabled={!(isChanged.image || (isChanged.nickname && valid))}
/>
</div>
);
Expand Down
11 changes: 7 additions & 4 deletions src/pages/Mypage/components/MyPageHeader.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { useNavigate } from 'react-router-dom';
import ChevronLeft from '../../../asset/icon/chevronLeft.svg';
import Notification from '../../../asset/icon/Notification.svg';
import { ProfileHeaderType } from '../index.d';

export default function MyPageHeader({ title }: { title: string }) {
export default function MyPageHeader({ title, isAlert }: ProfileHeaderType) {
const navigate = useNavigate();
return (
<div className="mx-auto flex h-[48px] w-full max-w-screen-sm flex-row items-center justify-between px-4">
Expand All @@ -16,9 +17,11 @@ export default function MyPageHeader({ title }: { title: string }) {
</button>
<div className="font-bole mt-1 font-semibold">{title}</div>
</div>
<button>
<img className="mt-1 h-12 w-10" src={Notification} alt="알림" />
</button>
{isAlert && (
<button>
<img className="mt-1 h-12 w-10" src={Notification} alt="알림" />
</button>
)}
</div>
);
}
11 changes: 2 additions & 9 deletions src/pages/Mypage/components/Profile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export default function Profile() {
const navigate = useNavigate();
const resetAuth = useResetRecoilState(authState);

const { setTitle } = useOutletContext<MyPageContextType>();
const { setProfileHeader } = useOutletContext<MyPageContextType>();

const logout = useMutation('logout', () => kakaoLogout(), {
onMutate: () => console.log('RUN logout'),
Expand All @@ -25,15 +25,8 @@ export default function Profile() {
},
});

// useQuery를 사용하여 fetch 함수 실행 (getProfile)
const { data: profile } = useQuery('getProfile', () => getProfile(), {
onSuccess: (data) => {
console.log(data);
},
});

useEffect(() => {
setTitle('마이페이지');
setProfileHeader({ title: '마이페이지', isAlert: true });
}, []);

return (
Expand Down
10 changes: 9 additions & 1 deletion src/pages/Mypage/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
import { MemberInfoDto } from '@src/types/user';

export type MyPageContextType = {
setTitle: React.Dispatch<React.SetStateAction<string>>;
setProfileHeader: React.Dispatch<React.SetStateAction<ProfileHeaderType>>;
profile: MemberInfoDto;
};

export type NewProfileType = {
nickname: string;
image: string | undefined;
};

export type ProfileHeaderType = {
title: string;
isAlert: boolean;
};
22 changes: 19 additions & 3 deletions src/pages/Mypage/index.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,29 @@
import React, { useState } from 'react';
import { Outlet } from 'react-router-dom';
import getProfile from '@src/api/mypage';
import { useQuery } from 'react-query';
import MyPageHeader from './components/MyPageHeader';
import { ProfileHeaderType } from './index.d';

export default function Mypage() {
const [title, setTitle] = useState('마이페이지');
// useQuery를 사용하여 fetch 함수 실행 (getProfile)
const { data: profile } = useQuery('getProfile', () => getProfile(), {
onSuccess: (data) => {
console.log(data);
},
});

const [profileHeader, setProfileHeader] = useState<ProfileHeaderType>({
title: '마이페이지',
isAlert: true,
});
return (
<>
<MyPageHeader title={title} />
<Outlet context={{ setTitle }} />
<MyPageHeader
title={profileHeader.title}
isAlert={profileHeader.isAlert}
/>
<Outlet context={{ setProfileHeader, profile }} />
</>
);
}
7 changes: 7 additions & 0 deletions src/types/user.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,10 @@ export type TokenProviderType = {
tokenDto: { accessToken: string; refreshToken: string };
baseRole: 'ADMIN' | 'USER' | 'GUEST';
};

export type MemberInfoDto = {
nickname: string;
profileImageUrl: string;
mapX: number;
mapY: number;
};

0 comments on commit a2e9185

Please sign in to comment.