박권수

feat. qrcode 생성

This diff is collapsed. Click to expand it.
......@@ -14,6 +14,7 @@
"highcharts": "^9.2.0",
"highcharts-react-official": "^3.0.0",
"moment": "^2.29.1",
"qrcode": "^1.4.4",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-router-dom": "^5.2.0",
......@@ -52,6 +53,7 @@
]
},
"devDependencies": {
"@types/qrcode": "^1.4.1",
"@types/react-router-dom": "^5.1.8",
"@types/styled-components": "^5.1.12",
"@types/validator": "^13.6.3",
......
......@@ -9,6 +9,12 @@ export const token = atom({
effects_UNSTABLE : [persistAtom],
});
export const userId = atom({
key : 'userId',
default : null,
effects_UNSTABLE : [persistAtom],
});
export const userTypeCd = atom({
key : 'userTypeCd',
default : 'NORMAL',
......
......@@ -23,6 +23,7 @@ const LoginContainer = (props : LoginProps) => {
});
const [token, setToken] = useRecoilState(recoilUtil.token);
const [userId, setUserId] = useRecoilState(recoilUtil.userId);
const [userTypeCd, setUserTypeCd] = useRecoilState(recoilUtil.userTypeCd);
......@@ -58,12 +59,13 @@ const LoginContainer = (props : LoginProps) => {
const result : any = await authApi.login(loginForm);
if(result.statusText === 'OK' && result.data.userTypeCd !== 'NORMAL') {
setToken(result.data.token);
setUserId(loginForm.userId);
setUserTypeCd(result.data.userTypeCd);
Alert.onSuccess('로그인 성공, 메인 화면으로 이동합니다.', () => props.history.push('/'));
} else if(result.data.userTypeCd === 'NORMAL') {
Alert.onError('권한이 없는 유저입니다.', () => props.history.push('/'));
}
} catch(e) {
} catch(e : any) {
Alert.onError(e.response.data.error, () => null);
}
......
......@@ -10,6 +10,8 @@ import * as Alert from '../../../util/alertMessage';
import { doctorApi, medicineApi } from '../../../api';
import QRCode from 'qrcode';
//toDo : Generate QR Code By Medicine Id
......@@ -18,6 +20,7 @@ type DoctorMenuProps = RouteComponentProps
const DoctorMenuContainer = (props : DoctorMenuProps) => {
const token = useRecoilValue(recoilUtil.token);
const userId = useRecoilValue(recoilUtil.userId);
const [loading, setLoading] = useRecoilState(recoilUtil.loading);
const [doctorInfo, setDoctorInfo] = useState<any>({
......@@ -52,9 +55,13 @@ const DoctorMenuContainer = (props : DoctorMenuProps) => {
const [newPatientSearchResult, setNewPatientSearchResult] = useState<any | null>(null);
const [prescribeModal, setPrescribeModal] = useState<boolean>(false);
const [prescribeModalStep, setPrescribeModalStep] = useState<number>(1);
const [searchMedicineKeyword, setSearchMedicineKeyword] = useState<string>('');
const [medicineList, setMedicineList] = useState<any>([]);
const [prescribeMedicine, setPrescribeMedicine] = useState<any>(null);
const [dosage, setDosage] = useState<string>('1');
const [qrcodeUrl, setQrcodeUrl] = useState<string | null>(null);
const fetchData = async() => {
......@@ -213,9 +220,11 @@ const DoctorMenuContainer = (props : DoctorMenuProps) => {
setEditModal(false);
setEditPatientInfo('');
setPrescribeModal(false);
setPrescribeModalStep(1);
setSearchMedicineKeyword('');
setMedicineList([]);
setPrescribeMedicine(null);
setDosage('1');
};
const onGoBottleDetail = (bottleId : number) => {
......@@ -233,7 +242,6 @@ const DoctorMenuContainer = (props : DoctorMenuProps) => {
setLoading(true);
const res = await medicineApi.searchMedicine(token, searchMedicineKeyword);
if(res.statusText === 'OK') {
console.log(res.data.medicineList)
setMedicineList(res.data.medicineList);
}
setLoading(false);
......@@ -242,9 +250,32 @@ const DoctorMenuContainer = (props : DoctorMenuProps) => {
}
};
const onSetDosage = (e : React.ChangeEvent<HTMLInputElement>) => {
setDosage(e.target.value);
};
const onSetNextStepPrescribe = () => {
if(prescribeMedicine) setPrescribeModalStep(prescribeModalStep + 1);
else Alert.onWarning('먼저 처방할 약을 선택해야 합니다.', () => null);
};
const onSetPrevStepPrescribe = () => {
if(prescribeModalStep > 1) setPrescribeModalStep(prescribeModalStep - 1);
};
const onPrescribeSubmit = async() => {
//toDo : 처방해서, QR코드 생성
Alert.onWarning('작업 중입니다.', () => null);
Alert.onCheck(`${prescribeMedicine.name}(일 복용량:${dosage})\n을 처방하시겠습니까?`, async () => {
setQrcodeUrl(await QRCode.toDataURL(`${prescribeMedicine.name}/${prescribeMedicine.medicineId}/${dosage}/${userId}`, {
type : "image/png",
color : {dark : '#337DFF', light : '#FFF'},
}));
Alert.onSuccess('처방 정보가 생성 되었습니다.', () => onSetNextStepPrescribe());
}, () => null);
};
const onPrintQrcode = async() => {
//toDo : QR코드 출력
Alert.onWarning('준비 중입니다.', () => null);
};
const onPrescribeCancel = () => {
......@@ -298,14 +329,21 @@ const DoctorMenuContainer = (props : DoctorMenuProps) => {
onCloseModal = {onCloseModal}
prescribeModal = {prescribeModal}
prescribeModalStep = {prescribeModalStep}
onSetNextStepPrescribe = {onSetNextStepPrescribe}
onSetPrevStepPrescribe = {onSetPrevStepPrescribe}
setPrescribeModal = {setPrescribeModal}
searchMedicineKeyword = {searchMedicineKeyword}
onSetSearchMedicineKeyword = {onSetSearchMedicineKeyword}
medicineList = {medicineList}
searchMedicine = {searchMedicine}
prescribeMedicine = {prescribeMedicine}
dosage = {dosage}
onSetDosage = {onSetDosage}
qrcodeUrl = {qrcodeUrl}
setPrescribeMedicine = {setPrescribeMedicine}
onPrescribeSubmit = {onPrescribeSubmit}
onPrintQrcode = {onPrintQrcode}
onPrescribeCancel = {onPrescribeCancel}
newPatientSearchResult = {newPatientSearchResult}
......
......@@ -48,6 +48,10 @@ interface DoctorMenuProps {
prescribeModal : boolean;
setPrescribeModal : any;
prescribeModalStep : number;
onSetNextStepPrescribe : () => void;
onSetPrevStepPrescribe : () => void;
searchMedicineKeyword : string;
onSetSearchMedicineKeyword : React.ChangeEventHandler<HTMLInputElement>;
......@@ -57,7 +61,13 @@ interface DoctorMenuProps {
prescribeMedicine : any;
setPrescribeMedicine : (arg0 : any) => void;
dosage : string;
onSetDosage : React.ChangeEventHandler<HTMLInputElement>;
qrcodeUrl : string | null;
onPrescribeSubmit : () => void;
onPrintQrcode : () => void;
onPrescribeCancel : () => void;
}
......@@ -189,8 +199,17 @@ const DoctorMenuPresenter = (props : DoctorMenuProps) => {
<styled.ModalContentWrapper>
<styled.ModalContent>
<styled.MedicineSearchTitle>
약 검색
{
props.prescribeModalStep === 1 ?
'약 검색' :
props.prescribeModalStep === 2 ?
'복용량 입력' :
'처방 정보 QR코드'
}
</styled.MedicineSearchTitle>
{
props.prescribeModalStep === 1 ?
<>
<styled.MedicineSearchInputWrapper>
<styled.MedicineSearchInput
placeholder = '증상, 또는 약 이름을 검색하세요.'
......@@ -210,7 +229,10 @@ const DoctorMenuPresenter = (props : DoctorMenuProps) => {
return (
<styled.MedicineSearchResultEach
key = {medicine.medicineId}
onClick = {() => props.setPrescribeMedicine(medicine)}
onClick = {() => props.setPrescribeMedicine(
props.prescribeMedicine && props.prescribeMedicine.medicineId === medicine.medicineId ?
null : medicine
)}
>
<styled.MedicineSearchResultEachInfo>
{medicine.name}
......@@ -229,13 +251,53 @@ const DoctorMenuPresenter = (props : DoctorMenuProps) => {
</styled.NothingWrapper>
}
</styled.MedicineSearchResultWrapper>
</>
:
props.prescribeModalStep === 2 ?
<styled.MedicineDosageSetWrapper>
<styled.MedicineDosageInfo>
*하루 복용량을 입력하세요.
</styled.MedicineDosageInfo>
<styled.MedicineDosageInput
value = {props.dosage}
onChange = {props.onSetDosage}
/>
</styled.MedicineDosageSetWrapper>
:
<styled.MedicineQRCodeWrapper>
<styled.MedicineQRCodeInfo>
*어플리케이션에서 QR코드를 스캔하면 약병에 약이 등록됩니다.
</styled.MedicineQRCodeInfo>
{
props.qrcodeUrl ?
<styled.MedicineQRCode src = {props.qrcodeUrl}/> : null
}
</styled.MedicineQRCodeWrapper>
}
<styled.MedicinePrescribeButtonWrapper>
{
props.prescribeModalStep === 1 ?
<styled.MedicinePrescribeButton
isClose = {false}
onClick = {props.onSetNextStepPrescribe}
>
다음 단계
</styled.MedicinePrescribeButton> :
props.prescribeModalStep === 2 ?
<styled.MedicinePrescribeButton
isClose = {false}
onClick = {props.onPrescribeSubmit}
>
처방
</styled.MedicinePrescribeButton>
:
<styled.MedicinePrescribeButton
isClose = {false}
onClick = {props.onPrintQrcode}
>
출력
</styled.MedicinePrescribeButton>
}
<styled.MedicinePrescribeButton
isClose = {true}
onClick = {props.onPrescribeCancel}
......
......@@ -436,6 +436,7 @@ export const MedicineSearchButtonImg = styled.img `
height : 15px;
width : 15px;
transition : .25s all;
`;
export const MedicineSearchResultWrapper = styled.div `
......@@ -499,6 +500,92 @@ export const MedicineSelectButtonImg = styled.img `
width : 15px;
`;
export const MedicineDosageSetWrapper = styled.div `
width : 80%;
display : flex;
flex-direction : column;
justify-content : center;
align-items : center;
border : none;
margin : 20px 0;
height : 200px;
`;
export const MedicineDosageInfo = styled.div `
font-size : 15px;
font-weight : 500;
color : #a0a0a0;
width : 100%;
margin : 0 0 20px 0;
border : none;
background-color : transparent;
text-align : center;
`;
export const MedicineDosageInput = styled.input.attrs({
type : 'number',
min : '1',
max : '3',
}) `
width : 40%;
padding : 10px 20px;
color : #337DFF;
font-size : 20px;
font-weight : 700;
border : none;
border-bottom : 1px solid #337DFF;
display : flex;
flex-direction : row;
text-align : center;
transition : .25s all;
`;
export const MedicineQRCodeWrapper = styled.div `
width : 80%;
height : 200px;
display : flex;
flex-direction : column;
justify-content : center;
align-items : center;
margin : 20px 0;
border : none;
`;
export const MedicineQRCodeInfo = styled.div `
font-size : 15px;
font-weight : 500;
color : #a0a0a0;
text-align : center;
`;
export const MedicineQRCode = styled.img `
margin : 10px 0 0 0;
height : 170px;
width : 170px;
`;
export const MedicinePrescribeButtonWrapper = styled.div `
margin : 20px 0 0 0;
......
This diff could not be displayed because it is too large.