박권수

feat. 탈퇴 요청 뷰 구성

......@@ -9,6 +9,13 @@ export default {
},
});
},
getDoctorSecReqList : (token : RecoilState<any>) => {
return client.get('/manage/doctor/secession', {
headers : {
Authorization : token,
},
});
},
getDoctorRegReqDetail : (token : RecoilState<any>, doctorId : string) => {
return client.get(`/manage/doctor/${doctorId}`, {
headers : {
......@@ -17,14 +24,21 @@ export default {
});
},
acceptDoctorRegReq : (token : RecoilState<any>, Data : any) => {
return client.post('/manage/doctor/accept', Data, {
return client.patch('/manage/doctor/accept', Data, {
headers : {
Authorization : token,
},
});
},
rejectDoctorRegReq : (token : RecoilState<any>, Data : any) => {
return client.post('/manage/doctor/reject', Data, {
return client.patch('/manage/doctor/reject', Data, {
headers : {
Authorization : token,
},
});
},
acceptDoctorSecReq : (token : RecoilState<any>, Data : any) => {
return client.patch('/manage/doctor/secession', Data, {
headers : {
Authorization : token,
},
......
......@@ -17,7 +17,9 @@ const ManagerMenuContainer = (props : ManagerMenuProps) => {
const token = useRecoilValue(recoilUtil.token);
const [doctorRegReqList, setDoctorRegReqList] = useState<any>([]);
const [doctorList, setDoctorList] = useState<any>([]);
const [viewType, setViewType] = useState<string>('reg');
const [doctorDetail, setDoctorDetail] = useState<any>({});
const [modalUp, setModalUp] = useState<boolean>(false);
......@@ -31,20 +33,28 @@ const ManagerMenuContainer = (props : ManagerMenuProps) => {
setValidate('W');
try {
await managerApi.getDoctorRegReqList(token)
.then((res : any) => {
if(res.statusText === 'OK') {
setDoctorRegReqList(res.data.doctorRegReqList);
}
}).catch(err => {
Alert.onError(err.response.data.error, () => null);
});
const res = viewType === 'reg' ? await managerApi.getDoctorRegReqList(token) : await managerApi.getDoctorSecReqList(token);
if(res.statusText === 'OK') {
setDoctorList(res.data.doctorList);
} else {
Alert.onError(res.data.error, () => null);
}
} catch(e : any) {
Alert.onError(e.response.data.error, () => null);
}
};
//가입요청 보기
const onViewRegList = () => {
setViewType('reg');
};
//탈퇴요청 보기
const onViewSecList = () => {
setViewType('sec');
};
//가입요청 상세보기
const onViewDetailReq = async (doctorId : string) => {
setValidate('W');
......@@ -72,7 +82,7 @@ const ManagerMenuContainer = (props : ManagerMenuProps) => {
};
//회원 가입 수락
const onAcceptRequest = () => {
const onAcceptRegReq = () => {
if(validate === 'W') {
Alert.onError('먼저 의사의 자격번호가 유효한지 검증해주세요.', () => null);
return;
......@@ -118,6 +128,7 @@ const ManagerMenuContainer = (props : ManagerMenuProps) => {
Alert.onCheck('회원 가입 요청을 취소하시겠습니까?', onReject, () => null);
};
//회원 자격번호 유효 검증 api
const onValidate = async () => {
try {
await managerApi.validateDoctorLicense(token, {
......@@ -140,6 +151,24 @@ const ManagerMenuContainer = (props : ManagerMenuProps) => {
}
};
const onAcceptSecReq = (doctorId : string) => {
const onAccept = async () => {
try {
const res = await managerApi.acceptDoctorSecReq(token, {
doctorId,
});
if(res.statusText === 'OK') {
Alert.onSuccess('탈퇴를 승인했습니다.', fetchData);
}
} catch (e : any) {
Alert.onError(e.response.data.error, () => null);
}
};
Alert.onCheck('회원 탈퇴를 승인하시겠습니까?\n이 작업은 되돌릴 수 없습니다.', onAccept, () => null);
};
useEffect(() => {
setValidate('W');
......@@ -148,11 +177,15 @@ const ManagerMenuContainer = (props : ManagerMenuProps) => {
useEffect(() => {
fetchData();
}, []);
}, [viewType]);
return (
<ManagerMenuPresenter
doctorRegReqList = {doctorRegReqList}
viewType = {viewType}
onViewRegList = {onViewRegList}
onViewSecList = {onViewSecList}
doctorList = {doctorList}
doctorDetail = {doctorDetail}
modalUp = {modalUp}
......@@ -166,7 +199,8 @@ const ManagerMenuContainer = (props : ManagerMenuProps) => {
validateDoctorLicense = {validateDoctorLicense}
onSetValidateDoctorLicense = {onSetValidateDoctorLicense}
onAcceptRequest = {onAcceptRequest}
onAcceptRegReq = {onAcceptRegReq}
onAcceptSecReq = {onAcceptSecReq}
onRejectRequest = {onRejectRequest}
/>
);
......
......@@ -5,7 +5,11 @@ import * as styled from './ManagerMenuStyled';
interface ManagerMenuProps {
doctorRegReqList : any[];
viewType : string;
onViewRegList : () => void;
onViewSecList : () => void;
doctorList : any[];
doctorDetail : any;
modalUp : boolean;
......@@ -19,7 +23,8 @@ interface ManagerMenuProps {
validateDoctorLicense : string;
onSetValidateDoctorLicense : React.ChangeEventHandler<HTMLInputElement>;
onAcceptRequest : () => void;
onAcceptRegReq : () => void;
onAcceptSecReq : (arg0 : string) => void;
onRejectRequest : () => void;
}
......@@ -98,7 +103,7 @@ const ManagerMenuPresenter = (props : ManagerMenuProps) => {
</styled.ModalBodyWrapper>
<styled.ModalButtonWrapper>
<styled.ModalButton
onClick = {props.onAcceptRequest}
onClick = {props.onAcceptRegReq}
isAccept = {true}
>
수락
......@@ -114,37 +119,71 @@ const ManagerMenuPresenter = (props : ManagerMenuProps) => {
</Modal> : null
}
<styled.ContentWrapper>
<styled.ContentButtonWrapper>
<styled.ContentButton
isSelect = {props.viewType === 'reg'}
onClick = {props.onViewRegList}
>
가입 대기
</styled.ContentButton>
<styled.ContentButton
isSelect = {props.viewType === 'sec'}
onClick = {props.onViewSecList}
>
탈퇴 요청
</styled.ContentButton>
</styled.ContentButtonWrapper>
<styled.ContentTitle>
가입 대기 중 의사 회원
<styled.ContentExplain>
*클릭하면 상세정보를 확인할 수 있습니다.
</styled.ContentExplain>
{
props.viewType === 'sec' ?
<>
탈퇴 대기 중 의사 회원
<styled.ContentExplain>
*승인을 누르면 탈퇴를 승인합니다.
</styled.ContentExplain>
</> :
<>
가입 대기 중 의사 회원
<styled.ContentExplain>
*클릭하면 상세정보를 확인할 수 있습니다.
</styled.ContentExplain>
</>
}
</styled.ContentTitle>
<styled.ContentBody>
<styled.ContentInfoWrapper>
<styled.ContentInfo
isLast = {false}
>
분야
</styled.ContentInfo>
<styled.ContentInfo
isLast = {false}
>
이름
</styled.ContentInfo>
<styled.ContentInfo
<styled.ContentInfoWrapper>
<styled.ContentInfo
isLast = {false}
>
분야
</styled.ContentInfo>
<styled.ContentInfo
isLast = {false}
>
이름
</styled.ContentInfo>
<styled.ContentInfo
isLast = {props.viewType !== 'sec'}
>
이메일
</styled.ContentInfo>
{
props.viewType === 'sec' ?
<styled.ContentInfo
isLast = {true}
>
이메일
</styled.ContentInfo>
</styled.ContentInfoWrapper>
탈퇴 수락
</styled.ContentInfo> : null
}
</styled.ContentInfoWrapper>
<styled.ContentBody>
{
props.doctorRegReqList.length ?
props.doctorRegReqList.map((doctor : any) => {
props.doctorList.length ?
props.doctorList.map((doctor : any) => {
return (
<styled.EachContentWrapper
key = {doctor.doctorId}
onClick = {() => props.onViewDetailReq(doctor.doctorId)}
disabled = {props.viewType === 'sec'}
>
<styled.EachContentNm
isLast = {false}
......@@ -157,10 +196,22 @@ const ManagerMenuPresenter = (props : ManagerMenuProps) => {
{doctor.info.doctorNm}
</styled.EachContentNm>
<styled.EachContentNm
isLast = {true}
isLast = {props.viewType !== 'sec'}
>
{doctor.doctorId}
</styled.EachContentNm>
{
props.viewType === 'sec' ?
<styled.EachContentNm
isLast = {true}
>
<styled.AcceptButton
onClick = {() => props.onAcceptSecReq(doctor.doctorId)}
>
승인
</styled.AcceptButton>
</styled.EachContentNm> : null
}
</styled.EachContentWrapper>
)
}) :
......
......@@ -251,8 +251,45 @@ export const ContentWrapper = styled.div `
`;
export const ContentButtonWrapper = styled.div `
width : 100%;
height : 10%;
border : none;
display : flex;
flex-direction : row;
justify-content : center;
align-items : flex-end;
gap : 10%;
background-color : transparent;
`;
export const ContentButton = styled.button<{isSelect : boolean}> `
background-color : ${props => props.isSelect ? '#337DFF' : 'transparent'};
color : ${props => props.isSelect ? '#fff' : '#337DFF'};
border : 1px solid #337DFF;
border-radius : 4px;
padding : 4px 10px;
cursor : pointer;
display : flex;
justify-content : center;
align-items : center;
transition : .25s all;
&:hover {
opacity : .5;
}
`;
export const ContentTitle = styled.div `
width : 100%;
height : 20%;
border : none;
border-bottom : 1px solid #ddd;
......@@ -261,7 +298,6 @@ export const ContentTitle = styled.div `
justify-content : center;
align-items : center;
padding : 4% 0;
font-size : 22px;
font-weight : 600;
letter-spacing : 1px;
......@@ -281,16 +317,17 @@ export const ContentExplain = styled.div `
export const ContentBody = styled.div `
overflow : scroll;
height : 79%;
min-height : 60%;
max-height : 60%;
border : none;
padding : 0 0 0 3px;
display : flex;
flex-direction : column;
align-items : center;
padding : 0 0 0 3px;
&::-webkit-scrollbar {
width : 3px;
background-color : transparent;
......@@ -304,6 +341,7 @@ export const ContentBody = styled.div `
export const ContentInfoWrapper = styled.div `
width : 100%;
height : 10%;
border : none;
border-bottom : 1px solid #a0a0a0;
......@@ -313,7 +351,6 @@ export const ContentInfoWrapper = styled.div `
justify-content : center;
align-items : center;
padding : 12px 0px;
`;
export const ContentInfo = styled.div<{isLast : boolean}> `
......@@ -351,13 +388,15 @@ export const EachContentWrapper = styled.button `
padding : 10px 0px;
cursor : pointer;
:not(:disabled) {
cursor : pointer;
transition : .1s all;
transition : .1s all;
&:hover {
background-color : #337DFF;
color : #fff;
&:hover {
background-color : #337DFF;
color : #fff;
}
}
`;
......@@ -380,10 +419,33 @@ export const EachContentNm = styled.div<{isLast : boolean}> `
`;
export const AcceptButton = styled.button `
background-color : transparent;
color : #337DFF;
border : 1px solid #337DFF;
border-radius : 3px;
padding : 2px 10px;
display : flex;
justify-content : center;
align-items : center;
cursor : pointer;
transition : .25s all;
&:hover {
background-color : #337DFF;
color : #fff;
}
`;
export const NothingWrapper = styled.div `
height : 100%;
width : 100%;
border : none;
display : flex;
justify-content : center;
align-items : center;
......