diff --git a/assets/images/clinicIcons/1.svg b/assets/images/clinicIcons/1.svg new file mode 100644 index 0000000..70f4171 --- /dev/null +++ b/assets/images/clinicIcons/1.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/clinicIcons/104.svg b/assets/images/clinicIcons/104.svg new file mode 100644 index 0000000..3fd875f --- /dev/null +++ b/assets/images/clinicIcons/104.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/assets/images/clinicIcons/105.svg b/assets/images/clinicIcons/105.svg new file mode 100644 index 0000000..a9f4bd1 --- /dev/null +++ b/assets/images/clinicIcons/105.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/images/clinicIcons/106.svg b/assets/images/clinicIcons/106.svg new file mode 100644 index 0000000..bd103ad --- /dev/null +++ b/assets/images/clinicIcons/106.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/clinicIcons/107.svg b/assets/images/clinicIcons/107.svg new file mode 100644 index 0000000..b1946db --- /dev/null +++ b/assets/images/clinicIcons/107.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/images/clinicIcons/108.svg b/assets/images/clinicIcons/108.svg new file mode 100644 index 0000000..a29fe00 --- /dev/null +++ b/assets/images/clinicIcons/108.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/images/clinicIcons/11.svg b/assets/images/clinicIcons/11.svg new file mode 100644 index 0000000..1c276aa --- /dev/null +++ b/assets/images/clinicIcons/11.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/clinicIcons/110.svg b/assets/images/clinicIcons/110.svg new file mode 100644 index 0000000..6d533e2 --- /dev/null +++ b/assets/images/clinicIcons/110.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/clinicIcons/111.svg b/assets/images/clinicIcons/111.svg new file mode 100644 index 0000000..46ba92f --- /dev/null +++ b/assets/images/clinicIcons/111.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/clinicIcons/118.svg b/assets/images/clinicIcons/118.svg new file mode 100644 index 0000000..238cd5a --- /dev/null +++ b/assets/images/clinicIcons/118.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/clinicIcons/12.svg b/assets/images/clinicIcons/12.svg new file mode 100644 index 0000000..cb6a23f --- /dev/null +++ b/assets/images/clinicIcons/12.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/images/clinicIcons/126.svg b/assets/images/clinicIcons/126.svg new file mode 100644 index 0000000..9d26d97 --- /dev/null +++ b/assets/images/clinicIcons/126.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/clinicIcons/128.svg b/assets/images/clinicIcons/128.svg new file mode 100644 index 0000000..0888a5f --- /dev/null +++ b/assets/images/clinicIcons/128.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/images/clinicIcons/130.svg b/assets/images/clinicIcons/130.svg new file mode 100644 index 0000000..5598ebb --- /dev/null +++ b/assets/images/clinicIcons/130.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/clinicIcons/131.svg b/assets/images/clinicIcons/131.svg new file mode 100644 index 0000000..dbf94b5 --- /dev/null +++ b/assets/images/clinicIcons/131.svg @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/clinicIcons/134.svg b/assets/images/clinicIcons/134.svg new file mode 100644 index 0000000..42f8417 --- /dev/null +++ b/assets/images/clinicIcons/134.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/clinicIcons/14.svg b/assets/images/clinicIcons/14.svg new file mode 100644 index 0000000..46ba92f --- /dev/null +++ b/assets/images/clinicIcons/14.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/clinicIcons/140.svg b/assets/images/clinicIcons/140.svg new file mode 100644 index 0000000..56c7a53 --- /dev/null +++ b/assets/images/clinicIcons/140.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/images/clinicIcons/148.svg b/assets/images/clinicIcons/148.svg new file mode 100644 index 0000000..bd103ad --- /dev/null +++ b/assets/images/clinicIcons/148.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/clinicIcons/149.svg b/assets/images/clinicIcons/149.svg new file mode 100644 index 0000000..0888a5f --- /dev/null +++ b/assets/images/clinicIcons/149.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/images/clinicIcons/16.svg b/assets/images/clinicIcons/16.svg new file mode 100644 index 0000000..e1ed316 --- /dev/null +++ b/assets/images/clinicIcons/16.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/clinicIcons/17.svg b/assets/images/clinicIcons/17.svg new file mode 100644 index 0000000..44bad05 --- /dev/null +++ b/assets/images/clinicIcons/17.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/images/clinicIcons/18.svg b/assets/images/clinicIcons/18.svg new file mode 100644 index 0000000..1148ad6 --- /dev/null +++ b/assets/images/clinicIcons/18.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/clinicIcons/19.svg b/assets/images/clinicIcons/19.svg new file mode 100644 index 0000000..5b7d43b --- /dev/null +++ b/assets/images/clinicIcons/19.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/clinicIcons/2.svg b/assets/images/clinicIcons/2.svg new file mode 100644 index 0000000..b4b1521 --- /dev/null +++ b/assets/images/clinicIcons/2.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/images/clinicIcons/20.svg b/assets/images/clinicIcons/20.svg new file mode 100644 index 0000000..9e6db60 --- /dev/null +++ b/assets/images/clinicIcons/20.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/images/clinicIcons/21.svg b/assets/images/clinicIcons/21.svg new file mode 100644 index 0000000..9b9ee82 --- /dev/null +++ b/assets/images/clinicIcons/21.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/images/clinicIcons/23.svg b/assets/images/clinicIcons/23.svg new file mode 100644 index 0000000..4f8b915 --- /dev/null +++ b/assets/images/clinicIcons/23.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/images/clinicIcons/24.svg b/assets/images/clinicIcons/24.svg new file mode 100644 index 0000000..70f4171 --- /dev/null +++ b/assets/images/clinicIcons/24.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/clinicIcons/25.svg b/assets/images/clinicIcons/25.svg new file mode 100644 index 0000000..70f4171 --- /dev/null +++ b/assets/images/clinicIcons/25.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/clinicIcons/250.svg b/assets/images/clinicIcons/250.svg new file mode 100644 index 0000000..b4b1521 --- /dev/null +++ b/assets/images/clinicIcons/250.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/images/clinicIcons/252.svg b/assets/images/clinicIcons/252.svg new file mode 100644 index 0000000..9545d24 --- /dev/null +++ b/assets/images/clinicIcons/252.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/images/clinicIcons/253.svg b/assets/images/clinicIcons/253.svg new file mode 100644 index 0000000..7118231 --- /dev/null +++ b/assets/images/clinicIcons/253.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/clinicIcons/254.svg b/assets/images/clinicIcons/254.svg new file mode 100644 index 0000000..5e24ad4 --- /dev/null +++ b/assets/images/clinicIcons/254.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/images/clinicIcons/255.svg b/assets/images/clinicIcons/255.svg new file mode 100644 index 0000000..e9ccd2b --- /dev/null +++ b/assets/images/clinicIcons/255.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/images/clinicIcons/257.svg b/assets/images/clinicIcons/257.svg new file mode 100644 index 0000000..b4b1521 --- /dev/null +++ b/assets/images/clinicIcons/257.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/images/clinicIcons/26.svg b/assets/images/clinicIcons/26.svg new file mode 100644 index 0000000..b82e118 --- /dev/null +++ b/assets/images/clinicIcons/26.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/images/clinicIcons/260.svg b/assets/images/clinicIcons/260.svg new file mode 100644 index 0000000..60ed9c2 --- /dev/null +++ b/assets/images/clinicIcons/260.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/images/clinicIcons/262.svg b/assets/images/clinicIcons/262.svg new file mode 100644 index 0000000..371c0ba --- /dev/null +++ b/assets/images/clinicIcons/262.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/assets/images/clinicIcons/264.svg b/assets/images/clinicIcons/264.svg new file mode 100644 index 0000000..b1f231e --- /dev/null +++ b/assets/images/clinicIcons/264.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/clinicIcons/27.svg b/assets/images/clinicIcons/27.svg new file mode 100644 index 0000000..6da1ed7 --- /dev/null +++ b/assets/images/clinicIcons/27.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/clinicIcons/28.svg b/assets/images/clinicIcons/28.svg new file mode 100644 index 0000000..483893c --- /dev/null +++ b/assets/images/clinicIcons/28.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/images/clinicIcons/29.svg b/assets/images/clinicIcons/29.svg new file mode 100644 index 0000000..009a406 --- /dev/null +++ b/assets/images/clinicIcons/29.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/images/clinicIcons/3.svg b/assets/images/clinicIcons/3.svg new file mode 100644 index 0000000..7a313ee --- /dev/null +++ b/assets/images/clinicIcons/3.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/clinicIcons/30.svg b/assets/images/clinicIcons/30.svg new file mode 100644 index 0000000..d16a33a --- /dev/null +++ b/assets/images/clinicIcons/30.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/images/clinicIcons/31.svg b/assets/images/clinicIcons/31.svg new file mode 100644 index 0000000..93becf0 --- /dev/null +++ b/assets/images/clinicIcons/31.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/clinicIcons/32.svg b/assets/images/clinicIcons/32.svg new file mode 100644 index 0000000..9256566 --- /dev/null +++ b/assets/images/clinicIcons/32.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/images/clinicIcons/34.svg b/assets/images/clinicIcons/34.svg new file mode 100644 index 0000000..b592ad8 --- /dev/null +++ b/assets/images/clinicIcons/34.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/clinicIcons/35.svg b/assets/images/clinicIcons/35.svg new file mode 100644 index 0000000..c5ac879 --- /dev/null +++ b/assets/images/clinicIcons/35.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/clinicIcons/36.svg b/assets/images/clinicIcons/36.svg new file mode 100644 index 0000000..1d171d4 --- /dev/null +++ b/assets/images/clinicIcons/36.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/images/clinicIcons/38.svg b/assets/images/clinicIcons/38.svg new file mode 100644 index 0000000..9448feb --- /dev/null +++ b/assets/images/clinicIcons/38.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/images/clinicIcons/4.svg b/assets/images/clinicIcons/4.svg new file mode 100644 index 0000000..beb7239 --- /dev/null +++ b/assets/images/clinicIcons/4.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/clinicIcons/40.svg b/assets/images/clinicIcons/40.svg new file mode 100644 index 0000000..168ece6 --- /dev/null +++ b/assets/images/clinicIcons/40.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/images/clinicIcons/41.svg b/assets/images/clinicIcons/41.svg new file mode 100644 index 0000000..93becf0 --- /dev/null +++ b/assets/images/clinicIcons/41.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/clinicIcons/42.svg b/assets/images/clinicIcons/42.svg new file mode 100644 index 0000000..5b7d43b --- /dev/null +++ b/assets/images/clinicIcons/42.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/clinicIcons/44.svg b/assets/images/clinicIcons/44.svg new file mode 100644 index 0000000..e9edf9a --- /dev/null +++ b/assets/images/clinicIcons/44.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/clinicIcons/46.svg b/assets/images/clinicIcons/46.svg new file mode 100644 index 0000000..926ad19 --- /dev/null +++ b/assets/images/clinicIcons/46.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/images/clinicIcons/5.svg b/assets/images/clinicIcons/5.svg new file mode 100644 index 0000000..d25576e --- /dev/null +++ b/assets/images/clinicIcons/5.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/clinicIcons/50.svg b/assets/images/clinicIcons/50.svg new file mode 100644 index 0000000..662a64e --- /dev/null +++ b/assets/images/clinicIcons/50.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/images/clinicIcons/51.svg b/assets/images/clinicIcons/51.svg new file mode 100644 index 0000000..8ef6791 --- /dev/null +++ b/assets/images/clinicIcons/51.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/images/clinicIcons/53.svg b/assets/images/clinicIcons/53.svg new file mode 100644 index 0000000..56c7a53 --- /dev/null +++ b/assets/images/clinicIcons/53.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/images/clinicIcons/55.svg b/assets/images/clinicIcons/55.svg new file mode 100644 index 0000000..a94748c --- /dev/null +++ b/assets/images/clinicIcons/55.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/images/clinicIcons/56.svg b/assets/images/clinicIcons/56.svg new file mode 100644 index 0000000..be81445 --- /dev/null +++ b/assets/images/clinicIcons/56.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/clinicIcons/58.svg b/assets/images/clinicIcons/58.svg new file mode 100644 index 0000000..4987166 --- /dev/null +++ b/assets/images/clinicIcons/58.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/clinicIcons/59.svg b/assets/images/clinicIcons/59.svg new file mode 100644 index 0000000..87e2269 --- /dev/null +++ b/assets/images/clinicIcons/59.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/clinicIcons/6.svg b/assets/images/clinicIcons/6.svg new file mode 100644 index 0000000..50e0c7b --- /dev/null +++ b/assets/images/clinicIcons/6.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/images/clinicIcons/67.svg b/assets/images/clinicIcons/67.svg new file mode 100644 index 0000000..4f8b915 --- /dev/null +++ b/assets/images/clinicIcons/67.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/images/clinicIcons/68.svg b/assets/images/clinicIcons/68.svg new file mode 100644 index 0000000..d16a33a --- /dev/null +++ b/assets/images/clinicIcons/68.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/images/clinicIcons/69.svg b/assets/images/clinicIcons/69.svg new file mode 100644 index 0000000..70f4171 --- /dev/null +++ b/assets/images/clinicIcons/69.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/clinicIcons/7.svg b/assets/images/clinicIcons/7.svg new file mode 100644 index 0000000..b1ec62e --- /dev/null +++ b/assets/images/clinicIcons/7.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/clinicIcons/74.svg b/assets/images/clinicIcons/74.svg new file mode 100644 index 0000000..6237181 --- /dev/null +++ b/assets/images/clinicIcons/74.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/clinicIcons/78.svg b/assets/images/clinicIcons/78.svg new file mode 100644 index 0000000..60ed9c2 --- /dev/null +++ b/assets/images/clinicIcons/78.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/images/clinicIcons/79.svg b/assets/images/clinicIcons/79.svg new file mode 100644 index 0000000..1decce9 --- /dev/null +++ b/assets/images/clinicIcons/79.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/images/clinicIcons/8.svg b/assets/images/clinicIcons/8.svg new file mode 100644 index 0000000..d16a33a --- /dev/null +++ b/assets/images/clinicIcons/8.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/images/clinicIcons/83.svg b/assets/images/clinicIcons/83.svg new file mode 100644 index 0000000..87e2269 --- /dev/null +++ b/assets/images/clinicIcons/83.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/clinicIcons/84.svg b/assets/images/clinicIcons/84.svg new file mode 100644 index 0000000..ed242ec --- /dev/null +++ b/assets/images/clinicIcons/84.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/images/clinicIcons/85.svg b/assets/images/clinicIcons/85.svg new file mode 100644 index 0000000..076d201 --- /dev/null +++ b/assets/images/clinicIcons/85.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/images/clinicIcons/86.svg b/assets/images/clinicIcons/86.svg new file mode 100644 index 0000000..4615e67 --- /dev/null +++ b/assets/images/clinicIcons/86.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/images/clinicIcons/87.svg b/assets/images/clinicIcons/87.svg new file mode 100644 index 0000000..d0b95ae --- /dev/null +++ b/assets/images/clinicIcons/87.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/images/clinicIcons/88.svg b/assets/images/clinicIcons/88.svg new file mode 100644 index 0000000..93f3042 --- /dev/null +++ b/assets/images/clinicIcons/88.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/clinicIcons/89.svg b/assets/images/clinicIcons/89.svg new file mode 100644 index 0000000..768ef4a --- /dev/null +++ b/assets/images/clinicIcons/89.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/images/clinicIcons/9.svg b/assets/images/clinicIcons/9.svg new file mode 100644 index 0000000..aa0acfb --- /dev/null +++ b/assets/images/clinicIcons/9.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/clinicIcons/90.svg b/assets/images/clinicIcons/90.svg new file mode 100644 index 0000000..6f8a44b --- /dev/null +++ b/assets/images/clinicIcons/90.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/clinicIcons/91.svg b/assets/images/clinicIcons/91.svg new file mode 100644 index 0000000..4234428 --- /dev/null +++ b/assets/images/clinicIcons/91.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/clinicIcons/93.svg b/assets/images/clinicIcons/93.svg new file mode 100644 index 0000000..be1b4a6 --- /dev/null +++ b/assets/images/clinicIcons/93.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/clinicIcons/98.svg b/assets/images/clinicIcons/98.svg new file mode 100644 index 0000000..93f3042 --- /dev/null +++ b/assets/images/clinicIcons/98.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/clinicIcons/Cardiac Surgery.svg b/assets/images/clinicIcons/Cardiac Surgery.svg new file mode 100644 index 0000000..2075871 --- /dev/null +++ b/assets/images/clinicIcons/Cardiac Surgery.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/images/clinicIcons/Colorectal Oncology Clinic 2.svg b/assets/images/clinicIcons/Colorectal Oncology Clinic 2.svg new file mode 100644 index 0000000..b3898e5 --- /dev/null +++ b/assets/images/clinicIcons/Colorectal Oncology Clinic 2.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/clinicIcons/Dental Employee Clinic.svg b/assets/images/clinicIcons/Dental Employee Clinic.svg new file mode 100644 index 0000000..44bad05 --- /dev/null +++ b/assets/images/clinicIcons/Dental Employee Clinic.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/images/clinicIcons/ENT Oncology Clinic 2.svg b/assets/images/clinicIcons/ENT Oncology Clinic 2.svg new file mode 100644 index 0000000..7defb9c --- /dev/null +++ b/assets/images/clinicIcons/ENT Oncology Clinic 2.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/images/clinicIcons/ER CLINIC.svg b/assets/images/clinicIcons/ER CLINIC.svg new file mode 100644 index 0000000..cb239be --- /dev/null +++ b/assets/images/clinicIcons/ER CLINIC.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/images/clinicIcons/EXCELLENCE CLINIC.svg b/assets/images/clinicIcons/EXCELLENCE CLINIC.svg new file mode 100644 index 0000000..b6cc121 --- /dev/null +++ b/assets/images/clinicIcons/EXCELLENCE CLINIC.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/images/clinicIcons/Frame.svg b/assets/images/clinicIcons/Frame.svg new file mode 100644 index 0000000..c573a48 --- /dev/null +++ b/assets/images/clinicIcons/Frame.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/images/clinicIcons/Gynecology oncology Clinic.svg b/assets/images/clinicIcons/Gynecology oncology Clinic.svg new file mode 100644 index 0000000..9bef9cb --- /dev/null +++ b/assets/images/clinicIcons/Gynecology oncology Clinic.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/images/clinicIcons/Interventional Radiology Clinic.svg b/assets/images/clinicIcons/Interventional Radiology Clinic.svg new file mode 100644 index 0000000..5b7d43b --- /dev/null +++ b/assets/images/clinicIcons/Interventional Radiology Clinic.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/clinicIcons/LIVER , GALLBLADDER, PANCREATIC CLINIC.svg b/assets/images/clinicIcons/LIVER , GALLBLADDER, PANCREATIC CLINIC.svg new file mode 100644 index 0000000..117b29b --- /dev/null +++ b/assets/images/clinicIcons/LIVER , GALLBLADDER, PANCREATIC CLINIC.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/images/clinicIcons/Maternal-Fetal Medicine Clinic.svg b/assets/images/clinicIcons/Maternal-Fetal Medicine Clinic.svg new file mode 100644 index 0000000..708d85f --- /dev/null +++ b/assets/images/clinicIcons/Maternal-Fetal Medicine Clinic.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/images/clinicIcons/Maxilliofacial Surgery.svg b/assets/images/clinicIcons/Maxilliofacial Surgery.svg new file mode 100644 index 0000000..66a0fbd --- /dev/null +++ b/assets/images/clinicIcons/Maxilliofacial Surgery.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/clinicIcons/OB-GYNE physiotherapy clinic-1.svg b/assets/images/clinicIcons/OB-GYNE physiotherapy clinic-1.svg new file mode 100644 index 0000000..5e24ad4 --- /dev/null +++ b/assets/images/clinicIcons/OB-GYNE physiotherapy clinic-1.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/images/clinicIcons/Occupational Therapy Clinic.svg b/assets/images/clinicIcons/Occupational Therapy Clinic.svg new file mode 100644 index 0000000..3181519 --- /dev/null +++ b/assets/images/clinicIcons/Occupational Therapy Clinic.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/images/clinicIcons/Orthopedic Oncology Surgery Clinic.svg b/assets/images/clinicIcons/Orthopedic Oncology Surgery Clinic.svg new file mode 100644 index 0000000..226d56c --- /dev/null +++ b/assets/images/clinicIcons/Orthopedic Oncology Surgery Clinic.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/images/clinicIcons/RRT Clinic 2.svg b/assets/images/clinicIcons/RRT Clinic 2.svg new file mode 100644 index 0000000..f4e451a --- /dev/null +++ b/assets/images/clinicIcons/RRT Clinic 2.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/clinicIcons/Radiation Oncology Clinic 2.svg b/assets/images/clinicIcons/Radiation Oncology Clinic 2.svg new file mode 100644 index 0000000..ac8e5e1 --- /dev/null +++ b/assets/images/clinicIcons/Radiation Oncology Clinic 2.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/images/clinicIcons/Retinopathy of prematurity(ROP).svg b/assets/images/clinicIcons/Retinopathy of prematurity(ROP).svg new file mode 100644 index 0000000..814b1a7 --- /dev/null +++ b/assets/images/clinicIcons/Retinopathy of prematurity(ROP).svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/clinicIcons/SKIN AND HAIR CARE.svg b/assets/images/clinicIcons/SKIN AND HAIR CARE.svg new file mode 100644 index 0000000..dbe3972 --- /dev/null +++ b/assets/images/clinicIcons/SKIN AND HAIR CARE.svg @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/clinicIcons/SPA SKIN CARE.svg b/assets/images/clinicIcons/SPA SKIN CARE.svg new file mode 100644 index 0000000..55ce473 --- /dev/null +++ b/assets/images/clinicIcons/SPA SKIN CARE.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/clinicIcons/Smell Clinic 2.svg b/assets/images/clinicIcons/Smell Clinic 2.svg new file mode 100644 index 0000000..5341759 --- /dev/null +++ b/assets/images/clinicIcons/Smell Clinic 2.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/images/clinicIcons/Surgical Oncology Clinic.svg b/assets/images/clinicIcons/Surgical Oncology Clinic.svg new file mode 100644 index 0000000..7e7f1db --- /dev/null +++ b/assets/images/clinicIcons/Surgical Oncology Clinic.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/images/clinicIcons/Thoracic Clinic.svg b/assets/images/clinicIcons/Thoracic Clinic.svg new file mode 100644 index 0000000..9d26d97 --- /dev/null +++ b/assets/images/clinicIcons/Thoracic Clinic.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/clinicIcons/Urology Oncology Clinic.svg b/assets/images/clinicIcons/Urology Oncology Clinic.svg new file mode 100644 index 0000000..935af2e --- /dev/null +++ b/assets/images/clinicIcons/Urology Oncology Clinic.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/images/svg/change_language_home_page.svg b/assets/images/svg/change_language_home_page.svg new file mode 100644 index 0000000..716a3b0 --- /dev/null +++ b/assets/images/svg/change_language_home_page.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/assets/images/svg/doctor_response_icon.svg b/assets/images/svg/doctor_response_icon.svg new file mode 100644 index 0000000..1c4b156 --- /dev/null +++ b/assets/images/svg/doctor_response_icon.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/langs/ar-SA.json b/assets/langs/ar-SA.json index 3ceb2e9..90103c0 100644 --- a/assets/langs/ar-SA.json +++ b/assets/langs/ar-SA.json @@ -1385,7 +1385,7 @@ "seekMedicalAdviceDescription": "ليست حالة طوارئ ولكن من الأفضل مراقبة الأعراض.", "emergencyDescription": "تحتاج إلى استشارة الطبيب في أقرب وقت ممكن قبل فوات الأوان.", "colorScience": "دلالات الألوان", - "noNeedToVisitDoctor": "لا حاجة لزي��رة الطبيب", + "noNeedToVisitDoctor": "لا حاجة لزيرة الطبيب", "commonSymptom": "الأعراض الشائعة", "bookAppointment": "احجز موعد", "notApplicable": "لا ينطبق", diff --git a/lib/core/api/api_client.dart b/lib/core/api/api_client.dart index 39a6177..ba8f627 100644 --- a/lib/core/api/api_client.dart +++ b/lib/core/api/api_client.dart @@ -212,7 +212,7 @@ class ApiClientImp implements ApiClient { final int statusCode = response.statusCode; log("uri: ${Uri.parse(url.trim())}"); log("body: ${json.encode(body)}"); - log("response.body: ${response.body}"); + // log("response.body: ${response.body}"); if (statusCode < 200 || statusCode >= 400) { onFailure('Error While Fetching data', statusCode, failureType: StatusCodeFailure("Error While Fetching data")); logApiEndpointError(endPoint, 'Error While Fetching data', statusCode); diff --git a/lib/core/api_consts.dart b/lib/core/api_consts.dart index f715305..dbf3566 100644 --- a/lib/core/api_consts.dart +++ b/lib/core/api_consts.dart @@ -680,7 +680,7 @@ const DASHBOARD = 'Services/Patients.svc/REST/PatientDashboard'; class ApiConsts { static const maxSmallScreen = 660; - static AppEnvironmentTypeEnum appEnvironmentType = AppEnvironmentTypeEnum.uat; + static AppEnvironmentTypeEnum appEnvironmentType = AppEnvironmentTypeEnum.prod; // static String baseUrl = 'https://uat.hmgwebservices.com/'; // HIS API URL UAT diff --git a/lib/core/app_assets.dart b/lib/core/app_assets.dart index e0a99a7..35d48d6 100644 --- a/lib/core/app_assets.dart +++ b/lib/core/app_assets.dart @@ -310,6 +310,9 @@ class AppAssets { static const String arLangIcon = '$svgBasePath/ar_lang_icon.svg'; static const String enLangIcon = '$svgBasePath/en_lang_icon.svg'; + static const String doctorResponseIcon = '$svgBasePath/doctor_response_icon.svg'; + static const String changeLanguageHomePageIcon = '$svgBasePath/change_language_home_page.svg'; + // PNGS // static const String hmgLogo = '$pngBasePath/hmg_logo.png'; static const String liveCareService = '$pngBasePath/livecare_service.png'; diff --git a/lib/core/dependencies.dart b/lib/core/dependencies.dart index 44a8bde..d020eaa 100644 --- a/lib/core/dependencies.dart +++ b/lib/core/dependencies.dart @@ -4,6 +4,8 @@ import 'package:get_it/get_it.dart'; import 'package:hmg_patient_app_new/core/api/api_client.dart'; import 'package:hmg_patient_app_new/core/app_state.dart'; import 'package:hmg_patient_app_new/core/location_util.dart'; +import 'package:hmg_patient_app_new/features/ask_doctor/ask_doctor_repo.dart'; +import 'package:hmg_patient_app_new/features/ask_doctor/ask_doctor_view_model.dart'; import 'package:hmg_patient_app_new/features/authentication/authentication_repo.dart'; import 'package:hmg_patient_app_new/features/authentication/authentication_view_model.dart'; import 'package:hmg_patient_app_new/features/blood_donation/blood_donation_repo.dart'; @@ -166,6 +168,7 @@ class AppDependencies { getIt.registerLazySingleton(() => MonthlyReportsRepoImp(loggerService: getIt(), apiClient: getIt())); getIt.registerLazySingleton(() => QrParkingRepoImp(loggerService: getIt(), apiClient: getIt())); getIt.registerLazySingleton(() => NotificationsRepoImp(loggerService: getIt(), apiClient: getIt())); + getIt.registerLazySingleton(() => AskDoctorRepoImp(loggerService: getIt(), apiClient: getIt())); // ViewModels // Global/shared VMs → LazySingleton @@ -306,5 +309,7 @@ class AppDependencies { ), ); + getIt.registerLazySingleton(() => AskDoctorViewModel(askDoctorRepo: getIt(), errorHandlerService: getIt())); + } } diff --git a/lib/features/ask_doctor/ask_doctor_repo.dart b/lib/features/ask_doctor/ask_doctor_repo.dart new file mode 100644 index 0000000..4e4a400 --- /dev/null +++ b/lib/features/ask_doctor/ask_doctor_repo.dart @@ -0,0 +1,128 @@ +import 'package:dartz/dartz.dart'; +import 'package:hmg_patient_app_new/core/api/api_client.dart'; +import 'package:hmg_patient_app_new/core/api_consts.dart'; +import 'package:hmg_patient_app_new/core/common_models/generic_api_model.dart'; +import 'package:hmg_patient_app_new/core/exceptions/api_failure.dart'; +import 'package:hmg_patient_app_new/core/utils/date_util.dart'; +import 'package:hmg_patient_app_new/features/ask_doctor/models/ask_doctor_appointments_list.dart'; +import 'package:hmg_patient_app_new/features/ask_doctor/models/doctor_response_model.dart'; +import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/ask_doctor_request_type_response_model.dart'; +import 'package:hmg_patient_app_new/services/logger_service.dart'; + +abstract class AskDoctorRepo { + Future>>> getAskDoctorAppointmentsList(); + + Future>>> getDoctorResponse({ + required String fromDate, + }); +} + +class AskDoctorRepoImp implements AskDoctorRepo { + final ApiClient apiClient; + final LoggerService loggerService; + + AskDoctorRepoImp({ + required this.loggerService, + required this.apiClient, + }); + + @override + Future>>> getAskDoctorAppointmentsList() async { + Map mapDevice = { + "Top": 25, + "beforeDays": 15, + "exludType": 4, + }; + + try { + GenericApiModel>? apiResponse; + Failure? failure; + await apiClient.post( + IS_ALLOW_ASK_DOCTOR, + body: mapDevice, + onFailure: (error, statusCode, {messageStatus, failureType}) { + failure = failureType; + }, + onSuccess: (response, statusCode, {messageStatus, errorMessage}) { + try { + final list = response['PatientDoctorAppointmentResultList']; + + final clinicsList = list.map((item) => AskDoctorAppointmentHistoryList.fromJson(item as Map)).toList().cast(); + + apiResponse = GenericApiModel>( + messageStatus: messageStatus, + statusCode: statusCode, + errorMessage: null, + data: clinicsList, + ); + } catch (e) { + failure = DataParsingFailure(e.toString()); + } + }, + ); + if (failure != null) return Left(failure!); + if (apiResponse == null) return Left(ServerFailure("Unknown error")); + return Right(apiResponse!); + } catch (e) { + return Left(UnknownFailure(e.toString())); + } + } + + @override + Future>>> getDoctorResponse({ + required String fromDate, + }) async { + Map mapDevice = { + "isDentalAllowedBackend": false, + "from": fromDate, + }; + + try { + GenericApiModel>? apiResponse; + Failure? failure; + await apiClient.post( + GET_DOCTOR_RESPONSE, + body: mapDevice, + onFailure: (error, statusCode, {messageStatus, failureType}) { + failure = failureType; + }, + onSuccess: (response, statusCode, {messageStatus, errorMessage}) { + try { + final list = response['List_DoctorResponse']; + + if (list == null || list.isEmpty) { + // Return empty list if no responses + apiResponse = GenericApiModel>( + messageStatus: messageStatus, + statusCode: statusCode, + errorMessage: null, + data: [], + ); + return; + } + + final doctorResponsesList = list + .map((item) => DoctorResponseModel.fromJson(item as Map)) + .toList() + .cast(); + + apiResponse = GenericApiModel>( + messageStatus: messageStatus, + statusCode: statusCode, + errorMessage: null, + data: doctorResponsesList, + ); + } catch (e) { + failure = DataParsingFailure(e.toString()); + } + }, + ); + if (failure != null) return Left(failure!); + if (apiResponse == null) return Left(ServerFailure("Unknown error")); + return Right(apiResponse!); + } catch (e) { + loggerService.logError("AskDoctorRepo.getDoctorResponse error: $e"); + return Left(UnknownFailure(e.toString())); + } + } +} diff --git a/lib/features/ask_doctor/ask_doctor_view_model.dart b/lib/features/ask_doctor/ask_doctor_view_model.dart new file mode 100644 index 0000000..2b9600e --- /dev/null +++ b/lib/features/ask_doctor/ask_doctor_view_model.dart @@ -0,0 +1,93 @@ +import 'package:flutter/material.dart'; +import 'package:hmg_patient_app_new/core/utils/date_util.dart'; +import 'package:hmg_patient_app_new/features/ask_doctor/ask_doctor_repo.dart'; +import 'package:hmg_patient_app_new/features/ask_doctor/models/ask_doctor_appointments_list.dart'; +import 'package:hmg_patient_app_new/features/ask_doctor/models/doctor_response_model.dart'; +import 'package:hmg_patient_app_new/services/error_handler_service.dart'; + +class AskDoctorViewModel extends ChangeNotifier { + final AskDoctorRepo askDoctorRepo; + final ErrorHandlerService errorHandlerService; + + AskDoctorViewModel({ + required this.askDoctorRepo, + required this.errorHandlerService, + }); + + bool isAskDoctorAppointmentsLoading = false; + bool isDoctorResponsesLoading = false; + + List askDoctorAppointmentsList = []; + List doctorResponsesList = []; + + /// Initialize the view model + void initAskDoctorViewModel() { + askDoctorAppointmentsList.clear(); + doctorResponsesList.clear(); + isAskDoctorAppointmentsLoading = true; + getAskDoctorAppointmentsList(); + notifyListeners(); + } + + Future getAskDoctorAppointmentsList({Function(dynamic)? onSuccess, Function(String)? onError}) async { + final result = await askDoctorRepo.getAskDoctorAppointmentsList(); + + result.fold( + (failure) async => await errorHandlerService.handleError(failure: failure), + (apiResponse) { + if (apiResponse.messageStatus == 2) { + // dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {}); + } else if (apiResponse.messageStatus == 1) { + askDoctorAppointmentsList = apiResponse.data!; + isAskDoctorAppointmentsLoading = false; + notifyListeners(); + if (onSuccess != null) { + onSuccess(apiResponse); + } + } + }, + ); + } + + /// Get doctor responses from a specific date + Future getDoctorResponses({ + String? fromDate, + Function(dynamic)? onSuccess, + Function(String)? onError, + }) async { + isDoctorResponsesLoading = true; + notifyListeners(); + + // If no date provided, use current date minus 30 days + final dateToUse = "${DateTime.now().year}-${DateTime.now().month}-${DateTime.now().day} ${DateTime.now().hour}:${DateTime.now().minute}:00"; + + final result = await askDoctorRepo.getDoctorResponse(fromDate: dateToUse); + + result.fold( + (failure) async { + isDoctorResponsesLoading = false; + notifyListeners(); + await errorHandlerService.handleError(failure: failure); + if (onError != null) { + onError(failure.toString()); + } + }, + (apiResponse) { + isDoctorResponsesLoading = false; + + if (apiResponse.messageStatus == 2) { + notifyListeners(); + if (onError != null) { + onError(apiResponse.errorMessage ?? "Unknown error"); + } + } else if (apiResponse.messageStatus == 1) { + doctorResponsesList = apiResponse.data ?? []; + notifyListeners(); + if (onSuccess != null) { + onSuccess(apiResponse); + } + } + }, + ); + } +} diff --git a/lib/features/ask_doctor/models/ask_doctor_appointments_list.dart b/lib/features/ask_doctor/models/ask_doctor_appointments_list.dart new file mode 100644 index 0000000..7f40d71 --- /dev/null +++ b/lib/features/ask_doctor/models/ask_doctor_appointments_list.dart @@ -0,0 +1,200 @@ +class AskDoctorAppointmentHistoryList { + String? setupID; + int? projectID; + int? appointmentNo; + String? appointmentDate; + bool? appointmentType; + String? bookDate; + bool? patientType; + int? patientID; + int? clinicID; + int? doctorID; + String? endDate; + String? startTime; + String? endTime; + bool? status; + bool? visitType; + bool? isReminderActivated; + int? companyID; + String? bookedOn; + String? confirmedOn; + String? arrivedOn; + String? editedOn; + int? appointmentDays; + int? isActive; + int? actualDoctorRate; + String? clinicName; + String? date; + num? decimalDoctorRate; + String? doctorCases; + String? doctorImageURL; + String? doctorInfo; + String? doctorName; + num? doctorRate; + num? doctorStarsRate; + String? doctorTitle; + int? gender; + String? genderDescription; + bool? isActiveDoctorProfile; + bool? isAppointmentAllowed; + bool? isDoctorAllowVedioCall; + bool? isLiveCareClinic; + String? nationalityFlagURL; + String? nationalityID; + String? nationalityName; + int? noOfPatientsRate; + String? projectName; + String? qR; + List? speciality; + + AskDoctorAppointmentHistoryList( + {this.setupID, + this.projectID, + this.appointmentNo, + this.appointmentDate, + this.appointmentType, + this.bookDate, + this.patientType, + this.patientID, + this.clinicID, + this.doctorID, + this.endDate, + this.startTime, + this.endTime, + this.status, + this.visitType, + this.isReminderActivated, + this.companyID, + this.bookedOn, + this.confirmedOn, + this.arrivedOn, + this.editedOn, + this.appointmentDays, + this.isActive, + this.actualDoctorRate, + this.clinicName, + this.date, + this.decimalDoctorRate, + this.doctorCases, + this.doctorImageURL, + this.doctorInfo, + this.doctorName, + this.doctorRate, + this.doctorStarsRate, + this.doctorTitle, + this.gender, + this.genderDescription, + this.isActiveDoctorProfile, + this.isAppointmentAllowed, + this.isDoctorAllowVedioCall, + this.isLiveCareClinic, + this.nationalityFlagURL, + this.nationalityID, + this.nationalityName, + this.noOfPatientsRate, + this.projectName, + this.qR, + this.speciality}); + + AskDoctorAppointmentHistoryList.fromJson(Map json) { + setupID = json['SetupID']; + projectID = json['ProjectID']; + appointmentNo = json['AppointmentNo']; + appointmentDate = json['AppointmentDate']; + appointmentType = json['AppointmentType']; + bookDate = json['BookDate']; + patientType = json['PatientType']; + patientID = json['PatientID']; + clinicID = json['ClinicID']; + doctorID = json['DoctorID']; + endDate = json['EndDate']; + startTime = json['StartTime']; + endTime = json['EndTime']; + status = json['Status']; + visitType = json['VisitType']; + isReminderActivated = json['IsReminderActivated']; + companyID = json['CompanyID']; + bookedOn = json['BookedOn']; + confirmedOn = json['ConfirmedOn']; + arrivedOn = json['ArrivedOn']; + editedOn = json['EditedOn']; + appointmentDays = json['AppointmentDays']; + isActive = json['IsActive']; + actualDoctorRate = json['ActualDoctorRate']; + clinicName = json['ClinicName']; + date = json['Date']; + decimalDoctorRate = json['DecimalDoctorRate']; + doctorCases = json['DoctorCases']; + doctorImageURL = json['DoctorImageURL']; + doctorInfo = json['DoctorInfo']; + doctorName = json['DoctorName']; + doctorRate = json['DoctorRate']; + doctorStarsRate = json['DoctorStarsRate']; + doctorTitle = json['DoctorTitle']; + gender = json['Gender']; + genderDescription = json['GenderDescription']; + isActiveDoctorProfile = json['IsActiveDoctorProfile']; + isAppointmentAllowed = json['IsAppointmentAllowed']; + isDoctorAllowVedioCall = json['IsDoctorAllowVedioCall']; + isLiveCareClinic = json['IsLiveCareClinic']; + nationalityFlagURL = json['NationalityFlagURL']; + nationalityID = json['NationalityID']; + nationalityName = json['NationalityName']; + noOfPatientsRate = json['NoOfPatientsRate']; + projectName = json['ProjectName']; + qR = json['QR']; + speciality = json['Speciality'].cast(); + } + + Map toJson() { + final Map data = new Map(); + data['SetupID'] = this.setupID; + data['ProjectID'] = this.projectID; + data['AppointmentNo'] = this.appointmentNo; + data['AppointmentDate'] = this.appointmentDate; + data['AppointmentType'] = this.appointmentType; + data['BookDate'] = this.bookDate; + data['PatientType'] = this.patientType; + data['PatientID'] = this.patientID; + data['ClinicID'] = this.clinicID; + data['DoctorID'] = this.doctorID; + data['EndDate'] = this.endDate; + data['StartTime'] = this.startTime; + data['EndTime'] = this.endTime; + data['Status'] = this.status; + data['VisitType'] = this.visitType; + data['IsReminderActivated'] = this.isReminderActivated; + data['CompanyID'] = this.companyID; + data['BookedOn'] = this.bookedOn; + data['ConfirmedOn'] = this.confirmedOn; + data['ArrivedOn'] = this.arrivedOn; + data['EditedOn'] = this.editedOn; + data['AppointmentDays'] = this.appointmentDays; + data['IsActive'] = this.isActive; + data['ActualDoctorRate'] = this.actualDoctorRate; + data['ClinicName'] = this.clinicName; + data['Date'] = this.date; + data['DecimalDoctorRate'] = this.decimalDoctorRate; + data['DoctorCases'] = this.doctorCases; + data['DoctorImageURL'] = this.doctorImageURL; + data['DoctorInfo'] = this.doctorInfo; + data['DoctorName'] = this.doctorName; + data['DoctorRate'] = this.doctorRate; + data['DoctorStarsRate'] = this.doctorStarsRate; + data['DoctorTitle'] = this.doctorTitle; + data['Gender'] = this.gender; + data['GenderDescription'] = this.genderDescription; + data['IsActiveDoctorProfile'] = this.isActiveDoctorProfile; + data['IsAppointmentAllowed'] = this.isAppointmentAllowed; + data['IsDoctorAllowVedioCall'] = this.isDoctorAllowVedioCall; + data['IsLiveCareClinic'] = this.isLiveCareClinic; + data['NationalityFlagURL'] = this.nationalityFlagURL; + data['NationalityID'] = this.nationalityID; + data['NationalityName'] = this.nationalityName; + data['NoOfPatientsRate'] = this.noOfPatientsRate; + data['ProjectName'] = this.projectName; + data['QR'] = this.qR; + data['Speciality'] = this.speciality; + return data; + } +} diff --git a/lib/features/ask_doctor/models/doctor_response_model.dart b/lib/features/ask_doctor/models/doctor_response_model.dart new file mode 100644 index 0000000..b44ee0a --- /dev/null +++ b/lib/features/ask_doctor/models/doctor_response_model.dart @@ -0,0 +1,180 @@ +class DoctorResponseModel { + int? projectID; + int? transactionNo; + int? patientID; + int? doctorID; + int? requestType; + String? requestTypeDescription; + dynamic requestTypeDescriptionN; + int? status; + String? remarks; + String? createdOn; + int? readStatus; + String? doctorResponse; + dynamic clinicID; + dynamic clinicName; + int? createdBy; + String? doctorName; + dynamic infoStatusDescription; + bool? isDoctorRespond; + bool? isPatientRead; + dynamic memberName; + dynamic memberNameN; + dynamic patientDateofBirth; + dynamic patientGender; + dynamic patientMobileNumber; + dynamic patientName; + dynamic patientNameN; + dynamic projectName; + dynamic statusDescription; + List? transactions; + + DoctorResponseModel( + {this.projectID, + this.transactionNo, + this.patientID, + this.doctorID, + this.requestType, + this.requestTypeDescription, + this.requestTypeDescriptionN, + this.status, + this.remarks, + this.createdOn, + this.readStatus, + this.doctorResponse, + this.clinicID, + this.clinicName, + this.createdBy, + this.doctorName, + this.infoStatusDescription, + this.isDoctorRespond, + this.isPatientRead, + this.memberName, + this.memberNameN, + this.patientDateofBirth, + this.patientGender, + this.patientMobileNumber, + this.patientName, + this.patientNameN, + this.projectName, + this.statusDescription, + this.transactions}); + + DoctorResponseModel.fromJson(Map json) { + projectID = json['ProjectID']; + transactionNo = json['TransactionNo']; + patientID = json['PatientID']; + doctorID = json['DoctorID']; + requestType = json['RequestType']; + requestTypeDescription = json['RequestTypeDescription']; + requestTypeDescriptionN = json['RequestTypeDescriptionN']; + status = json['Status']; + remarks = json['Remarks']; + createdOn = json['CreatedOn']; + readStatus = json['ReadStatus']; + doctorResponse = json['DoctorResponse']; + clinicID = json['ClinicID']; + clinicName = json['ClinicName']; + createdBy = json['CreatedBy']; + doctorName = json['DoctorName']; + infoStatusDescription = json['InfoStatusDescription']; + isDoctorRespond = json['IsDoctorRespond']; + isPatientRead = json['IsPatientRead']; + memberName = json['MemberName']; + memberNameN = json['MemberNameN']; + patientDateofBirth = json['PatientDateofBirth']; + patientGender = json['PatientGender']; + patientMobileNumber = json['PatientMobileNumber']; + patientName = json['PatientName']; + patientNameN = json['PatientNameN']; + projectName = json['ProjectName']; + statusDescription = json['StatusDescription']; + if (json['Transactions'] != null) { + transactions = []; + json['Transactions'].forEach((v) { + transactions!.add(new Transactions.fromJson(v)); + }); + } + } + + Map toJson() { + final Map data = new Map(); + data['ProjectID'] = this.projectID; + data['TransactionNo'] = this.transactionNo; + data['PatientID'] = this.patientID; + data['DoctorID'] = this.doctorID; + data['RequestType'] = this.requestType; + data['RequestTypeDescription'] = this.requestTypeDescription; + data['RequestTypeDescriptionN'] = this.requestTypeDescriptionN; + data['Status'] = this.status; + data['Remarks'] = this.remarks; + data['CreatedOn'] = this.createdOn; + data['ReadStatus'] = this.readStatus; + data['DoctorResponse'] = this.doctorResponse; + data['ClinicID'] = this.clinicID; + data['ClinicName'] = this.clinicName; + data['CreatedBy'] = this.createdBy; + data['DoctorName'] = this.doctorName; + data['InfoStatusDescription'] = this.infoStatusDescription; + data['IsDoctorRespond'] = this.isDoctorRespond; + data['IsPatientRead'] = this.isPatientRead; + data['MemberName'] = this.memberName; + data['MemberNameN'] = this.memberNameN; + data['PatientDateofBirth'] = this.patientDateofBirth; + data['PatientGender'] = this.patientGender; + data['PatientMobileNumber'] = this.patientMobileNumber; + data['PatientName'] = this.patientName; + data['PatientNameN'] = this.patientNameN; + data['ProjectName'] = this.projectName; + data['StatusDescription'] = this.statusDescription; + if (this.transactions != null) { + data['Transactions'] = this.transactions!.map((v) => v.toJson()).toList(); + } + return data; + } +} + +class Transactions { + int? lineItemNo; + String? doctorResponse; + int? infoEnteredBy; + String? infoEnteredOn; + String? createdOn; + int? infoStatus; + String? infoStatusDescription; + dynamic infoStatusDescriptionN; + + Transactions( + {this.lineItemNo, + this.doctorResponse, + this.infoEnteredBy, + this.infoEnteredOn, + this.createdOn, + this.infoStatus, + this.infoStatusDescription, + this.infoStatusDescriptionN}); + + Transactions.fromJson(Map json) { + lineItemNo = json['LineItemNo']; + doctorResponse = json['DoctorResponse']; + infoEnteredBy = json['InfoEnteredBy']; + infoEnteredOn = json['InfoEnteredOn']; + createdOn = json['CreatedOn']; + infoStatus = json['InfoStatus']; + infoStatusDescription = json['InfoStatusDescription']; + infoStatusDescriptionN = json['InfoStatusDescriptionN']; + } + + Map toJson() { + final Map data = new Map(); + data['LineItemNo'] = this.lineItemNo; + data['DoctorResponse'] = this.doctorResponse; + data['InfoEnteredBy'] = this.infoEnteredBy; + data['InfoEnteredOn'] = this.infoEnteredOn; + data['CreatedOn'] = this.createdOn; + data['InfoStatus'] = this.infoStatus; + data['InfoStatusDescription'] = this.infoStatusDescription; + data['InfoStatusDescriptionN'] = this.infoStatusDescriptionN; + return data; + } +} diff --git a/lib/main.dart b/lib/main.dart index ec3b7ec..79b600c 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -8,6 +8,7 @@ import 'package:flutter/services.dart'; import 'package:hmg_patient_app_new/core/app_state.dart'; import 'package:hmg_patient_app_new/core/dependencies.dart'; import 'package:hmg_patient_app_new/core/utils/utils.dart'; +import 'package:hmg_patient_app_new/features/ask_doctor/ask_doctor_view_model.dart'; import 'package:hmg_patient_app_new/features/authentication/authentication_view_model.dart'; import 'package:hmg_patient_app_new/features/blood_donation/blood_donation_view_model.dart'; import 'package:hmg_patient_app_new/features/active_prescriptions/active_prescriptions_view_model.dart'; @@ -197,6 +198,9 @@ void main() async { ), ChangeNotifierProvider( create: (_) => getIt.get(), + ), + ChangeNotifierProvider( + create: (_) => getIt.get(), ) ], child: MyApp()), ), diff --git a/lib/presentation/ask_doctor/ask_doctor_page.dart b/lib/presentation/ask_doctor/ask_doctor_page.dart new file mode 100644 index 0000000..4c2c267 --- /dev/null +++ b/lib/presentation/ask_doctor/ask_doctor_page.dart @@ -0,0 +1,104 @@ +import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_staggered_animations/flutter_staggered_animations.dart'; +import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; +import 'package:hmg_patient_app_new/core/utils/utils.dart'; +import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; +import 'package:hmg_patient_app_new/features/ask_doctor/ask_doctor_view_model.dart'; +import 'package:hmg_patient_app_new/features/medical_file/models/patient_sickleave_response_model.dart'; +import 'package:hmg_patient_app_new/features/my_appointments/my_appointments_view_model.dart'; +import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; +import 'package:hmg_patient_app_new/presentation/appointments/widgets/appointment_card.dart'; +import 'package:hmg_patient_app_new/presentation/ask_doctor/doctor_response_page.dart'; +import 'package:hmg_patient_app_new/presentation/ask_doctor/widgets/ask_doctor_appointment_card.dart'; +import 'package:hmg_patient_app_new/presentation/medical_file/widgets/patient_sick_leave_card.dart'; +import 'package:hmg_patient_app_new/theme/colors.dart'; +import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart'; +import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; +import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart'; +import 'package:provider/provider.dart'; + +class AskDoctorPage extends StatefulWidget { + const AskDoctorPage({super.key}); + + @override + State createState() => _AskDoctorPageState(); +} + +class _AskDoctorPageState extends State { + late MyAppointmentsViewModel myAppointmentsViewModel; + + @override + Widget build(BuildContext context) { + myAppointmentsViewModel = Provider.of(context, listen: false); + return Scaffold( + backgroundColor: AppColors.bgScaffoldColor, + body: Consumer( + builder: (context, askDoctorVM, child) { + return CollapsingListView( + title: LocaleKeys.askDoctor.tr(context: context), + doctorResponse: () { + askDoctorVM.getDoctorResponses(); + Navigator.of(context).push( + CustomPageRoute( + page: DoctorResponsePage(), + ), + ); + }, + child: SingleChildScrollView( + child: Column(children: [ + SizedBox(height: 16.h), + ListView.builder( + padding: EdgeInsets.only(top: 8.h), + shrinkWrap: true, + physics: NeverScrollableScrollPhysics(), + itemCount: askDoctorVM.isAskDoctorAppointmentsLoading + ? 4 + : askDoctorVM.askDoctorAppointmentsList.isNotEmpty + ? askDoctorVM.askDoctorAppointmentsList.length + : 1, + itemBuilder: (context, index) { + return askDoctorVM.isAskDoctorAppointmentsLoading + ? Container( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.h, hasShadow: true), + child: PatientSickLeaveCard( + patientSickLeavesResponseModel: PatientSickLeavesResponseModel(), + isLoading: true, + )).paddingSymmetrical(0.w, 12.h) + : askDoctorVM.askDoctorAppointmentsList.isNotEmpty + ? AnimationConfiguration.staggeredList( + position: index, + duration: const Duration(milliseconds: 500), + child: SlideAnimation( + verticalOffset: 100.0, + child: FadeInAnimation( + child: AnimatedContainer( + duration: Duration(milliseconds: 300), + curve: Curves.easeInOut, + margin: EdgeInsets.symmetric(vertical: 8.h), + decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 20.h, hasShadow: true), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + AskDoctorAppointmentCard( + askDoctorAppointmentHistoryList: askDoctorVM.askDoctorAppointmentsList[index], + myAppointmentsViewModel: myAppointmentsViewModel, + ) + ], + ), + ), + ), + ), + ) + : Utils.getNoDataWidget(context, noDataText: LocaleKeys.noAppointmentsYet.tr(context: context)); + }, + ).paddingSymmetrical(24.h, 0.h), + SizedBox(height: 24.h), + ]), + ), + ); + }, + ), + ); + } +} diff --git a/lib/presentation/ask_doctor/doctor_response_page.dart b/lib/presentation/ask_doctor/doctor_response_page.dart new file mode 100644 index 0000000..9cd19ef --- /dev/null +++ b/lib/presentation/ask_doctor/doctor_response_page.dart @@ -0,0 +1,157 @@ +import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_staggered_animations/flutter_staggered_animations.dart'; +import 'package:hmg_patient_app_new/core/app_assets.dart'; +import 'package:hmg_patient_app_new/core/utils/date_util.dart'; +import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; +import 'package:hmg_patient_app_new/core/utils/utils.dart'; +import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; +import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; +import 'package:hmg_patient_app_new/features/ask_doctor/ask_doctor_view_model.dart'; +import 'package:hmg_patient_app_new/features/medical_file/models/patient_sickleave_response_model.dart'; +import 'package:hmg_patient_app_new/features/my_appointments/my_appointments_view_model.dart'; +import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; +import 'package:hmg_patient_app_new/presentation/appointments/widgets/appointment_card.dart'; +import 'package:hmg_patient_app_new/presentation/ask_doctor/widgets/ask_doctor_appointment_card.dart'; +import 'package:hmg_patient_app_new/presentation/ask_doctor/widgets/doctor_response_transactions.dart'; +import 'package:hmg_patient_app_new/presentation/medical_file/widgets/patient_sick_leave_card.dart'; +import 'package:hmg_patient_app_new/theme/colors.dart'; +import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart'; +import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; +import 'package:hmg_patient_app_new/widgets/chip/app_custom_chip_widget.dart'; +import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart'; +import 'package:provider/provider.dart'; + +class DoctorResponsePage extends StatefulWidget { + const DoctorResponsePage({super.key}); + + @override + State createState() => _DoctorResponsePageState(); +} + +class _DoctorResponsePageState extends State { + late MyAppointmentsViewModel myAppointmentsViewModel; + + @override + Widget build(BuildContext context) { + myAppointmentsViewModel = Provider.of(context, listen: false); + return Scaffold( + backgroundColor: AppColors.bgScaffoldColor, + body: CollapsingListView( + title: LocaleKeys.doctorResponses.tr(context: context), + child: SingleChildScrollView( + child: Column( + children: [ + SizedBox(height: 16.h), + Consumer(builder: (context, askDoctorVM, child) { + return ListView.builder( + padding: EdgeInsets.zero, + shrinkWrap: true, + physics: NeverScrollableScrollPhysics(), + itemCount: askDoctorVM.isDoctorResponsesLoading + ? 4 + : askDoctorVM.doctorResponsesList.isNotEmpty + ? askDoctorVM.doctorResponsesList.length + : 1, + itemBuilder: (context, index) { + return askDoctorVM.isDoctorResponsesLoading + ? Container( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.h, hasShadow: true), + child: PatientSickLeaveCard( + patientSickLeavesResponseModel: PatientSickLeavesResponseModel(), + isLoading: true, + )).paddingSymmetrical(0.w, 12.h) + : askDoctorVM.doctorResponsesList.isNotEmpty + ? AnimationConfiguration.staggeredList( + position: index, + duration: const Duration(milliseconds: 500), + child: SlideAnimation( + verticalOffset: 100.0, + child: FadeInAnimation( + child: AnimatedContainer( + duration: Duration(milliseconds: 300), + curve: Curves.easeInOut, + margin: EdgeInsets.symmetric(vertical: 8.h), + decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 20.h, hasShadow: true), + child: Padding( + padding: EdgeInsets.all(16.w), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + askDoctorVM.doctorResponsesList[index].requestTypeDescription!.toText18(isBold: true), + SizedBox(height: 24.h), + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Image.network( + "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown.png", + width: 50.w, + height: 50.h, + fit: BoxFit.cover, + ).circle(100.r), + ], + ), + SizedBox(width: 16.h), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + askDoctorVM.doctorResponsesList[index].doctorName!.toText16(isBold: true, maxlines: 1), + SizedBox(height: 8.h), + Wrap( + direction: Axis.horizontal, + spacing: 3.h, + runSpacing: 4.h, + children: [ + AppCustomChipWidget( + labelText: (askDoctorVM.doctorResponsesList[index].clinicName ?? "").length > 15 + ? '${askDoctorVM.doctorResponsesList[index].clinicName!.substring(0, 12)}...' + : askDoctorVM.doctorResponsesList[index].clinicName ?? "", + ), + AppCustomChipWidget( + labelText: (askDoctorVM.doctorResponsesList[index].projectName ?? "").length > 15 + ? '${askDoctorVM.doctorResponsesList[index].projectName!.substring(0, 12)}...' + : askDoctorVM.doctorResponsesList[index].projectName ?? ""), + AppCustomChipWidget( + labelPadding: EdgeInsetsDirectional.only(start: -4.w, end: 6.w), + icon: AppAssets.appointment_calendar_icon, + labelText: DateUtil.formatDateToDate(DateUtil.convertStringToDate(askDoctorVM.doctorResponsesList[index].createdOn), false), + ), + ], + ), + ], + ), + ), + ], + ), + ], + ), + ), + ).onPress(() { + showCommonBottomSheetWithoutHeight( + context, + title: askDoctorVM.doctorResponsesList[index].requestTypeDescription!, + child: DoctorResponseTransactions(doctorResponseModel: askDoctorVM.doctorResponsesList[index],), + callBackFunc: () {}, + isFullScreen: false, + isCloseButtonVisible: true, + ); + }), + ), + ), + ) + : Utils.getNoDataWidget(context, noDataText: LocaleKeys.noDataAvailable.tr(context: context)); + }, + ).paddingSymmetrical(24.h, 0.h); + }), + SizedBox(height: 24.h), + ], + ), + ), + ), + ); + } +} diff --git a/lib/presentation/ask_doctor/widgets/ask_doctor_appointment_card.dart b/lib/presentation/ask_doctor/widgets/ask_doctor_appointment_card.dart new file mode 100644 index 0000000..4ff24c7 --- /dev/null +++ b/lib/presentation/ask_doctor/widgets/ask_doctor_appointment_card.dart @@ -0,0 +1,205 @@ +import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/material.dart'; +import 'package:hmg_patient_app_new/core/app_assets.dart'; +import 'package:hmg_patient_app_new/core/app_state.dart'; +import 'package:hmg_patient_app_new/core/dependencies.dart'; +import 'package:hmg_patient_app_new/core/utils/date_util.dart'; +import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; +import 'package:hmg_patient_app_new/core/utils/utils.dart'; +import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; +import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; +import 'package:hmg_patient_app_new/features/ask_doctor/models/ask_doctor_appointments_list.dart'; +import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/patient_appointment_history_response_model.dart'; +import 'package:hmg_patient_app_new/features/my_appointments/my_appointments_view_model.dart'; +import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; +import 'package:hmg_patient_app_new/presentation/appointments/widgets/ask_doctor_request_type_select.dart'; +import 'package:hmg_patient_app_new/theme/colors.dart'; +import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; +import 'package:hmg_patient_app_new/widgets/chip/app_custom_chip_widget.dart'; +import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart'; +import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart'; + +class AskDoctorAppointmentCard extends StatelessWidget { + final AskDoctorAppointmentHistoryList askDoctorAppointmentHistoryList; + final MyAppointmentsViewModel myAppointmentsViewModel; + + const AskDoctorAppointmentCard({super.key, required this.askDoctorAppointmentHistoryList, required this.myAppointmentsViewModel}); + + @override + Widget build(BuildContext context) { + final appState = getIt.get(); + return Padding( + padding: EdgeInsets.all(14.h), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + _buildHeader(context, appState), + SizedBox(height: 16.h), + _buildDoctorRow(context), + SizedBox(height: 16.h), + _buildActionArea(context, appState), + ], + ), + ); + } + + Widget _buildHeader(BuildContext context, AppState appState) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded(child: _buildChips(context, appState)), + ], + ); + } + + Widget _buildChips(BuildContext context, AppState appState) { + return Wrap( + alignment: WrapAlignment.start, + direction: Axis.horizontal, + spacing: 6.w, + runSpacing: 6.h, + children: [ + AppCustomChipWidget( + icon: AppAssets.walkin_appointment_icon, + iconColor: AppColors.textColor, + labelText: LocaleKeys.walkin.tr(context: context), + backgroundColor: AppColors.greyColor, + textColor: AppColors.textColor, + ), + AppCustomChipWidget( + labelText: LocaleKeys.outPatient.tr(context: context), + backgroundColor: AppColors.primaryRedColor.withValues(alpha: 0.1), + textColor: AppColors.primaryRedColor, + ), + AppCustomChipWidget( + labelText: LocaleKeys.booked.tr(context: context), + backgroundColor: AppColors.successColor.withValues(alpha: 0.1), + textColor: AppColors.successColor, + ), + ], + ); + } + + Widget _buildDoctorRow(BuildContext context) { + return Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Image.network( + askDoctorAppointmentHistoryList.doctorImageURL!, + width: 63.h, + height: 63.h, + fit: BoxFit.cover, + ).circle(100.r), + Transform.translate( + offset: Offset(0.0, -20.h), + child: Container( + width: 40.w, + height: 40.h, + decoration: BoxDecoration( + color: AppColors.whiteColor, + shape: BoxShape.circle, // Makes the container circular + border: Border.all( + color: AppColors.scaffoldBgColor, // Color of the border + width: 1.5.w, // Width of the border + ), + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Utils.buildSvgWithAssets(icon: AppAssets.rating_icon, width: 15.w, height: 15.h), + SizedBox(height: 2.h), + "${askDoctorAppointmentHistoryList.decimalDoctorRate}".toText11(isBold: true, color: AppColors.textColor), + ], + ), + ).circle(100), + ), + ], + ), + SizedBox(width: 16.h), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ("${askDoctorAppointmentHistoryList.doctorTitle} ${askDoctorAppointmentHistoryList.doctorName!}").toText16(isBold: true, maxlines: 1), + SizedBox(height: 8.h), + Wrap( + direction: Axis.horizontal, + spacing: 3.h, + runSpacing: 4.h, + children: [ + AppCustomChipWidget( + labelText: + askDoctorAppointmentHistoryList.clinicName!.length > 15 ? '${askDoctorAppointmentHistoryList.clinicName!.substring(0, 12)}...' : askDoctorAppointmentHistoryList.clinicName!, + ), + AppCustomChipWidget( + labelText: askDoctorAppointmentHistoryList.projectName!.length > 15 + ? '${askDoctorAppointmentHistoryList.projectName!.substring(0, 12)}...' + : askDoctorAppointmentHistoryList.projectName!), + AppCustomChipWidget( + labelPadding: EdgeInsetsDirectional.only(start: -4.w, end: 6.w), + icon: AppAssets.appointment_calendar_icon, + labelText: DateUtil.formatDateToDate(DateUtil.convertStringToDate(askDoctorAppointmentHistoryList.appointmentDate), false), + ), + ], + ), + ], + ), + ), + ], + ); + } + + Widget _buildActionArea(BuildContext context, AppState appState) { + return CustomButton( + text: LocaleKeys.askDoctor.tr(context: context), + onPressed: () async { + LoaderBottomSheet.showLoader(loadingText: LocaleKeys.checkingDoctorAvailability.tr(context: context)); + await myAppointmentsViewModel.isDoctorAvailable( + projectID: askDoctorAppointmentHistoryList.projectID!, + doctorId: askDoctorAppointmentHistoryList.doctorID!, + clinicId: askDoctorAppointmentHistoryList.clinicID!, + onSuccess: (value) async { + if (value) { + await myAppointmentsViewModel.getAskDoctorRequestTypes(onSuccess: (val) { + LoaderBottomSheet.hideLoader(); + showCommonBottomSheetWithoutHeight( + context, + title: LocaleKeys.askDoctor.tr(context: context), + child: AskDoctorRequestTypeSelect( + askDoctorRequestTypeList: myAppointmentsViewModel.askDoctorRequestTypeList, + myAppointmentsViewModel: myAppointmentsViewModel, + patientAppointmentHistoryResponseModel: PatientAppointmentHistoryResponseModel() + // myAppointmentsVM.patientAppointmentsHistoryList[index], + ), + callBackFunc: () {}, + isFullScreen: false, + isCloseButtonVisible: true, + ); + }); + } else { + LoaderBottomSheet.hideLoader(); + } + }, + onError: (_) { + LoaderBottomSheet.hideLoader(); + }, + ); + }, + backgroundColor: AppColors.secondaryLightRedColor, + borderColor: AppColors.secondaryLightRedColor, + textColor: AppColors.primaryRedColor, + fontSize: 14.f, + fontWeight: FontWeight.w500, + borderRadius: 12.r, + padding: EdgeInsets.symmetric(horizontal: 10.w), + // height: isTablet || isFoldable ? 46.h : 40.h, + height: 40.h, + icon: AppAssets.ask_doctor_icon, + iconColor: AppColors.primaryRedColor, + iconSize: 16.h, + ); + } +} diff --git a/lib/presentation/ask_doctor/widgets/doctor_response_transactions.dart b/lib/presentation/ask_doctor/widgets/doctor_response_transactions.dart new file mode 100644 index 0000000..33b544d --- /dev/null +++ b/lib/presentation/ask_doctor/widgets/doctor_response_transactions.dart @@ -0,0 +1,131 @@ +import 'package:flutter/material.dart'; +import 'package:hmg_patient_app_new/core/app_assets.dart'; +import 'package:hmg_patient_app_new/core/app_state.dart'; +import 'package:hmg_patient_app_new/core/dependencies.dart'; +import 'package:hmg_patient_app_new/core/utils/date_util.dart'; +import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; +import 'package:hmg_patient_app_new/core/utils/utils.dart'; +import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; +import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; +import 'package:hmg_patient_app_new/features/ask_doctor/models/doctor_response_model.dart'; +import 'package:hmg_patient_app_new/theme/colors.dart'; +import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; +import 'package:hmg_patient_app_new/widgets/chip/app_custom_chip_widget.dart'; + +class DoctorResponseTransactions extends StatelessWidget { + const DoctorResponseTransactions({super.key, required this.doctorResponseModel}); + + final DoctorResponseModel doctorResponseModel; + + @override + Widget build(BuildContext context) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Image.network( + "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown.png", + width: 50.w, + height: 50.h, + fit: BoxFit.cover, + ).circle(100.r), + ], + ), + SizedBox(width: 16.h), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + doctorResponseModel.doctorName!.toText16(isBold: true, maxlines: 1), + SizedBox(height: 8.h), + Wrap( + direction: Axis.horizontal, + spacing: 3.h, + runSpacing: 4.h, + children: [ + AppCustomChipWidget( + labelText: (doctorResponseModel.clinicName ?? "").length > 15 ? '${doctorResponseModel.clinicName!.substring(0, 12)}...' : doctorResponseModel.clinicName ?? "", + ), + AppCustomChipWidget( + labelText: (doctorResponseModel.projectName ?? "").length > 15 ? '${doctorResponseModel.projectName!.substring(0, 12)}...' : doctorResponseModel.projectName ?? ""), + AppCustomChipWidget( + labelPadding: EdgeInsetsDirectional.only(start: -4.w, end: 6.w), + icon: AppAssets.appointment_calendar_icon, + labelText: DateUtil.formatDateToDate(DateUtil.convertStringToDate(doctorResponseModel.createdOn), false), + ), + ], + ), + ], + ), + ), + ], + ), + SizedBox(height: 16.h), + Divider(color: AppColors.dividerColor, height: 1.h), + SizedBox(height: 16.h), + Padding( + padding: EdgeInsets.symmetric(horizontal: 72.w), + child: CustomButton( + text: DateUtil.formatDateToDate(DateUtil.convertStringToDate(doctorResponseModel.createdOn), false), + onPressed: () {}, + backgroundColor: AppColors.greyColor, + borderColor: AppColors.greyColor, + textColor: AppColors.textColor, + fontSize: 14.f, + fontWeight: FontWeight.w500, + borderRadius: 10.r, + height: 40.h, + ).paddingSymmetrical(16.w, 0.h), + ), + SizedBox(height: 16.h), + Row( + children: [ + Image.asset(getIt.get().getAuthenticatedUser()?.gender == 1 ? AppAssets.maleImg : AppAssets.femaleImg, width: 42.w, height: 42.h), + SizedBox(width: 8.w), + Container( + padding: EdgeInsets.all(8.w), + decoration: BoxDecoration( + color: AppColors.infoColor.withAlpha(20), + borderRadius: BorderRadius.circular(8.r), + ), + child: doctorResponseModel.requestTypeDescription!.toText12(color: AppColors.infoColor, fontWeight: FontWeight.w500), + ), + ], + ), + SizedBox(height: 24.h), + ListView.builder( + padding: EdgeInsets.zero, + itemCount: doctorResponseModel.transactions!.length, + shrinkWrap: true, + physics: NeverScrollableScrollPhysics(), + itemBuilder: (context, index) { + return Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Container( + padding: EdgeInsets.all(8.w), + decoration: BoxDecoration( + color: AppColors.infoColor.withAlpha(20), + borderRadius: BorderRadius.circular(8.r), + ), + child: doctorResponseModel.transactions![index].doctorResponse!.toText12(color: AppColors.textColor, fontWeight: FontWeight.w500), + ), + SizedBox(width: 8.w), + Image.network("https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown.png", fit: BoxFit.cover, width: 42.w, height: 42.h).circle(100.r), + ], + ), + ], + ); + }, + ), + ], + ); + } +} diff --git a/lib/presentation/authentication/register.dart b/lib/presentation/authentication/register.dart index d14419f..71bddb3 100644 --- a/lib/presentation/authentication/register.dart +++ b/lib/presentation/authentication/register.dart @@ -162,10 +162,12 @@ class _RegisterNew extends State { GestureDetector( onTap: () { // Navigate to terms and conditions page - Navigator.of(context).pushNamed('/terms'); + Utils.openWebView( + url: 'https://hmg.com/en/Pages/Terms.aspx', + ); }, child: Text( - LocaleKeys.termsConditoins.tr(context: context), + " ${LocaleKeys.termsConditoins.tr(context: context)}", style: context.dynamicTextStyle( fontSize: 14.f, fontWeight: FontWeight.w500, diff --git a/lib/presentation/book_appointment/book_appointment_page.dart b/lib/presentation/book_appointment/book_appointment_page.dart index bc0c49a..b95e0c2 100644 --- a/lib/presentation/book_appointment/book_appointment_page.dart +++ b/lib/presentation/book_appointment/book_appointment_page.dart @@ -314,11 +314,9 @@ class _BookAppointmentPageState extends State { ).paddingSymmetrical(24.h, 0.h); case 1: //TODO: Get LiveCare type Select UI from Hussain - return - // appState.isAuthenticated - // ? - Column( - children: [ + return appState.isAuthenticated + ? Column( + children: [ Container( decoration: RoundedRectangleBorder().toSmoothCornerDecoration( color: AppColors.whiteColor, @@ -429,8 +427,7 @@ class _BookAppointmentPageState extends State { ), ], ).paddingSymmetrical(24.h, 0.h) - // : getLiveCareNotLoggedInUI() - ; + : getLiveCareNotLoggedInUI(); default: SizedBox.shrink(); } @@ -459,9 +456,10 @@ class _BookAppointmentPageState extends State { SizedBox(width: 16.w), CustomButton( height: 40.h, + width: 40.w, text: "", onPressed: () => context.navigateWithName(AppRoutes.userInfoSelection), - icon: AppAssets.arrow_forward, + icon: getIt.get().isArabic() ? AppAssets.arrow_back : AppAssets.arrow_forward, ) ], ).paddingAll(24.w), diff --git a/lib/presentation/book_appointment/widgets/clinic_card.dart b/lib/presentation/book_appointment/widgets/clinic_card.dart index cab3b1a..7e3c8df 100644 --- a/lib/presentation/book_appointment/widgets/clinic_card.dart +++ b/lib/presentation/book_appointment/widgets/clinic_card.dart @@ -32,9 +32,9 @@ class ClinicCard extends StatelessWidget { child: Column( children: [ Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Utils.buildSvgWithAssets(icon: AppAssets.generic_clinic_icon, width: 24.h, height: 24.h, fit: BoxFit.contain).toShimmer2(isShow: isLoading), + Utils.buildSvgWithAssets(icon: "assets/images/clinicIcons/${clinicsListResponseModel.clinicID ?? 1}.svg", width: 24.w, height: 24.h, fit: BoxFit.contain).toShimmer2(isShow: isLoading), (clinicsListResponseModel.isLiveCareClinicAndOnline ?? true) - ? Utils.buildSvgWithAssets(icon: AppAssets.livecare_clinic_icon, width: 32.h, height: 32.h, fit: BoxFit.contain).toShimmer2(isShow: isLoading) + ? Utils.buildSvgWithAssets(icon: AppAssets.livecare_clinic_icon, width: 32.w, height: 32.h, fit: BoxFit.contain).toShimmer2(isShow: isLoading) : SizedBox.shrink(), ], ), diff --git a/lib/presentation/hmg_services/services_view.dart b/lib/presentation/hmg_services/services_view.dart index 59efb73..99085a5 100644 --- a/lib/presentation/hmg_services/services_view.dart +++ b/lib/presentation/hmg_services/services_view.dart @@ -24,11 +24,12 @@ class ServiceGridViewItem extends StatelessWidget { @override Widget build(BuildContext context) { return InkWell( - onTap: () => hmgServiceComponentModel.isExternalLink - ? _openLink(hmgServiceComponentModel.route!) - : getIt - .get() - .pushPageRoute(hmgServiceComponentModel.route!), + onTap: () => hmgServiceComponentModel.route != null ? getIt.get().pushPageRoute(hmgServiceComponentModel.route!) : hmgServiceComponentModel.onTap!(), + // onTap: () => hmgServiceComponentModel.isExternalLink + // ? _openLink(hmgServiceComponentModel.route!) + // : getIt + // .get() + // .pushPageRoute(hmgServiceComponentModel.route!), child: Column( mainAxisSize: MainAxisSize.max, crossAxisAlignment: CrossAxisAlignment.start, diff --git a/lib/presentation/home/landing_page.dart b/lib/presentation/home/landing_page.dart index b633404..770e953 100644 --- a/lib/presentation/home/landing_page.dart +++ b/lib/presentation/home/landing_page.dart @@ -249,7 +249,7 @@ class _LandingPageState extends State { ); }), !appState.isAuthenticated - ? Utils.buildSvgWithAssets(icon: appState.isArabic() ? AppAssets.enLangIcon : AppAssets.arLangIcon, height: 18.h, width: 18.h).onPress(() { + ? Utils.buildSvgWithAssets(icon: AppAssets.changeLanguageHomePageIcon, height: 18.h, width: 18.h).onPress(() { context.setLocale(appState.isArabic() ? Locale('en', 'US') : Locale('ar', 'SA')); }) : SizedBox.shrink() diff --git a/lib/presentation/home/widgets/habib_wallet_card.dart b/lib/presentation/home/widgets/habib_wallet_card.dart index fb04baf..0725b1d 100644 --- a/lib/presentation/home/widgets/habib_wallet_card.dart +++ b/lib/presentation/home/widgets/habib_wallet_card.dart @@ -24,13 +24,13 @@ class HabibWalletCard extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ LocaleKeys.myBalance.tr(context: context).toText16(isBold: true), - Row( - children: [ - LocaleKeys.viewAllServices.tr(context: context).toText12(color: AppColors.primaryRedColor), - SizedBox(width: 2.h), - Icon(Icons.arrow_forward_ios, color: AppColors.primaryRedColor, size: 10.h), - ], - ), + // Row( + // children: [ + // LocaleKeys.viewAllServices.tr(context: context).toText12(color: AppColors.primaryRedColor), + // SizedBox(width: 2.h), + // Icon(Icons.arrow_forward_ios, color: AppColors.primaryRedColor, size: 10.h), + // ], + // ), ], ).paddingSymmetrical(24.h, 0.h), SizedBox(height: 16.h), diff --git a/lib/presentation/medical_file/medical_file_page.dart b/lib/presentation/medical_file/medical_file_page.dart index fa8a591..1fdf8ea 100644 --- a/lib/presentation/medical_file/medical_file_page.dart +++ b/lib/presentation/medical_file/medical_file_page.dart @@ -17,6 +17,7 @@ import 'package:hmg_patient_app_new/extensions/route_extensions.dart'; import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; import 'package:hmg_patient_app_new/features/active_prescriptions/models/active_prescriptions_response_model.dart'; +import 'package:hmg_patient_app_new/features/ask_doctor/ask_doctor_view_model.dart'; import 'package:hmg_patient_app_new/features/book_appointments/book_appointments_view_model.dart'; import 'package:hmg_patient_app_new/features/book_appointments/models/resp_models/doctors_list_response_model.dart'; import 'package:hmg_patient_app_new/features/hmg_services/hmg_services_view_model.dart'; @@ -38,6 +39,7 @@ import 'package:hmg_patient_app_new/presentation/allergies/allergies_list_page.d import 'package:hmg_patient_app_new/presentation/appointments/my_appointments_page.dart'; import 'package:hmg_patient_app_new/presentation/appointments/my_doctors_page.dart'; import 'package:hmg_patient_app_new/presentation/appointments/widgets/ask_doctor_request_type_select.dart'; +import 'package:hmg_patient_app_new/presentation/ask_doctor/ask_doctor_page.dart'; import 'package:hmg_patient_app_new/presentation/book_appointment/book_appointment_page.dart'; import 'package:hmg_patient_app_new/presentation/book_appointment/doctor_profile_page.dart'; import 'package:hmg_patient_app_new/presentation/book_appointment/widgets/appointment_calendar.dart'; @@ -1374,7 +1376,14 @@ class _MedicalFilePageState extends State { svgIcon: AppAssets.ask_doctor_medical_file_icon, isLargeText: true, iconSize: 36.w, - ).onPress(() {}), + ).onPress(() { + getIt.get().initAskDoctorViewModel(); + Navigator.of(context).push( + CustomPageRoute( + page: AskDoctorPage(), + ), + ); + }), // MedicalFileCard( // label: LocaleKeys.internetPairing.tr(context: context), // textColor: AppColors.blackColor, diff --git a/lib/presentation/symptoms_checker/organ_selector_screen.dart b/lib/presentation/symptoms_checker/organ_selector_screen.dart index e3944c2..9a4a1d9 100644 --- a/lib/presentation/symptoms_checker/organ_selector_screen.dart +++ b/lib/presentation/symptoms_checker/organ_selector_screen.dart @@ -99,11 +99,11 @@ class _OrganSelectorPageState extends State { flipX: _appState.isArabic(), child: IconButton( icon: Utils.buildSvgWithAssets( - icon: AppAssets.arrow_back, - width: 32.h, - height: 32.h, + icon: AppAssets.forward_top_nav_icon, + width: 24.w, + height: 24.h, ), - padding: EdgeInsetsDirectional.only(start: 12), + padding: EdgeInsetsDirectional.only(start: 12, end: 12), onPressed: () => Navigator.pop(context), highlightColor: Colors.transparent, ), diff --git a/lib/presentation/symptoms_checker/risk_factors_screen.dart b/lib/presentation/symptoms_checker/risk_factors_screen.dart index 8264b8b..484ad2d 100644 --- a/lib/presentation/symptoms_checker/risk_factors_screen.dart +++ b/lib/presentation/symptoms_checker/risk_factors_screen.dart @@ -125,6 +125,7 @@ class _RiskFactorsScreenState extends State { fontSize: 13.f, fontWeight: FontWeight.w500, color: AppColors.greyInfoTextColor, + fontFamily: isArabic ? 'GESSTwo' : 'Poppins' ), children: [ TextSpan( diff --git a/lib/presentation/symptoms_checker/triage_screen.dart b/lib/presentation/symptoms_checker/triage_screen.dart index a7975e2..0811833 100644 --- a/lib/presentation/symptoms_checker/triage_screen.dart +++ b/lib/presentation/symptoms_checker/triage_screen.dart @@ -467,18 +467,14 @@ class _TriagePageState extends State { text: TextSpan( text: LocaleKeys.possibleSymptom.tr(context: context), style: TextStyle( - color: AppColors.greyTextColor, - fontWeight: FontWeight.w600, - fontSize: 14.f, - ), + color: AppColors.greyTextColor, fontWeight: FontWeight.w600, fontSize: 14.f, fontFamily: isArabic ? 'GESSTwo' : 'Poppins'), children: [ TextSpan( text: suggestedCondition, style: TextStyle( color: AppColors.textColor, fontWeight: FontWeight.w600, - fontSize: 14.f, - ), + fontSize: 14.f, fontFamily: isArabic ? 'GESSTwo' : 'Poppins'), ), ], ), @@ -494,6 +490,7 @@ class _TriagePageState extends State { text: TextSpan( text: "${probability.toStringAsFixed(1)}% ", style: TextStyle( + fontFamily: isArabic ? 'GESSTwo' : 'Poppins', color: AppColors.primaryRedColor, fontWeight: FontWeight.w600, fontSize: 14.f, @@ -505,6 +502,7 @@ class _TriagePageState extends State { color: AppColors.textColor, fontWeight: FontWeight.w500, fontSize: 13.f, + fontFamily: isArabic ? 'GESSTwo' : 'Poppins', ), ), ], diff --git a/lib/widgets/appbar/collapsing_list_view.dart b/lib/widgets/appbar/collapsing_list_view.dart index 897d241..3cae108 100644 --- a/lib/widgets/appbar/collapsing_list_view.dart +++ b/lib/widgets/appbar/collapsing_list_view.dart @@ -24,6 +24,7 @@ class CollapsingListView extends StatelessWidget { VoidCallback? instructions; VoidCallback? requests; VoidCallback? sendEmail; + VoidCallback? doctorResponse; Widget? bottomChild; Widget? trailing; bool isClose; @@ -44,6 +45,7 @@ class CollapsingListView extends StatelessWidget { this.instructions, this.requests, this.sendEmail, + this.doctorResponse, this.isLeading = true, this.trailing, this.leadingCallback, @@ -83,6 +85,7 @@ class CollapsingListView extends StatelessWidget { instructions: instructions, requests: requests, sendEmail: sendEmail, + doctorResponse: doctorResponse, bottomChild: bottomChild, trailing: trailing, ) @@ -114,6 +117,7 @@ class CollapsingListView extends StatelessWidget { instructions: instructions, requests: requests, sendEmail: sendEmail, + doctorResponse: doctorResponse, bottomChild: bottomChild, trailing: trailing, ), @@ -188,6 +192,7 @@ class ScrollAnimatedTitle extends StatefulWidget implements PreferredSizeWidget VoidCallback? instructions; VoidCallback? requests; VoidCallback? sendEmail; + VoidCallback? doctorResponse; Widget? bottomChild; Widget? trailing; @@ -203,6 +208,7 @@ class ScrollAnimatedTitle extends StatefulWidget implements PreferredSizeWidget this.instructions, this.requests, this.sendEmail, + this.doctorResponse, this.bottomChild, this.trailing, }); @@ -277,6 +283,7 @@ class _ScrollAnimatedTitleState extends State { if (widget.instructions != null) actionButton(context, t, title: LocaleKeys.instructions.tr(context: context), icon: AppAssets.requests).onPress(widget.instructions!), if (widget.requests != null) actionButton(context, t, title: LocaleKeys.requests.tr(context: context), icon: AppAssets.insurance_history_icon).onPress(widget.requests!), if (widget.sendEmail != null) actionButton(context, t, title: LocaleKeys.sendEmail.tr(context: context), icon: AppAssets.email).onPress(widget.sendEmail!), + if (widget.doctorResponse != null) actionButton(context, t, title: LocaleKeys.doctorResponses.tr(context: context), icon: AppAssets.doctorResponseIcon).onPress(widget.doctorResponse!), if (widget.search != null) Utils.buildSvgWithAssets(icon: AppAssets.search_icon).onPress(widget.search!), if (widget.trailing != null) widget.trailing!, ] diff --git a/pubspec.yaml b/pubspec.yaml index cdad394..26903b6 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -115,6 +115,7 @@ flutter: - assets/images/png/body_parts/female/ - assets/images/svg/ - assets/images/png/ + - assets/images/clinicIcons/ - assets/images/png/zoom/ - assets/images/png/smartwatches/ - assets/animations/