박권수

Merge branch 'web'

...@@ -20,7 +20,8 @@ ...@@ -20,7 +20,8 @@
20 "@koa/cors": "^3.1.0", 20 "@koa/cors": "^3.1.0",
21 "firebase-admin": "^9.11.1", 21 "firebase-admin": "^9.11.1",
22 "moment": "^2.29.1", 22 "moment": "^2.29.1",
23 - "mqtt": "^4.2.6" 23 + "mqtt": "^4.2.6",
24 + "node-cron": "^3.0.0"
24 }, 25 },
25 "devDependencies": { 26 "devDependencies": {
26 "eslint": "^7.32.0" 27 "eslint": "^7.32.0"
......
...@@ -143,14 +143,11 @@ exports.getBottleInfo = async(ctx) => { ...@@ -143,14 +143,11 @@ exports.getBottleInfo = async(ctx) => {
143 const message = 'req'; 143 const message = 'req';
144 await Mqtt.mqttPublishMessage(client, { topic, message }); 144 await Mqtt.mqttPublishMessage(client, { topic, message });
145 145
146 - const bottleMedicine = await BottleMedicine.find({ bottleId }) 146 + const bottleMedicine = await BottleMedicine.findOne({ bottleId, useYn : 'Y' });
147 - .sort({ regDtm : 'desc' })
148 - .limit(1);
149 147
150 - if(bottleMedicine.length) { 148 + if(bottleMedicine) {
151 -
152 const takeMedicineHist = await TakeMedicineHist 149 const takeMedicineHist = await TakeMedicineHist
153 - .find({ bmId : bottleMedicine[0]._id }) 150 + .find({ bmId : bottleMedicine._id })
154 .sort({ takeDate : 'desc' }) 151 .sort({ takeDate : 'desc' })
155 .populate('bmId'); 152 .populate('bmId');
156 153
...@@ -208,12 +205,10 @@ exports.getBottleFeedback = async ctx => { ...@@ -208,12 +205,10 @@ exports.getBottleFeedback = async ctx => {
208 return; 205 return;
209 } 206 }
210 207
211 - const bottleMedicine = await BottleMedicine.find({ bottleId }) 208 + const bottleMedicine = await BottleMedicine.findOne({ bottleId, useYn : 'Y' });
212 - .sort({ regDtm : 'desc' })
213 - .limit(1);
214 209
215 - if(bottleMedicine.length) { 210 + if(bottleMedicine) {
216 - const feedbackList = await Feedback.find({ bmId : bottleMedicine[0]._id }) 211 + const feedbackList = await Feedback.find({ bmId : bottleMedicine._id })
217 .sort({ fdbDtm : 'desc' }) 212 .sort({ fdbDtm : 'desc' })
218 .populate('bmId'); 213 .populate('bmId');
219 214
...@@ -294,6 +289,7 @@ exports.setMedicine = async(ctx) => { ...@@ -294,6 +289,7 @@ exports.setMedicine = async(ctx) => {
294 bottleMedicine.setDoctorId(doctorId); 289 bottleMedicine.setDoctorId(doctorId);
295 } 290 }
296 291
292 + await BottleMedicine.updateMany({ bottleId }, { useYn : 'N '});
297 293
298 bottleMedicine.save(); 294 bottleMedicine.save();
299 295
......
...@@ -145,11 +145,12 @@ exports.getPatientDetail = async ctx => { ...@@ -145,11 +145,12 @@ exports.getPatientDetail = async ctx => {
145 145
146 const reqUserBmList = []; 146 const reqUserBmList = [];
147 await Promise.all(reqUserBottleList.map(async bottle => { 147 await Promise.all(reqUserBottleList.map(async bottle => {
148 - const bmList = await BottleMedicine.find({ 148 + const bm = await BottleMedicine.findOne({
149 doctorId : userId, 149 doctorId : userId,
150 bottleId : bottle.bottleId, 150 bottleId : bottle.bottleId,
151 - }).sort({ regDtm : 'desc' }).limit(1); 151 + useYn : 'Y',
152 - reqUserBmList.push(...bmList); 152 + });
153 + reqUserBmList.push(bm);
153 })); 154 }));
154 155
155 const bottleList = await Promise.all(reqUserBmList.map(async bottleMedicine => { 156 const bottleList = await Promise.all(reqUserBmList.map(async bottleMedicine => {
...@@ -207,7 +208,7 @@ exports.getBottleDetail = async ctx => { ...@@ -207,7 +208,7 @@ exports.getBottleDetail = async ctx => {
207 return; 208 return;
208 } 209 }
209 210
210 - const bottleMedicine = await BottleMedicine.findOne({ bottleId, doctorId : userId }); 211 + const bottleMedicine = await BottleMedicine.findOne({ bottleId, doctorId : userId, useYn : 'Y' });
211 if(!bottleMedicine) { 212 if(!bottleMedicine) {
212 ctx.status = 403; 213 ctx.status = 403;
213 ctx.body = { 214 ctx.body = {
...@@ -318,11 +319,9 @@ exports.writeReqBottleFeedback = async ctx => { ...@@ -318,11 +319,9 @@ exports.writeReqBottleFeedback = async ctx => {
318 return; 319 return;
319 } 320 }
320 321
321 - const bottleMedicine = await BottleMedicine.find({ bottleId, doctorId : userId }) 322 + const bottleMedicine = await BottleMedicine.findOne({ bottleId, doctorId : userId, useYn : 'Y' });
322 - .sort({ regDtm : 'desc' })
323 - .limit(1);
324 323
325 - if(!bottleMedicine.length) { 324 + if(!bottleMedicine) {
326 ctx.status = 403; 325 ctx.status = 403;
327 ctx.body = { 326 ctx.body = {
328 error : '약병에 대한 권한 없음' 327 error : '약병에 대한 권한 없음'
...@@ -332,7 +331,7 @@ exports.writeReqBottleFeedback = async ctx => { ...@@ -332,7 +331,7 @@ exports.writeReqBottleFeedback = async ctx => {
332 331
333 const newFeedback = new Feedback({ 332 const newFeedback = new Feedback({
334 fdbType, 333 fdbType,
335 - bmId : bottleMedicine[0]._id, 334 + bmId : bottleMedicine._id,
336 doctorId : userId, 335 doctorId : userId,
337 feedback, 336 feedback,
338 }); 337 });
......
...@@ -63,7 +63,7 @@ const bottleInfoUpdate = async(data) => { ...@@ -63,7 +63,7 @@ const bottleInfoUpdate = async(data) => {
63 humidity = parseFloat(humidity); 63 humidity = parseFloat(humidity);
64 balance = parseInt(balance); 64 balance = parseInt(balance);
65 65
66 - const bottleMedicine = await BottleMedicine.find({ bottleId }).sort((a, b) => a.regDtm < b.regDtm)[0]; 66 + const bottleMedicine = await BottleMedicine.findOne({ bottleId, useYn : 'Y' });
67 67
68 if(bottleMedicine) { 68 if(bottleMedicine) {
69 if(isOpen) { 69 if(isOpen) {
...@@ -83,7 +83,7 @@ const bottleInfoUpdate = async(data) => { ...@@ -83,7 +83,7 @@ const bottleInfoUpdate = async(data) => {
83 const transPublishingTopicAndMessage = async(bottleId) => { 83 const transPublishingTopicAndMessage = async(bottleId) => {
84 const topic = 'bottle/' + bottleId + '/stb'; 84 const topic = 'bottle/' + bottleId + '/stb';
85 85
86 - const bottleMedicine = await BottleMedicine.find({ bottleId }).sort((a, b) => a.regDtm < b.regDtm)[0]; 86 + const bottleMedicine = await BottleMedicine.findOne({ bottleId, useYn : 'Y' });
87 const takeMedicineHist = await TakeMedicineHist.find({ 87 const takeMedicineHist = await TakeMedicineHist.find({
88 bmId : bottleMedicine._id 88 bmId : bottleMedicine._id
89 }).sort((a, b) => a.takeDate < b.takeDate)[0]; 89 }).sort((a, b) => a.takeDate < b.takeDate)[0];
......
...@@ -28,11 +28,20 @@ const BottleMedicineSchema = new Schema({ ...@@ -28,11 +28,20 @@ const BottleMedicineSchema = new Schema({
28 required : true, 28 required : true,
29 default : Date.now, 29 default : Date.now,
30 }, 30 },
31 + useYn : {
32 + type : String,
33 + required : true,
34 + default : 'Y',
35 + },
31 }); 36 });
32 37
33 BottleMedicineSchema.methods.setDoctorId = function(doctorId) { 38 BottleMedicineSchema.methods.setDoctorId = function(doctorId) {
34 this.doctorId = doctorId; 39 this.doctorId = doctorId;
35 }; 40 };
36 41
42 +BottleMedicineSchema.methods.setUseYn = function(useYn) {
43 + this.useYn = useYn;
44 +};
45 +
37 46
38 module.exports = mongoose.model('BottleMedicine', BottleMedicineSchema); 47 module.exports = mongoose.model('BottleMedicine', BottleMedicineSchema);
...\ No newline at end of file ...\ No newline at end of file
......
1 +//toDO : Batch System
2 +/**
3 + * 21/09/14
4 + * Author : 박권수
5 + * 배치 시스템
6 + * 1) 매년 지나면 프로필의 Age를 +1
7 + * 2) Dosage에 따라, Push Notification 발송
8 + */
9 +
10 +const cron = require('node-cron');
11 +
12 +const Profile = require('../models/profile');
13 +const BottleMedicine = require('../models/bottleMedicine');
...\ No newline at end of file ...\ No newline at end of file
This diff is collapsed. Click to expand it.
...@@ -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",
......
...@@ -74,7 +74,7 @@ const Header = (props : HeaderProps) => { ...@@ -74,7 +74,7 @@ const Header = (props : HeaderProps) => {
74 </styled.HeaderLeftWrapper> 74 </styled.HeaderLeftWrapper>
75 <styled.HeaderCenterWrapper> 75 <styled.HeaderCenterWrapper>
76 <styled.TitleImg src = {headerImg} /> 76 <styled.TitleImg src = {headerImg} />
77 - <styled.Title>내 손 안의 주치의</styled.Title> 77 + <styled.Title>SMART MEDICINE BOX for Doctor</styled.Title>
78 </styled.HeaderCenterWrapper> 78 </styled.HeaderCenterWrapper>
79 <styled.HeaderRightWrapper> 79 <styled.HeaderRightWrapper>
80 { 80 {
......
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 : '',
...@@ -39,7 +42,7 @@ const DoctorMenuContainer = (props : DoctorMenuProps) => { ...@@ -39,7 +42,7 @@ const DoctorMenuContainer = (props : DoctorMenuProps) => {
39 const [searchPatientKeyword, setSearchPatientKeyword] = useState<string>(''); 42 const [searchPatientKeyword, setSearchPatientKeyword] = useState<string>('');
40 const [filteringPatientList, setFilteringPatientList] = useState<any>([]); 43 const [filteringPatientList, setFilteringPatientList] = useState<any>([]);
41 44
42 - const [patientDetail, setPatientDetail] = useState<any>(); 45 + const [patientDetail, setPatientDetail] = useState<any>(null);
43 46
44 const [editModal, setEditModal] = useState<boolean>(false); 47 const [editModal, setEditModal] = useState<boolean>(false);
45 const [editPatientInfo, setEditPatientInfo] = useState<string>(''); 48 const [editPatientInfo, setEditPatientInfo] = useState<string>('');
...@@ -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,13 +103,16 @@ const DoctorMenuContainer = (props : DoctorMenuProps) => { ...@@ -95,13 +103,16 @@ 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
103 const onInitialize = async () => { 113 const onInitialize = async () => {
104 await fetchData(); 114 await fetchData();
115 + setPatientDetail(null);
105 setInfo({ 116 setInfo({
106 infoType : 'DOCTOR', 117 infoType : 'DOCTOR',
107 userNm : doctorInfo.doctorNm, 118 userNm : doctorInfo.doctorNm,
...@@ -112,12 +123,7 @@ const DoctorMenuContainer = (props : DoctorMenuProps) => { ...@@ -112,12 +123,7 @@ const DoctorMenuContainer = (props : DoctorMenuProps) => {
112 }); 123 });
113 setFilteringPatientList([]); 124 setFilteringPatientList([]);
114 setSearchPatientKeyword(''); 125 setSearchPatientKeyword('');
115 - setEditModal(false); 126 + onCloseModal();
116 - setEditPatientInfo('');
117 - setNewPatientRegisterModal(false);
118 - setNewPatientSearchId('');
119 - setNewPatientSearchResult(null);
120 - setPatientDetail(null);
121 }; 127 };
122 128
123 const onEditPatientInfo = (e : React.ChangeEvent<HTMLTextAreaElement>) => { 129 const onEditPatientInfo = (e : React.ChangeEvent<HTMLTextAreaElement>) => {
...@@ -149,7 +155,6 @@ const DoctorMenuContainer = (props : DoctorMenuProps) => { ...@@ -149,7 +155,6 @@ const DoctorMenuContainer = (props : DoctorMenuProps) => {
149 Alert.onError('환자의 특이사항을 기록하세요.', () => null); 155 Alert.onError('환자의 특이사항을 기록하세요.', () => null);
150 } 156 }
151 157
152 -
153 }; 158 };
154 159
155 160
...@@ -159,14 +164,18 @@ const DoctorMenuContainer = (props : DoctorMenuProps) => { ...@@ -159,14 +164,18 @@ const DoctorMenuContainer = (props : DoctorMenuProps) => {
159 164
160 const onSearchNewPatientByEmail = async () => { 165 const onSearchNewPatientByEmail = async () => {
161 try { 166 try {
167 + setLoading(true);
162 await doctorApi.searchPatientById(token, newPatientSearchId).then(res => { 168 await doctorApi.searchPatientById(token, newPatientSearchId).then(res => {
163 setNewPatientSearchResult(res.data); 169 setNewPatientSearchResult(res.data);
170 + setLoading(false);
164 }).catch(err => { 171 }).catch(err => {
165 console.log(err); 172 console.log(err);
173 + setLoading(false);
166 Alert.onError('검색 결과가 없습니다.', () => null); 174 Alert.onError('검색 결과가 없습니다.', () => null);
167 setNewPatientSearchResult(null); 175 setNewPatientSearchResult(null);
168 }); 176 });
169 } catch(e : any) { 177 } catch(e : any) {
178 + setLoading(false);
170 Alert.onError(e.response.data.error, () => null); 179 Alert.onError(e.response.data.error, () => null);
171 } 180 }
172 }; 181 };
...@@ -203,6 +212,8 @@ const DoctorMenuContainer = (props : DoctorMenuProps) => { ...@@ -203,6 +212,8 @@ const DoctorMenuContainer = (props : DoctorMenuProps) => {
203 setEditPatientInfo(''); 212 setEditPatientInfo('');
204 setPrescribeModal(false); 213 setPrescribeModal(false);
205 setSearchMedicineKeyword(''); 214 setSearchMedicineKeyword('');
215 + setMedicineList([]);
216 + setPrescribeMedicine(null);
206 }; 217 };
207 218
208 const onGoBottleDetail = (bottleId : number) => { 219 const onGoBottleDetail = (bottleId : number) => {
...@@ -214,16 +225,32 @@ const DoctorMenuContainer = (props : DoctorMenuProps) => { ...@@ -214,16 +225,32 @@ const DoctorMenuContainer = (props : DoctorMenuProps) => {
214 }; 225 };
215 226
216 const searchMedicine = async() => { 227 const searchMedicine = async() => {
228 + setMedicineList([]);
229 + setPrescribeMedicine(null);
217 try { 230 try {
231 + setLoading(true);
218 const res = await medicineApi.searchMedicine(token, searchMedicineKeyword); 232 const res = await medicineApi.searchMedicine(token, searchMedicineKeyword);
219 if(res.statusText === 'OK') { 233 if(res.statusText === 'OK') {
220 - setMedicineInfo(res.data); 234 + console.log(res.data.medicineList)
235 + setMedicineList(res.data.medicineList);
221 } 236 }
237 + setLoading(false);
222 } catch(e : any) { 238 } catch(e : any) {
223 Alert.onError(e.response.data.error, () => null); 239 Alert.onError(e.response.data.error, () => null);
224 } 240 }
225 }; 241 };
226 242
243 + const onPrescribeSubmit = async() => {
244 + //toDo : 처방해서, QR코드 생성
245 + Alert.onWarning('작업 중입니다.', () => null);
246 + };
247 +
248 + const onPrescribeCancel = () => {
249 + Alert.onCheck('취소하시면 작업중인 내용이 사라집니다.', () => {
250 + onCloseModal();
251 + }, () => null)
252 + };
253 +
227 254
228 useEffect(() => { 255 useEffect(() => {
229 if(!token || !token.length) { 256 if(!token || !token.length) {
...@@ -272,8 +299,12 @@ const DoctorMenuContainer = (props : DoctorMenuProps) => { ...@@ -272,8 +299,12 @@ const DoctorMenuContainer = (props : DoctorMenuProps) => {
272 setPrescribeModal = {setPrescribeModal} 299 setPrescribeModal = {setPrescribeModal}
273 searchMedicineKeyword = {searchMedicineKeyword} 300 searchMedicineKeyword = {searchMedicineKeyword}
274 onSetSearchMedicineKeyword = {onSetSearchMedicineKeyword} 301 onSetSearchMedicineKeyword = {onSetSearchMedicineKeyword}
275 - medicineInfo = {medicineInfo} 302 + medicineList = {medicineList}
276 searchMedicine = {searchMedicine} 303 searchMedicine = {searchMedicine}
304 + prescribeMedicine = {prescribeMedicine}
305 + setPrescribeMedicine = {setPrescribeMedicine}
306 + onPrescribeSubmit = {onPrescribeSubmit}
307 + onPrescribeCancel = {onPrescribeCancel}
277 308
278 newPatientSearchResult = {newPatientSearchResult} 309 newPatientSearchResult = {newPatientSearchResult}
279 /> 310 />
......
...@@ -8,6 +8,8 @@ const lensImg = '/static/img/lens.png'; ...@@ -8,6 +8,8 @@ const lensImg = '/static/img/lens.png';
8 const closeButton = '/static/img/close.png'; 8 const closeButton = '/static/img/close.png';
9 const edit = '/static/img/edit.png'; 9 const edit = '/static/img/edit.png';
10 const refreshing = '/static/img/refreshing.png'; 10 const refreshing = '/static/img/refreshing.png';
11 +const check = '/static/img/check.png';
12 +const uncheck = '/static/img/uncheck.png'
11 13
12 14
13 interface DoctorMenuProps { 15 interface DoctorMenuProps {
...@@ -49,8 +51,14 @@ interface DoctorMenuProps { ...@@ -49,8 +51,14 @@ interface DoctorMenuProps {
49 searchMedicineKeyword : string; 51 searchMedicineKeyword : string;
50 onSetSearchMedicineKeyword : React.ChangeEventHandler<HTMLInputElement>; 52 onSetSearchMedicineKeyword : React.ChangeEventHandler<HTMLInputElement>;
51 53
52 - medicineInfo : any; 54 + medicineList : any;
53 searchMedicine : () => void; 55 searchMedicine : () => void;
56 +
57 + prescribeMedicine : any;
58 + setPrescribeMedicine : (arg0 : any) => void;
59 +
60 + onPrescribeSubmit : () => void;
61 + onPrescribeCancel : () => void;
54 } 62 }
55 63
56 const DoctorMenuPresenter = (props : DoctorMenuProps) => { 64 const DoctorMenuPresenter = (props : DoctorMenuProps) => {
...@@ -180,7 +188,61 @@ const DoctorMenuPresenter = (props : DoctorMenuProps) => { ...@@ -180,7 +188,61 @@ const DoctorMenuPresenter = (props : DoctorMenuProps) => {
180 </styled.ModalClsButtonWrapper> 188 </styled.ModalClsButtonWrapper>
181 <styled.ModalContentWrapper> 189 <styled.ModalContentWrapper>
182 <styled.ModalContent> 190 <styled.ModalContent>
183 - 191 + <styled.MedicineSearchTitle>
192 + 약 검색
193 + </styled.MedicineSearchTitle>
194 + <styled.MedicineSearchInputWrapper>
195 + <styled.MedicineSearchInput
196 + placeholder = '증상, 또는 약 이름을 검색하세요.'
197 + onChange = {props.onSetSearchMedicineKeyword}
198 + value = {props.searchMedicineKeyword}
199 + />
200 + <styled.MedicineSearchButton
201 + onClick = {props.searchMedicine}
202 + >
203 + <styled.MedicineSearchButtonImg src = {lensImg}/>
204 + </styled.MedicineSearchButton>
205 + </styled.MedicineSearchInputWrapper>
206 + <styled.MedicineSearchResultWrapper>
207 + {
208 + props.medicineList.length ?
209 + props.medicineList.map((medicine : any) => {
210 + return (
211 + <styled.MedicineSearchResultEach
212 + key = {medicine.medicineId}
213 + onClick = {() => props.setPrescribeMedicine(medicine)}
214 + >
215 + <styled.MedicineSearchResultEachInfo>
216 + {medicine.name}
217 + </styled.MedicineSearchResultEachInfo>
218 + <styled.MedicineSearchButtonImg
219 + src = {
220 + props.prescribeMedicine && props.prescribeMedicine.medicineId === medicine.medicineId ?
221 + check : uncheck
222 + }
223 + />
224 + </styled.MedicineSearchResultEach>
225 + )
226 + }) :
227 + <styled.NothingWrapper style = {{fontSize : 13,}}>
228 + 🤔검색 결과가 없습니다.
229 + </styled.NothingWrapper>
230 + }
231 + </styled.MedicineSearchResultWrapper>
232 + <styled.MedicinePrescribeButtonWrapper>
233 + <styled.MedicinePrescribeButton
234 + isClose = {false}
235 + onClick = {props.onPrescribeSubmit}
236 + >
237 + 처방
238 + </styled.MedicinePrescribeButton>
239 + <styled.MedicinePrescribeButton
240 + isClose = {true}
241 + onClick = {props.onPrescribeCancel}
242 + >
243 + 취소
244 + </styled.MedicinePrescribeButton>
245 + </styled.MedicinePrescribeButtonWrapper>
184 </styled.ModalContent> 246 </styled.ModalContent>
185 </styled.ModalContentWrapper> 247 </styled.ModalContentWrapper>
186 <styled.ModalClsButtonWrapper/> 248 <styled.ModalClsButtonWrapper/>
...@@ -303,7 +365,7 @@ const DoctorMenuPresenter = (props : DoctorMenuProps) => { ...@@ -303,7 +365,7 @@ const DoctorMenuPresenter = (props : DoctorMenuProps) => {
303 </styled.InfoAndSearchWrapper> 365 </styled.InfoAndSearchWrapper>
304 <styled.BottleListWrapper> 366 <styled.BottleListWrapper>
305 { 367 {
306 - props.patientDetail && props.patientDetail.bottleList ? 368 + props.patientDetail && props.patientDetail.bottleList.length ?
307 props.patientDetail.bottleList.map((bottle : any) => { 369 props.patientDetail.bottleList.map((bottle : any) => {
308 return ( 370 return (
309 <styled.EachBottleWrapper 371 <styled.EachBottleWrapper
...@@ -316,6 +378,11 @@ const DoctorMenuPresenter = (props : DoctorMenuProps) => { ...@@ -316,6 +378,11 @@ const DoctorMenuPresenter = (props : DoctorMenuProps) => {
316 </styled.EachBottleWrapper> 378 </styled.EachBottleWrapper>
317 ) 379 )
318 }) : 380 }) :
381 + props.patientDetail && !props.patientDetail.bottleList.length ?
382 + <styled.NothingWrapper>
383 + 🤔관리하고 있는 환자의 약병이 없습니다.
384 + </styled.NothingWrapper>
385 + :
319 <styled.NothingWrapper> 386 <styled.NothingWrapper>
320 🤔먼저 환자를 선택하세요. 387 🤔먼저 환자를 선택하세요.
321 </styled.NothingWrapper> 388 </styled.NothingWrapper>
......
...@@ -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 `
...@@ -508,6 +668,12 @@ export const NewPatientButton = styled.button ` ...@@ -508,6 +668,12 @@ export const NewPatientButton = styled.button `
508 background-color : #337DFF; 668 background-color : #337DFF;
509 color : #fff; 669 color : #fff;
510 } 670 }
671 +
672 + &:disabled {
673 + cursor : default;
674 + background-color : #337DFF;
675 + color : #fff;
676 + }
511 `; 677 `;
512 678
513 export const SearchAndDetailWrapper = styled.div ` 679 export const SearchAndDetailWrapper = styled.div `
......
This diff could not be displayed because it is too large.