박권수

feat. 처방 뷰 작성 완료

...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
18 "react-dom": "^17.0.2", 18 "react-dom": "^17.0.2",
19 "react-router-dom": "^5.2.0", 19 "react-router-dom": "^5.2.0",
20 "react-scripts": "4.0.3", 20 "react-scripts": "4.0.3",
21 + "react-spinners": "^0.11.0",
21 "recoil": "^0.4.0", 22 "recoil": "^0.4.0",
22 "recoil-persist": "^3.0.0", 23 "recoil-persist": "^3.0.0",
23 "styled-components": "^5.3.0", 24 "styled-components": "^5.3.0",
......
1 +import styled from 'styled-components';
2 +
3 +export const Container = styled.div `
4 + z-index : 9999;
5 +
6 + position : absolute;
7 +
8 + height : 110vh;
9 + width : 100%;
10 +
11 + display : flex;
12 + justify-content : center;
13 + align-items : center;
14 +
15 + background-color : rgba(0, 0, 0, .3);
16 +`;
...\ No newline at end of file ...\ No newline at end of file
1 +import React, { useEffect } from 'react';
2 +
3 +import { useRecoilValue } from 'recoil';
4 +import * as recoilItem from '../../util/recoilUtil';
5 +
6 +import * as styled from './LoadingStyled';
7 +import Loader from 'react-spinners/BeatLoader'
8 +
9 +const LoadingContainer = () => {
10 +
11 + const loading = useRecoilValue(recoilItem.loading);
12 +
13 + return (
14 + loading ?
15 + <styled.Container>
16 + <Loader color = '#337DFF' loading = {loading} size = {20}/>
17 + </styled.Container> : null
18 + )
19 +};
20 +
21 +export default LoadingContainer;
...\ No newline at end of file ...\ No newline at end of file
...@@ -13,4 +13,10 @@ export const userTypeCd = atom({ ...@@ -13,4 +13,10 @@ export const userTypeCd = atom({
13 key : 'userTypeCd', 13 key : 'userTypeCd',
14 default : 'NORMAL', 14 default : 'NORMAL',
15 effects_UNSTABLE : [persistAtom], 15 effects_UNSTABLE : [persistAtom],
16 +});
17 +
18 +export const loading = atom({
19 + key : 'loading',
20 + default : false,
21 + effects_UNSTABLE : [persistAtom],
16 }); 22 });
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -2,6 +2,7 @@ import React from "react"; ...@@ -2,6 +2,7 @@ import React from "react";
2 import { BrowserRouter, Route, Switch, Redirect } from 'react-router-dom'; 2 import { BrowserRouter, Route, Switch, Redirect } from 'react-router-dom';
3 3
4 import Error from '../components/error'; 4 import Error from '../components/error';
5 +import Loading from '../components/Loading';
5 import { LoginContainer } from "./login"; 6 import { LoginContainer } from "./login";
6 import { RegisterContainer } from './register'; 7 import { RegisterContainer } from './register';
7 import { MainContainer } from "./main"; 8 import { MainContainer } from "./main";
...@@ -12,6 +13,7 @@ const Router = () => { ...@@ -12,6 +13,7 @@ const Router = () => {
12 return ( 13 return (
13 <BrowserRouter> 14 <BrowserRouter>
14 <Error /> 15 <Error />
16 + <Loading />
15 <Switch> 17 <Switch>
16 <Route exact path = '/' component = {MainContainer}/> 18 <Route exact path = '/' component = {MainContainer}/>
17 <Route exact path = '/login' component = {LoginContainer}/> 19 <Route exact path = '/login' component = {LoginContainer}/>
......
...@@ -11,11 +11,14 @@ import * as Alert from '../../../util/alertMessage'; ...@@ -11,11 +11,14 @@ import * as Alert from '../../../util/alertMessage';
11 import { doctorApi, medicineApi } from '../../../api'; 11 import { doctorApi, medicineApi } from '../../../api';
12 12
13 13
14 +//toDo : Generate QR Code By Medicine Id
15 +
14 type DoctorMenuProps = RouteComponentProps 16 type DoctorMenuProps = RouteComponentProps
15 17
16 const DoctorMenuContainer = (props : DoctorMenuProps) => { 18 const DoctorMenuContainer = (props : DoctorMenuProps) => {
17 19
18 const token = useRecoilValue(recoilUtil.token); 20 const token = useRecoilValue(recoilUtil.token);
21 + const [loading, setLoading] = useRecoilState(recoilUtil.loading);
19 22
20 const [doctorInfo, setDoctorInfo] = useState<any>({ 23 const [doctorInfo, setDoctorInfo] = useState<any>({
21 doctorNm : '', 24 doctorNm : '',
...@@ -50,11 +53,13 @@ const DoctorMenuContainer = (props : DoctorMenuProps) => { ...@@ -50,11 +53,13 @@ const DoctorMenuContainer = (props : DoctorMenuProps) => {
50 53
51 const [prescribeModal, setPrescribeModal] = useState<boolean>(false); 54 const [prescribeModal, setPrescribeModal] = useState<boolean>(false);
52 const [searchMedicineKeyword, setSearchMedicineKeyword] = useState<string>(''); 55 const [searchMedicineKeyword, setSearchMedicineKeyword] = useState<string>('');
53 - const [medicineInfo, setMedicineInfo] = useState<any>(); 56 + const [medicineList, setMedicineList] = useState<any>([]);
57 + const [prescribeMedicine, setPrescribeMedicine] = useState<any>(null);
54 58
55 59
56 const fetchData = async() => { 60 const fetchData = async() => {
57 try { 61 try {
62 + setLoading(true);
58 const res = await doctorApi.getDoctorsInfo(token); 63 const res = await doctorApi.getDoctorsInfo(token);
59 if(res.statusText === 'OK') { 64 if(res.statusText === 'OK') {
60 const { doctorInfo } = res.data; 65 const { doctorInfo } = res.data;
...@@ -73,8 +78,10 @@ const DoctorMenuContainer = (props : DoctorMenuProps) => { ...@@ -73,8 +78,10 @@ const DoctorMenuContainer = (props : DoctorMenuProps) => {
73 setPatientList(res.data.patientList); 78 setPatientList(res.data.patientList);
74 }).catch(error => console.log(error)); 79 }).catch(error => console.log(error));
75 } 80 }
81 + setLoading(false);
76 } catch(e) { 82 } catch(e) {
77 console.log(e); 83 console.log(e);
84 + setLoading(false);
78 } 85 }
79 }; 86 };
80 87
...@@ -84,6 +91,7 @@ const DoctorMenuContainer = (props : DoctorMenuProps) => { ...@@ -84,6 +91,7 @@ const DoctorMenuContainer = (props : DoctorMenuProps) => {
84 91
85 const onFetchPatientDetail = async (patientId : string) => { 92 const onFetchPatientDetail = async (patientId : string) => {
86 try { 93 try {
94 + setLoading(true);
87 await doctorApi.getPatientDetail(token, patientId).then(res => { 95 await doctorApi.getPatientDetail(token, patientId).then(res => {
88 setPatientDetail(res.data); 96 setPatientDetail(res.data);
89 setInfo({ 97 setInfo({
...@@ -95,8 +103,10 @@ const DoctorMenuContainer = (props : DoctorMenuProps) => { ...@@ -95,8 +103,10 @@ const DoctorMenuContainer = (props : DoctorMenuProps) => {
95 patientInfo : res.data.info, 103 patientInfo : res.data.info,
96 }); 104 });
97 }).catch(err => console.log(err)); 105 }).catch(err => console.log(err));
106 + setLoading(false);
98 } catch(e) { 107 } catch(e) {
99 console.log(e); 108 console.log(e);
109 + setLoading(false);
100 } 110 }
101 }; 111 };
102 112
...@@ -112,12 +122,7 @@ const DoctorMenuContainer = (props : DoctorMenuProps) => { ...@@ -112,12 +122,7 @@ const DoctorMenuContainer = (props : DoctorMenuProps) => {
112 }); 122 });
113 setFilteringPatientList([]); 123 setFilteringPatientList([]);
114 setSearchPatientKeyword(''); 124 setSearchPatientKeyword('');
115 - setEditModal(false); 125 + onCloseModal();
116 - setEditPatientInfo('');
117 - setNewPatientRegisterModal(false);
118 - setNewPatientSearchId('');
119 - setNewPatientSearchResult(null);
120 - setPatientDetail(null);
121 }; 126 };
122 127
123 const onEditPatientInfo = (e : React.ChangeEvent<HTMLTextAreaElement>) => { 128 const onEditPatientInfo = (e : React.ChangeEvent<HTMLTextAreaElement>) => {
...@@ -149,7 +154,6 @@ const DoctorMenuContainer = (props : DoctorMenuProps) => { ...@@ -149,7 +154,6 @@ const DoctorMenuContainer = (props : DoctorMenuProps) => {
149 Alert.onError('환자의 특이사항을 기록하세요.', () => null); 154 Alert.onError('환자의 특이사항을 기록하세요.', () => null);
150 } 155 }
151 156
152 -
153 }; 157 };
154 158
155 159
...@@ -159,14 +163,18 @@ const DoctorMenuContainer = (props : DoctorMenuProps) => { ...@@ -159,14 +163,18 @@ const DoctorMenuContainer = (props : DoctorMenuProps) => {
159 163
160 const onSearchNewPatientByEmail = async () => { 164 const onSearchNewPatientByEmail = async () => {
161 try { 165 try {
166 + setLoading(true);
162 await doctorApi.searchPatientById(token, newPatientSearchId).then(res => { 167 await doctorApi.searchPatientById(token, newPatientSearchId).then(res => {
163 setNewPatientSearchResult(res.data); 168 setNewPatientSearchResult(res.data);
169 + setLoading(false);
164 }).catch(err => { 170 }).catch(err => {
165 console.log(err); 171 console.log(err);
172 + setLoading(false);
166 Alert.onError('검색 결과가 없습니다.', () => null); 173 Alert.onError('검색 결과가 없습니다.', () => null);
167 setNewPatientSearchResult(null); 174 setNewPatientSearchResult(null);
168 }); 175 });
169 } catch(e : any) { 176 } catch(e : any) {
177 + setLoading(false);
170 Alert.onError(e.response.data.error, () => null); 178 Alert.onError(e.response.data.error, () => null);
171 } 179 }
172 }; 180 };
...@@ -203,6 +211,8 @@ const DoctorMenuContainer = (props : DoctorMenuProps) => { ...@@ -203,6 +211,8 @@ const DoctorMenuContainer = (props : DoctorMenuProps) => {
203 setEditPatientInfo(''); 211 setEditPatientInfo('');
204 setPrescribeModal(false); 212 setPrescribeModal(false);
205 setSearchMedicineKeyword(''); 213 setSearchMedicineKeyword('');
214 + setMedicineList([]);
215 + setPrescribeMedicine(null);
206 }; 216 };
207 217
208 const onGoBottleDetail = (bottleId : number) => { 218 const onGoBottleDetail = (bottleId : number) => {
...@@ -214,16 +224,32 @@ const DoctorMenuContainer = (props : DoctorMenuProps) => { ...@@ -214,16 +224,32 @@ const DoctorMenuContainer = (props : DoctorMenuProps) => {
214 }; 224 };
215 225
216 const searchMedicine = async() => { 226 const searchMedicine = async() => {
227 + setMedicineList([]);
228 + setPrescribeMedicine(null);
217 try { 229 try {
230 + setLoading(true);
218 const res = await medicineApi.searchMedicine(token, searchMedicineKeyword); 231 const res = await medicineApi.searchMedicine(token, searchMedicineKeyword);
219 if(res.statusText === 'OK') { 232 if(res.statusText === 'OK') {
220 - setMedicineInfo(res.data); 233 + console.log(res.data.medicineList)
234 + setMedicineList(res.data.medicineList);
221 } 235 }
236 + setLoading(false);
222 } catch(e : any) { 237 } catch(e : any) {
223 Alert.onError(e.response.data.error, () => null); 238 Alert.onError(e.response.data.error, () => null);
224 } 239 }
225 }; 240 };
226 241
242 + const onPrescribeSubmit = async() => {
243 + //toDo : 처방해서, QR코드 생성
244 + Alert.onWarning('작업 중입니다.', () => null);
245 + };
246 +
247 + const onPrescribeCancel = () => {
248 + Alert.onCheck('취소하시면 작업중인 내용이 사라집니다.', () => {
249 + onCloseModal();
250 + }, () => null)
251 + };
252 +
227 253
228 useEffect(() => { 254 useEffect(() => {
229 if(!token || !token.length) { 255 if(!token || !token.length) {
...@@ -272,8 +298,12 @@ const DoctorMenuContainer = (props : DoctorMenuProps) => { ...@@ -272,8 +298,12 @@ const DoctorMenuContainer = (props : DoctorMenuProps) => {
272 setPrescribeModal = {setPrescribeModal} 298 setPrescribeModal = {setPrescribeModal}
273 searchMedicineKeyword = {searchMedicineKeyword} 299 searchMedicineKeyword = {searchMedicineKeyword}
274 onSetSearchMedicineKeyword = {onSetSearchMedicineKeyword} 300 onSetSearchMedicineKeyword = {onSetSearchMedicineKeyword}
275 - medicineInfo = {medicineInfo} 301 + medicineList = {medicineList}
276 searchMedicine = {searchMedicine} 302 searchMedicine = {searchMedicine}
303 + prescribeMedicine = {prescribeMedicine}
304 + setPrescribeMedicine = {setPrescribeMedicine}
305 + onPrescribeSubmit = {onPrescribeSubmit}
306 + onPrescribeCancel = {onPrescribeCancel}
277 307
278 newPatientSearchResult = {newPatientSearchResult} 308 newPatientSearchResult = {newPatientSearchResult}
279 /> 309 />
......
...@@ -49,8 +49,14 @@ interface DoctorMenuProps { ...@@ -49,8 +49,14 @@ interface DoctorMenuProps {
49 searchMedicineKeyword : string; 49 searchMedicineKeyword : string;
50 onSetSearchMedicineKeyword : React.ChangeEventHandler<HTMLInputElement>; 50 onSetSearchMedicineKeyword : React.ChangeEventHandler<HTMLInputElement>;
51 51
52 - medicineInfo : any; 52 + medicineList : any;
53 searchMedicine : () => void; 53 searchMedicine : () => void;
54 +
55 + prescribeMedicine : any;
56 + setPrescribeMedicine : (arg0 : any) => void;
57 +
58 + onPrescribeSubmit : () => void;
59 + onPrescribeCancel : () => void;
54 } 60 }
55 61
56 const DoctorMenuPresenter = (props : DoctorMenuProps) => { 62 const DoctorMenuPresenter = (props : DoctorMenuProps) => {
...@@ -180,7 +186,61 @@ const DoctorMenuPresenter = (props : DoctorMenuProps) => { ...@@ -180,7 +186,61 @@ const DoctorMenuPresenter = (props : DoctorMenuProps) => {
180 </styled.ModalClsButtonWrapper> 186 </styled.ModalClsButtonWrapper>
181 <styled.ModalContentWrapper> 187 <styled.ModalContentWrapper>
182 <styled.ModalContent> 188 <styled.ModalContent>
183 - 189 + <styled.MedicineSearchTitle>
190 + 약 검색
191 + </styled.MedicineSearchTitle>
192 + <styled.MedicineSearchInputWrapper>
193 + <styled.MedicineSearchInput
194 + placeholder = '증상, 또는 약 이름을 검색하세요.'
195 + onChange = {props.onSetSearchMedicineKeyword}
196 + value = {props.searchMedicineKeyword}
197 + />
198 + <styled.MedicineSearchButton
199 + onClick = {props.searchMedicine}
200 + >
201 + <styled.MedicineSearchButtonImg src = {lensImg}/>
202 + </styled.MedicineSearchButton>
203 + </styled.MedicineSearchInputWrapper>
204 + <styled.MedicineSearchResultWrapper>
205 + {
206 + props.medicineList.length ?
207 + props.medicineList.map((medicine : any) => {
208 + return (
209 + <styled.MedicineSearchResultEach
210 + key = {medicine.medicineId}
211 + onClick = {() => props.setPrescribeMedicine(medicine)}
212 + >
213 + <styled.MedicineSearchResultEachInfo>
214 + {medicine.name}
215 + </styled.MedicineSearchResultEachInfo>
216 + <styled.MedicineSearchButtonImg
217 + src = {
218 + props.prescribeMedicine && props.prescribeMedicine.medicineId === medicine.medicineId ?
219 + lensImg : addButton
220 + }
221 + />
222 + </styled.MedicineSearchResultEach>
223 + )
224 + }) :
225 + <styled.NothingWrapper style = {{fontSize : 13,}}>
226 + 🤔검색 결과가 없습니다.
227 + </styled.NothingWrapper>
228 + }
229 + </styled.MedicineSearchResultWrapper>
230 + <styled.MedicinePrescribeButtonWrapper>
231 + <styled.MedicinePrescribeButton
232 + isClose = {false}
233 + onClick = {props.onPrescribeSubmit}
234 + >
235 + 처방
236 + </styled.MedicinePrescribeButton>
237 + <styled.MedicinePrescribeButton
238 + isClose = {true}
239 + onClick = {props.onPrescribeCancel}
240 + >
241 + 취소
242 + </styled.MedicinePrescribeButton>
243 + </styled.MedicinePrescribeButtonWrapper>
184 </styled.ModalContent> 244 </styled.ModalContent>
185 </styled.ModalContentWrapper> 245 </styled.ModalContentWrapper>
186 <styled.ModalClsButtonWrapper/> 246 <styled.ModalClsButtonWrapper/>
......
...@@ -372,6 +372,166 @@ export const PatientInfoEditButton = styled.button ` ...@@ -372,6 +372,166 @@ export const PatientInfoEditButton = styled.button `
372 } 372 }
373 `; 373 `;
374 374
375 +export const MedicineSearchTitle = styled.div `
376 + font-size : 20px;
377 + font-weight : 700;
378 +
379 + color : #337DFF;
380 +`;
381 +
382 +export const MedicineSearchInputWrapper = styled.div `
383 + margin : 20px 0;
384 +
385 + display : flex;
386 + flex-direction : row;
387 +
388 + justify-content : space-between;
389 + align-items : center;
390 +
391 + width : 80%;
392 +
393 + border : none;
394 + border-bottom : 1px solid #343434;
395 +`;
396 +
397 +export const MedicineSearchInput = styled.input `
398 + width : 80%;
399 + border : none;
400 + padding : 10px;
401 +
402 + font-size : 15px;
403 + font-weight : 500;
404 +
405 + color : #343434;
406 +
407 + transition : .25s all;
408 +
409 + &::placeholder {
410 + color : #dedede;
411 + }
412 +`;
413 +
414 +export const MedicineSearchButton = styled.button `
415 + width : 30px;
416 + height : 30px;
417 +
418 + display : flex;
419 + justify-content : center;
420 + align-items : center;
421 +
422 + border : none;
423 + background : transparent;
424 +
425 + cursor : pointer;
426 +
427 + transition : .25s all;
428 +
429 + &:hover {
430 + opacity : .5;
431 + }
432 +
433 +`;
434 +
435 +export const MedicineSearchButtonImg = styled.img `
436 + height : 15px;
437 + width : 15px;
438 +
439 +`;
440 +
441 +export const MedicineSearchResultWrapper = styled.div `
442 + overflow : scroll;
443 +
444 + border : 1px solid;
445 + min-height : 180px;
446 + max-height : 180px;
447 +
448 + width : 80%;
449 +
450 + border : .5px solid #337DFF;
451 +
452 + &::-webkit-scrollbar {
453 + width : 3px;
454 + background-color : transparent;
455 + height : 1px;
456 + }
457 +
458 + &::-webkit-scrollbar-thumb {
459 + background-color : #337DFF;
460 + }
461 +`;
462 +
463 +export const MedicineSearchResultEach = styled.button `
464 + width : 100%;
465 + height : 36px;
466 +
467 + display : flex;
468 + flex-direction : row;
469 +
470 + align-items : center;
471 + justify-content : space-between;
472 +
473 + border : none;
474 + border-bottom : 1px solid #dedede;
475 +
476 + cursor : pointer;
477 +
478 + background : transparent;
479 + color : #343434;
480 +
481 + font-size : 15px;
482 + font-weight : 500;
483 +
484 + transition : .1s all;
485 +
486 + &:hover {
487 + background-color : #337DFF;
488 + color : #fff;
489 + }
490 +
491 +`;
492 +
493 +export const MedicineSearchResultEachInfo = styled.div `
494 + margin : 0 10px;
495 +`;
496 +
497 +export const MedicineSelectButtonImg = styled.img `
498 + height : 15px;
499 + width : 15px;
500 +`;
501 +
502 +export const MedicinePrescribeButtonWrapper = styled.div `
503 + margin : 20px 0 0 0;
504 +
505 + width : 40%;
506 +
507 + display : flex;
508 + flex-direction : row;
509 +
510 + justify-content : space-between;
511 +
512 +`;
513 +
514 +export const MedicinePrescribeButton = styled.button<{isClose : boolean}> `
515 + height : 40px;
516 + width : 100px;
517 +
518 + background-color : ${props => props.isClose ? 'transparent' : '#337DFF'};
519 + border : 1px solid ${props => props.isClose ? '#343434' : '#337DFF'};
520 + border-radius : 4px;
521 +
522 + font-size : 16px;
523 + font-weight : 600;
524 +
525 + color : ${props => props.isClose ? '#343434' : '#fff'};
526 +
527 + cursor : pointer;
528 +
529 + transition : .25s all;
530 +
531 + &:hover {
532 + opacity : .7;
533 + }
534 +`;
375 535
376 536
377 export const InfoAndSearchWrapper = styled.div ` 537 export const InfoAndSearchWrapper = styled.div `
......
This diff could not be displayed because it is too large.