박권수

feat. manager view

......@@ -16,7 +16,7 @@ export default {
},
});
},
acceotDoctorRegReq : (token : RecoilState<any>, Data : any) => {
acceptDoctorRegReq : (token : RecoilState<any>, Data : any) => {
return client.post('/manage/doctor/accept', Data, {
headers : {
Authorization : token,
......
......@@ -43,4 +43,18 @@ export const onCheck = (text : string, confirmAction : () => void, denyAction :
denyAction();
}
});
}
\ No newline at end of file
};
export const onWarning = (text : string, confirmAction : () => void) => {
Swal.fire({
title : '주의',
icon : 'warning',
text,
confirmButtonText : '확인',
confirmButtonColor : '#337DFF',
}).then(res => {
if(res.isConfirmed) {
confirmAction();
}
});
};
\ No newline at end of file
......
......@@ -120,7 +120,6 @@ export const ModalContent = styled.div `
`;
export const MedicineNameWrapper = styled.div `
flex : 1
border : none;
border-bottom : 1px solid #ddd;
width : 100%;
......
......@@ -17,7 +17,7 @@ const LoginPresenter = (props : LoginProps) => {
return (
<styled.Container>
<styled.LoginWrapper>
<styled.LoginTitle>🩺로그인</styled.LoginTitle>
<styled.LoginTitle>🩺 로그인</styled.LoginTitle>
<styled.LoginInputWrapper>
<styled.LoginEachInputWrapper>
<styled.LoginInputText>
......
......@@ -96,6 +96,10 @@ export const LoginInput = styled.input `
border-radius : 3px;
width : 100%;
align-self : center;
&::placeholder {
color : #ddd;
}
`;
export const RegisterButtonWrapper = styled.div `
......
......@@ -5,15 +5,108 @@ import { RouteComponentProps} from 'react-router-dom';
import { useRecoilValue } from "recoil";
import * as recoilUtil from '../../../util/recoilUtil';
import * as Alert from '../../../util/alertMessage';
import ManagerMenuPresenter from "./ManagerMenuPresenter";
import { managerApi } from '../../../api';
type ManagerMenuProps = RouteComponentProps;
const ManagerMenuContainer = (props : ManagerMenuProps) => {
const token = useRecoilValue(recoilUtil.token);
const [doctorRegReqList, setDoctorRegReqList] = useState<any>([]);
const [doctorDetail, setDoctorDetail] = useState<any>({});
const [modalUp, setModalUp] = useState<boolean>(false);
const fetchData = async() => {
setModalUp(false);
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);
})
} catch(e) {
Alert.onError(e.response.data.error, () => null);
}
};
const onViewDetailReq = async (doctorId : string) => {
try {
await managerApi.getDoctorRegReqDetail(token, doctorId)
.then((res : any) => {
if(res.statusText === 'OK') {
setDoctorDetail(res.data.doctorInfo);
setModalUp(true);
}
})
} catch(e) {
Alert.onError(e.response.data.error, () => setModalUp(false));
}
};
//회원 가입 수락
const onAcceptRequest = () => {
const onAccept = async() => {
try {
await managerApi.acceptDoctorRegReq(token, doctorDetail)
.then((res : any) => {
if(res.statusText === 'OK') {
Alert.onSuccess('회원 등록이 완료되었습니다.', fetchData);
}
})
} catch(e) {
Alert.onError(e.response.data.error, () => setModalUp(false));
}
};
Alert.onCheck('회원 가입 요청을 수락하시겠습니까?', onAccept, () => null);
};
//회원 가입 거절
const onRejectRequest = () => {
const onReject = async() => {
try {
await managerApi.rejectDoctorRegReq(token, doctorDetail)
.then((res : any) => {
if(res.statusText === 'OK') {
Alert.onSuccess('회원 등록이 취소되었습니다.', fetchData);
}
})
} catch(e) {
Alert.onError(e.response.data.error, () => setModalUp(false));
}
};
Alert.onCheck('회원 가입 요청을 취소하시겠습니까?', onReject, () => null);
};
useEffect(() => {
fetchData();
}, []);
return (
<ManagerMenuPresenter
doctorRegReqList = {doctorRegReqList}
doctorDetail = {doctorDetail}
modalUp = {modalUp}
setModalUp = {setModalUp}
onViewDetailReq = {onViewDetailReq}
onAcceptRequest = {onAcceptRequest}
onRejectRequest = {onRejectRequest}
/>
);
};
......
......@@ -2,14 +2,144 @@ import React from 'react';
import * as styled from './ManagerMenuStyled';
const closeButton = '/static/img/close.png';
// eslint-disable-next-line @typescript-eslint/no-empty-interface
interface ManagerMenuProps {}
interface ManagerMenuProps {
doctorRegReqList : any[];
doctorDetail : any;
modalUp : boolean;
setModalUp : any;
onViewDetailReq : (arg0 : string) => void;
onAcceptRequest : () => void;
onRejectRequest : () => void;
}
const ManagerMenuPresenter = (props : ManagerMenuProps) => {
return (
<styled.Container>
관리자 메뉴
{
props.modalUp ?
<styled.ModalContainer>
<styled.ModalClsButtonWrapper>
<styled.ModalClsButton
onClick = {() => props.setModalUp(false)}
>
<styled.ModalClsButtonImg src = {closeButton}/>
<styled.ModalClsButtonText>닫기</styled.ModalClsButtonText>
</styled.ModalClsButton>
</styled.ModalClsButtonWrapper>
<styled.ModalContentWrapper>
<styled.ModalContent>
<styled.ModalTitleWrapper>
<styled.ModalTitle>가입 요청 정보</styled.ModalTitle>
</styled.ModalTitleWrapper>
<styled.ModalBodyWrapper>
<styled.ModalBodyLeftAndRight>
<styled.ModalInfoWrapper>
<styled.ModalInfoExplain>의사 자격 번호</styled.ModalInfoExplain>
<styled.ModalInfo>{props.doctorDetail.info.doctorLicense}</styled.ModalInfo>
</styled.ModalInfoWrapper>
<styled.ModalInfoWrapper>
<styled.ModalInfoExplain>이름</styled.ModalInfoExplain>
<styled.ModalInfo>{props.doctorDetail.info.doctorNm}</styled.ModalInfo>
</styled.ModalInfoWrapper>
<styled.ModalInfoWrapper>
<styled.ModalInfoExplain>연락처</styled.ModalInfoExplain>
<styled.ModalInfo>{props.doctorDetail.info.contact}</styled.ModalInfo>
</styled.ModalInfoWrapper>
</styled.ModalBodyLeftAndRight>
<styled.ModalBodyLeftAndRight>
<styled.ModalInfoWrapper>
<styled.ModalInfoExplain>전문 분야</styled.ModalInfoExplain>
<styled.ModalInfo>{props.doctorDetail.info.doctorType}</styled.ModalInfo>
</styled.ModalInfoWrapper>
<styled.ModalInfoWrapper>
<styled.ModalInfoExplain>병원명</styled.ModalInfoExplain>
<styled.ModalInfo>{props.doctorDetail.info.hospitalNm}</styled.ModalInfo>
</styled.ModalInfoWrapper>
<styled.ModalInfoWrapper>
<styled.ModalInfoExplain>병원 주소</styled.ModalInfoExplain>
<styled.ModalInfo>{props.doctorDetail.info.hospitalAddr}</styled.ModalInfo>
</styled.ModalInfoWrapper>
</styled.ModalBodyLeftAndRight>
</styled.ModalBodyWrapper>
<styled.ModalButtonWrapper>
<styled.ModalButton
onClick = {props.onAcceptRequest}
isAccept = {true}
>
수락
</styled.ModalButton>
<styled.ModalButton
onClick = {props.onRejectRequest}
isAccept = {false}
>
거절
</styled.ModalButton>
</styled.ModalButtonWrapper>
</styled.ModalContent>
</styled.ModalContentWrapper>
<styled.ModalClsButtonWrapper/>
</styled.ModalContainer> : null
}
<styled.ContentWrapper>
<styled.ContentTitle>
가입 대기 중 의사 회원
<styled.ContentExplain>
*클릭하면 상세정보를 확인할 수 있습니다.
</styled.ContentExplain>
</styled.ContentTitle>
<styled.ContentBody>
<styled.ContentInfoWrapper>
<styled.ContentInfo
isLast = {false}
>
분야
</styled.ContentInfo>
<styled.ContentInfo
isLast = {false}
>
이름
</styled.ContentInfo>
<styled.ContentInfo
isLast = {true}
>
이메일
</styled.ContentInfo>
</styled.ContentInfoWrapper>
{
props.doctorRegReqList.map((doctor : any) => {
return (
<styled.EachContentWrapper
key = {doctor.doctorId}
onClick = {() => props.onViewDetailReq(doctor.doctorId)}
>
<styled.EachContentNm
isLast = {false}
>
{doctor.info.doctorType}
</styled.EachContentNm>
<styled.EachContentNm
isLast = {false}
>
{doctor.info.doctorNm}
</styled.EachContentNm>
<styled.EachContentNm
isLast = {true}
>
{doctor.doctorId}
</styled.EachContentNm>
</styled.EachContentWrapper>
)
})
}
</styled.ContentBody>
</styled.ContentWrapper>
</styled.Container>
)
};
......
import styled from 'styled-components';
import styled, { keyframes } from 'styled-components';
const ModalOn = keyframes `
0% {
background-color : rgba(52, 52, 52, .0);
}
20% {
background-color : rgba(52, 52, 52, .2);
}
40% {
background-color : rgba(52, 52, 52, .4);
}
60% {
background-color : rgba(52, 52, 52, .5);
}
80% {
background-color : rgba(52, 52, 52, .6);
}
100% {
background-color : rgba(52, 52, 52, .7);
}
`;
export const Container = styled.div `
width : 100%;
height : 80vh;
display : flex;
justify-content : center;
align-items : center;
`;
export const ModalContainer = styled.div `
height : 100%;
width : 100%;
z-index : 99;
position : absolute;
display : flex;
flex-direction : column;
animation : ${ModalOn} .5s;
background-color : rgba(52, 52, 52, .7);
`;
export const ModalClsButtonWrapper = styled.div `
flex : 1;
display : flex;
justify-content : flex-end;
align-items : center;
padding : 0 20px;
border : none;
background-color : transprent;
`;
export const ModalClsButton = styled.button `
border : none;
background-color : transparent;
cursor : pointer;
color : #fff;
display : flex;
flex-direction : row;
justify-content : center;
align-items : center;
transition : .25s all;
&:hover {
opacity : .5;
}
`;
export const ModalClsButtonImg = styled.img `
height : 20px;
width : 20px;
margin : 0 10px 0 0;
`;
export const ModalClsButtonText = styled.div `
font-size : 18px;
font-weight : 700;
`;
export const ModalContentWrapper = styled.div `
flex : 8;
display : flex;
flex-direction : column;
justify-content : center;
align-items : center;
border : none;
`;
export const ModalContent = styled.div `
width : 700px;
height : 500px;
background-color : #fff;
border : 1.2px solid #337DFF;
border-radius : 5px;
display : flex;
flex-direction : column;
// justify-content : center;
align-items : center;
`;
export const ModalTitleWrapper = styled.div `
flex : 1;
border : none;
border-bottom : 1px solid #ddd;
width : 100%;
display : flex;
flex-direction : column;
justify-content : center;
align-items : center;
`;
export const ModalTitle = styled.div `
font-size : 20px;
font-weight : 700;
letter-spacing : 1px;
color : #337DFF;
`;
export const ModalBodyWrapper = styled.div `
flex : 5;
width : 100%;
border : none;
display : flex;
flex-direction : row;
`;
export const ModalBodyLeftAndRight = styled.div `
flex : 1;
border : none;
padding : 20px;
display : flex;
flex-direction : column;
justify-content :center;
align-items : center;
`;
export const ModalInfoWrapper = styled.div `
flex : 1;
border : none;
width : 80%;
display : flex;
flex-direction : column;
justify-content : center;
align-items : flex-start;
`;
export const ModalInfoExplain = styled.div `
font-size : 16px;
font-weight : 500;
letter-spacing : 1px;
border : none;
border-bottom : 1px solid #337DFF;
color : #337DFF;
padding : 2px 5px;
`;
export const ModalInfo = styled.div `
margin : 5px 0 20px 0;
font-size : 20px;
font-weight : 700;
`;
export const ModalButtonWrapper = styled.div `
flex : 1.5;
display : flex;
flex-direction : row;
justify-content : center;
align-items : center;
border : none
`;
export const ModalButton = styled.button<{isAccept : boolean}> `
margin : 0 30px;
border-radius : 3px;
border : 1px solid #337DFF;
background-color : ${props => props.isAccept ? '#337DFF' : 'transparent'};
color : ${props => props.isAccept ? '#fff' : '#337DFF'};
font-size : 18px;
font-weight : 600;
letter-spacing : 1px;
padding : 10px 40px;
display : flex;
justify-content : center;
align-items : center;
cursor : pointer;
transition : .25s all;
&:hover {
background-color : #343434;
color : #fff;
border : 1px solid #343434;
}
`;
export const ContentWrapper = styled.div `
height : 80%;
width : 60%;
border : 1px solid #ddd;
border-radius : 4px;
box-shadow: 0px 0px 10px #a0a0a0;
`;
export const ContentTitle = styled.div `
width : 100%;
border : none;
border-bottom : 1px solid #ddd;
display : flex;
flex-direction : column;
justify-content : center;
align-items : center;
padding : 4% 0;
font-size : 22px;
font-weight : 600;
letter-spacing : 1px;
color : #343434;
`;
export const ContentExplain = styled.div `
margin : 2px 0 0 0;
font-size : 14px;
color : #a0a0a0;
font-weight : 500;
letter-spacing : 1px;
`;
export const ContentBody = styled.div `
overflow : scroll;
height : 79%;
border : none;
padding : 0 0 0 3px;
display : flex;
flex-direction : column;
align-items : center;
&::-webkit-scrollbar {
width : 3px;
background-color : transparent;
height : 0px;
}
&::-webkit-scrollbar-thumb {
background-color : #337DFF;
}
`;
export const ContentInfoWrapper = styled.div `
width : 100%;
border : none;
border-bottom : 1px solid #a0a0a0;
display : flex;
flex-direction : row;
justify-content : center;
align-items : center;
padding : 12px 0px;
`;
export const ContentInfo = styled.div<{isLast : boolean}> `
flex : 1;
display : flex;
flex-direction : row;
justify-content : center;
align-items : center;
font-size : 16px;
font-weight : 600;
color : #377DFF;
border : none;
border-right : ${props => props.isLast ? '1px solid transparent' : '1px solid #ddd'};
`;
export const EachContentWrapper = styled.button `
width : 100%;
border : none;
border-bottom : 1px solid #ddd;
background-color : transparent;
display : flex;
flex-direction : row;
justify-content : center;
align-items : center;
color : #343434;
padding : 10px 0px;
cursor : pointer;
transition : .1s all;
&:hover {
background-color : #337DFF;
color : #fff;
}
`;
export const EachContentNm = styled.div<{isLast : boolean}> `
flex : 1;
display : flex;
flex-direction : row;
justify-content : center;
align-items : center;
font-size : 14px;
font-weight : 500;
border : none;
border-right : ${props => props.isLast ? '1px solid transparent' : '1px solid #ddd'};
`;
\ No newline at end of file
......