Showing
8 changed files
with
203 additions
and
6 deletions
This diff is collapsed. Click to expand it.
... | @@ -14,6 +14,7 @@ | ... | @@ -14,6 +14,7 @@ |
14 | "highcharts": "^9.2.0", | 14 | "highcharts": "^9.2.0", |
15 | "highcharts-react-official": "^3.0.0", | 15 | "highcharts-react-official": "^3.0.0", |
16 | "moment": "^2.29.1", | 16 | "moment": "^2.29.1", |
17 | + "qrcode": "^1.4.4", | ||
17 | "react": "^17.0.2", | 18 | "react": "^17.0.2", |
18 | "react-dom": "^17.0.2", | 19 | "react-dom": "^17.0.2", |
19 | "react-router-dom": "^5.2.0", | 20 | "react-router-dom": "^5.2.0", |
... | @@ -52,6 +53,7 @@ | ... | @@ -52,6 +53,7 @@ |
52 | ] | 53 | ] |
53 | }, | 54 | }, |
54 | "devDependencies": { | 55 | "devDependencies": { |
56 | + "@types/qrcode": "^1.4.1", | ||
55 | "@types/react-router-dom": "^5.1.8", | 57 | "@types/react-router-dom": "^5.1.8", |
56 | "@types/styled-components": "^5.1.12", | 58 | "@types/styled-components": "^5.1.12", |
57 | "@types/validator": "^13.6.3", | 59 | "@types/validator": "^13.6.3", | ... | ... |
... | @@ -9,6 +9,12 @@ export const token = atom({ | ... | @@ -9,6 +9,12 @@ export const token = atom({ |
9 | effects_UNSTABLE : [persistAtom], | 9 | effects_UNSTABLE : [persistAtom], |
10 | }); | 10 | }); |
11 | 11 | ||
12 | +export const userId = atom({ | ||
13 | + key : 'userId', | ||
14 | + default : null, | ||
15 | + effects_UNSTABLE : [persistAtom], | ||
16 | +}); | ||
17 | + | ||
12 | export const userTypeCd = atom({ | 18 | export const userTypeCd = atom({ |
13 | key : 'userTypeCd', | 19 | key : 'userTypeCd', |
14 | default : 'NORMAL', | 20 | default : 'NORMAL', | ... | ... |
... | @@ -23,6 +23,7 @@ const LoginContainer = (props : LoginProps) => { | ... | @@ -23,6 +23,7 @@ const LoginContainer = (props : LoginProps) => { |
23 | }); | 23 | }); |
24 | 24 | ||
25 | const [token, setToken] = useRecoilState(recoilUtil.token); | 25 | const [token, setToken] = useRecoilState(recoilUtil.token); |
26 | + const [userId, setUserId] = useRecoilState(recoilUtil.userId); | ||
26 | const [userTypeCd, setUserTypeCd] = useRecoilState(recoilUtil.userTypeCd); | 27 | const [userTypeCd, setUserTypeCd] = useRecoilState(recoilUtil.userTypeCd); |
27 | 28 | ||
28 | 29 | ||
... | @@ -58,12 +59,13 @@ const LoginContainer = (props : LoginProps) => { | ... | @@ -58,12 +59,13 @@ const LoginContainer = (props : LoginProps) => { |
58 | const result : any = await authApi.login(loginForm); | 59 | const result : any = await authApi.login(loginForm); |
59 | if(result.statusText === 'OK' && result.data.userTypeCd !== 'NORMAL') { | 60 | if(result.statusText === 'OK' && result.data.userTypeCd !== 'NORMAL') { |
60 | setToken(result.data.token); | 61 | setToken(result.data.token); |
62 | + setUserId(loginForm.userId); | ||
61 | setUserTypeCd(result.data.userTypeCd); | 63 | setUserTypeCd(result.data.userTypeCd); |
62 | Alert.onSuccess('로그인 성공, 메인 화면으로 이동합니다.', () => props.history.push('/')); | 64 | Alert.onSuccess('로그인 성공, 메인 화면으로 이동합니다.', () => props.history.push('/')); |
63 | } else if(result.data.userTypeCd === 'NORMAL') { | 65 | } else if(result.data.userTypeCd === 'NORMAL') { |
64 | Alert.onError('권한이 없는 유저입니다.', () => props.history.push('/')); | 66 | Alert.onError('권한이 없는 유저입니다.', () => props.history.push('/')); |
65 | } | 67 | } |
66 | - } catch(e) { | 68 | + } catch(e : any) { |
67 | Alert.onError(e.response.data.error, () => null); | 69 | Alert.onError(e.response.data.error, () => null); |
68 | } | 70 | } |
69 | 71 | ... | ... |
... | @@ -10,6 +10,8 @@ import * as Alert from '../../../util/alertMessage'; | ... | @@ -10,6 +10,8 @@ import * as Alert from '../../../util/alertMessage'; |
10 | 10 | ||
11 | import { doctorApi, medicineApi } from '../../../api'; | 11 | import { doctorApi, medicineApi } from '../../../api'; |
12 | 12 | ||
13 | +import QRCode from 'qrcode'; | ||
14 | + | ||
13 | 15 | ||
14 | //toDo : Generate QR Code By Medicine Id | 16 | //toDo : Generate QR Code By Medicine Id |
15 | 17 | ||
... | @@ -18,6 +20,7 @@ type DoctorMenuProps = RouteComponentProps | ... | @@ -18,6 +20,7 @@ type DoctorMenuProps = RouteComponentProps |
18 | const DoctorMenuContainer = (props : DoctorMenuProps) => { | 20 | const DoctorMenuContainer = (props : DoctorMenuProps) => { |
19 | 21 | ||
20 | const token = useRecoilValue(recoilUtil.token); | 22 | const token = useRecoilValue(recoilUtil.token); |
23 | + const userId = useRecoilValue(recoilUtil.userId); | ||
21 | const [loading, setLoading] = useRecoilState(recoilUtil.loading); | 24 | const [loading, setLoading] = useRecoilState(recoilUtil.loading); |
22 | 25 | ||
23 | const [doctorInfo, setDoctorInfo] = useState<any>({ | 26 | const [doctorInfo, setDoctorInfo] = useState<any>({ |
... | @@ -52,9 +55,13 @@ const DoctorMenuContainer = (props : DoctorMenuProps) => { | ... | @@ -52,9 +55,13 @@ const DoctorMenuContainer = (props : DoctorMenuProps) => { |
52 | const [newPatientSearchResult, setNewPatientSearchResult] = useState<any | null>(null); | 55 | const [newPatientSearchResult, setNewPatientSearchResult] = useState<any | null>(null); |
53 | 56 | ||
54 | const [prescribeModal, setPrescribeModal] = useState<boolean>(false); | 57 | const [prescribeModal, setPrescribeModal] = useState<boolean>(false); |
58 | + const [prescribeModalStep, setPrescribeModalStep] = useState<number>(1); | ||
55 | const [searchMedicineKeyword, setSearchMedicineKeyword] = useState<string>(''); | 59 | const [searchMedicineKeyword, setSearchMedicineKeyword] = useState<string>(''); |
56 | const [medicineList, setMedicineList] = useState<any>([]); | 60 | const [medicineList, setMedicineList] = useState<any>([]); |
57 | const [prescribeMedicine, setPrescribeMedicine] = useState<any>(null); | 61 | const [prescribeMedicine, setPrescribeMedicine] = useState<any>(null); |
62 | + const [dosage, setDosage] = useState<string>('1'); | ||
63 | + | ||
64 | + const [qrcodeUrl, setQrcodeUrl] = useState<string | null>(null); | ||
58 | 65 | ||
59 | 66 | ||
60 | const fetchData = async() => { | 67 | const fetchData = async() => { |
... | @@ -213,9 +220,11 @@ const DoctorMenuContainer = (props : DoctorMenuProps) => { | ... | @@ -213,9 +220,11 @@ const DoctorMenuContainer = (props : DoctorMenuProps) => { |
213 | setEditModal(false); | 220 | setEditModal(false); |
214 | setEditPatientInfo(''); | 221 | setEditPatientInfo(''); |
215 | setPrescribeModal(false); | 222 | setPrescribeModal(false); |
223 | + setPrescribeModalStep(1); | ||
216 | setSearchMedicineKeyword(''); | 224 | setSearchMedicineKeyword(''); |
217 | setMedicineList([]); | 225 | setMedicineList([]); |
218 | setPrescribeMedicine(null); | 226 | setPrescribeMedicine(null); |
227 | + setDosage('1'); | ||
219 | }; | 228 | }; |
220 | 229 | ||
221 | const onGoBottleDetail = (bottleId : number) => { | 230 | const onGoBottleDetail = (bottleId : number) => { |
... | @@ -233,7 +242,6 @@ const DoctorMenuContainer = (props : DoctorMenuProps) => { | ... | @@ -233,7 +242,6 @@ const DoctorMenuContainer = (props : DoctorMenuProps) => { |
233 | setLoading(true); | 242 | setLoading(true); |
234 | const res = await medicineApi.searchMedicine(token, searchMedicineKeyword); | 243 | const res = await medicineApi.searchMedicine(token, searchMedicineKeyword); |
235 | if(res.statusText === 'OK') { | 244 | if(res.statusText === 'OK') { |
236 | - console.log(res.data.medicineList) | ||
237 | setMedicineList(res.data.medicineList); | 245 | setMedicineList(res.data.medicineList); |
238 | } | 246 | } |
239 | setLoading(false); | 247 | setLoading(false); |
... | @@ -242,9 +250,32 @@ const DoctorMenuContainer = (props : DoctorMenuProps) => { | ... | @@ -242,9 +250,32 @@ const DoctorMenuContainer = (props : DoctorMenuProps) => { |
242 | } | 250 | } |
243 | }; | 251 | }; |
244 | 252 | ||
253 | + const onSetDosage = (e : React.ChangeEvent<HTMLInputElement>) => { | ||
254 | + setDosage(e.target.value); | ||
255 | + }; | ||
256 | + | ||
257 | + const onSetNextStepPrescribe = () => { | ||
258 | + if(prescribeMedicine) setPrescribeModalStep(prescribeModalStep + 1); | ||
259 | + else Alert.onWarning('먼저 처방할 약을 선택해야 합니다.', () => null); | ||
260 | + }; | ||
261 | + | ||
262 | + const onSetPrevStepPrescribe = () => { | ||
263 | + if(prescribeModalStep > 1) setPrescribeModalStep(prescribeModalStep - 1); | ||
264 | + }; | ||
265 | + | ||
245 | const onPrescribeSubmit = async() => { | 266 | const onPrescribeSubmit = async() => { |
246 | - //toDo : 처방해서, QR코드 생성 | 267 | + Alert.onCheck(`${prescribeMedicine.name}(일 복용량:${dosage})\n을 처방하시겠습니까?`, async () => { |
247 | - Alert.onWarning('작업 중입니다.', () => null); | 268 | + setQrcodeUrl(await QRCode.toDataURL(`${prescribeMedicine.name}/${prescribeMedicine.medicineId}/${dosage}/${userId}`, { |
269 | + type : "image/png", | ||
270 | + color : {dark : '#337DFF', light : '#FFF'}, | ||
271 | + })); | ||
272 | + Alert.onSuccess('처방 정보가 생성 되었습니다.', () => onSetNextStepPrescribe()); | ||
273 | + }, () => null); | ||
274 | + }; | ||
275 | + | ||
276 | + const onPrintQrcode = async() => { | ||
277 | + //toDo : QR코드 출력 | ||
278 | + Alert.onWarning('준비 중입니다.', () => null); | ||
248 | }; | 279 | }; |
249 | 280 | ||
250 | const onPrescribeCancel = () => { | 281 | const onPrescribeCancel = () => { |
... | @@ -298,14 +329,21 @@ const DoctorMenuContainer = (props : DoctorMenuProps) => { | ... | @@ -298,14 +329,21 @@ const DoctorMenuContainer = (props : DoctorMenuProps) => { |
298 | onCloseModal = {onCloseModal} | 329 | onCloseModal = {onCloseModal} |
299 | 330 | ||
300 | prescribeModal = {prescribeModal} | 331 | prescribeModal = {prescribeModal} |
332 | + prescribeModalStep = {prescribeModalStep} | ||
333 | + onSetNextStepPrescribe = {onSetNextStepPrescribe} | ||
334 | + onSetPrevStepPrescribe = {onSetPrevStepPrescribe} | ||
301 | setPrescribeModal = {setPrescribeModal} | 335 | setPrescribeModal = {setPrescribeModal} |
302 | searchMedicineKeyword = {searchMedicineKeyword} | 336 | searchMedicineKeyword = {searchMedicineKeyword} |
303 | onSetSearchMedicineKeyword = {onSetSearchMedicineKeyword} | 337 | onSetSearchMedicineKeyword = {onSetSearchMedicineKeyword} |
304 | medicineList = {medicineList} | 338 | medicineList = {medicineList} |
305 | searchMedicine = {searchMedicine} | 339 | searchMedicine = {searchMedicine} |
306 | prescribeMedicine = {prescribeMedicine} | 340 | prescribeMedicine = {prescribeMedicine} |
341 | + dosage = {dosage} | ||
342 | + onSetDosage = {onSetDosage} | ||
343 | + qrcodeUrl = {qrcodeUrl} | ||
307 | setPrescribeMedicine = {setPrescribeMedicine} | 344 | setPrescribeMedicine = {setPrescribeMedicine} |
308 | onPrescribeSubmit = {onPrescribeSubmit} | 345 | onPrescribeSubmit = {onPrescribeSubmit} |
346 | + onPrintQrcode = {onPrintQrcode} | ||
309 | onPrescribeCancel = {onPrescribeCancel} | 347 | onPrescribeCancel = {onPrescribeCancel} |
310 | 348 | ||
311 | newPatientSearchResult = {newPatientSearchResult} | 349 | newPatientSearchResult = {newPatientSearchResult} | ... | ... |
... | @@ -48,6 +48,10 @@ interface DoctorMenuProps { | ... | @@ -48,6 +48,10 @@ interface DoctorMenuProps { |
48 | 48 | ||
49 | prescribeModal : boolean; | 49 | prescribeModal : boolean; |
50 | setPrescribeModal : any; | 50 | setPrescribeModal : any; |
51 | + prescribeModalStep : number; | ||
52 | + onSetNextStepPrescribe : () => void; | ||
53 | + onSetPrevStepPrescribe : () => void; | ||
54 | + | ||
51 | searchMedicineKeyword : string; | 55 | searchMedicineKeyword : string; |
52 | onSetSearchMedicineKeyword : React.ChangeEventHandler<HTMLInputElement>; | 56 | onSetSearchMedicineKeyword : React.ChangeEventHandler<HTMLInputElement>; |
53 | 57 | ||
... | @@ -57,7 +61,13 @@ interface DoctorMenuProps { | ... | @@ -57,7 +61,13 @@ interface DoctorMenuProps { |
57 | prescribeMedicine : any; | 61 | prescribeMedicine : any; |
58 | setPrescribeMedicine : (arg0 : any) => void; | 62 | setPrescribeMedicine : (arg0 : any) => void; |
59 | 63 | ||
64 | + dosage : string; | ||
65 | + onSetDosage : React.ChangeEventHandler<HTMLInputElement>; | ||
66 | + | ||
67 | + qrcodeUrl : string | null; | ||
68 | + | ||
60 | onPrescribeSubmit : () => void; | 69 | onPrescribeSubmit : () => void; |
70 | + onPrintQrcode : () => void; | ||
61 | onPrescribeCancel : () => void; | 71 | onPrescribeCancel : () => void; |
62 | } | 72 | } |
63 | 73 | ||
... | @@ -189,8 +199,17 @@ const DoctorMenuPresenter = (props : DoctorMenuProps) => { | ... | @@ -189,8 +199,17 @@ const DoctorMenuPresenter = (props : DoctorMenuProps) => { |
189 | <styled.ModalContentWrapper> | 199 | <styled.ModalContentWrapper> |
190 | <styled.ModalContent> | 200 | <styled.ModalContent> |
191 | <styled.MedicineSearchTitle> | 201 | <styled.MedicineSearchTitle> |
192 | - 약 검색 | 202 | + { |
203 | + props.prescribeModalStep === 1 ? | ||
204 | + '약 검색' : | ||
205 | + props.prescribeModalStep === 2 ? | ||
206 | + '복용량 입력' : | ||
207 | + '처방 정보 QR코드' | ||
208 | + } | ||
193 | </styled.MedicineSearchTitle> | 209 | </styled.MedicineSearchTitle> |
210 | + { | ||
211 | + props.prescribeModalStep === 1 ? | ||
212 | + <> | ||
194 | <styled.MedicineSearchInputWrapper> | 213 | <styled.MedicineSearchInputWrapper> |
195 | <styled.MedicineSearchInput | 214 | <styled.MedicineSearchInput |
196 | placeholder = '증상, 또는 약 이름을 검색하세요.' | 215 | placeholder = '증상, 또는 약 이름을 검색하세요.' |
... | @@ -210,7 +229,10 @@ const DoctorMenuPresenter = (props : DoctorMenuProps) => { | ... | @@ -210,7 +229,10 @@ const DoctorMenuPresenter = (props : DoctorMenuProps) => { |
210 | return ( | 229 | return ( |
211 | <styled.MedicineSearchResultEach | 230 | <styled.MedicineSearchResultEach |
212 | key = {medicine.medicineId} | 231 | key = {medicine.medicineId} |
213 | - onClick = {() => props.setPrescribeMedicine(medicine)} | 232 | + onClick = {() => props.setPrescribeMedicine( |
233 | + props.prescribeMedicine && props.prescribeMedicine.medicineId === medicine.medicineId ? | ||
234 | + null : medicine | ||
235 | + )} | ||
214 | > | 236 | > |
215 | <styled.MedicineSearchResultEachInfo> | 237 | <styled.MedicineSearchResultEachInfo> |
216 | {medicine.name} | 238 | {medicine.name} |
... | @@ -229,13 +251,53 @@ const DoctorMenuPresenter = (props : DoctorMenuProps) => { | ... | @@ -229,13 +251,53 @@ const DoctorMenuPresenter = (props : DoctorMenuProps) => { |
229 | </styled.NothingWrapper> | 251 | </styled.NothingWrapper> |
230 | } | 252 | } |
231 | </styled.MedicineSearchResultWrapper> | 253 | </styled.MedicineSearchResultWrapper> |
254 | + </> | ||
255 | + : | ||
256 | + props.prescribeModalStep === 2 ? | ||
257 | + <styled.MedicineDosageSetWrapper> | ||
258 | + <styled.MedicineDosageInfo> | ||
259 | + *하루 복용량을 입력하세요. | ||
260 | + </styled.MedicineDosageInfo> | ||
261 | + <styled.MedicineDosageInput | ||
262 | + value = {props.dosage} | ||
263 | + onChange = {props.onSetDosage} | ||
264 | + /> | ||
265 | + </styled.MedicineDosageSetWrapper> | ||
266 | + : | ||
267 | + <styled.MedicineQRCodeWrapper> | ||
268 | + <styled.MedicineQRCodeInfo> | ||
269 | + *어플리케이션에서 QR코드를 스캔하면 약병에 약이 등록됩니다. | ||
270 | + </styled.MedicineQRCodeInfo> | ||
271 | + { | ||
272 | + props.qrcodeUrl ? | ||
273 | + <styled.MedicineQRCode src = {props.qrcodeUrl}/> : null | ||
274 | + } | ||
275 | + </styled.MedicineQRCodeWrapper> | ||
276 | + } | ||
232 | <styled.MedicinePrescribeButtonWrapper> | 277 | <styled.MedicinePrescribeButtonWrapper> |
278 | + { | ||
279 | + props.prescribeModalStep === 1 ? | ||
280 | + <styled.MedicinePrescribeButton | ||
281 | + isClose = {false} | ||
282 | + onClick = {props.onSetNextStepPrescribe} | ||
283 | + > | ||
284 | + 다음 단계 | ||
285 | + </styled.MedicinePrescribeButton> : | ||
286 | + props.prescribeModalStep === 2 ? | ||
233 | <styled.MedicinePrescribeButton | 287 | <styled.MedicinePrescribeButton |
234 | isClose = {false} | 288 | isClose = {false} |
235 | onClick = {props.onPrescribeSubmit} | 289 | onClick = {props.onPrescribeSubmit} |
236 | > | 290 | > |
237 | 처방 | 291 | 처방 |
238 | </styled.MedicinePrescribeButton> | 292 | </styled.MedicinePrescribeButton> |
293 | + : | ||
294 | + <styled.MedicinePrescribeButton | ||
295 | + isClose = {false} | ||
296 | + onClick = {props.onPrintQrcode} | ||
297 | + > | ||
298 | + 출력 | ||
299 | + </styled.MedicinePrescribeButton> | ||
300 | + } | ||
239 | <styled.MedicinePrescribeButton | 301 | <styled.MedicinePrescribeButton |
240 | isClose = {true} | 302 | isClose = {true} |
241 | onClick = {props.onPrescribeCancel} | 303 | onClick = {props.onPrescribeCancel} | ... | ... |
... | @@ -436,6 +436,7 @@ export const MedicineSearchButtonImg = styled.img ` | ... | @@ -436,6 +436,7 @@ export const MedicineSearchButtonImg = styled.img ` |
436 | height : 15px; | 436 | height : 15px; |
437 | width : 15px; | 437 | width : 15px; |
438 | 438 | ||
439 | + transition : .25s all; | ||
439 | `; | 440 | `; |
440 | 441 | ||
441 | export const MedicineSearchResultWrapper = styled.div ` | 442 | export const MedicineSearchResultWrapper = styled.div ` |
... | @@ -499,6 +500,92 @@ export const MedicineSelectButtonImg = styled.img ` | ... | @@ -499,6 +500,92 @@ export const MedicineSelectButtonImg = styled.img ` |
499 | width : 15px; | 500 | width : 15px; |
500 | `; | 501 | `; |
501 | 502 | ||
503 | +export const MedicineDosageSetWrapper = styled.div ` | ||
504 | + width : 80%; | ||
505 | + | ||
506 | + display : flex; | ||
507 | + flex-direction : column; | ||
508 | + | ||
509 | + justify-content : center; | ||
510 | + align-items : center; | ||
511 | + | ||
512 | + border : none; | ||
513 | + | ||
514 | + margin : 20px 0; | ||
515 | + | ||
516 | + height : 200px; | ||
517 | +`; | ||
518 | + | ||
519 | +export const MedicineDosageInfo = styled.div ` | ||
520 | + font-size : 15px; | ||
521 | + font-weight : 500; | ||
522 | + | ||
523 | + color : #a0a0a0; | ||
524 | + | ||
525 | + width : 100%; | ||
526 | + margin : 0 0 20px 0; | ||
527 | + | ||
528 | + border : none; | ||
529 | + background-color : transparent; | ||
530 | + | ||
531 | + text-align : center; | ||
532 | +`; | ||
533 | + | ||
534 | +export const MedicineDosageInput = styled.input.attrs({ | ||
535 | + type : 'number', | ||
536 | + min : '1', | ||
537 | + max : '3', | ||
538 | +}) ` | ||
539 | + width : 40%; | ||
540 | + | ||
541 | + padding : 10px 20px; | ||
542 | + color : #337DFF; | ||
543 | + font-size : 20px; | ||
544 | + | ||
545 | + font-weight : 700; | ||
546 | + | ||
547 | + border : none; | ||
548 | + border-bottom : 1px solid #337DFF; | ||
549 | + | ||
550 | + display : flex; | ||
551 | + flex-direction : row; | ||
552 | + | ||
553 | + text-align : center; | ||
554 | + | ||
555 | + transition : .25s all; | ||
556 | +`; | ||
557 | + | ||
558 | +export const MedicineQRCodeWrapper = styled.div ` | ||
559 | + width : 80%; | ||
560 | + height : 200px; | ||
561 | + | ||
562 | + display : flex; | ||
563 | + flex-direction : column; | ||
564 | + | ||
565 | + justify-content : center; | ||
566 | + align-items : center; | ||
567 | + | ||
568 | + margin : 20px 0; | ||
569 | + | ||
570 | + border : none; | ||
571 | +`; | ||
572 | + | ||
573 | +export const MedicineQRCodeInfo = styled.div ` | ||
574 | + font-size : 15px; | ||
575 | + font-weight : 500; | ||
576 | + | ||
577 | + color : #a0a0a0; | ||
578 | + | ||
579 | + text-align : center; | ||
580 | +`; | ||
581 | + | ||
582 | +export const MedicineQRCode = styled.img ` | ||
583 | + margin : 10px 0 0 0; | ||
584 | + | ||
585 | + height : 170px; | ||
586 | + width : 170px; | ||
587 | +`; | ||
588 | + | ||
502 | export const MedicinePrescribeButtonWrapper = styled.div ` | 589 | export const MedicinePrescribeButtonWrapper = styled.div ` |
503 | margin : 20px 0 0 0; | 590 | margin : 20px 0 0 0; |
504 | 591 | ... | ... |
This diff could not be displayed because it is too large.
-
Please register or login to post a comment