From fc749de77ea9af00cef75bb6475c128d083c252f Mon Sep 17 00:00:00 2001 From: Mohammad Aljammal Date: Tue, 21 Jul 2020 12:16:32 +0300 Subject: [PATCH 1/9] create doctor card and medical page --- assets/images/Icon-awesome-calendar.png | Bin 0 -> 408 bytes assets/images/medical/doctor_icon.png | Bin 0 -> 1073 bytes .../medical/insurance_approvals_icon.png | Bin 0 -> 1040 bytes assets/images/medical/insurance_card_icon.png | Bin 0 -> 700 bytes assets/images/medical/lab_result_icon.png | Bin 0 -> 1208 bytes .../images/medical/medical_history_icon.png | Bin 0 -> 1189 bytes assets/images/medical/prescription_icon.png | Bin 0 -> 990 bytes assets/images/medical/radiology_icon.png | Bin 0 -> 1491 bytes ios/Flutter/Debug.xcconfig | 1 + ios/Flutter/Release.xcconfig | 1 + lib/main.dart | 3 +- lib/pages/landing/landing_page.dart | 4 +- lib/pages/medical/medical_page.dart | 132 ++++++++++++++++++ lib/pages/medical/my_admissions_page.dart | 61 ++++++++ lib/widgets/avatar/large_avatar.dart | 8 +- .../data_display/medical/doctor_card.dart | 99 +++++++++++++ .../medical/medical_profile_item.dart | 53 +++++++ lib/widgets/others/StarRating.dart | 39 ++++++ .../others/app_expandable_notifier.dart | 8 +- lib/widgets/others/card_with_bg_widget.dart | 71 ++++++++++ .../others/rounded_container_widget.dart | 86 ++++++++++++ .../others/sliver_app_bar_delegate.dart | 34 +++++ pubspec.yaml | 1 + 23 files changed, 591 insertions(+), 10 deletions(-) create mode 100644 assets/images/Icon-awesome-calendar.png create mode 100644 assets/images/medical/doctor_icon.png create mode 100644 assets/images/medical/insurance_approvals_icon.png create mode 100644 assets/images/medical/insurance_card_icon.png create mode 100644 assets/images/medical/lab_result_icon.png create mode 100644 assets/images/medical/medical_history_icon.png create mode 100644 assets/images/medical/prescription_icon.png create mode 100644 assets/images/medical/radiology_icon.png create mode 100644 lib/pages/medical/medical_page.dart create mode 100644 lib/pages/medical/my_admissions_page.dart create mode 100644 lib/widgets/data_display/medical/doctor_card.dart create mode 100644 lib/widgets/data_display/medical/medical_profile_item.dart create mode 100644 lib/widgets/others/StarRating.dart create mode 100644 lib/widgets/others/card_with_bg_widget.dart create mode 100644 lib/widgets/others/rounded_container_widget.dart create mode 100644 lib/widgets/others/sliver_app_bar_delegate.dart diff --git a/assets/images/Icon-awesome-calendar.png b/assets/images/Icon-awesome-calendar.png new file mode 100644 index 0000000000000000000000000000000000000000..f058ca7751708be04ea0caccb087948640534906 GIT binary patch literal 408 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 HDWM4fAch|v literal 0 HcmV?d00001 diff --git a/assets/images/medical/lab_result_icon.png b/assets/images/medical/lab_result_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..c9425278f5831ecac7f49e134b2177cb6eb83e3c GIT binary patch literal 1208 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 M07*qoM6N<$f<$z$DgXcg literal 0 HcmV?d00001 diff --git a/assets/images/medical/radiology_icon.png b/assets/images/medical/radiology_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..9e760d650364c8792746b380ad7f7597fb328b9c GIT binary patch literal 1491 zcmV;^1uXiBP)Px#IAvH#W=%~1DgXcg2mk?xX#fNO00031000^Q000000-yo_1ONa40RR91C7=TU z1ONa40RR91D*ylh01PmlQ~&@4Nl8ROR9FeMmH&0rRuF{^hyPJ3h^Qb+1%9c3r2>lz zPzM$juvB2V0yY(_r~st`$rX61!1?a(j59n-UU8D#b3V2e`uf2ELE-d z>hBHZvFE-n7=6zV=Id+x0%uh*;fwWY3K)Xty)9k>%^bje#SW6i=qvA`2)%)Pm9%&l zCQI^sb9s^u7$NpsYN>+gAE-6&Qg7?Ux!5z%W(xt77UJs}UmLi7B^jZEkMJ2>-$~xV3z$F`a%m4;)HQgrCTgQL4A$iGcE*NSflIae zLO)(tL6TqxH4JbM@}(YHSS4+~u}N*9jT)=-P+^SVmr}gRhpg6K6LcW;(7`Hc<7AVH zsTA%2)z8`ECCIhK=*^7z#jAWW)Mdz(4xrzOzLp&vAQ|$tv7`%1chDHR*aW@B zinxK#ARSKO^jvc(U!b^yEBO7i{J7bB^VP4-S9lFQXiWthNbm*O|i$?E)&692|}n$H>Wt{`8x#hXCd zfY#+R>iwXON`o#fIDp>9-WZ9RnV^OSRJ&J^cfs3}i*M$&L@9yRC|NUj#HN1iM@D*MdgvYP1P=Pk5F#l|@b#qbKh~nd?F)s#f=xaRc zjTCVxXxWA_fRgqsfMP@H}yDp!(t+8bG=3X6DK|Xlkf|1gli}vO8fXm zQCt2bR5&H*uofgO&_)j+U+9ym?jeD60C^2)O$+Yn&1u~TaYo)1lm_9cw4oM>7F;?+ zJzZw7ydp;F0If^G)Vd99LA@O$a1A8#wQuES9utO!G@Pr%P;Zkp3hKS}{D2SHjLIH% zN`kajYYy_3ep5ZYJ2(yzqqITPCB-$2@CH5_Ux{0ge+4CIt=>ky#{p03^mwJmf_C`T zOmD!ug)gCZN3I`v2fBcy!{vX44qV?!HeOitb9R~kq-<~=p1A)Q+9*K@u0(PGtrJ_2 z3P^_XTnR(-$KG>qYRFe+^;}=xTbrwirR4`=Z~0s(&D7kpU*B1I55Q+hkLr1DPwDxmHg2=AnmQihxgXY9zbD>U?lT@WTYzgMX}vfX zdj@vdkT&qm^QgmWNU(>zAM1v`OMa}~pN+aupLOEKOSvw$)N|kWt!y?Ck6QW{-TMQ{ zr56_e%IdkYm@_kPvbxOt#s6mVxwx>&o7DPO`m@E@zN2{jQ;!Yut<{yq-s0KNGNISK z$tKU$Hh{p$B=Z)iS9Cicvaj0zarGchw{lRN#ugvD!_G-plOe zvZbYid&m_pHqul*rv}q6A1|ueGW1lhQpc1w)TfzK!t?_*^9kOMll*b!TpK>jz2C2>hV tobzI7>L-0|T0jRAxN4FTb}+yy{SCB?2F(eR$hH6g002ovPDHLkV1iQ0&P@OS literal 0 HcmV?d00001 diff --git a/ios/Flutter/Debug.xcconfig b/ios/Flutter/Debug.xcconfig index 592ceee8..e8efba11 100644 --- a/ios/Flutter/Debug.xcconfig +++ b/ios/Flutter/Debug.xcconfig @@ -1 +1,2 @@ +#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" #include "Generated.xcconfig" diff --git a/ios/Flutter/Release.xcconfig b/ios/Flutter/Release.xcconfig index 592ceee8..399e9340 100644 --- a/ios/Flutter/Release.xcconfig +++ b/ios/Flutter/Release.xcconfig @@ -1 +1,2 @@ +#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" #include "Generated.xcconfig" diff --git a/lib/main.dart b/lib/main.dart index 2eb5dd26..186ec52f 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -53,6 +53,7 @@ class MyApp extends StatelessWidget { hintColor: Colors.grey[400], disabledColor: Colors.grey[300], errorColor: Color.fromRGBO(235, 80, 60, 1.0), + scaffoldBackgroundColor: Colors.grey[100], textSelectionColor: Color.fromRGBO(80, 100, 253, 0.5), textSelectionHandleColor: Color.fromRGBO(80, 100, 253, 1.0), canvasColor: Colors.white, @@ -63,7 +64,7 @@ class MyApp extends StatelessWidget { cursorColor: Color.fromRGBO(78, 62, 253, 1.0), iconTheme: IconThemeData(), appBarTheme: AppBarTheme( - color: Colors.grey, + color: Colors.grey[700], brightness: Brightness.light, elevation: 0.0, actionsIconTheme: IconThemeData( diff --git a/lib/pages/landing/landing_page.dart b/lib/pages/landing/landing_page.dart index ec9e1524..b92804a5 100644 --- a/lib/pages/landing/landing_page.dart +++ b/lib/pages/landing/landing_page.dart @@ -1,4 +1,6 @@ import 'package:diplomaticquarterapp/pages/landing/replay_page.dart'; +import 'package:diplomaticquarterapp/pages/medical/medical_page.dart'; +import 'package:diplomaticquarterapp/pages/medical/my_admissions_page.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/bottom_navigation/bottom_nav_bar.dart'; import 'package:diplomaticquarterapp/widgets/drawer/app_drawer_widget.dart'; @@ -55,7 +57,7 @@ class _LandingPageState extends State { body: PageView( physics: NeverScrollableScrollPhysics(), controller: pageController, - children: [HomePage(), ReplayPage(), Container(), Container()], + children: [HomePage(), ReplayPage(), MedicalPage(), MyAdmissionsPage()], ), bottomNavigationBar: BottomNavBar(changeIndex: _changeCurrentTab), ); diff --git a/lib/pages/medical/medical_page.dart b/lib/pages/medical/medical_page.dart new file mode 100644 index 00000000..049ba0bc --- /dev/null +++ b/lib/pages/medical/medical_page.dart @@ -0,0 +1,132 @@ +import 'dart:math'; + +import 'package:diplomaticquarterapp/widgets/data_display/medical/medical_profile_item.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/others/sliver_app_bar_delegate.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +class MedicalPage extends StatefulWidget { + @override + _MedicalPageState createState() => _MedicalPageState(); + +} + +class _MedicalPageState extends State { + @override + Widget build(BuildContext context) { + return AppScaffold( + body: CustomScrollView( + physics: BouncingScrollPhysics(), + key: PageStorageKey("medical"), + slivers: [ + SliverPersistentHeader( + delegate: SliverAppBarDelegate( + maxHeight: 200.0, + minHeight: 200.0, + child: Container( + width: double.infinity, + height: 200, + color: Colors.grey, + ), + ), + ), + SliverPersistentHeader( + delegate: SliverAppBarDelegate( + maxHeight: double.maxFinite, + minHeight: double.maxFinite, + child: Padding( + padding: EdgeInsets.symmetric(vertical: 12.0), + child: Column( + children: [ + + Row( + children: [ + Expanded( + flex: 1, + child: MedicalProfileItem( + title: 'My Doctor', + imagePath: 'doctor_icon.png', + subTitle: 'List', + ), + ), + Expanded( + flex: 1, + child: MedicalProfileItem( + title: 'Lab', + imagePath: 'lab_result_icon.png', + subTitle: 'Result', + ), + ) + ], + ), + Row( + children: [ + Expanded( + flex: 1, + child: MedicalProfileItem( + title: 'Radiology', + imagePath: 'radiology_icon.png', + subTitle: 'Service', + ), + ), + Expanded( + flex: 1, + child: MedicalProfileItem( + title: 'Medicines', + imagePath: 'prescription_icon.png', + subTitle: 'Prescriptions', + ), + ) + ], + ), + Row( + children: [ + Expanded( + flex: 1, + child: MedicalProfileItem( + title: 'Insurance', + imagePath: 'insurance_card_icon.png', + subTitle: 'Card', + ), + ), + Expanded( + flex: 1, + child: MedicalProfileItem( + title: 'Insurance', + imagePath: 'insurance_approvals_icon.png', + subTitle: 'Approvals', + ), + ) + ], + ), + Row( + children: [ + Expanded( + flex: 1, + child: MedicalProfileItem( + title: 'Medical', + imagePath: 'medical_history_icon.png', + subTitle: 'Reports', + ), + ), + Expanded( + flex: 1, + child: Container(), + ) + + ], + ), + ], + ), + ), + ), + ), + ], + + ), + ); + } +} + + diff --git a/lib/pages/medical/my_admissions_page.dart b/lib/pages/medical/my_admissions_page.dart new file mode 100644 index 00000000..ff25884e --- /dev/null +++ b/lib/pages/medical/my_admissions_page.dart @@ -0,0 +1,61 @@ +import 'package:diplomaticquarterapp/widgets/data_display/medical/doctor_card.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_expandable_notifier.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:flutter/cupertino.dart'; + +class MyAdmissionsPage extends StatefulWidget { + @override + _MyAdmissionsPageState createState() => _MyAdmissionsPageState(); +} + +class _MyAdmissionsPageState extends State { + @override + Widget build(BuildContext context) { + return AppScaffold( + body: ListView( + children: [ + AppExpandableNotifier( + title: 'Arryan Hospital', + bodyWidget: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + DoctorCard( + name: 'Dr Mohammad Aljammal', + date: 'Feb 14, 2020', + profileUrl: + 'https://scontent.famm4-1.fna.fbcdn.net/v/t31.0-8/30425660_1862582094040824_7851633779570222226_o.jpg?_nc_cat=101&_nc_sid=09cbfe&_nc_eui2=AeF3TI6D2_tFS5QoQsqyaCKd2zBfzh74hOzbMF_OHviE7PQdLHRwmBoIOiKyWmK9MskOshPjkU73a5EdQMA3dqnV&_nc_ohc=1feou2fDCuIAX_Ra9qB&_nc_ht=scontent.famm4-1.fna&oh=709d34d1c284de1d0aa08ed37b0ac09a&oe=5F3C5ACB', + rat: 3.8, + subName: 'Jammal', + ), + DoctorCard( + name: 'Dr Mohammad Aljammal', + date: 'Feb 14, 2020', + profileUrl: + 'https://scontent.famm4-1.fna.fbcdn.net/v/t31.0-8/30425660_1862582094040824_7851633779570222226_o.jpg?_nc_cat=101&_nc_sid=09cbfe&_nc_eui2=AeF3TI6D2_tFS5QoQsqyaCKd2zBfzh74hOzbMF_OHviE7PQdLHRwmBoIOiKyWmK9MskOshPjkU73a5EdQMA3dqnV&_nc_ohc=1feou2fDCuIAX_Ra9qB&_nc_ht=scontent.famm4-1.fna&oh=709d34d1c284de1d0aa08ed37b0ac09a&oe=5F3C5ACB', + rat: 3.8, + subName: 'Jammal', + ), + ], + ), + ), + + AppExpandableNotifier( + title: 'Arryan Hospital', + bodyWidget: DoctorCard( + onTap: () { + //TODO when we need it + }, + name: 'Dr Mohammad Aljammal', + date: 'Feb 14, 2020', + profileUrl: + 'https://scontent.famm4-1.fna.fbcdn.net/v/t31.0-8/30425660_1862582094040824_7851633779570222226_o.jpg?_nc_cat=101&_nc_sid=09cbfe&_nc_eui2=AeF3TI6D2_tFS5QoQsqyaCKd2zBfzh74hOzbMF_OHviE7PQdLHRwmBoIOiKyWmK9MskOshPjkU73a5EdQMA3dqnV&_nc_ohc=1feou2fDCuIAX_Ra9qB&_nc_ht=scontent.famm4-1.fna&oh=709d34d1c284de1d0aa08ed37b0ac09a&oe=5F3C5ACB', + rat: 4.8, + subName: 'Jammal', + ), + ), + + ], + ), + ); + } +} diff --git a/lib/widgets/avatar/large_avatar.dart b/lib/widgets/avatar/large_avatar.dart index cd6ee539..ed904d03 100644 --- a/lib/widgets/avatar/large_avatar.dart +++ b/lib/widgets/avatar/large_avatar.dart @@ -16,9 +16,9 @@ class LargeAvatar extends StatelessWidget { @required this.name, this.url, this.disableProfileView: false, - this.radius = 60.0, - this.width = 90, - this.height = 90, + this.radius = 70.0, + this.width = 70, + this.height = 60, this.onTap}) : super(key: key); @@ -71,7 +71,7 @@ class LargeAvatar extends StatelessWidget { offset: Offset(0.0, 5.0), blurRadius: 16.0) ], - borderRadius: BorderRadius.all(Radius.circular(50.0)), + borderRadius: BorderRadius.all(Radius.circular(radius)), ), width: width, height: height, diff --git a/lib/widgets/data_display/medical/doctor_card.dart b/lib/widgets/data_display/medical/doctor_card.dart new file mode 100644 index 00000000..e9a94895 --- /dev/null +++ b/lib/widgets/data_display/medical/doctor_card.dart @@ -0,0 +1,99 @@ +import 'package:diplomaticquarterapp/widgets/avatar/large_avatar.dart'; +import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/widgets/others/StarRating.dart'; +import 'package:diplomaticquarterapp/widgets/others/rounded_container_widget.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; + +class DoctorCard extends StatelessWidget { + final String name; + final String subName; + final double rat; + final String date; + final String profileUrl; + final Function onTap; + + DoctorCard( + {this.name, + this.subName, + this.rat, + this.date, + this.profileUrl, + this.onTap}); + + @override + Widget build(BuildContext context) { + return RoundedContainer( + child: InkWell( + onTap: onTap, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.all(8.0), + child: Row( + children: [ + Expanded( + flex: 1, + child: LargeAvatar( + name: name, + url: profileUrl, + ), + ), + Expanded( + flex: 4, + child: Container( + margin: EdgeInsets.all(10), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Texts( + name, + bold: true, + ), + Texts( + subName, + variant: 'bodyText', + ), + StarRating(totalAverage: rat, forceStars: true), + ], + ), + ), + ), + ], + ), + ), + + Divider( + height: 8, + color: Colors.grey[400], + ), + Padding( + padding: const EdgeInsets.all(5.0), + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + SizedBox( + width: 10, + ), + Image.asset( + 'assets/images/Icon-awesome-calendar.png', + width: 30, + height: 30, + ), + Expanded( + child: Texts( + date, + variant: 'bodyText', + ), + ) + ], + ), + ) + ], + ), + ), + ); + } +} diff --git a/lib/widgets/data_display/medical/medical_profile_item.dart b/lib/widgets/data_display/medical/medical_profile_item.dart new file mode 100644 index 00000000..6357d830 --- /dev/null +++ b/lib/widgets/data_display/medical/medical_profile_item.dart @@ -0,0 +1,53 @@ +import 'package:diplomaticquarterapp/config/size_config.dart'; +import 'package:diplomaticquarterapp/widgets/others/rounded_container_widget.dart'; +import 'package:flutter/material.dart'; +import 'package:hexcolor/hexcolor.dart'; + +class MedicalProfileItem extends StatelessWidget { + MedicalProfileItem({ + @required this.imagePath, + @required this.title, + @required this.subTitle, + }); + + final String imagePath; + final String title; + final String subTitle; + + @override + Widget build(BuildContext context) { + return RoundedContainer( + child: Container( + padding: EdgeInsets.all(5), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + title, + style: TextStyle( + fontSize: 1.7 * SizeConfig.textMultiplier, + color: Hexcolor('#B8382C'), + fontWeight: FontWeight.bold), + ), + RichText( + text: TextSpan( + style: TextStyle(color: Colors.black), + children: [ + TextSpan(text: subTitle), + ], + ), + ), + Align( + alignment: Alignment.bottomRight, + child: Image.asset( + "assets/images/medical/$imagePath", + height: SizeConfig.heightMultiplier * 7, + ), + ) + ], + ), + ), + ); + } +} diff --git a/lib/widgets/others/StarRating.dart b/lib/widgets/others/StarRating.dart new file mode 100644 index 00000000..f33ced32 --- /dev/null +++ b/lib/widgets/others/StarRating.dart @@ -0,0 +1,39 @@ +import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:eva_icons_flutter/eva_icons_flutter.dart'; +import 'package:flutter/material.dart'; + +class StarRating extends StatelessWidget { + + final double totalAverage; + final double size; + final int totalCount; + final bool forceStars; + + StarRating({Key key, this.totalAverage: 0.0, this.size: 16.0, this.totalCount, this.forceStars = false}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + if (!forceStars && (totalAverage==null || totalAverage==0)) + Texts("New", style: "caption"), + if (forceStars || (totalAverage!=null && totalAverage>0)) + ...List.generate(5, (index) => + Padding( + padding: EdgeInsets.only(right: 1.0), + child: Icon( + (index+1) <= (totalAverage ?? 0) ? EvaIcons.star : EvaIcons.starOutline, + size: size, + color: (index+1) <= (totalAverage ?? 0) ? Color.fromRGBO(255, 186, 0, 1.0) : Theme.of(context).hintColor + ), + ) + ), + if (totalCount!=null) + SizedBox(width: 9.0), + if (totalCount!=null) + Texts("("+totalCount.toString()+")", style: "overline", color: Colors.grey[400],) + ] + ); + } +} \ No newline at end of file diff --git a/lib/widgets/others/app_expandable_notifier.dart b/lib/widgets/others/app_expandable_notifier.dart index fca61f1f..0e2a3c4b 100644 --- a/lib/widgets/others/app_expandable_notifier.dart +++ b/lib/widgets/others/app_expandable_notifier.dart @@ -19,7 +19,7 @@ class AppExpandableNotifier extends StatelessWidget { Widget build(BuildContext context) { return ExpandableNotifier( child: Padding( - padding: const EdgeInsets.all(10), + padding: const EdgeInsets.only(left: 10,right: 10,top: 4), child: Card( clipBehavior: Clip.antiAlias, child: Column( @@ -39,14 +39,14 @@ class AppExpandableNotifier extends StatelessWidget { padding: EdgeInsets.all(10), child: Text( title, - style: TextStyle(fontWeight: FontWeight.bold), + style: TextStyle(fontWeight: FontWeight.bold,fontSize: 22,), ), ), - collapsed: collapsed, + collapsed: collapsed ?? Container(), expanded: bodyWidget, builder: (_, collapsed, expanded) { return Padding( - padding: EdgeInsets.only(left: 10, right: 10, bottom: 10), + padding: EdgeInsets.only(left: 5, right: 5, bottom: 5), child: Expandable( collapsed: collapsed, expanded: expanded, diff --git a/lib/widgets/others/card_with_bg_widget.dart b/lib/widgets/others/card_with_bg_widget.dart new file mode 100644 index 00000000..1b96008a --- /dev/null +++ b/lib/widgets/others/card_with_bg_widget.dart @@ -0,0 +1,71 @@ +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:flutter/material.dart'; +import 'package:hexcolor/hexcolor.dart'; +import 'package:provider/provider.dart'; + +/* + *@author: Mohammad Aljammal + *@Date:27/4/2020 + *@param: Widget + *@return: + *@desc: Card With Bg Widget + */ + +class CardWithBgWidget extends StatelessWidget { + final Widget child; + + CardWithBgWidget({@required this.child}); + + @override + Widget build(BuildContext context) { + ProjectViewModel projectProvider = Provider.of(context); + return Container( + margin: EdgeInsets.symmetric(vertical: 10.0), + width: double.infinity, + decoration: BoxDecoration( + borderRadius: BorderRadius.all( + Radius.circular(10.0), + ), + border: Border.all(color: Colors.grey, width: 1.0), + ), + child: Material( + borderRadius: BorderRadius.all(Radius.circular(10.0)), + child: Stack( + children: [ + if (projectProvider.isArabic) + Positioned( + child: Container( + width: 10, + color: Hexcolor('#58434F'), + ), + bottom: 0, + top: 0, + right: 0, + ) + else + Positioned( + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.only( + topLeft: Radius.circular(9.0), + bottomLeft: Radius.circular(9.0), + ),color: Colors.blueAccent, + + ), + width: 15, + + ), + bottom: 0, + top: 0, + left: 0, + ), + Container( + padding: EdgeInsets.all(15.0), + margin: EdgeInsets.only(left: 10), + child: child) + ], + ), + ), + ); + } +} diff --git a/lib/widgets/others/rounded_container_widget.dart b/lib/widgets/others/rounded_container_widget.dart new file mode 100644 index 00000000..58d9a034 --- /dev/null +++ b/lib/widgets/others/rounded_container_widget.dart @@ -0,0 +1,86 @@ +import 'package:flutter/material.dart'; + +/// DESCRIPTION : Custom widget for rounded container and custom decoration + +class RoundedContainer extends StatefulWidget { + final double width; + final double height; + final double raduis; + final Color backgroundColor; + final double margin; + final double elevation; + final bool showBorder; + final Color borderColor; + final bool customCornerRaduis; + final double topLeft; + final double bottomRight; + final double topRight; + final double bottomLeft; + final Widget child; + final double borderWidth; + + RoundedContainer( + {@required this.child, + this.width, + this.height, + this.raduis = 10, + this.backgroundColor = Colors.white, + this.margin = 10, + this.elevation = 1, + this.showBorder = false, + this.borderColor = Colors.grey, + this.customCornerRaduis = false, + this.topLeft = 0, + this.topRight = 0, + this.bottomRight = 0, + this.bottomLeft = 0, + this.borderWidth = 1}); + + @override + _RoundedContainerState createState() => _RoundedContainerState(); +} + +class _RoundedContainerState extends State { + @override + Widget build(BuildContext context) { + return Container( + width: widget.width, + height: widget.height, + margin: EdgeInsets.all(widget.margin), + decoration: widget.showBorder == true + ? BoxDecoration( + color: Theme.of(context).primaryColor, + border: Border.all( + color: widget.borderColor, width: widget.borderWidth), + borderRadius: widget.customCornerRaduis + ? BorderRadius.only( + topLeft: Radius.circular(widget.topLeft), + topRight: Radius.circular(widget.topRight), + bottomRight: Radius.circular(widget.bottomRight), + bottomLeft: Radius.circular(widget.bottomLeft)) + : BorderRadius.circular(widget.raduis), + boxShadow: [ + BoxShadow( + color: Colors.grey.withOpacity(0.1), + spreadRadius: 10, + blurRadius: 5, + offset: Offset(0, 5), // changes position of shadow + ), + ]) + : null, + child: Card( + margin: EdgeInsets.all(0), + shape: RoundedRectangleBorder( + borderRadius: widget.customCornerRaduis + ? BorderRadius.only( + topLeft: Radius.circular(widget.topLeft), + topRight: Radius.circular(widget.topRight), + bottomRight: Radius.circular(widget.bottomRight), + bottomLeft: Radius.circular(widget.bottomLeft)) + : BorderRadius.circular(widget.raduis), + ), + color: widget.backgroundColor, + child: widget.child, + )); + } +} diff --git a/lib/widgets/others/sliver_app_bar_delegate.dart b/lib/widgets/others/sliver_app_bar_delegate.dart new file mode 100644 index 00000000..49c9b4fd --- /dev/null +++ b/lib/widgets/others/sliver_app_bar_delegate.dart @@ -0,0 +1,34 @@ +import 'dart:math'; + +import 'package:flutter/cupertino.dart'; + +class SliverAppBarDelegate extends SliverPersistentHeaderDelegate { + SliverAppBarDelegate({ + @required this.minHeight, + @required this.maxHeight, + @required this.child, + }); + + final double minHeight; + final double maxHeight; + final Widget child; + + @override + double get minExtent => minHeight; + + @override + double get maxExtent => max(maxHeight, minHeight); + + @override + Widget build( + BuildContext context, + double shrinkOffset, + bool overlapsContent) + { + return new SizedBox.expand(child: child); + } + @override + bool shouldRebuild(SliverAppBarDelegate oldDelegate) { + return false; + } +} \ No newline at end of file diff --git a/pubspec.yaml b/pubspec.yaml index 4bb76eaa..426404b8 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -84,6 +84,7 @@ flutter: # assets: assets: - assets/images/ + - assets/images/medical/ fonts: - family: WorkSans From c018597d90e89ff0e132b954576888affa015776 Mon Sep 17 00:00:00 2001 From: Sultan Khan Date: Wed, 22 Jul 2020 12:03:11 +0300 Subject: [PATCH 2/9] confrim login page added --- lib/config/localized_values.dart | 4 + lib/pages/login/confirm-login.dart | 151 +++++++++++++++++++++++ lib/pages/login/login.dart | 6 +- lib/routes.dart | 5 +- lib/uitl/translations_delegate_base.dart | 2 + 5 files changed, 165 insertions(+), 3 deletions(-) create mode 100644 lib/pages/login/confirm-login.dart diff --git a/lib/config/localized_values.dart b/lib/config/localized_values.dart index 2527e363..57a4e403 100644 --- a/lib/config/localized_values.dart +++ b/lib/config/localized_values.dart @@ -48,4 +48,8 @@ const Map> localizedValues = { "dob": {"en": "Birth Date:", "ar": "تاريخ الميلاد"}, "hijri-date": {"en": "Hijri Date", "ar": "التاريخ الهجري"}, "gregorian-date": {"en": "Gregorian Date", "ar": "التاريخ الميلادي"}, + "verify-login-with": { + "en": "Please choose one of the following options to verify", + "ar": "الرجاء اختيار احدى الخيارات التالية للتحقق من البيانات" + } }; diff --git a/lib/pages/login/confirm-login.dart b/lib/pages/login/confirm-login.dart new file mode 100644 index 00000000..d6552883 --- /dev/null +++ b/lib/pages/login/confirm-login.dart @@ -0,0 +1,151 @@ +import 'package:diplomaticquarterapp/config/size_config.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/card/rounded_container.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/text/app_texts_widget.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:diplomaticquarterapp/routes.dart'; + +class ConfirmLogin extends StatelessWidget { + static int loginType = 0; + + @override + Widget build(BuildContext context) { + return AppScaffold( + appBarTitle: TranslationBase.of(context).welcome, + isShowAppBar: true, + body: Padding( + padding: EdgeInsets.all(20), + child: Column( + children: [ + Expanded( + flex: 4, + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Image.asset( + 'assets/images/habib-logo.png', + height: 80, + width: 80, + ), + AppText( + TranslationBase.of(context).verifyLoginWith, + fontSize: SizeConfig.textMultiplier * 3.5, + textAlign: TextAlign.left, + ), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Expanded( + child: InkWell( + onTap: () => {}, + child: RoundedContainer( + borderColor: Colors.grey, + showBorder: true, + child: Padding( + padding: EdgeInsets.fromLTRB( + 20, 10, 20, 10), + child: Column( + mainAxisAlignment: + MainAxisAlignment.center, + children: [ + Image.asset( + 'assets/images/id_card_icon.png', + height: SizeConfig + .imageSizeMultiplier * + 12, + width: SizeConfig + .imageSizeMultiplier * + 15, + ), + SizedBox( + height: 20, + ), + AppText( + TranslationBase.of(context) + .nationalID, + fontSize: + SizeConfig.textMultiplier * + 2, + ) + ], + ), + )))), + Expanded( + child: InkWell( + onTap: () => {}, + child: RoundedContainer( + borderColor: Colors.grey, + showBorder: true, + child: Padding( + padding: EdgeInsets.fromLTRB( + 25, 10, 25, 10), + child: Column( + children: [ + Image.asset( + 'assets/images/my_file_white_icon.png', + height: SizeConfig + .imageSizeMultiplier * + 12, + width: SizeConfig + .imageSizeMultiplier * + 15, + ), + SizedBox( + height: 20, + ), + AppText( + TranslationBase.of(context) + .fileNo, + fontSize: + SizeConfig.textMultiplier * + 2, + ) + ], + ), + )))) + ], + ), + Divider( + color: Colors.grey, + height: 2, + ), + Center( + child: InkWell( + onTap: () => {}, + child: AppText( + TranslationBase.of(context).forgotPassword, + fontSize: SizeConfig.textMultiplier * 3, + margin: 10, + underline: true))) + ]), + ), + Expanded( + flex: 2, + child: Column( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Row( + children: [ + Expanded( + child: RaisedButton( + color: Colors.grey, + textColor: Colors.white, + child: + Text(TranslationBase.of(context).registerNow), + onPressed: () => { + Navigator.of(context).pushNamed( + REGISTER, + ) + }, + )) + ], + ), + ], + )) + ], + ))); + } +} diff --git a/lib/pages/login/login.dart b/lib/pages/login/login.dart index 7bb61da5..ad88371b 100644 --- a/lib/pages/login/login.dart +++ b/lib/pages/login/login.dart @@ -4,6 +4,7 @@ import 'package:diplomaticquarterapp/core/model/auth/check_paitent_authenticatio import 'package:diplomaticquarterapp/core/service/client/base_app_client.dart'; import 'package:diplomaticquarterapp/pages/login/login-type.dart'; import 'package:diplomaticquarterapp/providers/auth_provider.dart'; +import 'package:diplomaticquarterapp/routes.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/utils.dart'; @@ -147,10 +148,11 @@ class _Login extends State { } sharedPref.setObject(REGISTER_DATA_FOR_REGISTER, request); authService.checkPatientAuthentication(request).then((value) => { - if (value.isSMSSent) + if (value['isSMSSent']) { - sharedPref.setString(LOGIN_TOKEN_ID, value.LogInTokenID), + sharedPref.setString(LOGIN_TOKEN_ID, value['LogInTokenID']), sharedPref.setObject(REGISTER_DATA_FOR_LOGIIN, request), + Navigator.of(context).pushNamed(CONFIRM_LOGIN) } else { diff --git a/lib/routes.dart b/lib/routes.dart index 8b3d1d4b..0ee2364b 100644 --- a/lib/routes.dart +++ b/lib/routes.dart @@ -1,4 +1,5 @@ import 'package:diplomaticquarterapp/pages/landing/landing_page.dart'; +import 'package:diplomaticquarterapp/pages/login/confirm-login.dart'; import 'package:diplomaticquarterapp/pages/login/forgot-password.dart'; import 'package:diplomaticquarterapp/pages/login/welcome.dart'; import 'package:diplomaticquarterapp/pages/login/login-type.dart'; @@ -14,6 +15,7 @@ const String LOGIN_TYPE = 'login-type'; const String LOGIN_PAGE = 'login-page'; const String FORGOT_PASSWORD = 'forgot-password'; const String REGISTER = 'register'; +const String CONFIRM_LOGIN = 'confrim-login'; var routes = { // ROOT: (_) => RootPage(), HOME: (_) => LandingPage(), @@ -21,5 +23,6 @@ var routes = { LOGIN_TYPE: (_) => LoginType(), LOGIN_PAGE: (_) => Login(), FORGOT_PASSWORD: (_) => ForgotPassword(), - REGISTER: (_) => Register() + REGISTER: (_) => Register(), + CONFIRM_LOGIN: (_) => ConfirmLogin() }; diff --git a/lib/uitl/translations_delegate_base.dart b/lib/uitl/translations_delegate_base.dart index 8a99c420..3a7d379d 100644 --- a/lib/uitl/translations_delegate_base.dart +++ b/lib/uitl/translations_delegate_base.dart @@ -64,6 +64,8 @@ class TranslationBase { String get hijriDate => localizedValues['hijri-date'][locale.languageCode]; String get gregorianDate => localizedValues['gregorian-date'][locale.languageCode]; + String get verifyLoginWith => + localizedValues['verify-login-with'][locale.languageCode]; } class TranslationBaseDelegate extends LocalizationsDelegate { From 76aeeffad7246b97fefd8bb79e7744578c7f046d Mon Sep 17 00:00:00 2001 From: Sultan Khan Date: Thu, 23 Jul 2020 17:50:41 +0300 Subject: [PATCH 3/9] login page changes --- .vscode/launch.json | 13 + android/app/src/main/AndroidManifest.xml | 1 + .../diplomaticquarterapp/MainActivity.kt | 13 +- assets/images/login/101.png | Bin 0 -> 3484 bytes assets/images/login/102.png | Bin 0 -> 3991 bytes assets/images/login/103.png | Bin 0 -> 2377 bytes assets/images/login/104.png | Bin 0 -> 4981 bytes assets/images/login/fileNum.png | Bin 0 -> 1515 bytes assets/images/login/forget.png | Bin 0 -> 1980 bytes assets/images/login/id.png | Bin 0 -> 1308 bytes assets/images/login/nationalID.png | Bin 0 -> 2834 bytes lib/config/localized_values.dart | 26 +- lib/config/shared_pref_kay.dart | 1 + .../check_paitent_authentication_req.dart | 0 .../get_mobile_info_request.dart | 96 +++++ .../get_mobile_info_response.dart | 292 ++++++++++++++ .../select_device_imei_res.dart | 0 .../send_activation_request.dart | 100 +++++ lib/pages/landing/landing_page.dart | 5 +- lib/pages/login/confirm-login.dart | 372 +++++++++++++++--- lib/pages/login/login-type.dart | 12 +- lib/pages/login/login.dart | 133 ++++--- lib/pages/login/register.dart | 17 +- lib/pages/login/welcome.dart | 29 +- .../authentication}/auth_provider.dart | 30 +- lib/uitl/translations_delegate_base.dart | 36 +- lib/widgets/buttons/defaultButton.dart | 26 ++ lib/widgets/drawer/app_drawer_widget.dart | 3 +- pubspec.yaml | 1 + 29 files changed, 1046 insertions(+), 160 deletions(-) create mode 100644 .vscode/launch.json create mode 100644 assets/images/login/101.png create mode 100644 assets/images/login/102.png create mode 100644 assets/images/login/103.png create mode 100644 assets/images/login/104.png create mode 100644 assets/images/login/fileNum.png create mode 100644 assets/images/login/forget.png create mode 100644 assets/images/login/id.png create mode 100644 assets/images/login/nationalID.png rename lib/{core/model/auth => models/Authentication}/check_paitent_authentication_req.dart (100%) create mode 100644 lib/models/Authentication/get_mobile_info_request.dart create mode 100644 lib/models/Authentication/get_mobile_info_response.dart rename lib/{core/model/auth => models/Authentication}/select_device_imei_res.dart (100%) create mode 100644 lib/models/Authentication/send_activation_request.dart rename lib/{providers => services/authentication}/auth_provider.dart (75%) create mode 100644 lib/widgets/buttons/defaultButton.dart diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 00000000..3287bb67 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,13 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Flutter", + "request": "launch", + "type": "dart" + } + ] +} \ No newline at end of file diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 02c26fa6..540276ba 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -51,4 +51,5 @@ + diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/MainActivity.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/MainActivity.kt index 7ae40d3f..b8a87c8c 100644 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/MainActivity.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/MainActivity.kt @@ -1,6 +1,11 @@ package com.cloud.diplomaticquarterapp +import androidx.annotation.NonNull; + import io.flutter.embedding.android.FlutterFragmentActivity + import io.flutter.embedding.engine.FlutterEngine + import io.flutter.plugins.GeneratedPluginRegistrant -import io.flutter.embedding.android.FlutterActivity - -class MainActivity: FlutterActivity() { -} +class MainActivity: FlutterFragmentActivity() { + override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) { + GeneratedPluginRegistrant.registerWith(flutterEngine); + } +} \ No newline at end of file diff --git a/assets/images/login/101.png b/assets/images/login/101.png new file mode 100644 index 0000000000000000000000000000000000000000..90c1c575a19e47ad913fbe1e2be3f9182be3f826 GIT binary patch literal 3484 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 ZIgsNVRcpaEn4PP#nej=?ebiaz{{cCP0nY#c literal 0 HcmV?d00001 diff --git a/assets/images/login/103.png b/assets/images/login/103.png new file mode 100644 index 0000000000000000000000000000000000000000..3326814bc80e6682a73f4a36f62f4cbd5b15f36d GIT binary patch literal 2377 zcmaJ@cT`hZ9)1bvMh9FeHrhNAR9qlU2qYMRkkBNE5Rj2(Ade72ib;?FYQV7(P{9$g zuF4=55QgT`22>Df!wf3oAO{uO*Fr4%_8{fU!T52S?aRlY}z1+)gOP zEHcm`X|#kVmhnVFP|L`U5+%r}XjtjzEeOP4Xob>+GQkDI$=PBY0gKmeX)%z={Qsc> z!Ix;MECBkC-v3D~WhIFrTmU2$B}k&-gNwmvQ;8|=5{NAmNmwFL{9+aTV?{ENG*%=A z-QBfSa{{e*@`M~wqIAuLZBuw( z*Fyg)-vXBNRV@U@SFt!)3{HEv|8>}lOR$5q!!Oo_Ctu7D31P=eU~8LCIi3N4CDq<^ zH=N^s8Ds4cK8b(m$_7)nbmh>oA#W>;fzd&iOpEumRzFtDe;bj%JDq;W%+NRF zqy??ahrXRQbH#!s)`eE-nk%pt#ybtH@{Z`|{eGisT|*v!_t@={k2SYy9g`yEzeC9d zwR0&o^~JY}Cxn?E7(};cAPSM{3LwFisQ^kBeAQ48UjHQ4-q&>!oU{^QB7H12&HD&B z<{D3RgxWKG_5)gN88jnRDbN=GbjcoA-{ALg*DT}CpBvXa>lneRe>DQ4Qn*pzw}{A zf~LsA<424Y7c(mP+dr5jtmt~J-xN`}UcIKHtX;X{QdoTJg{;W<0wr=?)E3*(kU`YF zrdXUV2p|!tg=#IKsr;rr47mH{mW+fS?Ceiru!?a!VK>PA(e;9M&= zVzu#(u)Z$Zt#bw2dOP*1w+XW^jFvn}Y`dKOsylKV0fo%!$C+PT-A$^@aoLfS5p?P9 zyn9%;(ZqDbypi+ezud3pKHK|P{hT$de$bt0l`gb8;^OtXZn4eSK*I8-nV5P8e>#+>C+m+g63uCHYj=eYN z-5b(Vv^4AXkr~@z7!jnC&($#7_k^1tt+-amsCT8c*Tw}rtx{h0cYeO7<7Z7mg#%(z zb^f--)ayB7lTAfkrS2nx1Brbzdd`J9j~rAf;WcFln5dVOvcLE3iyuqJQTaDDc0Kz9 zWUZoJq=9d8Y4tEb?uFY^RT+f4QHGfRtR>3bD->I%>zv;7hKWBB)~Vk4xd z1j7NX`;NDTYJT&6e2VMb(JE^#Jz{^Zuh=;`JkF~~{gedhpB8L%3H>%zCvRJ*4zotG z#IO*SMZEBhZ_kS+mp4EZ#o*WEPuUT?(DRuuO0TYexZ>P0ul6YpA8A-ySE)mMf&b~% zv@vM3@?K`39mUM*W?N`&@R>UHM^ZNR*jUBGNlwPg{?zeboDT%&s)Li$;`Y50_yvxy z>E==!gQ&SCk0c|eRWt5UryZRp&Z_*g@vZC}lxwFB$Y;#F^>4v-N?vj?q^$4JDR-Z( zOOVvAF1<5~P&=vy7^K5Dj0$rSTp#;rd=62m6SS_Ff=LOt>%^eZLB-mh6|f8Wz8w+R zUc%{{Je~4*ouN);%EiKV%^@KNTHkG_;IXY&Z`DWfd;CczyXsPGc zyVD%+N}8Xgptkwvkq?%pLFGI9d-f00J*_Kd>w`Z~eGgbp8Q5INFHw$dD&%4+%bL^X z0y)!3Co{&FH~t(=)pbm<)Wag-JM!~Q2_P9y6i7Xw3VFkY99pw DG{ouR literal 0 HcmV?d00001 diff --git a/assets/images/login/104.png b/assets/images/login/104.png new file mode 100644 index 0000000000000000000000000000000000000000..ad55ff74ccab0ca8b0e74beefb641f0d55274f09 GIT binary patch literal 4981 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 literal 0 HcmV?d00001 diff --git a/assets/images/login/fileNum.png b/assets/images/login/fileNum.png new file mode 100644 index 0000000000000000000000000000000000000000..386299b71c8891a99fa03ee33616a4045bb7e1a7 GIT binary patch literal 1515 zcmeAS@N?(olHy`uVBq!ia0vp^k|4~%1|*NXY)uAnN?apKg7ec#$`gxH85~pclTsBt za}(23gHjVyDhp4h+AuIMt7V2nltlRYSS9D@>Lr5I=vCwv0Ch7k*w|MTBqnF4mMA2p zrf25aD!t#mUr8Y|#a1cY)Yrhbz&SM|)1#^=HMq(zB)KX(*)m1R-cG@$!U||WZfZ%Q zLPc&)Ua?h$trFN=Dz9|8 z>y;bpKhp88yV>WRp=I1=9MH?=;jqG!%T2VElw`VEGWs$&r<-In3$Ab zT4JjNbScCOxdm`z^NOLt1Pn0!io^naLp=kKmtYEgeeo;J&4sHjE(uCSxEHIz#UYgi zsro^w#rdU0$-sz9QwCX8VC7ttnpl!w6q28x0}I7~jQo=P;*9(P1!reas97jzglFcZ z|Z5PA)9>IEf-+ybD@E~!PCWvMA{Mftf3U~gMx;&h9l zD^ByEdQ)(^#n26>UVWfr^g)q}6xlE#UXa%Gads*vRAZsrY^%^n9k zcf{5=9M^iR@z7VtELDWFc}ms!)#sf3Q^LMiCHPP6KK@VbbEor_C!9MB{)V01{(6p0 zlXbxAESu#5@xdOt{OJp|&kAerJgnsyeR=NGkK3eLQ?`zJe92QOY`BS%J!ACvQ>vKLOUft&R{Q3GL*V6<# zOQuc-mj#PnPRIHZt82`Ti~3Uk?B!Ylp0*+7m{3+ootz+WN)WnQ(*-(AUCxn zQK2F?C$HG5!d3}vt`(3C64qBz04piUwpD^SD#ABF!8yMuRl!uxOgGuk#7M#1QqR!L zz|zP>N5ROz&|KfZT;I@G*TB%qz|6|nQUMB-fVLH-q*(>IxIyg#@@$ndN=gc>^!3Zj z%k|2Q_413-^$jg8E%gnI^o@*kfhu&1EAvVcD|GXUm0>2hq!uR^WfqiV=I1GZOiWD5 zFD$Tv3bSNU;+l1ennz|zM-B0$V)JVzP|XC=H|jx7ncO3BHWAB;NpiyW)Z+ZoqGVvir744~DzI`cN=+=uFAB-e&w+(vKt_H^esM;Afr7I$DAX(zG{Q6U zQu51-HNkp(eXTt6ic1pnl2bihY?Xkf=w)W6SeY0Z8=JbAy1E)!8XFqAT3Q-g8aNv} zS~xj6IXPNdy213iEv!_1oxXPkT zDaO(tEs6~a3{4IK42}vM4GID*9%_$1)!wgt7akkI`KiVyDk5-(+Q}Vj>v(qCN_INU zcx&GFFMb-c(Bec%j}L6Sdsbx@+*rR{WlQv?4kKpGIFCp+HMNgUDi%6jgJ$rOxZilDsn=b#%Wm_aNYgar+ zlMc6o00)x-2MePBOA`afrKc9VT4(#HY0mWv))C|0a(QV`XVK0%|0K+0LSJ3Yn)>Va z)f>yhR)%C06l|!D6+6!tdL*G@+Nvw_9nw73hAqx8S>nY15*%(~o`_+S%#lHoW?}Yf4peUS8j`=g%`UGFB}8Jb(WD%<@4Zj& zRyLa1BgSHGZa&LHt>*UEjhi<=-j#p-`t@5!juhR!2W(`sxLGo1LCrWwdYF)gf(SYWlV6OyrcwDXu#-tSl`r8gF2m zJ$v>%mY?hH?91$B&s&%GS|?HbM&ABin+%?;{{8OVyRSO}G%g%G*!XyVadmaK*IjNs zef`q!TefXmc3t@S^XDtBgeD{=HeS1aJu@NUz}4S(_wgGZVSl{q@ynMlV|gA)-N z+xd4)*s9bsx4R$`m^&sE9N1n}>8@;liX}T-_f6W9WY65>4=2->UhlhlHT3@Nw$qyw zCwko2XJ=;CCb3AUzrSBVh2sqC!kLQ~E3b)*t;^jX&3dhO0Os)=Qv18 z1m!&tt4451Ut&O;y^e?6;{`nJHO*c2NmK0aKGi;^eB-8~j+`N%RJ{INlX=XQAGRmR gbDjS5c|Q{mgUjL{4U(<*w}a|aPgg&ebxsLQ02Xi>SO5S3 literal 0 HcmV?d00001 diff --git a/assets/images/login/id.png b/assets/images/login/id.png new file mode 100644 index 0000000000000000000000000000000000000000..9260cf11180d8e60b98b933e0fc6841698ddac67 GIT binary patch literal 1308 zcmeAS@N?(olHy`uVBq!ia0vp^k|4~%1|*NXY)uAnN?apKg7ec#$`gxH85~pclTsBt za}(23gHjVyDhp4h+AuIMt7V2nltlRYSS9D@>Lr5I=vCwv0Ch7k*w|MTBqnF4mMA2p zrf25aD!t#mUr8Y|#a1cY)Yrhbz&SM|)1#^=HMq(zB)KX(*)m1R-cG@$!U||WZfZ%Q zLPc&)Ua?h$trFN=Dz9|8 z>y;bpKhp88yV>WRp=I1=9MH?=;jqG!%T2VElw`VEGWs$&r<-In3$Ab zT4JjNbScCOxdm`z^NOLt1Pn0!io^naLp=kKmtYEgeeo;J&4sHjE(uCSxEHIz#UYgi zsro^w#rdU0$-sz9QwCX8VC7ttnpl!w6q28x0}I7~jQo=P;*9(P1!reas97jzglFcZ z12bv3duGcJdP9C8bQHoK%2WtOF;xE1B+DuBIhm5JLe z&N$73>P^Az78jg)^?{Dj2SqMYWW$7jDG0=bCtV;1p7>MqfGNHRn6zK^f9z&pVC?a9 zaSW-rmGtNTe|zS&jKa*a46!O=R0koXr7Mcj2q1a^w}S&Whkv=Oj0#rwr5&dwIEf#U`A^ar%?vmqXdoJf*s$P zK2~c;OIz?A(JuHYHeGd6MvdeOM+I+@3r`%Tydo{-?$a-u^su}u!CQO zH{uF6b91k>M2ddL*`6kcJN-wdGdxmK5MzDh?ocDoUdOjZqc_6as4;@ocMVrZWy6e_ z0ngOTc3j!ev60bmh04@pf-wpoxFurFdvprtG)T^Bxms|do}DdR`NAUUDG^Lwp-Wk= zG(1`}N5cCX!$!HNn!U|xi2*AW+LtHH@zU5)vEYl4#xb^E9hzYi&NM|A$wnP(=$h#1 z@TYysCT$KJp00i_>zopr04ad7(EtDd literal 0 HcmV?d00001 diff --git a/assets/images/login/nationalID.png b/assets/images/login/nationalID.png new file mode 100644 index 0000000000000000000000000000000000000000..5779d562ab78bf6196fe63e7ab2f96de3e420700 GIT binary patch literal 2834 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 localizedValues = { 'clinicName': {'en': 'Clinic Name', 'ar': 'اسم العيادة'}, 'doctorName': {'en': 'Doctor Name', 'ar': 'إسم الطبيب'}, 'nearestAppo': {'en': 'Nearest appointment', 'ar': 'أقرب موعد'}, - 'searchByDocText': {'en': 'Type the name of the doctor to help you find him', 'ar': 'اكتب اسم الطبيب لمساعدتك في العثور عليه'}, + 'searchByDocText': { + 'en': 'Type the name of the doctor to help you find him', + 'ar': 'اكتب اسم الطبيب لمساعدتك في العثور عليه' + }, 'enterDocName': {'en': 'Enter Doctor name', 'ar': 'أدخل إسم الطبيب'}, 'search': {'en': 'Search', 'ar': 'بحث'}, 'bookNow': {'en': 'BOOK NOW', 'ar': 'احجز الآن'}, @@ -29,19 +32,23 @@ const Map> localizedValues = { 'gender': {'en': 'Gender', 'ar': 'الجنس'}, 'nationality': {'en': 'nationality', 'ar': 'الجنسية'}, 'docQualifications': {'en': 'Doctor Qualifications', 'ar': 'مؤهلات الطبيب'}, - 'confirmAppoHeading': {'en': 'Kindly confirm your Appointment', 'ar': 'يرجى تأكيد موعدك'}, + 'confirmAppoHeading': { + 'en': 'Kindly confirm your Appointment', + 'ar': 'يرجى تأكيد موعدك' + }, 'patientInfo': {'en': 'Patient Information', 'ar': 'معلومات المريض'}, 'bookSuccess': {'en': 'Book Success', 'ar': 'تم حجز الموعد بنجاح'}, 'patientShare': {'en': 'Patient Share', 'ar': 'المبلغ المستحق'}, - 'patientShareWithTax': {'en': 'Patient Share with Tax', 'ar': 'المبلغ الإجمالي المستحق'}, + 'patientShareWithTax': { + 'en': 'Patient Share with Tax', + 'ar': 'المبلغ الإجمالي المستحق' + }, 'confirmAppo': {'en': 'Confirm Appointment', 'ar': 'تأكيد الموعد'}, 'confirm': {'en': 'Confirm', 'ar': 'تأكيد'}, 'appointment': {'en': 'Appointment', 'ar': 'الموعد'}, 'confirmLater': {'en': 'Confirm Later', 'ar': 'تأكيد لاحقا'}, 'todoList': {'en': 'Todo List', 'ar': 'مهامي'}, 'appoActions': {'en': 'Appointment Actions', 'ar': 'إجراءات الموعد'}, - - 'login': {'en': 'Login', 'ar': 'تسجيل الدخول'}, 'loginregister': {'en': 'Login / Register', 'ar': 'دخولتسجيل'}, 'welcome': {'en': 'Welcome', 'ar': 'أهلا بك'}, @@ -82,5 +89,12 @@ const Map> localizedValues = { "verify-login-with": { "en": "Please choose one of the following options to verify", "ar": "الرجاء اختيار احدى الخيارات التالية للتحقق من البيانات" - } + }, + "register-user": {"en": "Register", "ar": "تسجيل"}, + "verify-with-fingerprint": {"en": "Fingerprint", "ar": "بصمة"}, + "verify-with-faceid": {"en": "Face ID", "ar": "معرف الوجه"}, + "verify-with-sms": {"en": "SMS", "ar": "الرسائل القصيرة"}, + "verify-with-whatsapp": {"en": "Whatsapp", "ar": " الواتس اب"}, + "last-login": {"en": "LAST LOGIN AT:", "ar": "آخر تسجيل دخول"}, + "last-login-with": {"en": "VERIFICATION TYPE:", "ar": "نوع التحقق:"}, }; diff --git a/lib/config/shared_pref_kay.dart b/lib/config/shared_pref_kay.dart index 1e75a802..6826de00 100644 --- a/lib/config/shared_pref_kay.dart +++ b/lib/config/shared_pref_kay.dart @@ -5,3 +5,4 @@ const PUSH_TOKEN = 'push-token'; const REGISTER_DATA_FOR_REGISTER = 'register-data-for-register'; const LOGIN_TOKEN_ID = 'register-data-for-register'; const REGISTER_DATA_FOR_LOGIIN = 'register-data-for-login'; +const LAST_LOGIN = 'last-login'; diff --git a/lib/core/model/auth/check_paitent_authentication_req.dart b/lib/models/Authentication/check_paitent_authentication_req.dart similarity index 100% rename from lib/core/model/auth/check_paitent_authentication_req.dart rename to lib/models/Authentication/check_paitent_authentication_req.dart diff --git a/lib/models/Authentication/get_mobile_info_request.dart b/lib/models/Authentication/get_mobile_info_request.dart new file mode 100644 index 00000000..51a58d88 --- /dev/null +++ b/lib/models/Authentication/get_mobile_info_request.dart @@ -0,0 +1,96 @@ +class GetMobileLoginInfoRequest { + int patientMobileNumber; + String mobileNo; + String deviceToken; + int projectOutSA; + int loginType; + String zipCode; + bool isRegister; + String logInTokenID; + int searchType; + int patientID; + String nationalID; + String patientIdentificationID; + double versionID; + int channel; + int languageID; + String iPAdress; + String generalid; + int patientOutSA; + Null sessionID; + bool isDentalAllowedBackend; + int deviceTypeID; + + GetMobileLoginInfoRequest( + {this.patientMobileNumber, + this.mobileNo, + this.deviceToken, + this.projectOutSA, + this.loginType, + this.zipCode, + this.isRegister, + this.logInTokenID, + this.searchType, + this.patientID, + this.nationalID, + this.patientIdentificationID, + this.versionID, + this.channel, + this.languageID, + this.iPAdress, + this.generalid, + this.patientOutSA, + this.sessionID, + this.isDentalAllowedBackend, + this.deviceTypeID}); + + GetMobileLoginInfoRequest.fromJson(Map json) { + patientMobileNumber = json['PatientMobileNumber']; + mobileNo = json['MobileNo']; + deviceToken = json['DeviceToken']; + projectOutSA = json['ProjectOutSA']; + loginType = json['LoginType']; + zipCode = json['ZipCode']; + isRegister = json['isRegister']; + logInTokenID = json['LogInTokenID']; + searchType = json['SearchType']; + patientID = json['PatientID']; + nationalID = json['NationalID']; + patientIdentificationID = json['PatientIdentificationID']; + versionID = json['VersionID']; + channel = json['Channel']; + languageID = json['LanguageID']; + iPAdress = json['IPAdress']; + generalid = json['generalid']; + patientOutSA = json['PatientOutSA']; + sessionID = json['SessionID']; + isDentalAllowedBackend = json['isDentalAllowedBackend']; + deviceTypeID = json['DeviceTypeID']; + } + + Map toJson() { + final Map data = new Map(); + data['PatientMobileNumber'] = this.patientMobileNumber; + data['MobileNo'] = this.mobileNo; + data['DeviceToken'] = this.deviceToken; + data['ProjectOutSA'] = this.projectOutSA; + data['LoginType'] = this.loginType; + data['ZipCode'] = this.zipCode; + data['isRegister'] = this.isRegister; + data['LogInTokenID'] = this.logInTokenID; + data['SearchType'] = this.searchType; + data['PatientID'] = this.patientID; + data['NationalID'] = this.nationalID; + data['PatientIdentificationID'] = this.patientIdentificationID; + data['VersionID'] = this.versionID; + data['Channel'] = this.channel; + data['LanguageID'] = this.languageID; + data['IPAdress'] = this.iPAdress; + data['generalid'] = this.generalid; + data['PatientOutSA'] = this.patientOutSA; + data['SessionID'] = this.sessionID; + data['isDentalAllowedBackend'] = this.isDentalAllowedBackend; + data['DeviceTypeID'] = this.deviceTypeID; + return data; + } +} diff --git a/lib/models/Authentication/get_mobile_info_response.dart b/lib/models/Authentication/get_mobile_info_response.dart new file mode 100644 index 00000000..562c82dd --- /dev/null +++ b/lib/models/Authentication/get_mobile_info_response.dart @@ -0,0 +1,292 @@ +class GetMobileLoginInfoResponse { + Null date; + int languageID; + int serviceName; + Null time; + Null androidLink; + Null authenticationTokenID; + Null data; + bool dataw; + int dietType; + Null errorCode; + Null errorEndUserMessage; + Null errorEndUserMessageN; + Null errorMessage; + int errorType; + int foodCategory; + Null iOSLink; + bool isAuthenticated; + int mealOrderStatus; + int mealType; + int messageStatus; + int numberOfResultRecords; + Null patientBlodType; + Null successMsg; + Null successMsgN; + Null doctorInformationList; + Null getAllPendingRecordsList; + Null getAllSharedRecordsByStatusList; + Null getResponseFileList; + bool isHMGPatient; + bool isLoginSuccessfully; + bool isNeedUpdateIdintificationNo; + bool kioskSendSMS; + Null list; + Null listAskHabibMobileLoginInfo; + Null listAskHabibPatientFile; + Null listMergeFiles; + List listMobileLoginInfo; + Null listPatientCount; + String logInTokenID; + Null mohemmPrivilegeList; + int pateintID; + Null patientBloodType; + bool patientHasFile; + Null patientMergedIDs; + bool patientOutSA; + int patientShareRequestID; + int patientType; + int projectIDOut; + Null returnMessage; + bool sMSLoginRequired; + Null servicePrivilegeList; + Null sharePatientName; + Null verificationCode; + Null email; + Null errorList; + bool hasFile; + bool isActiveCode; + bool isMerged; + bool isNeedUserAgreement; + bool isSMSSent; + Null memberList; + Null message; + int statusCode; + + GetMobileLoginInfoResponse( + {this.date, + this.languageID, + this.serviceName, + this.time, + this.androidLink, + this.authenticationTokenID, + this.data, + this.dataw, + this.dietType, + this.errorCode, + this.errorEndUserMessage, + this.errorEndUserMessageN, + this.errorMessage, + this.errorType, + this.foodCategory, + this.iOSLink, + this.isAuthenticated, + this.mealOrderStatus, + this.mealType, + this.messageStatus, + this.numberOfResultRecords, + this.patientBlodType, + this.successMsg, + this.successMsgN, + this.doctorInformationList, + this.getAllPendingRecordsList, + this.getAllSharedRecordsByStatusList, + this.getResponseFileList, + this.isHMGPatient, + this.isLoginSuccessfully, + this.isNeedUpdateIdintificationNo, + this.kioskSendSMS, + this.list, + this.listAskHabibMobileLoginInfo, + this.listAskHabibPatientFile, + this.listMergeFiles, + this.listMobileLoginInfo, + this.listPatientCount, + this.logInTokenID, + this.mohemmPrivilegeList, + this.pateintID, + this.patientBloodType, + this.patientHasFile, + this.patientMergedIDs, + this.patientOutSA, + this.patientShareRequestID, + this.patientType, + this.projectIDOut, + this.returnMessage, + this.sMSLoginRequired, + this.servicePrivilegeList, + this.sharePatientName, + this.verificationCode, + this.email, + this.errorList, + this.hasFile, + this.isActiveCode, + this.isMerged, + this.isNeedUserAgreement, + this.isSMSSent, + this.memberList, + this.message, + this.statusCode}); + + GetMobileLoginInfoResponse.fromJson(Map json) { + date = json['Date']; + languageID = json['LanguageID']; + serviceName = json['ServiceName']; + time = json['Time']; + androidLink = json['AndroidLink']; + authenticationTokenID = json['AuthenticationTokenID']; + data = json['Data']; + dataw = json['Dataw']; + dietType = json['DietType']; + errorCode = json['ErrorCode']; + errorEndUserMessage = json['ErrorEndUserMessage']; + errorEndUserMessageN = json['ErrorEndUserMessageN']; + errorMessage = json['ErrorMessage']; + errorType = json['ErrorType']; + foodCategory = json['FoodCategory']; + iOSLink = json['IOSLink']; + isAuthenticated = json['IsAuthenticated']; + mealOrderStatus = json['MealOrderStatus']; + mealType = json['MealType']; + messageStatus = json['MessageStatus']; + numberOfResultRecords = json['NumberOfResultRecords']; + patientBlodType = json['PatientBlodType']; + successMsg = json['SuccessMsg']; + successMsgN = json['SuccessMsgN']; + doctorInformationList = json['DoctorInformation_List']; + getAllPendingRecordsList = json['GetAllPendingRecordsList']; + getAllSharedRecordsByStatusList = json['GetAllSharedRecordsByStatusList']; + getResponseFileList = json['GetResponseFileList']; + isHMGPatient = json['IsHMGPatient']; + isLoginSuccessfully = json['IsLoginSuccessfully']; + isNeedUpdateIdintificationNo = json['IsNeedUpdateIdintificationNo']; + kioskSendSMS = json['KioskSendSMS']; + list = json['List']; + listAskHabibMobileLoginInfo = json['List_AskHabibMobileLoginInfo']; + listAskHabibPatientFile = json['List_AskHabibPatientFile']; + listMergeFiles = json['List_MergeFiles']; + if (json['List_MobileLoginInfo'] != null) { + listMobileLoginInfo = new List(); + json['List_MobileLoginInfo'].forEach((v) { + listMobileLoginInfo.add(new ListMobileLoginInfo.fromJson(v)); + }); + } + listPatientCount = json['List_PatientCount']; + logInTokenID = json['LogInTokenID']; + mohemmPrivilegeList = json['MohemmPrivilege_List']; + pateintID = json['PateintID']; + patientBloodType = json['PatientBloodType']; + patientHasFile = json['PatientHasFile']; + patientMergedIDs = json['PatientMergedIDs']; + patientOutSA = json['PatientOutSA']; + patientShareRequestID = json['PatientShareRequestID']; + patientType = json['PatientType']; + projectIDOut = json['ProjectIDOut']; + returnMessage = json['ReturnMessage']; + sMSLoginRequired = json['SMSLoginRequired']; + servicePrivilegeList = json['ServicePrivilege_List']; + sharePatientName = json['SharePatientName']; + verificationCode = json['VerificationCode']; + email = json['email']; + errorList = json['errorList']; + hasFile = json['hasFile']; + isActiveCode = json['isActiveCode']; + isMerged = json['isMerged']; + isNeedUserAgreement = json['isNeedUserAgreement']; + isSMSSent = json['isSMSSent']; + memberList = json['memberList']; + message = json['message']; + statusCode = json['statusCode']; + } + + Map toJson() { + final Map data = new Map(); + data['Date'] = this.date; + data['LanguageID'] = this.languageID; + data['ServiceName'] = this.serviceName; + data['Time'] = this.time; + data['AndroidLink'] = this.androidLink; + data['AuthenticationTokenID'] = this.authenticationTokenID; + data['Data'] = this.data; + data['Dataw'] = this.dataw; + data['DietType'] = this.dietType; + data['ErrorCode'] = this.errorCode; + data['ErrorEndUserMessage'] = this.errorEndUserMessage; + data['ErrorEndUserMessageN'] = this.errorEndUserMessageN; + data['ErrorMessage'] = this.errorMessage; + data['ErrorType'] = this.errorType; + data['FoodCategory'] = this.foodCategory; + data['IOSLink'] = this.iOSLink; + data['IsAuthenticated'] = this.isAuthenticated; + data['MealOrderStatus'] = this.mealOrderStatus; + data['MealType'] = this.mealType; + data['MessageStatus'] = this.messageStatus; + data['NumberOfResultRecords'] = this.numberOfResultRecords; + data['PatientBlodType'] = this.patientBlodType; + data['SuccessMsg'] = this.successMsg; + data['SuccessMsgN'] = this.successMsgN; + data['DoctorInformation_List'] = this.doctorInformationList; + data['GetAllPendingRecordsList'] = this.getAllPendingRecordsList; + data['GetAllSharedRecordsByStatusList'] = + this.getAllSharedRecordsByStatusList; + data['GetResponseFileList'] = this.getResponseFileList; + data['IsHMGPatient'] = this.isHMGPatient; + data['IsLoginSuccessfully'] = this.isLoginSuccessfully; + data['IsNeedUpdateIdintificationNo'] = this.isNeedUpdateIdintificationNo; + data['KioskSendSMS'] = this.kioskSendSMS; + data['List'] = this.list; + data['List_AskHabibMobileLoginInfo'] = this.listAskHabibMobileLoginInfo; + data['List_AskHabibPatientFile'] = this.listAskHabibPatientFile; + data['List_MergeFiles'] = this.listMergeFiles; + if (this.listMobileLoginInfo != null) { + data['List_MobileLoginInfo'] = + this.listMobileLoginInfo.map((v) => v.toJson()).toList(); + } + data['List_PatientCount'] = this.listPatientCount; + data['LogInTokenID'] = this.logInTokenID; + data['MohemmPrivilege_List'] = this.mohemmPrivilegeList; + data['PateintID'] = this.pateintID; + data['PatientBloodType'] = this.patientBloodType; + data['PatientHasFile'] = this.patientHasFile; + data['PatientMergedIDs'] = this.patientMergedIDs; + data['PatientOutSA'] = this.patientOutSA; + data['PatientShareRequestID'] = this.patientShareRequestID; + data['PatientType'] = this.patientType; + data['ProjectIDOut'] = this.projectIDOut; + data['ReturnMessage'] = this.returnMessage; + data['SMSLoginRequired'] = this.sMSLoginRequired; + data['ServicePrivilege_List'] = this.servicePrivilegeList; + data['SharePatientName'] = this.sharePatientName; + data['VerificationCode'] = this.verificationCode; + data['email'] = this.email; + data['errorList'] = this.errorList; + data['hasFile'] = this.hasFile; + data['isActiveCode'] = this.isActiveCode; + data['isMerged'] = this.isMerged; + data['isNeedUserAgreement'] = this.isNeedUserAgreement; + data['isSMSSent'] = this.isSMSSent; + data['memberList'] = this.memberList; + data['message'] = this.message; + data['statusCode'] = this.statusCode; + return data; + } +} + +class ListMobileLoginInfo { + int iD; + int loginType; + + ListMobileLoginInfo({this.iD, this.loginType}); + + ListMobileLoginInfo.fromJson(Map json) { + iD = json['ID']; + loginType = json['LoginType']; + } + + Map toJson() { + final Map data = new Map(); + data['ID'] = this.iD; + data['LoginType'] = this.loginType; + return data; + } +} diff --git a/lib/core/model/auth/select_device_imei_res.dart b/lib/models/Authentication/select_device_imei_res.dart similarity index 100% rename from lib/core/model/auth/select_device_imei_res.dart rename to lib/models/Authentication/select_device_imei_res.dart diff --git a/lib/models/Authentication/send_activation_request.dart b/lib/models/Authentication/send_activation_request.dart new file mode 100644 index 00000000..804f6ef0 --- /dev/null +++ b/lib/models/Authentication/send_activation_request.dart @@ -0,0 +1,100 @@ +class SendActivationRequest { + int patientMobileNumber; + String mobileNo; + String deviceToken; + int projectOutSA; + int loginType; + String zipCode; + bool isRegister; + String logInTokenID; + int searchType; + int patientID; + String nationalID; + String patientIdentificationID; + int oTPSendType; + int languageID; + double versionID; + int channel; + String iPAdress; + String generalid; + int patientOutSA; + Null sessionID; + bool isDentalAllowedBackend; + int deviceTypeID; + + SendActivationRequest( + {this.patientMobileNumber, + this.mobileNo, + this.deviceToken, + this.projectOutSA, + this.loginType, + this.zipCode, + this.isRegister, + this.logInTokenID, + this.searchType, + this.patientID, + this.nationalID, + this.patientIdentificationID, + this.oTPSendType, + this.languageID, + this.versionID, + this.channel, + this.iPAdress, + this.generalid, + this.patientOutSA, + this.sessionID, + this.isDentalAllowedBackend, + this.deviceTypeID}); + + SendActivationRequest.fromJson(Map json) { + patientMobileNumber = json['PatientMobileNumber']; + mobileNo = json['MobileNo']; + deviceToken = json['DeviceToken']; + projectOutSA = json['ProjectOutSA']; + loginType = json['LoginType']; + zipCode = json['ZipCode']; + isRegister = json['isRegister']; + logInTokenID = json['LogInTokenID']; + searchType = json['SearchType']; + patientID = json['PatientID']; + nationalID = json['NationalID']; + patientIdentificationID = json['PatientIdentificationID']; + oTPSendType = json['OTP_SendType']; + languageID = json['LanguageID']; + versionID = json['VersionID']; + channel = json['Channel']; + iPAdress = json['IPAdress']; + generalid = json['generalid']; + patientOutSA = json['PatientOutSA']; + sessionID = json['SessionID']; + isDentalAllowedBackend = json['isDentalAllowedBackend']; + deviceTypeID = json['DeviceTypeID']; + } + + Map toJson() { + final Map data = new Map(); + data['PatientMobileNumber'] = this.patientMobileNumber; + data['MobileNo'] = this.mobileNo; + data['DeviceToken'] = this.deviceToken; + data['ProjectOutSA'] = this.projectOutSA; + data['LoginType'] = this.loginType; + data['ZipCode'] = this.zipCode; + data['isRegister'] = this.isRegister; + data['LogInTokenID'] = this.logInTokenID; + data['SearchType'] = this.searchType; + data['PatientID'] = this.patientID; + data['NationalID'] = this.nationalID; + data['PatientIdentificationID'] = this.patientIdentificationID; + data['OTP_SendType'] = this.oTPSendType; + data['LanguageID'] = this.languageID; + data['VersionID'] = this.versionID; + data['Channel'] = this.channel; + data['IPAdress'] = this.iPAdress; + data['generalid'] = this.generalid; + data['PatientOutSA'] = this.patientOutSA; + data['SessionID'] = this.sessionID; + data['isDentalAllowedBackend'] = this.isDentalAllowedBackend; + data['DeviceTypeID'] = this.deviceTypeID; + return data; + } +} diff --git a/lib/pages/landing/landing_page.dart b/lib/pages/landing/landing_page.dart index 3b02024d..ab2ada4c 100644 --- a/lib/pages/landing/landing_page.dart +++ b/lib/pages/landing/landing_page.dart @@ -1,8 +1,9 @@ import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; -import 'package:diplomaticquarterapp/core/model/auth/select_device_imei_res.dart'; +import 'package:diplomaticquarterapp/config/size_config.dart'; +import 'package:diplomaticquarterapp/models/Authentication/select_device_imei_res.dart'; import 'package:diplomaticquarterapp/pages/ToDoList/ToDo.dart'; import 'package:diplomaticquarterapp/pages/landing/replay_page.dart'; -import 'package:diplomaticquarterapp/providers/auth_provider.dart'; +import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/bottom_navigation/bottom_nav_bar.dart'; import 'package:diplomaticquarterapp/widgets/drawer/app_drawer_widget.dart'; diff --git a/lib/pages/login/confirm-login.dart b/lib/pages/login/confirm-login.dart index d6552883..afbc5915 100644 --- a/lib/pages/login/confirm-login.dart +++ b/lib/pages/login/confirm-login.dart @@ -1,4 +1,11 @@ +import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/config/size_config.dart'; +import 'package:diplomaticquarterapp/models/Authentication/check_paitent_authentication_req.dart'; +import 'package:diplomaticquarterapp/models/Authentication/get_mobile_info_request.dart'; +import 'package:diplomaticquarterapp/models/Authentication/get_mobile_info_response.dart'; +import 'package:diplomaticquarterapp/models/Authentication/send_activation_request.dart'; +import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart'; +import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/card/rounded_container.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; @@ -6,9 +13,48 @@ import 'package:diplomaticquarterapp/widgets/text/app_texts_widget.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:diplomaticquarterapp/routes.dart'; +import 'package:flutter/services.dart'; +import 'package:local_auth/local_auth.dart'; -class ConfirmLogin extends StatelessWidget { - static int loginType = 0; +class ConfirmLogin extends StatefulWidget { + @override + _ConfirmLogin createState() => _ConfirmLogin(); +} + +class _ConfirmLogin extends State { + final LocalAuthentication auth = LocalAuthentication(); + List _availableBiometrics; + var sharedPref = new AppSharedPreferences(); + bool authenticated; + final authService = new AuthProvider(); + int mobileNumber; + + var user; + + CheckPatientAuthenticationReq registerd_data; + + var zipCode; + + var patientOutSA; + + var loginTokenID; + + var loginType; + + var deviceToken; + + var lastLogin; + + int selectedOption; + + bool onlySMSBox; + + @override + void initState() { + _getAvailableBiometrics(); + setDefault(); + super.initState(); + } @override Widget build(BuildContext context) { @@ -19,29 +65,43 @@ class ConfirmLogin extends StatelessWidget { padding: EdgeInsets.all(20), child: Column( children: [ + Expanded( + flex: 3, + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Image.asset( + 'assets/images/habib-logo.png', + height: 80, + width: 80, + ), + AppText( + TranslationBase.of(context).verifyLoginWith, + fontSize: SizeConfig.textMultiplier * 3.5, + textAlign: TextAlign.left, + ), + ])), Expanded( flex: 4, child: Column( mainAxisAlignment: MainAxisAlignment.spaceEvenly, crossAxisAlignment: CrossAxisAlignment.start, children: [ - Image.asset( - 'assets/images/habib-logo.png', - height: 80, - width: 80, - ), - AppText( - TranslationBase.of(context).verifyLoginWith, - fontSize: SizeConfig.textMultiplier * 3.5, - textAlign: TextAlign.left, - ), Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Expanded( child: InkWell( - onTap: () => {}, + onTap: () => { + authenticateUser( + 3, BiometricType.face.index) + }, child: RoundedContainer( + backgroundColor: + BiometricType.face.index == 1 + ? Colors.white + : Colors.white.withOpacity(.7), borderColor: Colors.grey, showBorder: true, child: Padding( @@ -52,20 +112,20 @@ class ConfirmLogin extends StatelessWidget { MainAxisAlignment.center, children: [ Image.asset( - 'assets/images/id_card_icon.png', + 'assets/images/login/101.png', height: SizeConfig .imageSizeMultiplier * - 12, + 13, width: SizeConfig .imageSizeMultiplier * - 15, + 16, ), SizedBox( height: 20, ), AppText( TranslationBase.of(context) - .nationalID, + .verifyFaceID, fontSize: SizeConfig.textMultiplier * 2, @@ -75,8 +135,15 @@ class ConfirmLogin extends StatelessWidget { )))), Expanded( child: InkWell( - onTap: () => {}, + onTap: () => { + authenticateUser(2, + BiometricType.fingerprint.index) + }, child: RoundedContainer( + backgroundColor: + BiometricType.fingerprint.index == 1 + ? Colors.white + : Colors.white.withOpacity(.7), borderColor: Colors.grey, showBorder: true, child: Padding( @@ -85,20 +152,20 @@ class ConfirmLogin extends StatelessWidget { child: Column( children: [ Image.asset( - 'assets/images/my_file_white_icon.png', + 'assets/images/login/102.png', height: SizeConfig .imageSizeMultiplier * - 12, + 13, width: SizeConfig .imageSizeMultiplier * - 15, + 16, ), SizedBox( height: 20, ), AppText( TranslationBase.of(context) - .fileNo, + .verifyFingerprint, fontSize: SizeConfig.textMultiplier * 2, @@ -108,18 +175,79 @@ class ConfirmLogin extends StatelessWidget { )))) ], ), - Divider( - color: Colors.grey, - height: 2, + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Expanded( + child: InkWell( + onTap: () => {authenticateUser(1, true)}, + child: RoundedContainer( + borderColor: Colors.grey, + showBorder: true, + child: Padding( + padding: EdgeInsets.fromLTRB( + 20, 10, 20, 10), + child: Column( + mainAxisAlignment: + MainAxisAlignment.center, + children: [ + Image.asset( + 'assets/images/login/103.png', + height: SizeConfig + .imageSizeMultiplier * + 13, + width: SizeConfig + .imageSizeMultiplier * + 16, + ), + SizedBox( + height: 20, + ), + AppText( + TranslationBase.of(context) + .verifySMS, + fontSize: + SizeConfig.textMultiplier * + 2, + ) + ], + ), + )))), + Expanded( + child: InkWell( + onTap: () => {authenticateUser(4, true)}, + child: RoundedContainer( + borderColor: Colors.grey, + showBorder: true, + child: Padding( + padding: EdgeInsets.fromLTRB( + 25, 10, 25, 10), + child: Column( + children: [ + Image.asset( + 'assets/images/login/104.png', + height: SizeConfig + .imageSizeMultiplier * + 13, + width: SizeConfig + .imageSizeMultiplier * + 16, + ), + SizedBox( + height: 20, + ), + AppText( + TranslationBase.of(context) + .verifyWhatsApp, + fontSize: + SizeConfig.textMultiplier * + 2, + ) + ], + ), + )))) + ], ), - Center( - child: InkWell( - onTap: () => {}, - child: AppText( - TranslationBase.of(context).forgotPassword, - fontSize: SizeConfig.textMultiplier * 3, - margin: 10, - underline: true))) ]), ), Expanded( @@ -127,25 +255,171 @@ class ConfirmLogin extends StatelessWidget { child: Column( mainAxisAlignment: MainAxisAlignment.end, children: [ - Row( - children: [ - Expanded( - child: RaisedButton( - color: Colors.grey, - textColor: Colors.white, - child: - Text(TranslationBase.of(context).registerNow), - onPressed: () => { - Navigator.of(context).pushNamed( - REGISTER, - ) - }, - )) - ], - ), + // Row( + // children: [ + // Expanded( + // child: RaisedButton( + // color: Colors.grey, + // textColor: Colors.white, + // child: + // Text(TranslationBase.of(context).registerNow), + // onPressed: () => { + // Navigator.of(context).pushNamed( + // REGISTER, + // ) + // }, + // )) + // ], + // ), ], )) ], ))); } + + Future _getAvailableBiometrics() async { + List availableBiometrics; + try { + availableBiometrics = await auth.getAvailableBiometrics(); + } on PlatformException catch (e) { + print(e); + } + if (!mounted) return; + + setState(() { + _availableBiometrics = availableBiometrics; + print(_availableBiometrics); + }); + } + + authenticateUser(type, isActive) { + this.selectedOption = + type; //this.selectedOption && !this.onlySMSBox ? this.selectedOption : this.fingrePrintBefore ? this.fingrePrintBefore : el.value; + + switch (type) { + case 1: + this.loginWithSMS(type, isActive); + break; + case 2: + this.loginWithFingurePrintFace(type, isActive); + break; + case 3: + this.loginWithFingurePrintFace(type, isActive); + break; + case 4: + this.loginWithWhatsapp(type, isActive); + break; + default: + break; + } + sharedPref.setInt(LAST_LOGIN, + type); //this.cs.sharedService.setStorage(this.selectedOption, AuthenticationService.LAST_LOGIN); + } + + loginWithSMS(type, isActive) {} + loginWithFingurePrintFace(type, isActive) async { + if (isActive == 1) { + // this.startBiometricLoginIfAvailable(); + authenticated = await auth.authenticateWithBiometrics( + localizedReason: 'Scan your fingerprint to authenticate', + useErrorDialogs: true, + stickyAuth: true); + print(authenticated); + if (authenticated == true) { + var request = this.getCommonRequest(); + this.getMobileInfo(request); + } + } + } + + loginWithWhatsapp(type, isActive) {} + getMobileInfo(request) { + this + .authService + .getLoginInfo(request) + .then((GetMobileLoginInfoResponse result) => { + if (!result.sMSLoginRequired) + { + this.loginTokenID = result.logInTokenID, + this.patientOutSA = result.patientOutSA, + // sms for register the biometric + if (result.isSMSSent) + { + this.onlySMSBox = false, + //this.button(); + } + else + { + //this.checkActivationCode(); + } + } + else + { + if (result.isAuthenticated) + { + // this.onlySMSBox = false; + // this.cs.sharedService.setSharedData(true, AuthenticationService.ONLY_SMS); + // this.cs.sharedService.setSharedData(this.selectedOption, AuthenticationService.FINGUREPRINT_BEFORE); + // this.cs.confirmLogin(); + // this.button(); + } + else + { + // this.cs.presentAlert(result.ErrorEndUserMessage); + } + } + }); + } + + setDefault() async { + // this.user = this.cs.sharedService.getSharedData( + // AuthenticationService.IMEI_USER_DATA, + // false + // ); + this.registerd_data = await sharedPref.getObject(REGISTER_DATA_FOR_LOGIIN); + this.mobileNumber = this.registerd_data != null + ? this.registerd_data.patientMobileNumber + : int.parse(this.user.Mobile); + this.zipCode = this.registerd_data != null + ? this.registerd_data.zipCode + : this.user.OutSA ? "971" : "966"; + this.patientOutSA = this.registerd_data != null + ? this.registerd_data.zipCode == "966" ? 0 : 1 + : this.user.OutSA; + if (this.registerd_data != null) { + this.loginTokenID = sharedPref.getString(LOGIN_TOKEN_ID); + this.loginType = this.registerd_data.searchType; + } + this.deviceToken = sharedPref.getString(PUSH_TOKEN); + this.lastLogin = sharedPref.getInt( + LAST_LOGIN); //this.cs.sharedService.getStorage(AuthenticationService.LAST_LOGIN); + } + + getCommonRequest() { + var request = SendActivationRequest(); + request.patientMobileNumber = this.mobileNumber; + request.mobileNo = '0' + this.mobileNumber.toString(); + request.deviceToken = this.deviceToken; + request.projectOutSA = this.patientOutSA; + request.loginType = this.selectedOption; + request.zipCode = this.zipCode; + request.isRegister = false; + request.logInTokenID = this.loginTokenID ?? ""; + if (this.registerd_data != null) { + request.searchType = this.registerd_data.searchType == 1 + ? this.registerd_data.searchType + : 1; + request.patientID = this.registerd_data.patientID != 0 + ? this.registerd_data.patientID + : 0; + request.patientIdentificationID = + request.nationalID = this.registerd_data.patientIdentificationID; + } else { + request.searchType = request.searchType == 1 ? request.searchType : 2; + request.patientID = int.parse(this.user.PatientID); + request.patientID = request.nationalID = + request.nationalID != null ? request.nationalID : 0; + } + return request; + } } diff --git a/lib/pages/login/login-type.dart b/lib/pages/login/login-type.dart index c0697099..7a8a940d 100644 --- a/lib/pages/login/login-type.dart +++ b/lib/pages/login/login-type.dart @@ -1,5 +1,6 @@ import 'package:diplomaticquarterapp/config/size_config.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; import 'package:diplomaticquarterapp/widgets/card/rounded_container.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/text/app_texts_widget.dart'; @@ -128,7 +129,7 @@ class LoginType extends StatelessWidget { }, child: AppText( TranslationBase.of(context).forgotPassword, - fontSize: SizeConfig.textMultiplier * 3, + fontSize: SizeConfig.textMultiplier * 2.5, margin: 10, underline: true))) ]), @@ -141,12 +142,9 @@ class LoginType extends StatelessWidget { Row( children: [ Expanded( - child: RaisedButton( - color: Colors.grey, - textColor: Colors.white, - child: - Text(TranslationBase.of(context).registerNow), - onPressed: () => { + child: DefaultButton( + TranslationBase.of(context).registerNow, + () => { Navigator.of(context).pushNamed( REGISTER, ) diff --git a/lib/pages/login/login.dart b/lib/pages/login/login.dart index ad88371b..982d75e3 100644 --- a/lib/pages/login/login.dart +++ b/lib/pages/login/login.dart @@ -1,18 +1,20 @@ import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/config/size_config.dart'; -import 'package:diplomaticquarterapp/core/model/auth/check_paitent_authentication_req.dart'; +import 'package:diplomaticquarterapp/models/Authentication/check_paitent_authentication_req.dart'; import 'package:diplomaticquarterapp/core/service/client/base_app_client.dart'; import 'package:diplomaticquarterapp/pages/login/login-type.dart'; -import 'package:diplomaticquarterapp/providers/auth_provider.dart'; +import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart'; import 'package:diplomaticquarterapp/routes.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/utils.dart'; import 'package:diplomaticquarterapp/widgets/buttons/button.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; import 'package:diplomaticquarterapp/widgets/card/rounded_container.dart'; import 'package:diplomaticquarterapp/widgets/input/text_field.dart'; import 'package:diplomaticquarterapp/widgets/mobile-no/mobile_no.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/progress_indicator/app_circular_progress_Indeicator.dart'; import 'package:diplomaticquarterapp/widgets/text/app_texts_widget.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; @@ -31,73 +33,77 @@ class _Login extends State { bool isButtonDisabled = true; final authService = new AuthProvider(); var sharedPref = new AppSharedPreferences(); + bool isLoading = false; @override Widget build(BuildContext context) { return AppScaffold( appBarTitle: TranslationBase.of(context).login, isShowAppBar: true, - body: SingleChildScrollView( - child: Container( - padding: EdgeInsets.only(top: 10, left: 20, right: 20), - height: SizeConfig.realScreenHeight * .8, - width: SizeConfig.realScreenWidth, - child: Column(children: [ - Expanded( - flex: 1, - child: AppText( - TranslationBase.of(context).enterNationalId, - fontSize: SizeConfig.textMultiplier * 3.5, - textAlign: TextAlign.left, - )), - Expanded( - flex: 2, - child: Column( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - MobileNo( - onNumberChange: (value) => - {mobileNo = value, validateForm()}, - onCountryChange: (value) => countryCode = value), - Container( - child: TextFields( - controller: nationalIDorFile, - onChanged: (value) => {validateForm()}, - prefixIcon: Icon( - loginType == 1 - ? Icons.chrome_reader_mode - : Icons.receipt, - color: Colors.red), - padding: EdgeInsets.only( - top: 20, bottom: 20, left: 10, right: 10), - hintText: loginType == 1 - ? TranslationBase.of(context).nationalID - : TranslationBase.of(context).fileNo, - )) - ], - ), - ), - Expanded( - flex: 2, - child: Column( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - Row( + body: isLoading == true + ? AppCircularProgressIndicator() + : SingleChildScrollView( + child: Container( + padding: + EdgeInsets.only(top: 10, left: 20, right: 20, bottom: 20), + height: SizeConfig.realScreenHeight * .9, + width: SizeConfig.realScreenWidth, + child: Column(children: [ + Expanded( + flex: 1, + child: AppText( + TranslationBase.of(context).enterNationalId, + fontSize: SizeConfig.textMultiplier * 3.5, + textAlign: TextAlign.left, + )), + Expanded( + flex: 2, + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ - Expanded( - child: RaisedButton( - color: isButtonDisabled == true - ? Colors.grey - : Colors.grey[600], - textColor: Colors.white, - child: Text(TranslationBase.of(context).login), - onPressed: () => {this.startLogin()}, + MobileNo( + onNumberChange: (value) => + {mobileNo = value, validateForm()}, + onCountryChange: (value) => countryCode = value), + Container( + child: TextFields( + controller: nationalIDorFile, + onChanged: (value) => {validateForm()}, + prefixIcon: Icon( + loginType == 1 + ? Icons.chrome_reader_mode + : Icons.receipt, + color: Colors.red), + padding: EdgeInsets.only( + top: 20, bottom: 20, left: 10, right: 10), + hintText: loginType == 1 + ? TranslationBase.of(context).nationalID + : TranslationBase.of(context).fileNo, )) ], ), - ], - )) - ]), - ))); + ), + Expanded( + flex: 3, + child: Column( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Row( + children: [ + Expanded( + child: DefaultButton( + TranslationBase.of(context).login, + () => {this.startLogin()}, + color: isButtonDisabled == true + ? Colors.grey + : Colors.grey[600], + textColor: Colors.white, + )) + ], + ), + ], + )) + ]), + ))); } startLogin() { @@ -133,6 +139,7 @@ class _Login extends State { } checkUserAuthentication() { + showLoader(true); var request = CheckPatientAuthenticationReq(); request.isRegister = false; request.patientMobileNumber = int.parse(mobileNo); @@ -148,6 +155,7 @@ class _Login extends State { } sharedPref.setObject(REGISTER_DATA_FOR_REGISTER, request); authService.checkPatientAuthentication(request).then((value) => { + showLoader(false), if (value['isSMSSent']) { sharedPref.setString(LOGIN_TOKEN_ID, value['LogInTokenID']), @@ -162,4 +170,9 @@ class _Login extends State { } checkActivationCode() {} + showLoader(bool isTrue) { + setState(() { + isLoading = isTrue; + }); + } } diff --git a/lib/pages/login/register.dart b/lib/pages/login/register.dart index 6c58ba72..31a4c4a1 100644 --- a/lib/pages/login/register.dart +++ b/lib/pages/login/register.dart @@ -2,6 +2,7 @@ import 'package:diplomaticquarterapp/config/size_config.dart'; import 'package:diplomaticquarterapp/pages/login/login-type.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/button.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; import 'package:diplomaticquarterapp/widgets/card/rounded_container.dart'; import 'package:diplomaticquarterapp/widgets/input/text_field.dart'; import 'package:diplomaticquarterapp/widgets/mobile-no/mobile_no.dart'; @@ -25,19 +26,19 @@ class _Register extends State { @override Widget build(BuildContext context) { return AppScaffold( - appBarTitle: TranslationBase.of(context).login, + appBarTitle: TranslationBase.of(context).register, isShowAppBar: true, body: SingleChildScrollView( child: Container( - padding: EdgeInsets.only(top: 10, left: 20, right: 20), - height: SizeConfig.realScreenHeight * .8, + padding: EdgeInsets.only(top: 10, left: 20, right: 20, bottom: 20), + height: SizeConfig.realScreenHeight * .9, width: SizeConfig.realScreenWidth, child: Column(children: [ Expanded( flex: 1, child: AppText( TranslationBase.of(context).enterNationalId, - fontSize: SizeConfig.textMultiplier * 3.5, + fontSize: SizeConfig.textMultiplier * 3, textAlign: TextAlign.left, )), Expanded( @@ -111,11 +112,9 @@ class _Register extends State { Row( children: [ Expanded( - child: RaisedButton( - color: Colors.grey, - textColor: Colors.white, - child: Text(TranslationBase.of(context).login), - onPressed: () => {}, + child: DefaultButton( + TranslationBase.of(context).login, + () => {}, )) ], ), diff --git a/lib/pages/login/welcome.dart b/lib/pages/login/welcome.dart index 978ff449..250f6d34 100644 --- a/lib/pages/login/welcome.dart +++ b/lib/pages/login/welcome.dart @@ -1,6 +1,7 @@ import 'package:diplomaticquarterapp/config/size_config.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/button.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; @@ -17,7 +18,7 @@ class WelcomeLogin extends StatelessWidget { child: Column( children: [ Expanded( - flex: 3, + flex: 4, child: Column( mainAxisAlignment: MainAxisAlignment.spaceEvenly, crossAxisAlignment: CrossAxisAlignment.start, @@ -41,35 +42,39 @@ class WelcomeLogin extends StatelessWidget { TranslationBase.of(context).welcomeText2, style: TextStyle(fontSize: 24), textAlign: TextAlign.left, + ), + SizedBox( + height: SizeConfig.realScreenHeight * .2, ) ]), ), Expanded( - flex: 2, + flex: 1, child: Column( - mainAxisAlignment: MainAxisAlignment.end, + // mainAxisAlignment: MainAxisAlignment.end, + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Row( children: [ Expanded( - child: RaisedButton( - color: Colors.red[900], - textColor: Colors.white, - child: Text(TranslationBase.of(context).yes), - onPressed: () => { + child: DefaultButton( + TranslationBase.of(context).yes, + () => { Navigator.of(context).pushNamed( LOGIN_TYPE, - ) + ), }, + color: Colors.red[900], + textColor: Colors.white, )) ], ), Row( children: [ Expanded( - child: RaisedButton( - child: Text(TranslationBase.of(context).no), - onPressed: () => { + child: DefaultButton( + TranslationBase.of(context).no, + () => { Navigator.of(context).pushNamed( REGISTER, ) diff --git a/lib/providers/auth_provider.dart b/lib/services/authentication/auth_provider.dart similarity index 75% rename from lib/providers/auth_provider.dart rename to lib/services/authentication/auth_provider.dart index 3590355b..96548939 100644 --- a/lib/providers/auth_provider.dart +++ b/lib/services/authentication/auth_provider.dart @@ -1,7 +1,9 @@ import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; -import 'package:diplomaticquarterapp/core/model/auth/check_paitent_authentication_req.dart'; -import 'package:diplomaticquarterapp/core/model/auth/select_device_imei_res.dart'; +import 'package:diplomaticquarterapp/models/Authentication/check_paitent_authentication_req.dart'; +import 'package:diplomaticquarterapp/models/Authentication/get_mobile_info_request.dart'; +import 'package:diplomaticquarterapp/models/Authentication/get_mobile_info_response.dart'; +import 'package:diplomaticquarterapp/models/Authentication/select_device_imei_res.dart'; import 'package:diplomaticquarterapp/core/service/client/base_app_client.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; @@ -16,6 +18,7 @@ const String SELECT_DEVICE_IMEI = '/Patients.svc/REST/Patient_SELECTDeviceIMEIbyIMEI'; const String CHECK_PATIENT_AUTH = '/Authentication.svc/REST/CheckPatientAuthentication'; +const GET_MOBILE_INFO = '/Authentication.svc/REST/GetMobileLoginInfo'; class AuthProvider with ChangeNotifier { bool isLogin = false; @@ -121,4 +124,27 @@ class AuthProvider with ChangeNotifier { throw error; } } + + Future getLoginInfo( + GetMobileLoginInfoRequest request) async { + request.versionID = VERSION_ID; + request.channel = CHANNEL; + request.iPAdress = IP_ADDRESS; + request.generalid = GENERAL_ID; + request.languageID = 2; + request.patientOutSA = request.zipCode == '966' ? 0 : 1; + try { + dynamic localRes; + await new BaseAppClient().post(GET_MOBILE_INFO, + onSuccess: (dynamic response, int statusCode) { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request.toJson()); + return Future.value(localRes); + } catch (error) { + print(error); + throw error; + } + } } diff --git a/lib/uitl/translations_delegate_base.dart b/lib/uitl/translations_delegate_base.dart index fd452325..237e6988 100644 --- a/lib/uitl/translations_delegate_base.dart +++ b/lib/uitl/translations_delegate_base.dart @@ -54,9 +54,11 @@ class TranslationBase { String get nearestAppo => localizedValues['nearestAppo'][locale.languageCode]; - String get searchByDocText => localizedValues['searchByDocText'][locale.languageCode]; + String get searchByDocText => + localizedValues['searchByDocText'][locale.languageCode]; - String get enterDocName => localizedValues['enterDocName'][locale.languageCode]; + String get enterDocName => + localizedValues['enterDocName'][locale.languageCode]; String get search => localizedValues['search'][locale.languageCode]; @@ -66,29 +68,35 @@ class TranslationBase { String get appoInfo => localizedValues['appoInfo'][locale.languageCode]; - String get availableAppo => localizedValues['availableAppo'][locale.languageCode]; + String get availableAppo => + localizedValues['availableAppo'][locale.languageCode]; String get gender => localizedValues['gender'][locale.languageCode]; String get nationality => localizedValues['nationality'][locale.languageCode]; - String get docQualifications => localizedValues['docQualifications'][locale.languageCode]; + String get docQualifications => + localizedValues['docQualifications'][locale.languageCode]; - String get confirmAppoHeading => localizedValues['confirmAppoHeading'][locale.languageCode]; + String get confirmAppoHeading => + localizedValues['confirmAppoHeading'][locale.languageCode]; String get patientInfo => localizedValues['patientInfo'][locale.languageCode]; String get bookSuccess => localizedValues['bookSuccess'][locale.languageCode]; - String get patientShare => localizedValues['patientShare'][locale.languageCode]; + String get patientShare => + localizedValues['patientShare'][locale.languageCode]; - String get patientShareWithTax => localizedValues['patientShareWithTax'][locale.languageCode]; + String get patientShareWithTax => + localizedValues['patientShareWithTax'][locale.languageCode]; String get confirmAppo => localizedValues['confirmAppo'][locale.languageCode]; String get confirm => localizedValues['confirm'][locale.languageCode]; - String get confirmLater => localizedValues['confirmLater'][locale.languageCode]; + String get confirmLater => + localizedValues['confirmLater'][locale.languageCode]; String get todoList => localizedValues['todoList'][locale.languageCode]; @@ -124,6 +132,18 @@ class TranslationBase { localizedValues['gregorian-date'][locale.languageCode]; String get verifyLoginWith => localizedValues['verify-login-with'][locale.languageCode]; + String get register => localizedValues['register-user'][locale.languageCode]; + String get verifyFingerprint => + localizedValues['verify-with-fingerprint'][locale.languageCode]; + String get verifyFaceID => + localizedValues['verify-with-faceid'][locale.languageCode]; + String get verifySMS => + localizedValues['verify-with-sms'][locale.languageCode]; + String get verifyWhatsApp => + localizedValues['verify-with-whatsapp'][locale.languageCode]; + String get lastLoginAt => localizedValues['last-login'][locale.languageCode]; + String get lastLoginWith => + localizedValues['last-login-with'][locale.languageCode]; } class TranslationBaseDelegate extends LocalizationsDelegate { diff --git a/lib/widgets/buttons/defaultButton.dart b/lib/widgets/buttons/defaultButton.dart new file mode 100644 index 00000000..bc56f474 --- /dev/null +++ b/lib/widgets/buttons/defaultButton.dart @@ -0,0 +1,26 @@ +import 'package:diplomaticquarterapp/config/size_config.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/material.dart'; + +class DefaultButton extends StatelessWidget { + final String text; + final Function onPress; + final Color textColor; + final Color color; + DefaultButton(this.text, this.onPress, {this.color, this.textColor}); + @override + Widget build(BuildContext context) { + return Container( + height: 60, + child: RaisedButton( + shape: + RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)), + color: color != null ? color : Colors.grey[700], + textColor: color != null ? textColor : Colors.white, + child: Text( + this.text, + style: TextStyle(fontSize: SizeConfig.textMultiplier * 2), + ), + onPressed: () => this.onPress())); + } +} diff --git a/lib/widgets/drawer/app_drawer_widget.dart b/lib/widgets/drawer/app_drawer_widget.dart index 4a5071d1..24d3bc4f 100644 --- a/lib/widgets/drawer/app_drawer_widget.dart +++ b/lib/widgets/drawer/app_drawer_widget.dart @@ -15,7 +15,8 @@ class AppDrawer extends StatefulWidget { class _AppDrawerState extends State { @override Widget build(BuildContext context) { - return FlexibleContainer( + return SizedBox( + width: MediaQuery.of(context).size.width * 0.75, child: Container( color: Colors.white, child: Drawer( diff --git a/pubspec.yaml b/pubspec.yaml index 9a13dcdd..3af9946a 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -95,6 +95,7 @@ flutter: assets: - assets/images/ - assets/images/new-design/ + - assets/images/login/ - assets/json/ fonts: From b0989d6ca079cd7bdadae73571e790c2ce75462c Mon Sep 17 00:00:00 2001 From: Sultan Khan Date: Mon, 27 Jul 2020 10:25:26 +0300 Subject: [PATCH 4/9] login pages changes --- lib/config/config.dart | 26 +- lib/config/localized_values.dart | 6 + lib/config/shared_pref_kay.dart | 1 + lib/core/service/client/base_app_client.dart | 6 +- lib/pages/login/confirm-login.dart | 326 +++++++++++------- lib/pages/login/login.dart | 6 +- lib/pages/login/register.dart | 2 +- lib/pages/login/welcome.dart | 8 +- .../authentication/auth_provider.dart | 31 +- lib/uitl/translations_delegate_base.dart | 2 + lib/widgets/otp/sms-popup.dart | 208 +++++++++++ 11 files changed, 466 insertions(+), 156 deletions(-) create mode 100644 lib/widgets/otp/sms-popup.dart diff --git a/lib/config/config.dart b/lib/config/config.dart index d7dc1325..fd5c6275 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -2,8 +2,6 @@ import 'package:diplomaticquarterapp/models/Request.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; import 'dart:io'; - - const MAX_SMALL_SCREEN = 660; const BASE_URL = 'https://hmgwebservices.com/Services'; @@ -12,35 +10,35 @@ const GET_PROJECT = '/Lists.svc/REST/GetProject'; //const BASE_URL = 'https://hmgwebservices.com/'; // Production Environment //const BASE_URL = 'https://uat.hmgwebservices.com/'; // UAT Environment - //URL to get clinic list const GET_CLINICS_LIST_URL = "Services/lists.svc/REST/GetClinicCentralized"; //URL to get doctors list const GET_DOCTORS_LIST_URL = "Services/Doctors.svc/REST/SearchDoctorsByTime"; +const CHANNEL = 3; +const GENERAL_ID = 'Cs2020@2016\$2958'; +const IP_ADDRESS = '10.20.10.20'; +const VERSION_ID = 5.5; +var DeviceTypeID = Platform.isIOS ? 1 : 2; class AppGlobal { static var context; + AppSharedPreferences sharedPref = AppSharedPreferences(); Request getPublicRequest() { Request request = new Request(); - request.VersionID = 5.3; //3.6; - request.Channel = 3; + request.VersionID = VERSION_ID; //5.3; //3.6; + request.Channel = CHANNEL; //3; // request.LanguageID = await sharedPref.getString(APP_LANGUAGE); - request.IPAdress = "10.20.10.20"; - request.generalid = 'Cs2020@2016\$2958'; + request.IPAdress = IP_ADDRESS; //"10.20.10.20"; + request.generalid = GENERAL_ID; //'Cs2020@2016\$2958'; request.PatientOutSA = 0; request.SessionID = null; request.isDentalAllowedBackend = false; - request.DeviceTypeID = Platform.isIOS ? 1 : 2; + request.DeviceTypeID = DeviceTypeID; + // Platform.isIOS ? 1 : 2; return request; } - } - -const CHANNEL = 3; -const GENERAL_ID = 'Cs2020@2016\$2958'; -const IP_ADDRESS = '10.20.10.20'; -const VERSION_ID = 5.5; diff --git a/lib/config/localized_values.dart b/lib/config/localized_values.dart index 4c9e16e5..d28800c3 100644 --- a/lib/config/localized_values.dart +++ b/lib/config/localized_values.dart @@ -97,4 +97,10 @@ const Map> localizedValues = { "verify-with-whatsapp": {"en": "Whatsapp", "ar": " الواتس اب"}, "last-login": {"en": "LAST LOGIN AT:", "ar": "آخر تسجيل دخول"}, "last-login-with": {"en": "VERIFICATION TYPE:", "ar": "نوع التحقق:"}, + "verify-fingerprint": { + "en": + "To activate the fingerprint login service, please verify data by using one of the following options.", + "ar": + "لتفعيل خدمة الدخول بالبصمة، يرجى اختيار احدى القنوات التالية للتحقق من البيانات" + } }; diff --git a/lib/config/shared_pref_kay.dart b/lib/config/shared_pref_kay.dart index 6826de00..69b0a7f5 100644 --- a/lib/config/shared_pref_kay.dart +++ b/lib/config/shared_pref_kay.dart @@ -6,3 +6,4 @@ const REGISTER_DATA_FOR_REGISTER = 'register-data-for-register'; const LOGIN_TOKEN_ID = 'register-data-for-register'; const REGISTER_DATA_FOR_LOGIIN = 'register-data-for-login'; const LAST_LOGIN = 'last-login'; +const ONLY_SMS = 'only-sms'; diff --git a/lib/core/service/client/base_app_client.dart b/lib/core/service/client/base_app_client.dart index 57686824..026ef6c6 100644 --- a/lib/core/service/client/base_app_client.dart +++ b/lib/core/service/client/base_app_client.dart @@ -41,10 +41,14 @@ class BaseAppClient { } else { var parsed = json.decode(response.body.toString()); if (!parsed['IsAuthenticated']) { + if (parsed['isSMSSent'] == true) { + onSuccess(parsed, statusCode); + } // await helpers.logout(); //helpers.showErrorToast('Your session expired Please login agian'); // TODO create logout fun - } else if (parsed['MessageStatus'] == 1) { + } else if (parsed['MessageStatus'] == 1 || + parsed['SMSLoginRequired'] == true) { onSuccess(parsed, statusCode); } else { onFailure(parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], diff --git a/lib/pages/login/confirm-login.dart b/lib/pages/login/confirm-login.dart index afbc5915..545283a1 100644 --- a/lib/pages/login/confirm-login.dart +++ b/lib/pages/login/confirm-login.dart @@ -9,6 +9,7 @@ import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/card/rounded_container.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/otp/sms-popup.dart'; import 'package:diplomaticquarterapp/widgets/text/app_texts_widget.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; @@ -47,7 +48,7 @@ class _ConfirmLogin extends State { int selectedOption; - bool onlySMSBox; + bool onlySMSBox = false; @override void initState() { @@ -59,7 +60,7 @@ class _ConfirmLogin extends State { @override Widget build(BuildContext context) { return AppScaffold( - appBarTitle: TranslationBase.of(context).welcome, + appBarTitle: TranslationBase.of(context).confirm, isShowAppBar: true, body: Padding( padding: EdgeInsets.all(20), @@ -76,105 +77,121 @@ class _ConfirmLogin extends State { height: 80, width: 80, ), - AppText( - TranslationBase.of(context).verifyLoginWith, - fontSize: SizeConfig.textMultiplier * 3.5, - textAlign: TextAlign.left, - ), + this.onlySMSBox == false + ? AppText( + TranslationBase.of(context).verifyLoginWith, + fontSize: SizeConfig.textMultiplier * 3.5, + textAlign: TextAlign.left, + ) + : AppText( + TranslationBase.of(context) + .verifyFingerprint2, + fontSize: SizeConfig.textMultiplier * 2.5, + textAlign: TextAlign.left, + ), ])), Expanded( flex: 4, child: Column( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, + mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Expanded( - child: InkWell( - onTap: () => { - authenticateUser( - 3, BiometricType.face.index) - }, - child: RoundedContainer( - backgroundColor: - BiometricType.face.index == 1 - ? Colors.white - : Colors.white.withOpacity(.7), - borderColor: Colors.grey, - showBorder: true, - child: Padding( - padding: EdgeInsets.fromLTRB( - 20, 10, 20, 10), - child: Column( - mainAxisAlignment: - MainAxisAlignment.center, - children: [ - Image.asset( - 'assets/images/login/101.png', - height: SizeConfig - .imageSizeMultiplier * - 13, - width: SizeConfig - .imageSizeMultiplier * - 16, - ), - SizedBox( - height: 20, - ), - AppText( - TranslationBase.of(context) - .verifyFaceID, - fontSize: - SizeConfig.textMultiplier * - 2, - ) - ], - ), - )))), - Expanded( - child: InkWell( - onTap: () => { - authenticateUser(2, - BiometricType.fingerprint.index) - }, - child: RoundedContainer( - backgroundColor: - BiometricType.fingerprint.index == 1 - ? Colors.white - : Colors.white.withOpacity(.7), - borderColor: Colors.grey, - showBorder: true, - child: Padding( - padding: EdgeInsets.fromLTRB( - 25, 10, 25, 10), - child: Column( - children: [ - Image.asset( - 'assets/images/login/102.png', - height: SizeConfig - .imageSizeMultiplier * - 13, - width: SizeConfig - .imageSizeMultiplier * - 16, - ), - SizedBox( - height: 20, - ), - AppText( - TranslationBase.of(context) - .verifyFingerprint, - fontSize: - SizeConfig.textMultiplier * - 2, - ) - ], - ), - )))) - ], - ), + onlySMSBox == false + ? Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Expanded( + child: InkWell( + onTap: () => { + authenticateUser( + 3, BiometricType.face.index) + }, + child: RoundedContainer( + backgroundColor: + BiometricType.face.index == 1 + ? Colors.white + : Colors.white + .withOpacity(.7), + borderColor: Colors.grey, + showBorder: true, + child: Padding( + padding: EdgeInsets.fromLTRB( + 20, 10, 20, 10), + child: Column( + mainAxisAlignment: + MainAxisAlignment.center, + children: [ + Image.asset( + 'assets/images/login/101.png', + height: SizeConfig + .imageSizeMultiplier * + 13, + width: SizeConfig + .imageSizeMultiplier * + 16, + ), + SizedBox( + height: 20, + ), + AppText( + TranslationBase.of( + context) + .verifyFaceID, + fontSize: SizeConfig + .textMultiplier * + 2, + ) + ], + ), + )))), + Expanded( + child: InkWell( + onTap: () => { + authenticateUser( + 2, + BiometricType + .fingerprint.index) + }, + child: RoundedContainer( + backgroundColor: BiometricType + .fingerprint.index == + 1 + ? Colors.white + : Colors.white + .withOpacity(.7), + borderColor: Colors.grey, + showBorder: true, + child: Padding( + padding: EdgeInsets.fromLTRB( + 25, 10, 25, 10), + child: Column( + children: [ + Image.asset( + 'assets/images/login/102.png', + height: SizeConfig + .imageSizeMultiplier * + 13, + width: SizeConfig + .imageSizeMultiplier * + 16, + ), + SizedBox( + height: 20, + ), + AppText( + TranslationBase.of( + context) + .verifyFingerprint, + fontSize: SizeConfig + .textMultiplier * + 2, + ) + ], + ), + )))) + ], + ) + : SizedBox(), Row( mainAxisAlignment: MainAxisAlignment.center, children: [ @@ -251,7 +268,7 @@ class _ConfirmLogin extends State { ]), ), Expanded( - flex: 2, + flex: 1, child: Column( mainAxisAlignment: MainAxisAlignment.end, children: [ @@ -316,7 +333,50 @@ class _ConfirmLogin extends State { type); //this.cs.sharedService.setStorage(this.selectedOption, AuthenticationService.LAST_LOGIN); } - loginWithSMS(type, isActive) {} + loginWithSMS(type, isActive) { + //if (!el.disabled) { + if (this.user != null && this.registerd_data != null) { + this.checkUserAuthentication(type); + } else { + if (this.loginTokenID != null) { + this.sendActivationCode(type); + } else { + this.checkUserAuthentication(type); + } + } + } + + checkUserAuthentication(type) {} + + sendActivationCode(type) { + // const imeiData = this.cs.sharedService.getSharedData(AuthenticationService.IMEI_USER_DATA, false); + this.startSMSService(type); + return false; + var request = this.getCommonRequest(); + + this.authService.sendActivationCode(request).then((result) => { + if (result['isSMSSent'] == true) + { + // this.sharedService.setSharedData({ + // MobileNumber: this.mobileNumber, + // loginType: type + // }, + // CheckActivation.SHARED_DATA + // ); + this.startSMSService(type) + } + }); + } + + startSMSService(type) { + new SMSOTP( + context, + type, + this.mobileNumber, + (value) => {this.checkActivationCode(value: value)}, + () => {print('Faild..')}).displayDialog(context); + } + loginWithFingurePrintFace(type, isActive) async { if (isActive == 1) { // this.startBiometricLoginIfAvailable(); @@ -334,41 +394,40 @@ class _ConfirmLogin extends State { loginWithWhatsapp(type, isActive) {} getMobileInfo(request) { - this - .authService - .getLoginInfo(request) - .then((GetMobileLoginInfoResponse result) => { - if (!result.sMSLoginRequired) + this.authService.getLoginInfo(request).then((result) => { + if (!result['SMSLoginRequired']) + { + this.loginTokenID = result.logInTokenID, + this.patientOutSA = result.patientOutSA, + // sms for register the biometric + if (result.isSMSSent) { - this.loginTokenID = result.logInTokenID, - this.patientOutSA = result.patientOutSA, - // sms for register the biometric - if (result.isSMSSent) - { - this.onlySMSBox = false, - //this.button(); - } - else - { - //this.checkActivationCode(); - } + this.onlySMSBox = false, + //this.button(); } else + {checkActivationCode()} + } + else + { + if (result['IsAuthenticated']) { - if (result.isAuthenticated) - { - // this.onlySMSBox = false; - // this.cs.sharedService.setSharedData(true, AuthenticationService.ONLY_SMS); - // this.cs.sharedService.setSharedData(this.selectedOption, AuthenticationService.FINGUREPRINT_BEFORE); - // this.cs.confirmLogin(); - // this.button(); - } - else - { - // this.cs.presentAlert(result.ErrorEndUserMessage); - } + setState(() { + this.onlySMSBox = true; + }), + + //sharedPref.setBool(ONLY_SMS, true), + // this.cs.sharedService.setSharedData(true, AuthenticationService.ONLY_SMS); + //this.cs.sharedService.setSharedData(this.selectedOption, AuthenticationService.FINGUREPRINT_BEFORE); + // this.cs.confirmLogin(); + //this.button(); } - }); + // else + // { + // // this.cs.presentAlert(result.ErrorEndUserMessage); + // } + } + }); } setDefault() async { @@ -376,7 +435,9 @@ class _ConfirmLogin extends State { // AuthenticationService.IMEI_USER_DATA, // false // ); - this.registerd_data = await sharedPref.getObject(REGISTER_DATA_FOR_LOGIIN); + this.registerd_data = CheckPatientAuthenticationReq.fromJson( + await sharedPref.getObject(REGISTER_DATA_FOR_LOGIIN)); + this.mobileNumber = this.registerd_data != null ? this.registerd_data.patientMobileNumber : int.parse(this.user.Mobile); @@ -387,11 +448,11 @@ class _ConfirmLogin extends State { ? this.registerd_data.zipCode == "966" ? 0 : 1 : this.user.OutSA; if (this.registerd_data != null) { - this.loginTokenID = sharedPref.getString(LOGIN_TOKEN_ID); + this.loginTokenID = await sharedPref.getString(LOGIN_TOKEN_ID); this.loginType = this.registerd_data.searchType; } - this.deviceToken = sharedPref.getString(PUSH_TOKEN); - this.lastLogin = sharedPref.getInt( + this.deviceToken = await sharedPref.getString(PUSH_TOKEN); + this.lastLogin = await sharedPref.getInt( LAST_LOGIN); //this.cs.sharedService.getStorage(AuthenticationService.LAST_LOGIN); } @@ -402,6 +463,7 @@ class _ConfirmLogin extends State { request.deviceToken = this.deviceToken; request.projectOutSA = this.patientOutSA; request.loginType = this.selectedOption; + request.oTPSendType = this.selectedOption; request.zipCode = this.zipCode; request.isRegister = false; request.logInTokenID = this.loginTokenID ?? ""; @@ -422,4 +484,6 @@ class _ConfirmLogin extends State { } return request; } + + checkActivationCode({value}) {} } diff --git a/lib/pages/login/login.dart b/lib/pages/login/login.dart index 982d75e3..b0f9a1fd 100644 --- a/lib/pages/login/login.dart +++ b/lib/pages/login/login.dart @@ -44,19 +44,19 @@ class _Login extends State { : SingleChildScrollView( child: Container( padding: - EdgeInsets.only(top: 10, left: 20, right: 20, bottom: 20), + EdgeInsets.only(top: 10, left: 20, right: 20, bottom: 30), height: SizeConfig.realScreenHeight * .9, width: SizeConfig.realScreenWidth, child: Column(children: [ Expanded( - flex: 1, + flex: 2, child: AppText( TranslationBase.of(context).enterNationalId, fontSize: SizeConfig.textMultiplier * 3.5, textAlign: TextAlign.left, )), Expanded( - flex: 2, + flex: 3, child: Column( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ diff --git a/lib/pages/login/register.dart b/lib/pages/login/register.dart index 31a4c4a1..0d4244b0 100644 --- a/lib/pages/login/register.dart +++ b/lib/pages/login/register.dart @@ -30,7 +30,7 @@ class _Register extends State { isShowAppBar: true, body: SingleChildScrollView( child: Container( - padding: EdgeInsets.only(top: 10, left: 20, right: 20, bottom: 20), + padding: EdgeInsets.only(top: 10, left: 20, right: 20, bottom: 30), height: SizeConfig.realScreenHeight * .9, width: SizeConfig.realScreenWidth, child: Column(children: [ diff --git a/lib/pages/login/welcome.dart b/lib/pages/login/welcome.dart index 250f6d34..1f2c0474 100644 --- a/lib/pages/login/welcome.dart +++ b/lib/pages/login/welcome.dart @@ -18,7 +18,7 @@ class WelcomeLogin extends StatelessWidget { child: Column( children: [ Expanded( - flex: 4, + flex: 6, child: Column( mainAxisAlignment: MainAxisAlignment.spaceEvenly, crossAxisAlignment: CrossAxisAlignment.start, @@ -49,10 +49,10 @@ class WelcomeLogin extends StatelessWidget { ]), ), Expanded( - flex: 1, + flex: 2, child: Column( - // mainAxisAlignment: MainAxisAlignment.end, - mainAxisAlignment: MainAxisAlignment.spaceBetween, + //mainAxisAlignment: MainAxisAlignment.end, + mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ Row( children: [ diff --git a/lib/services/authentication/auth_provider.dart b/lib/services/authentication/auth_provider.dart index 96548939..cc2aef99 100644 --- a/lib/services/authentication/auth_provider.dart +++ b/lib/services/authentication/auth_provider.dart @@ -19,6 +19,8 @@ const String SELECT_DEVICE_IMEI = const String CHECK_PATIENT_AUTH = '/Authentication.svc/REST/CheckPatientAuthentication'; const GET_MOBILE_INFO = '/Authentication.svc/REST/GetMobileLoginInfo'; +const SEND_ACTIVATION_CODE = + '/Authentication.svc/REST/SendActivationCodebyOTPNotificationType'; class AuthProvider with ChangeNotifier { bool isLogin = false; @@ -125,14 +127,15 @@ class AuthProvider with ChangeNotifier { } } - Future getLoginInfo( - GetMobileLoginInfoRequest request) async { + Future getLoginInfo(request) async { request.versionID = VERSION_ID; request.channel = CHANNEL; request.iPAdress = IP_ADDRESS; request.generalid = GENERAL_ID; request.languageID = 2; + request.deviceTypeID = DeviceTypeID; request.patientOutSA = request.zipCode == '966' ? 0 : 1; + request.isDentalAllowedBackend = false; try { dynamic localRes; await new BaseAppClient().post(GET_MOBILE_INFO, @@ -147,4 +150,28 @@ class AuthProvider with ChangeNotifier { throw error; } } + + Future sendActivationCode(request) async { + request.versionID = VERSION_ID; + request.channel = CHANNEL; + request.iPAdress = IP_ADDRESS; + request.generalid = GENERAL_ID; + request.languageID = 2; + request.deviceTypeID = DeviceTypeID; + request.patientOutSA = request.zipCode == '966' ? 0 : 1; + request.isDentalAllowedBackend = false; + try { + dynamic localRes; + await new BaseAppClient().post(SEND_ACTIVATION_CODE, + onSuccess: (dynamic response, int statusCode) { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request.toJson()); + return Future.value(localRes); + } catch (error) { + print(error); + throw error; + } + } } diff --git a/lib/uitl/translations_delegate_base.dart b/lib/uitl/translations_delegate_base.dart index 237e6988..54d3d872 100644 --- a/lib/uitl/translations_delegate_base.dart +++ b/lib/uitl/translations_delegate_base.dart @@ -144,6 +144,8 @@ class TranslationBase { String get lastLoginAt => localizedValues['last-login'][locale.languageCode]; String get lastLoginWith => localizedValues['last-login-with'][locale.languageCode]; + String get verifyFingerprint2 => + localizedValues['verify-fingerprint'][locale.languageCode]; } class TranslationBaseDelegate extends LocalizationsDelegate { diff --git a/lib/widgets/otp/sms-popup.dart b/lib/widgets/otp/sms-popup.dart new file mode 100644 index 00000000..5859a170 --- /dev/null +++ b/lib/widgets/otp/sms-popup.dart @@ -0,0 +1,208 @@ +import 'package:diplomaticquarterapp/config/size_config.dart'; +import 'package:diplomaticquarterapp/widgets/text/app_texts_widget.dart'; +import 'package:flutter/material.dart'; + +class SMSOTP { + final type; + final mobileNo; + final Function onSuccess; + final Function onFailure; + final context; + SMSOTP( + this.context, this.type, this.mobileNo, this.onSuccess, this.onFailure); + + Map verifyAccountFormValue = { + 'digit1': null, + 'digit2': null, + 'digit3': null, + 'digit4': null, + }; + final focusD1 = FocusNode(); + final focusD2 = FocusNode(); + final focusD3 = FocusNode(); + final focusD4 = FocusNode(); + displayDialog(BuildContext context) async { + return showDialog( + context: context, + builder: (context) { + return AlertDialog( + title: Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + IconButton( + icon: Icon(Icons.close), + onPressed: () => { + Navigator.pop(context), + this.onSuccess(verifyAccountFormValue) + }, + ) + ], + ), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.all(Radius.circular(10.0))), + + content: Builder(builder: (context) { + return Container( + color: Colors.white, + height: SizeConfig.realScreenHeight * 0.5, + width: SizeConfig.realScreenWidth * 0.8, + child: Center( + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Image.asset('assets/images/login/103.png'), + Padding( + padding: EdgeInsets.only(top: 20), + child: AppText( + 'Enter The Varification sent to XXXXXXX144', + textAlign: TextAlign.center, + )), + Padding( + padding: EdgeInsets.only(top: 20), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + Container( + width: SizeConfig.realScreenWidth * 0.15, + child: TextFormField( + textInputAction: TextInputAction.next, + style: buildTextStyle(), + autofocus: true, + maxLength: 1, + textAlign: TextAlign.center, + keyboardType: TextInputType.number, + decoration: buildInputDecoration(context), + onSaved: (val) { + verifyAccountFormValue['digit1'] = val; + }, + validator: validateCodeDigit, + onFieldSubmitted: (_) { + FocusScope.of(context).requestFocus(focusD2); + }, + onChanged: (val) { + if (val.length == 1) { + FocusScope.of(context) + .requestFocus(focusD2); + } + }, + ), + ), + Container( + width: SizeConfig.realScreenWidth * 0.15, + child: TextFormField( + focusNode: focusD2, + textInputAction: TextInputAction.next, + maxLength: 1, + textAlign: TextAlign.center, + style: buildTextStyle(), + keyboardType: TextInputType.number, + decoration: buildInputDecoration(context), + onSaved: (val) { + verifyAccountFormValue['digit2'] = val; + }, + onFieldSubmitted: (_) { + FocusScope.of(context) + .requestFocus(focusD3); + }, + onChanged: (val) { + if (val.length == 1) { + FocusScope.of(context) + .requestFocus(focusD3); + } + }, + validator: validateCodeDigit), + ), + Container( + width: SizeConfig.realScreenWidth * 0.15, + child: TextFormField( + focusNode: focusD3, + textInputAction: TextInputAction.next, + maxLength: 1, + textAlign: TextAlign.center, + style: buildTextStyle(), + keyboardType: TextInputType.number, + decoration: buildInputDecoration(context), + onSaved: (val) { + verifyAccountFormValue['digit3'] = val; + }, + onFieldSubmitted: (_) { + FocusScope.of(context) + .requestFocus(focusD4); + }, + onChanged: (val) { + if (val.length == 1) { + FocusScope.of(context) + .requestFocus(focusD4); + } + }, + validator: validateCodeDigit)), + Container( + width: SizeConfig.realScreenWidth * 0.15, + child: TextFormField( + focusNode: focusD4, + maxLength: 1, + textAlign: TextAlign.center, + style: buildTextStyle(), + keyboardType: TextInputType.number, + decoration: buildInputDecoration(context), + onSaved: (val) { + verifyAccountFormValue['digit4'] = val; + }, + validator: validateCodeDigit)) + ], + )) + ], + )), + ); + }), + // actions: [ + // new FlatButton( + // child: new Text('SUBMIT'), + // onPressed: () { + // Navigator.of(context).pop(); + // }, + // ) + // ], + ); + }); + } + + TextStyle buildTextStyle() { + return TextStyle( + fontSize: SizeConfig.textMultiplier * 3, + ); + } + + InputDecoration buildInputDecoration(BuildContext context) { + return InputDecoration( + // ts/images/password_icon.png + contentPadding: EdgeInsets.only(top: 20, bottom: 20), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.all(Radius.circular(10)), + borderSide: BorderSide(color: Colors.black), + ), + focusedBorder: OutlineInputBorder( + borderRadius: BorderRadius.all(Radius.circular(10.0)), + borderSide: BorderSide(color: Theme.of(context).primaryColor), + ), + errorBorder: OutlineInputBorder( + borderRadius: BorderRadius.all(Radius.circular(10.0)), + borderSide: BorderSide(color: Theme.of(context).errorColor), + ), + focusedErrorBorder: OutlineInputBorder( + borderRadius: BorderRadius.all(Radius.circular(10.0)), + borderSide: BorderSide(color: Theme.of(context).errorColor), + ), + ); + } + + String validateCodeDigit(value) { + if (value.isEmpty) { + return 'Please enter your Password'; + } else if (value.length == 3) { + print(value); + } else { + return null; + } + } +} From e92cb2e1aca41c5824b6636f5d56df5d5a63ac82 Mon Sep 17 00:00:00 2001 From: hussam al-habibeh Date: Tue, 28 Jul 2020 16:16:08 +0300 Subject: [PATCH 5/9] Design and return Pharmacy List --- lib/config/config.dart | 8 +- lib/config/localized_values.dart | 24 +- .../pharmacies/pharmacies_list_model.dart | 50 +++- .../model/pharmacies/pharmacies_model.dart | 6 +- lib/core/service/pharmacies_service.dart | 69 ++++-- .../viewModels/pharmacies_view_model.dart | 16 +- .../MyAppointments/AppointmentDetails.dart | 5 +- lib/pages/landing/home_page.dart | 3 +- .../pharmacies/medicine_search_screen.dart | 209 ++++++++-------- .../pharmacies/pharmacies_list_screen.dart | 230 ++++++++++++------ lib/uitl/translations_delegate_base.dart | 32 ++- lib/widgets/data_display/text.dart | 14 +- lib/widgets/pharmacy/drug_item.dart | 28 +-- pubspec.yaml | 1 + 14 files changed, 440 insertions(+), 255 deletions(-) diff --git a/lib/config/config.dart b/lib/config/config.dart index 60e9bbd3..5c63998d 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -4,22 +4,21 @@ import 'dart:io'; const MAX_SMALL_SCREEN = 660; - - const BASE_URL = 'https://hmgwebservices.com/Services'; const GET_PROJECT = '/Lists.svc/REST/GetProject'; //const BASE_URL = 'https://hmgwebservices.com/'; // Production Environment //const BASE_URL = 'https://uat.hmgwebservices.com/'; // UAT Environment - //URL to get clinic list const GET_CLINICS_LIST_URL = "Services/lists.svc/REST/GetClinicCentralized"; //URL to get doctors list const GET_DOCTORS_LIST_URL = "Services/Doctors.svc/REST/SearchDoctorsByTime"; +//URL to get medicine and pharmacies list const GET_PHARMCY_ITEMS = "/Lists.svc/REST/GetPharmcyItems_Region"; const GET_PHARMACY_LIST = "/Patients.svc/REST/GetPharmcyList"; + class AppGlobal { static var context; AppSharedPreferences sharedPref = AppSharedPreferences(); @@ -38,10 +37,9 @@ class AppGlobal { return request; } - } const CHANNEL = 3; const GENERAL_ID = 'Cs2020@2016\$2958'; const IP_ADDRESS = '10.20.10.20'; -const VERSION_ID = 5.5; +const VERSION_ID = 8.5; diff --git a/lib/config/localized_values.dart b/lib/config/localized_values.dart index c762812d..e317f309 100644 --- a/lib/config/localized_values.dart +++ b/lib/config/localized_values.dart @@ -19,7 +19,10 @@ const Map> localizedValues = { 'clinicName': {'en': 'Clinic Name', 'ar': 'اسم العيادة'}, 'doctorName': {'en': 'Doctor Name', 'ar': 'إسم الطبيب'}, 'nearestAppo': {'en': 'Nearest appointment', 'ar': 'أقرب موعد'}, - 'searchByDocText': {'en': 'Type the name of the doctor to help you find him', 'ar': 'اكتب اسم الطبيب لمساعدتك في العثور عليه'}, + 'searchByDocText': { + 'en': 'Type the name of the doctor to help you find him', + 'ar': 'اكتب اسم الطبيب لمساعدتك في العثور عليه' + }, 'enterDocName': {'en': 'Enter Doctor name', 'ar': 'أدخل إسم الطبيب'}, 'search': {'en': 'Search', 'ar': 'بحث'}, 'bookNow': {'en': 'BOOK NOW', 'ar': 'احجز الآن'}, @@ -29,19 +32,23 @@ const Map> localizedValues = { 'gender': {'en': 'Gender', 'ar': 'الجنس'}, 'nationality': {'en': 'nationality', 'ar': 'الجنسية'}, 'docQualifications': {'en': 'Doctor Qualifications', 'ar': 'مؤهلات الطبيب'}, - 'confirmAppoHeading': {'en': 'Kindly confirm your Appointment', 'ar': 'يرجى تأكيد موعدك'}, + 'confirmAppoHeading': { + 'en': 'Kindly confirm your Appointment', + 'ar': 'يرجى تأكيد موعدك' + }, 'patientInfo': {'en': 'Patient Information', 'ar': 'معلومات المريض'}, 'bookSuccess': {'en': 'Book Success', 'ar': 'تم حجز الموعد بنجاح'}, 'patientShare': {'en': 'Patient Share', 'ar': 'المبلغ المستحق'}, - 'patientShareWithTax': {'en': 'Patient Share with Tax', 'ar': 'المبلغ الإجمالي المستحق'}, + 'patientShareWithTax': { + 'en': 'Patient Share with Tax', + 'ar': 'المبلغ الإجمالي المستحق' + }, 'confirmAppo': {'en': 'Confirm Appointment', 'ar': 'تأكيد الموعد'}, 'confirm': {'en': 'Confirm', 'ar': 'تأكيد'}, 'appointment': {'en': 'Appointment', 'ar': 'الموعد'}, 'confirmLater': {'en': 'Confirm Later', 'ar': 'تأكيد لاحقا'}, 'todoList': {'en': 'Todo List', 'ar': 'مهامي'}, 'appoActions': {'en': 'Appointment Actions', 'ar': 'إجراءات الموعد'}, - - 'login': {'en': 'Login', 'ar': 'تسجيل الدخول'}, 'loginregister': {'en': 'Login / Register', 'ar': 'دخولتسجيل'}, 'welcome': {'en': 'Welcome', 'ar': 'أهلا بك'}, @@ -85,4 +92,11 @@ const Map> localizedValues = { 'en': 'Search Medicine Here', 'ar': 'ابحث عن الدواء هنا' }, + 'description': {'en': 'Description', 'ar': 'الوصف'}, + 'price': {'en': 'Price', 'ar': 'السعر'}, + 'youCanFindItIn': {'en': 'You can find it in', 'ar': 'يمكنكة ان تجده في'}, + 'pleaseEnterMedicineName': { + 'en': 'Please Enter Medicine Name', + 'ar': 'الرجائ ادخال اسم الدواء' + }, }; diff --git a/lib/core/model/pharmacies/pharmacies_list_model.dart b/lib/core/model/pharmacies/pharmacies_list_model.dart index 34228e11..01a43a0a 100644 --- a/lib/core/model/pharmacies/pharmacies_list_model.dart +++ b/lib/core/model/pharmacies/pharmacies_list_model.dart @@ -14,22 +14,46 @@ class PharmaciesListModel { int editedBy; int projectID; int clinicID; + double price; + String imageLocation; + String desLocation; + String itemDes; + String phoneNumber; + String longitude; + String latitude; - PharmaciesListModel({ - this.itemID, - this.patientTypeID = 1, - this.languageID = 2, - this.stamp = '2020-04-23T21:01:21.492Z', - this.iPAdress = '11.11.11.11', - this.versionID = 1.2, - this.tokenID, - this.sessionID = 'e29zoooEJ4', - this.isLoginForDoctorApp = true, - this.channel = 9, - //this.patientOutSA = true, - }); + PharmaciesListModel( + {this.itemID, + this.patientTypeID, + this.languageID, + this.stamp, + this.iPAdress, + this.versionID, + this.tokenID, + this.sessionID, + this.isLoginForDoctorApp, + this.channel, + this.editedBy, + this.doctorID, + this.patientOutSA, + this.clinicID, + this.projectID, + this.price, + this.imageLocation, + this.desLocation, + this.itemDes, + this.phoneNumber, + this.longitude, + this.latitude}); PharmaciesListModel.fromJson(Map json) { + longitude = json['Longitude']; + latitude = json['Latitude']; + phoneNumber = json['PhoneNumber']; + itemDes = json['ItemDescription']; + desLocation = json['LocationDescription']; + imageLocation = json['ProjectImageURL']; + price = json['SellingPrice']; itemID = json['ItemID']; patientTypeID = json['PatientTypeID']; languageID = json['LanguageID']; diff --git a/lib/core/model/pharmacies/pharmacies_model.dart b/lib/core/model/pharmacies/pharmacies_model.dart index 69576dd2..d1b9b967 100644 --- a/lib/core/model/pharmacies/pharmacies_model.dart +++ b/lib/core/model/pharmacies/pharmacies_model.dart @@ -20,6 +20,7 @@ class PharmaciesModel { bool isLoginForDoctorApp; String itemDes; String productImage; + int itemID; PharmaciesModel( {this.pHRItemName, @@ -42,9 +43,12 @@ class PharmaciesModel { this.stamp, this.itemDes, this.productImage, - this.isLoginForDoctorApp}); + this.isLoginForDoctorApp, + this.itemID}); PharmaciesModel.fromJson(Map json) { + itemID = json['ItemID']; + productImage = json['ProductImageBase64']; itemDes = json['ItemDescription']; pHRItemName = json['PHR_itemName']; diff --git a/lib/core/service/pharmacies_service.dart b/lib/core/service/pharmacies_service.dart index fb59dceb..b155d4d0 100644 --- a/lib/core/service/pharmacies_service.dart +++ b/lib/core/service/pharmacies_service.dart @@ -2,17 +2,23 @@ import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/pharmacies_list_model.dart'; import 'package:diplomaticquarterapp/core/service/base_service.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/pharmacies_model.dart'; -import 'package:diplomaticquarterapp/core/model/pharmacies/pharmacies_list_model.dart'; class PharmacyService extends BaseService { - List _pharmaciesList = List(); + List _medicineItem = List(); + List _pharmaciesList = List(); + + List get medicineItem => _medicineItem; + List get pharmaciesList => _pharmaciesList; - List get pharmaciesList => _pharmaciesList; bool isFinished = true; bool hasError = false; String errorMsg = ''; - void clearPharmaciesLis() { + void clearMedicineList() { + _medicineItem.clear(); + } + + void clearPharmaciesList() { _pharmaciesList.clear(); } @@ -35,17 +41,33 @@ class PharmacyService extends BaseService { sessionID: "BlUSkYymTt", stamp: "2020-04-27T12:17:17.721Z", tokenID: "6EfeKCLRu0GPdFutIt3m7Q==", - versionID: 5.3); + versionID: 8.3); - Future getMedicine({String drugName}) async { + PharmaciesListModel _pharmaciesListModel = PharmaciesListModel( + patientTypeID: 1, + languageID: 2, + stamp: '2020-04-23T21:01:21.492Z', + iPAdress: '11.11.11.11', + versionID: 8.3, + sessionID: 'e29zoooEJ4', + isLoginForDoctorApp: true, + channel: 9, + editedBy: 1485, + doctorID: 1485, + patientOutSA: 0, + clinicID: 1, + projectID: 15, + ); + + Future getMedicineList({String drugName}) async { hasError = false; - _requestGetPharmaciesModel.pHRItemName = drugName ?? 'panadol'; + _requestGetPharmaciesModel.pHRItemName = drugName; try { await baseAppClient.post(GET_PHARMCY_ITEMS, onSuccess: (dynamic response, int statusCode) { - _pharmaciesList.clear(); + _medicineItem.clear(); response['ListPharmcy_Region'].forEach((item) { - _pharmaciesList.add(PharmaciesModel.fromJson(item)); + _medicineItem.add(PharmaciesModel.fromJson(item)); }); }, onFailure: (String error, int statusCode) { hasError = true; @@ -56,17 +78,22 @@ class PharmacyService extends BaseService { } } - Future getMedicineList({String name}) async { - _requestGetPharmaciesModel.pHRItemName = name ?? 'panadol'; - await baseAppClient.post(GET_PHARMACY_LIST, - onSuccess: (dynamic response, int statusCode) { - _pharmaciesList.clear(); - response['PharmList'].forEach((item) { - _pharmaciesList.add(PharmaciesModel.fromJson(item)); - }); - }, onFailure: (String error, int statusCode) { - hasError = true; - super.error = error; - }, body: _requestGetPharmaciesModel.toJson()); + Future getPharmaciesList({int itemID}) async { + _pharmaciesListModel.itemID = itemID; + try { + await baseAppClient.post(GET_PHARMACY_LIST, + onSuccess: (dynamic response, int statusCode) { + _pharmaciesList.clear(); + response['PharmList'].forEach((item) { + _pharmaciesList.add(PharmaciesListModel.fromJson(item)); + hasError = false; + }); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: _pharmaciesListModel.toJson()); + } catch (error) { + throw error; + } } } diff --git a/lib/core/viewModels/pharmacies_view_model.dart b/lib/core/viewModels/pharmacies_view_model.dart index da40fbe3..01ad4e72 100644 --- a/lib/core/viewModels/pharmacies_view_model.dart +++ b/lib/core/viewModels/pharmacies_view_model.dart @@ -1,3 +1,4 @@ +import 'package:diplomaticquarterapp/core/model/pharmacies/pharmacies_list_model.dart'; import '../../locator.dart'; import 'base_view_model.dart'; import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; @@ -10,23 +11,26 @@ class PharmacyViewModel extends BaseViewModel { String errorMsg = ''; PharmacyService _pharmacyService = locator(); - List get pharmacy => _pharmacyService.pharmaciesList; + List get pharmacy => _pharmacyService.medicineItem; + List get pharmacyList => _pharmacyService.pharmaciesList; - Future getMedicine() async { + Future getPharmacies({int id}) async { setState(ViewState.Busy); - await _pharmacyService.getMedicine(); + + await _pharmacyService.getPharmaciesList(itemID: id); if (_pharmacyService.hasError) { error = _pharmacyService.error; setState(ViewState.Error); } else setState(ViewState.Idle); + //_pharmacyService.clearPharmaciesList(); } - Future getMedicine2({String name}) async { + Future getMedicine({String name}) async { hasError = false; - _pharmacyService.clearPharmaciesLis(); + _pharmacyService.clearMedicineList(); setState(ViewState.BusyLocal); - await _pharmacyService.getMedicine(drugName: name); + await _pharmacyService.getMedicineList(drugName: name); if (_pharmacyService.hasError) { error = _pharmacyService.error; setState(ViewState.ErrorLocal); diff --git a/lib/pages/MyAppointments/AppointmentDetails.dart b/lib/pages/MyAppointments/AppointmentDetails.dart index ffb5f6be..0fe7673c 100644 --- a/lib/pages/MyAppointments/AppointmentDetails.dart +++ b/lib/pages/MyAppointments/AppointmentDetails.dart @@ -4,14 +4,13 @@ import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:rating_bar/rating_bar.dart'; import 'Components/AppointmentActions.dart'; - class AppointmentDetails extends StatefulWidget { @override _AppointmentDetailsState createState() => _AppointmentDetailsState(); } -class _AppointmentDetailsState extends State with SingleTickerProviderStateMixin { - +class _AppointmentDetailsState extends State + with SingleTickerProviderStateMixin { TabController _tabController; bool showFooterButton = false; diff --git a/lib/pages/landing/home_page.dart b/lib/pages/landing/home_page.dart index d94251bd..6169fdf4 100644 --- a/lib/pages/landing/home_page.dart +++ b/lib/pages/landing/home_page.dart @@ -6,6 +6,7 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/pharmacies_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/pharmacies_view_model.dart'; +import 'package:diplomaticquarterapp/core/model/pharmacies/pharmacies_list_model.dart'; import '../base/base_view.dart'; @@ -18,7 +19,7 @@ class _HomePageState extends State { @override Widget build(BuildContext context) { return BaseView( - // onModelReady: (model) => model.getMedicine(), + onModelReady: (model) => model.getMedicine(), builder: (BuildContext context, PharmacyViewModel model, Widget child) => AppScaffold( baseViewModel: model, diff --git a/lib/pages/pharmacies/medicine_search_screen.dart b/lib/pages/pharmacies/medicine_search_screen.dart index 200a7838..644134b2 100644 --- a/lib/pages/pharmacies/medicine_search_screen.dart +++ b/lib/pages/pharmacies/medicine_search_screen.dart @@ -11,18 +11,11 @@ import '../base/base_view.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/input/text_field.dart'; -import 'package:diplomaticquarterapp/widgets/buttons/BottomButton.dart'; import 'package:diplomaticquarterapp/widgets/pharmacy/drug_item.dart'; -import '../../locator.dart'; import 'package:diplomaticquarterapp/core/service/pharmacies_service.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/pharmacies_list_screen.dart'; -class MedicineSearch extends StatefulWidget { - @override - _MedicineSearchState createState() => _MedicineSearchState(); -} - -class _MedicineSearchState extends State { +class MedicineSearch extends StatelessWidget { final textController = TextEditingController(); final _formKey = GlobalKey(); @override @@ -31,115 +24,121 @@ class _MedicineSearchState extends State { builder: (BuildContext context, PharmacyViewModel model, Widget child) => AppScaffold( baseViewModel: model, - appBarTitle: 'Search Medicine', - body: Column( - children: [ - Padding( - padding: EdgeInsets.only( - bottom: SizeConfig.heightMultiplier * 1, - right: SizeConfig.heightMultiplier * 2.5, - top: SizeConfig.heightMultiplier * 4, - left: SizeConfig.heightMultiplier * 2.5, - ), - child: Form( - key: _formKey, - child: TextFields( - hintText: 'Search Medicine here ', - inputAction: TextInputAction.search, - onSaved: (value) {}, - onSubmit: (value) { - searchMedicine(model); - }, - controller: textController, - validator: (value) { - if (value.isEmpty) { - return 'please enter medicine name'; - } - return null; - }, + appBarTitle: TranslationBase.of(context).searchMedicine, + body: Container( + height: SizeConfig.screenHeight, + child: Column( + children: [ + Padding( + padding: EdgeInsets.only( + bottom: SizeConfig.heightMultiplier * 1, + right: SizeConfig.heightMultiplier * 2.5, + top: SizeConfig.heightMultiplier * 4, + left: SizeConfig.heightMultiplier * 2.5, ), - ), - ), - Container( - margin: EdgeInsets.only( - bottom: SizeConfig.heightMultiplier * 0.0, - right: SizeConfig.heightMultiplier * 5, - top: SizeConfig.heightMultiplier * 1, - left: SizeConfig.heightMultiplier * 5, - ), - child: Wrap( - children: [ - Container( - child: Button( - loading: model.state == ViewState.BusyLocal, - label: 'Search', - onTap: () { - searchMedicine(model); - }), - width: 350.0, + child: Form( + key: _formKey, + child: TextFields( + hintText: + TranslationBase.of(context).searchMedicineHere, + inputAction: TextInputAction.search, + onSaved: (value) {}, + onSubmit: (value) { + searchMedicine(model, context); + }, + controller: textController, + validator: (value) { + if (value.isEmpty) { + return TranslationBase.of(context) + .pleaseEnterMedicineName; + } + return null; + }, ), - ], + ), ), - ), - Container( - margin: - EdgeInsets.only(left: SizeConfig.heightMultiplier * 2), - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Texts( - 'You Can Find ' + - '${model.pharmacy == null ? '0' : model.pharmacy.length.toString()}' - ' Item In Search ', - ), - ], + Container( + margin: EdgeInsets.only( + bottom: SizeConfig.heightMultiplier * 0.0, + right: SizeConfig.heightMultiplier * 5, + top: SizeConfig.heightMultiplier * 1, + left: SizeConfig.heightMultiplier * 5, + ), + child: Wrap( + children: [ + Container( + child: Button( + loading: model.state == ViewState.BusyLocal, + label: TranslationBase.of(context).search, + onTap: () { + searchMedicine(model, context); + }), + width: 350.0, + ), + ], + ), ), - ), - if (model.state == ViewState.ErrorLocal) Container( - child: Texts(model.error), + margin: EdgeInsets.only( + left: SizeConfig.heightMultiplier * 2), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Texts( + 'You Can Find ' + + '${model.pharmacy == null ? '0' : model.pharmacy.length.toString()}' + ' Item In Search ', + ), + ], + ), ), - Expanded( - child: Container( - width: SizeConfig.screenWidth * 0.85, - //child: _getHospitals(model.pharmacy), - child: ListView.builder( - scrollDirection: Axis.vertical, - shrinkWrap: true, - itemCount: model.pharmacy == null - ? 0 - : model.pharmacy.length, - itemBuilder: (BuildContext context, int index) { - return InkWell( - child: MedicineItemWidget( - label: model.pharmacy[index].itemDes, - url: model.pharmacy[index].productImage), - onTap: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => PharmaciesList()), - ); - }, - ); - }), + if (model.state == ViewState.ErrorLocal) + Container( + child: Texts(model.error), + ), + Expanded( + child: Container( + width: SizeConfig.screenWidth * 0.85, + //child: _getHospitals(model.pharmacy), + child: ListView.builder( + //physics: NeverScrollableScrollPhysics(), + scrollDirection: Axis.vertical, + shrinkWrap: true, + itemCount: model.pharmacy == null + ? 0 + : model.pharmacy.length, + itemBuilder: (BuildContext context, int index) { + return InkWell( + child: MedicineItemWidget( + label: model.pharmacy[index].itemDes, + url: model.pharmacy[index].productImage), + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => PharmaciesList( + medicineID: + model.pharmacy[index].itemID, + imageURL: model + .pharmacy[index].productImage, + medicineDescription: + model.pharmacy[index].itemDes), + ), + ); + }, + ); + }), + ), ), - ) - ], + ], + ), )), ); } - searchMedicine(PharmacyViewModel model) { + searchMedicine(PharmacyViewModel model, BuildContext context) { Utils.hideKeyboard(context); if (_formKey.currentState.validate()) - model.getMedicine2(name: textController.text); + model.getMedicine(name: textController.text); } - - Widget _getHospitals(List hospitals) => ListView.builder( - itemCount: hospitals.length, - itemBuilder: (BuildContext context, int index) => Container( - child: Texts(hospitals[index].itemDes), - ), - ); } diff --git a/lib/pages/pharmacies/pharmacies_list_screen.dart b/lib/pages/pharmacies/pharmacies_list_screen.dart index 8a43af56..040e5bee 100644 --- a/lib/pages/pharmacies/pharmacies_list_screen.dart +++ b/lib/pages/pharmacies/pharmacies_list_screen.dart @@ -1,99 +1,191 @@ +import 'package:diplomaticquarterapp/core/model/pharmacies/pharmacies_model.dart'; +import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:flutter/material.dart'; import 'package:diplomaticquarterapp/config/size_config.dart'; import 'package:flutter/cupertino.dart'; +import 'package:maps_launcher/maps_launcher.dart'; import '../base/base_view.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/progress_indicator/app_circular_progress_Indeicator.dart'; import 'package:diplomaticquarterapp/widgets/others/rounded_container.dart'; import 'dart:typed_data'; import 'dart:convert'; - +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/core/viewModels/pharmacies_view_model.dart'; import 'package:map_launcher/map_launcher.dart'; +import 'package:url_launcher/url_launcher.dart'; -class PharmaciesList extends StatefulWidget { - String medicineID; - int url; - - PharmaciesList({this.url, this.medicineID}); - - @override - _PharmaciesListState createState() => _PharmaciesListState(); +class PharmaciesList extends StatelessWidget { + final int medicineID; + final String imageURL; + final String medicineDescription; -// -} + PharmaciesList({this.medicineID, this.imageURL, this.medicineDescription}); -class _PharmaciesListState extends State { @override Widget build(BuildContext context) { return BaseView( - //onModelReady: (model) => model.getMedicine(), + onModelReady: (model) => model.getPharmacies(id: medicineID), builder: (BuildContext context, PharmacyViewModel model, Widget child) => AppScaffold( - appBarTitle: 'Pharmacies List', - body: !model.isFinished - ? AppCircularProgressIndicator() - : model.hasError - ? Center( - child: Text( - model.errorMsg, - style: TextStyle(color: Colors.red), + appBarTitle: TranslationBase.of(context).pharmaciesList, + baseViewModel: model, + body: Container( + height: SizeConfig.screenHeight, + child: ListView( + shrinkWrap: true, + scrollDirection: Axis.vertical, + physics: AlwaysScrollableScrollPhysics(), + children: [ + RoundedContainer( + child: Row( + children: [ + Expanded( + flex: 1, + child: ClipRRect( + borderRadius: BorderRadius.all( + Radius.circular(7), + ), + child: Image.memory( + dataFromBase64String(imageURL), + height: SizeConfig.imageSizeMultiplier * 19, + width: SizeConfig.imageSizeMultiplier * 18, + fit: BoxFit.cover, + ), + ), + ), + Expanded( + flex: 3, + child: Padding( + padding: EdgeInsets.symmetric( + horizontal: 6.8, vertical: 3.5), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Texts( + TranslationBase.of(context).description, + ), + Texts( + medicineDescription, + ), + Texts( + TranslationBase.of(context).price, + marginRight: 10, + marginLeft: 10, + marginBottom: 2.0, + ), + if (model.pharmacyList.length > 0) + Texts( + model.pharmacyList[0].price.toString(), + ), + ], + ), + ), + ), + ], + ), + ), + Container( + margin: EdgeInsets.only( + top: SizeConfig.widthMultiplier * 2.0, + bottom: SizeConfig.widthMultiplier * 3.0, + right: SizeConfig.widthMultiplier * 4.0, + left: SizeConfig.widthMultiplier * 2.5, + ), + child: Align( + alignment: Alignment.center, + child: Texts( + TranslationBase.of(context).youCanFindItIn, + ), + ), + alignment: Alignment.topRight, + ), + Container( + width: SizeConfig.screenWidth * 1.0, + child: ListView.builder( + shrinkWrap: true, + physics: NeverScrollableScrollPhysics(), + itemCount: model.pharmacyList == null + ? 0 + : model.pharmacyList.length, + itemBuilder: (BuildContext context, int index) { + return RoundedContainer( + child: Row( + children: [ + Expanded( + child: ClipRRect( + borderRadius: + BorderRadius.all(Radius.circular(7)), + child: Image.network( + model.pharmacyList[index].imageLocation, + height: SizeConfig.imageSizeMultiplier * 13.0, + width: SizeConfig.imageSizeMultiplier * 11.0, + fit: BoxFit.cover, + ), + ), + ), + Expanded( + flex: 4, + child: Padding( + padding: EdgeInsets.all(9.0), + child: Texts( + model.pharmacyList[index].desLocation, + ), + ), ), - ) - : Container( - height: SizeConfig.screenHeight, - child: ListView( - shrinkWrap: true, - scrollDirection: Axis.vertical, - physics: AlwaysScrollableScrollPhysics(), - children: [ - RoundedContainer( - child: Row( - children: [ - Expanded( - flex: 1, - child: ClipRRect( - borderRadius: BorderRadius.all( - Radius.circular(7), - ), - child: Image.memory( - dataFromBase64String( - widget.url.toString()), - height: - SizeConfig.imageSizeMultiplier * 19, - width: - SizeConfig.imageSizeMultiplier * 18, - fit: BoxFit.cover, - ), + Expanded( + flex: 2, + child: Wrap( + direction: Axis.horizontal, + alignment: WrapAlignment.end, + crossAxisAlignment: WrapCrossAlignment.end, + children: [ + Padding( + padding: EdgeInsets.all(6.0), + child: InkWell( + child: Icon( + Icons.phone, + color: Colors.red, ), + onTap: () => launch("tel://" + + model.pharmacyList[index].phoneNumber), ), - Expanded( - flex: 3, - child: Column( - mainAxisAlignment: - MainAxisAlignment.start, - crossAxisAlignment: - CrossAxisAlignment.stretch, - children: [], + ), + Padding( + padding: EdgeInsets.all(6.0), + child: InkWell( + child: Icon( + Icons.local_pharmacy, + color: Colors.red, ), - ) - ], - )) - ], - ), - )), + onTap: () { + MapsLauncher.launchCoordinates( + double.parse( + model.pharmacyList[index].latitude), + double.parse(model + .pharmacyList[index].longitude), + ); + }, + ), + ), + ], + ), + ) + ], + ), + ); + }, + ), + ), + ], + ), + ), + ), ); } - Image imageFromBase64String(String base64String) { - return Image.memory(base64Decode(base64String)); - } - Uint8List dataFromBase64String(String base64String) { return base64Decode(base64String); } - - String base64String(Uint8List data) { - return base64Encode(data); - } } diff --git a/lib/uitl/translations_delegate_base.dart b/lib/uitl/translations_delegate_base.dart index 26d30363..f9118197 100644 --- a/lib/uitl/translations_delegate_base.dart +++ b/lib/uitl/translations_delegate_base.dart @@ -54,9 +54,11 @@ class TranslationBase { String get nearestAppo => localizedValues['nearestAppo'][locale.languageCode]; - String get searchByDocText => localizedValues['searchByDocText'][locale.languageCode]; + String get searchByDocText => + localizedValues['searchByDocText'][locale.languageCode]; - String get enterDocName => localizedValues['enterDocName'][locale.languageCode]; + String get enterDocName => + localizedValues['enterDocName'][locale.languageCode]; String get search => localizedValues['search'][locale.languageCode]; @@ -66,29 +68,35 @@ class TranslationBase { String get appoInfo => localizedValues['appoInfo'][locale.languageCode]; - String get availableAppo => localizedValues['availableAppo'][locale.languageCode]; + String get availableAppo => + localizedValues['availableAppo'][locale.languageCode]; String get gender => localizedValues['gender'][locale.languageCode]; String get nationality => localizedValues['nationality'][locale.languageCode]; - String get docQualifications => localizedValues['docQualifications'][locale.languageCode]; + String get docQualifications => + localizedValues['docQualifications'][locale.languageCode]; - String get confirmAppoHeading => localizedValues['confirmAppoHeading'][locale.languageCode]; + String get confirmAppoHeading => + localizedValues['confirmAppoHeading'][locale.languageCode]; String get patientInfo => localizedValues['patientInfo'][locale.languageCode]; String get bookSuccess => localizedValues['bookSuccess'][locale.languageCode]; - String get patientShare => localizedValues['patientShare'][locale.languageCode]; + String get patientShare => + localizedValues['patientShare'][locale.languageCode]; - String get patientShareWithTax => localizedValues['patientShareWithTax'][locale.languageCode]; + String get patientShareWithTax => + localizedValues['patientShareWithTax'][locale.languageCode]; String get confirmAppo => localizedValues['confirmAppo'][locale.languageCode]; String get confirm => localizedValues['confirm'][locale.languageCode]; - String get confirmLater => localizedValues['confirmLater'][locale.languageCode]; + String get confirmLater => + localizedValues['confirmLater'][locale.languageCode]; String get todoList => localizedValues['todoList'][locale.languageCode]; @@ -126,6 +134,14 @@ class TranslationBase { localizedValues['searchMedicine'][locale.languageCode]; String get searchMedicineHere => localizedValues['searchMedicineHere'][locale.languageCode]; + String get pharmaciesList => + localizedValues['pharmaciesList'][locale.languageCode]; + String get description => localizedValues['description'][locale.languageCode]; + String get price => localizedValues['price'][locale.languageCode]; + String get youCanFindItIn => + localizedValues['youCanFindItIn'][locale.languageCode]; + String get pleaseEnterMedicineName => + localizedValues['pleaseEnterMedicineName'][locale.languageCode]; } class TranslationBaseDelegate extends LocalizationsDelegate { diff --git a/lib/widgets/data_display/text.dart b/lib/widgets/data_display/text.dart index 851c678d..c357b777 100644 --- a/lib/widgets/data_display/text.dart +++ b/lib/widgets/data_display/text.dart @@ -16,6 +16,11 @@ class Texts extends StatefulWidget { final bool allowExpand; final double fontSize; final String fontWeight; + final double margin; + final double marginTop; + final double marginRight; + final double marginBottom; + final double marginLeft; Texts(this.text, {Key key, @@ -32,7 +37,12 @@ class Texts extends StatefulWidget { this.readMore = false, this.style, this.fontSize, - this.fontWeight}) + this.fontWeight, + this.margin, + this.marginBottom, + this.marginLeft, + this.marginRight, + this.marginTop}) : super(key: key); @override @@ -228,7 +238,7 @@ class _TextsState extends State { Theme.of(context).backgroundColor.withOpacity(0), ], begin: Alignment.bottomCenter, end: Alignment.topCenter), ), - height: 30, + height: 30.0, ), ) ], diff --git a/lib/widgets/pharmacy/drug_item.dart b/lib/widgets/pharmacy/drug_item.dart index 608b1b98..b50f825a 100644 --- a/lib/widgets/pharmacy/drug_item.dart +++ b/lib/widgets/pharmacy/drug_item.dart @@ -29,7 +29,7 @@ class _MedicineItemWidgetState extends State { @override Widget build(BuildContext context) { return new RoundedContainer( - height: SizeConfig.heightMultiplier * 10.5, + height: SizeConfig.heightMultiplier * 12.9, child: Padding( padding: const EdgeInsets.all(2.0), child: Row( @@ -38,8 +38,8 @@ class _MedicineItemWidgetState extends State { children: [ if (widget.url != null) Container( - height: 39, - width: 39, + height: 39.0, + width: 39.0, child: ClipRRect( borderRadius: BorderRadius.all(Radius.circular(7)), child: Image.memory( @@ -51,11 +51,15 @@ class _MedicineItemWidgetState extends State { ), ), Expanded( - child: Padding( - padding: EdgeInsets.all(3), - child: Align( - alignment: Alignment.centerLeft, - child: Texts(widget.label), + child: Center( + child: Padding( + padding: EdgeInsets.all(2.5), + child: Align( + alignment: Alignment.centerLeft, + child: Texts( + widget.label, + ), + ), ), ), ) @@ -70,15 +74,7 @@ class _MedicineItemWidgetState extends State { ); } - Image imageFromBase64String(String base64String) { - return Image.memory(base64Decode(base64String)); - } - Uint8List dataFromBase64String(String base64String) { return base64Decode(base64String); } - - String base64String(Uint8List data) { - return base64Encode(data); - } } diff --git a/pubspec.yaml b/pubspec.yaml index 77e6d45b..10a7ecc6 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -86,6 +86,7 @@ dependencies: + dev_dependencies: flutter_test: sdk: flutter From 8de50bfe74d52bce001334df8d26b904b6c7cd72 Mon Sep 17 00:00:00 2001 From: Mohammad Aljammal Date: Tue, 4 Aug 2020 14:22:22 +0300 Subject: [PATCH 6/9] medical - my doctor and prescription services and pages --- lib/config/config.dart | 15 +- lib/core/enum/filter_type.dart | 1 + lib/core/model/doctor/doctor_profile.dart | 176 ++++++++++ lib/core/model/doctor/doctor_rating.dart | 32 ++ .../doctor/patient_doctor_appointment.dart | 325 ++++++++++++++++++ .../reques_patient_doctor_appointmentt.dart | 76 ++++ .../model/doctor/request_doctor_profile.dart | 72 ++++ .../model/doctor/request_doctor_rating.dart | 52 +++ .../model/prescriptions/Prescriptions.dart | 155 +++++++++ .../prescriptions/prescription_report.dart | 127 +++++++ .../prescriptions/prescriptions_order.dart | 134 ++++++++ .../request_prescription_report.dart | 88 +++++ .../prescriptions/request_prescriptions.dart | 64 ++++ .../request_prescriptions_orders.dart | 52 +++ .../request_send_prescription_email.dart | 112 ++++++ lib/core/service/client/base_app_client.dart | 1 + .../service/medical/my_doctor_service.dart | 102 ++++++ .../medical/prescriptions_service.dart | 149 ++++++++ .../medical/my_doctor_view_model.dart | 97 ++++++ .../medical/prescriptions_view_model.dart | 126 +++++++ lib/locator.dart | 8 + .../MyAppointments/AppointmentDetails.dart | 2 +- lib/pages/landing/landing_page.dart | 5 +- .../medical/doctor/doctor_home_page.dart | 110 ++++++ .../doctor/doctor_information_page.dart | 199 +++++++++++ .../medical/doctor/doctor_profile_page.dart | 181 ++++++++++ ...al_page.dart => medical_profile_page.dart} | 56 +-- .../prescription_details_page.dart | 175 ++++++++++ .../prescription_items_page.dart | 112 ++++++ .../prescriptions/prescriptions_history.dart | 13 + .../prescriptions_home_page.dart | 122 +++++++ .../prescriptions/prescriptions_page.dart | 102 ++++++ lib/widgets/buttons/button.dart | 4 +- .../data_display/medical/doctor_card.dart | 168 +++++---- lib/widgets/others/app_scaffold_widget.dart | 4 +- lib/widgets/others/card_with_bg_widget.dart | 6 +- 36 files changed, 3134 insertions(+), 89 deletions(-) create mode 100644 lib/core/enum/filter_type.dart create mode 100644 lib/core/model/doctor/doctor_profile.dart create mode 100644 lib/core/model/doctor/doctor_rating.dart create mode 100644 lib/core/model/doctor/patient_doctor_appointment.dart create mode 100644 lib/core/model/doctor/reques_patient_doctor_appointmentt.dart create mode 100644 lib/core/model/doctor/request_doctor_profile.dart create mode 100644 lib/core/model/doctor/request_doctor_rating.dart create mode 100644 lib/core/model/prescriptions/Prescriptions.dart create mode 100644 lib/core/model/prescriptions/prescription_report.dart create mode 100644 lib/core/model/prescriptions/prescriptions_order.dart create mode 100644 lib/core/model/prescriptions/request_prescription_report.dart create mode 100644 lib/core/model/prescriptions/request_prescriptions.dart create mode 100644 lib/core/model/prescriptions/request_prescriptions_orders.dart create mode 100644 lib/core/model/prescriptions/request_send_prescription_email.dart create mode 100644 lib/core/service/medical/my_doctor_service.dart create mode 100644 lib/core/service/medical/prescriptions_service.dart create mode 100644 lib/core/viewModels/medical/my_doctor_view_model.dart create mode 100644 lib/core/viewModels/medical/prescriptions_view_model.dart create mode 100644 lib/pages/medical/doctor/doctor_home_page.dart create mode 100644 lib/pages/medical/doctor/doctor_information_page.dart create mode 100644 lib/pages/medical/doctor/doctor_profile_page.dart rename lib/pages/medical/{medical_page.dart => medical_profile_page.dart} (68%) create mode 100644 lib/pages/medical/prescriptions/prescription_details_page.dart create mode 100644 lib/pages/medical/prescriptions/prescription_items_page.dart create mode 100644 lib/pages/medical/prescriptions/prescriptions_history.dart create mode 100644 lib/pages/medical/prescriptions/prescriptions_home_page.dart create mode 100644 lib/pages/medical/prescriptions/prescriptions_page.dart diff --git a/lib/config/config.dart b/lib/config/config.dart index 60e9bbd3..a4e7a415 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -9,8 +9,21 @@ const MAX_SMALL_SCREEN = 660; const BASE_URL = 'https://hmgwebservices.com/Services'; const GET_PROJECT = '/Lists.svc/REST/GetProject'; + +///Doctor +const GET_MY_DOCTOR = '/Doctors.svc/REST/GetPatientDoctorAppointmentResult'; +const GET_DOCTOR_PROFILE = '/Doctors.svc/REST/GetDocProfiles'; +const GET_DOCTOR_RATING = '/Doctors.svc/REST/dr_GetAvgDoctorRating'; + + +///Prescriptions +const PRESCRIPTIONS = '/Patients.svc/REST/GetPrescriptionApptList'; +const GET_PRESCRIPTIONS_ALL_ORDERS = '/Patients.svc/REST/PatientER_GetPatientAllPresOrders'; +const GET_PRESCRIPTION_REPORT = '/Patients.svc/REST/INP_GetPrescriptionReport'; +const SEND_PRESCRIPTION_EMAIL = '/Notifications.svc/REST/SendPrescriptionEmail'; + //const BASE_URL = 'https://hmgwebservices.com/'; // Production Environment -//const BASE_URL = 'https://uat.hmgwebservices.com/'; // UAT Environment +//const BASE_URL = 'https://uat.hmgwebservices.com/Services'; // UAT Environment //URL to get clinic list diff --git a/lib/core/enum/filter_type.dart b/lib/core/enum/filter_type.dart new file mode 100644 index 00000000..9da35c43 --- /dev/null +++ b/lib/core/enum/filter_type.dart @@ -0,0 +1 @@ +enum FilterType { Clinic, Hospital } diff --git a/lib/core/model/doctor/doctor_profile.dart b/lib/core/model/doctor/doctor_profile.dart new file mode 100644 index 00000000..9e222e5a --- /dev/null +++ b/lib/core/model/doctor/doctor_profile.dart @@ -0,0 +1,176 @@ +class DoctorProfile { + int doctorID; + String doctorName; + Null doctorNameN; + int clinicID; + String clinicDescription; + Null clinicDescriptionN; + Null licenseExpiry; + int employmentType; + Null setupID; + int projectID; + String projectName; + String nationalityID; + String nationalityName; + Null nationalityNameN; + int gender; + String genderDescription; + Null genderDescriptionN; + Null doctorTitle; + Null projectNameN; + bool isAllowWaitList; + String titleDescription; + Null titleDescriptionN; + Null isRegistered; + Null isDoctorDummy; + bool isActive; + Null isDoctorAppointmentDisplayed; + bool doctorClinicActive; + Null isbookingAllowed; + String doctorCases; + Null doctorPicture; + String doctorProfileInfo; + List specialty; + int actualDoctorRate; + String doctorImageURL; + int doctorRate; + String doctorTitleForProfile; + bool isAppointmentAllowed; + String nationalityFlagURL; + int noOfPatientsRate; + String qR; + int serviceID; + + DoctorProfile( + {this.doctorID, + this.doctorName, + this.doctorNameN, + this.clinicID, + this.clinicDescription, + this.clinicDescriptionN, + this.licenseExpiry, + this.employmentType, + this.setupID, + this.projectID, + this.projectName, + this.nationalityID, + this.nationalityName, + this.nationalityNameN, + this.gender, + this.genderDescription, + this.genderDescriptionN, + this.doctorTitle, + this.projectNameN, + this.isAllowWaitList, + this.titleDescription, + this.titleDescriptionN, + this.isRegistered, + this.isDoctorDummy, + this.isActive, + this.isDoctorAppointmentDisplayed, + this.doctorClinicActive, + this.isbookingAllowed, + this.doctorCases, + this.doctorPicture, + this.doctorProfileInfo, + this.specialty, + this.actualDoctorRate, + this.doctorImageURL, + this.doctorRate, + this.doctorTitleForProfile, + this.isAppointmentAllowed, + this.nationalityFlagURL, + this.noOfPatientsRate, + this.qR, + this.serviceID}); + + DoctorProfile.fromJson(Map json) { + doctorID = json['DoctorID']; + doctorName = json['DoctorName']; + doctorNameN = json['DoctorNameN']; + clinicID = json['ClinicID']; + clinicDescription = json['ClinicDescription']; + clinicDescriptionN = json['ClinicDescriptionN']; + licenseExpiry = json['LicenseExpiry']; + employmentType = json['EmploymentType']; + setupID = json['SetupID']; + projectID = json['ProjectID']; + projectName = json['ProjectName']; + nationalityID = json['NationalityID']; + nationalityName = json['NationalityName']; + nationalityNameN = json['NationalityNameN']; + gender = json['Gender']; + genderDescription = json['Gender_Description']; + genderDescriptionN = json['Gender_DescriptionN']; + doctorTitle = json['DoctorTitle']; + projectNameN = json['ProjectNameN']; + isAllowWaitList = json['IsAllowWaitList']; + titleDescription = json['Title_Description']; + titleDescriptionN = json['Title_DescriptionN']; + isRegistered = json['IsRegistered']; + isDoctorDummy = json['IsDoctorDummy']; + isActive = json['IsActive']; + isDoctorAppointmentDisplayed = json['IsDoctorAppointmentDisplayed']; + doctorClinicActive = json['DoctorClinicActive']; + isbookingAllowed = json['IsbookingAllowed']; + doctorCases = json['DoctorCases']; + doctorPicture = json['DoctorPicture']; + doctorProfileInfo = json['DoctorProfileInfo']; + specialty = json['Specialty'].cast(); + actualDoctorRate = json['ActualDoctorRate']; + doctorImageURL = json['DoctorImageURL']; + doctorRate = json['DoctorRate']; + doctorTitleForProfile = json['DoctorTitleForProfile']; + isAppointmentAllowed = json['IsAppointmentAllowed']; + nationalityFlagURL = json['NationalityFlagURL']; + noOfPatientsRate = json['NoOfPatientsRate']; + qR = json['QR']; + serviceID = json['ServiceID']; + } + + Map toJson() { + final Map data = new Map(); + data['DoctorID'] = this.doctorID; + data['DoctorName'] = this.doctorName; + data['DoctorNameN'] = this.doctorNameN; + data['ClinicID'] = this.clinicID; + data['ClinicDescription'] = this.clinicDescription; + data['ClinicDescriptionN'] = this.clinicDescriptionN; + data['LicenseExpiry'] = this.licenseExpiry; + data['EmploymentType'] = this.employmentType; + data['SetupID'] = this.setupID; + data['ProjectID'] = this.projectID; + data['ProjectName'] = this.projectName; + data['NationalityID'] = this.nationalityID; + data['NationalityName'] = this.nationalityName; + data['NationalityNameN'] = this.nationalityNameN; + data['Gender'] = this.gender; + data['Gender_Description'] = this.genderDescription; + data['Gender_DescriptionN'] = this.genderDescriptionN; + data['DoctorTitle'] = this.doctorTitle; + data['ProjectNameN'] = this.projectNameN; + data['IsAllowWaitList'] = this.isAllowWaitList; + data['Title_Description'] = this.titleDescription; + data['Title_DescriptionN'] = this.titleDescriptionN; + data['IsRegistered'] = this.isRegistered; + data['IsDoctorDummy'] = this.isDoctorDummy; + data['IsActive'] = this.isActive; + data['IsDoctorAppointmentDisplayed'] = this.isDoctorAppointmentDisplayed; + data['DoctorClinicActive'] = this.doctorClinicActive; + data['IsbookingAllowed'] = this.isbookingAllowed; + data['DoctorCases'] = this.doctorCases; + data['DoctorPicture'] = this.doctorPicture; + data['DoctorProfileInfo'] = this.doctorProfileInfo; + data['Specialty'] = this.specialty; + data['ActualDoctorRate'] = this.actualDoctorRate; + data['DoctorImageURL'] = this.doctorImageURL; + data['DoctorRate'] = this.doctorRate; + data['DoctorTitleForProfile'] = this.doctorTitleForProfile; + data['IsAppointmentAllowed'] = this.isAppointmentAllowed; + data['NationalityFlagURL'] = this.nationalityFlagURL; + data['NoOfPatientsRate'] = this.noOfPatientsRate; + data['QR'] = this.qR; + data['ServiceID'] = this.serviceID; + return data; + } +} diff --git a/lib/core/model/doctor/doctor_rating.dart b/lib/core/model/doctor/doctor_rating.dart new file mode 100644 index 00000000..f02e052b --- /dev/null +++ b/lib/core/model/doctor/doctor_rating.dart @@ -0,0 +1,32 @@ +class DoctorRating { + Null projectID; + Null clinicID; + int doctorID; + int patientNumber; + int doctorRate; + + DoctorRating( + {this.projectID, + this.clinicID, + this.doctorID, + this.patientNumber, + this.doctorRate}); + + DoctorRating.fromJson(Map json) { + projectID = json['ProjectID']; + clinicID = json['ClinicID']; + doctorID = json['DoctorID']; + patientNumber = json['PatientNumber']; + doctorRate = json['DoctorRate']; + } + + Map toJson() { + final Map data = new Map(); + data['ProjectID'] = this.projectID; + data['ClinicID'] = this.clinicID; + data['DoctorID'] = this.doctorID; + data['PatientNumber'] = this.patientNumber; + data['DoctorRate'] = this.doctorRate; + return data; + } +} diff --git a/lib/core/model/doctor/patient_doctor_appointment.dart b/lib/core/model/doctor/patient_doctor_appointment.dart new file mode 100644 index 00000000..265561cd --- /dev/null +++ b/lib/core/model/doctor/patient_doctor_appointment.dart @@ -0,0 +1,325 @@ +import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; + +class PatientDoctorAppointment { + String setupID; + int projectID; + int appointmentNo; + DateTime appointmentDate; + String appointmentDateN; + bool appointmentType; + DateTime bookDate; + bool patientType; + int patientID; + int clinicID; + int doctorID; + DateTime endDate; + String startTime; + String endTime; + bool status; + bool visitType; + String visitFor; + String patientStatusType; + String actualVisitStartTime; + String actualVisitEndTime; + bool isReminderActivated; + String reminderDisplayInterval; + String reminderDisplayIntervalUnit; + String mainAppointmentNo; + String notes; + int companyID; + String dHCCPatApptRef; + String bookedBy; + DateTime bookedOn; + String confirmedBy; + DateTime confirmedOn; + String arrivalChangedBy; + DateTime arrivedOn; + String rescheduledBy; + String rescheduledOn; + String mRStatus; + String mRSentBy; + String mRSentOn; + String mRReceiptBy; + String mRReceiptOn; + String isDocumentScanned; + String documentScanDateTime; + String documentScannedUser; + String editedBy; + String editedOn; + String isRecordedByNurse; + String isCheckedByDoctor; + String isVisitClosed; + String isRecurring; + String isPersonallyConfirmed; + String confirmationBy; + String relationId; + int appointmentDays; + int isActive; + int actualDoctorRate; + String clinicName; + String doctorCases; + String doctorImageURL; + String doctorInfo; + String doctorName; + int doctorRate; + String doctorTitle; + int gender; + String genderDescription; + bool isActiveDoctorProfile; + bool isAppointmentAllowed; + bool isDoctorAllowVedioCall; + String nationalityFlagURL; + String nationalityID; + String nationalityName; + int noOfPatientsRate; + String projectName; + String qR; + List speciality; + + PatientDoctorAppointment( + {this.setupID, + this.projectID, + this.appointmentNo, + this.appointmentDate, + this.appointmentDateN, + this.appointmentType, + this.bookDate, + this.patientType, + this.patientID, + this.clinicID, + this.doctorID, + this.endDate, + this.startTime, + this.endTime, + this.status, + this.visitType, + this.visitFor, + this.patientStatusType, + this.actualVisitStartTime, + this.actualVisitEndTime, + this.isReminderActivated, + this.reminderDisplayInterval, + this.reminderDisplayIntervalUnit, + this.mainAppointmentNo, + this.notes, + this.companyID, + this.dHCCPatApptRef, + this.bookedBy, + this.bookedOn, + this.confirmedBy, + this.confirmedOn, + this.arrivalChangedBy, + this.arrivedOn, + this.rescheduledBy, + this.rescheduledOn, + this.mRStatus, + this.mRSentBy, + this.mRSentOn, + this.mRReceiptBy, + this.mRReceiptOn, + this.isDocumentScanned, + this.documentScanDateTime, + this.documentScannedUser, + this.editedBy, + this.editedOn, + this.isRecordedByNurse, + this.isCheckedByDoctor, + this.isVisitClosed, + this.isRecurring, + this.isPersonallyConfirmed, + this.confirmationBy, + this.relationId, + this.appointmentDays, + this.isActive, + this.actualDoctorRate, + this.clinicName, + this.doctorCases, + this.doctorImageURL, + this.doctorInfo, + this.doctorName, + this.doctorRate, + this.doctorTitle, + this.gender, + this.genderDescription, + this.isActiveDoctorProfile, + this.isAppointmentAllowed, + this.isDoctorAllowVedioCall, + this.nationalityFlagURL, + this.nationalityID, + this.nationalityName, + this.noOfPatientsRate, + this.projectName, + this.qR, + this.speciality}); + + PatientDoctorAppointment.fromJson(Map json) { + try { + setupID = json['SetupID']; + projectID = json['ProjectID']; + appointmentNo = json['AppointmentNo']; + appointmentDate = DateUtil.convertStringToDate(json['AppointmentDate']); + appointmentDateN = json['AppointmentDateN']; + appointmentType = json['AppointmentType']; + bookDate = DateUtil.convertStringToDate(json['BookDate']); + patientType = json['PatientType']; + patientID = json['PatientID']; + clinicID = json['ClinicID']; + doctorID = json['DoctorID']; + endDate = DateUtil.convertStringToDate(json['EndDate']); + startTime = json['StartTime']; + endTime = json['EndTime']; + status = json['Status']; + visitType = json['VisitType']; + visitFor = json['VisitFor']; + patientStatusType = json['PatientStatusType']; + actualVisitStartTime = json['ActualVisitStartTime']; + actualVisitEndTime = json['ActualVisitEndTime']; + isReminderActivated = json['IsReminderActivated']; + reminderDisplayInterval = json['ReminderDisplayInterval']; + reminderDisplayIntervalUnit = json['ReminderDisplayIntervalUnit']; + mainAppointmentNo = json['MainAppointmentNo']; + notes = json['Notes']; + companyID = json['CompanyID']; + dHCCPatApptRef = json['DHCCPatApptRef']; + bookedBy = json['BookedBy']; + // bookedOn = DateUtil.convertStringToDate(json['BookedOn']); + confirmedBy = json['ConfirmedBy']; + // confirmedOn = DateUtil.convertStringToDate(json['ConfirmedOn']); + arrivalChangedBy = json['ArrivalChangedBy']; + // arrivedOn = DateUtil.convertStringToDate(json['ArrivedOn']); + rescheduledBy = json['RescheduledBy']; + rescheduledOn = json['RescheduledOn']; + mRStatus = json['MRStatus']; + mRSentBy = json['MRSentBy']; + mRSentOn = json['MRSentOn']; + mRReceiptBy = json['MRReceiptBy']; + mRReceiptOn = json['MRReceiptOn']; + isDocumentScanned = json['IsDocumentScanned']; + documentScanDateTime = json['DocumentScanDateTime']; + documentScannedUser = json['DocumentScannedUser']; + editedBy = json['EditedBy']; + editedOn = json['EditedOn']; + isRecordedByNurse = json['IsRecordedByNurse']; + isCheckedByDoctor = json['IsCheckedByDoctor']; + isVisitClosed = json['IsVisitClosed']; + isRecurring = json['IsRecurring']; + isPersonallyConfirmed = json['IsPersonallyConfirmed']; + confirmationBy = json['ConfirmationBy']; + relationId = json['RelationId']; + appointmentDays = json['AppointmentDays']; + isActive = json['IsActive']; + actualDoctorRate = json['ActualDoctorRate']; + clinicName = json['ClinicName']; + doctorCases = json['DoctorCases']; + doctorImageURL = json['DoctorImageURL']; + doctorInfo = json['DoctorInfo']; + doctorName = json['DoctorName']; + doctorRate = json['DoctorRate']; + doctorTitle = json['DoctorTitle']; + gender = json['Gender']; + genderDescription = json['GenderDescription']; + isActiveDoctorProfile = json['IsActiveDoctorProfile']; + isAppointmentAllowed = json['IsAppointmentAllowed']; + isDoctorAllowVedioCall = json['IsDoctorAllowVedioCall']; + nationalityFlagURL = json['NationalityFlagURL']; + nationalityID = json['NationalityID']; + nationalityName = json['NationalityName']; + noOfPatientsRate = json['NoOfPatientsRate']; + projectName = json['ProjectName']; + qR = json['QR']; + // speciality = json['Speciality'].cast(); + } catch (e) { + print(e); + } + } + + Map toJson() { + final Map data = new Map(); + data['SetupID'] = this.setupID; + data['ProjectID'] = this.projectID; + data['AppointmentNo'] = this.appointmentNo; + data['AppointmentDate'] = this.appointmentDate; + data['AppointmentDateN'] = this.appointmentDateN; + 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['VisitFor'] = this.visitFor; + data['PatientStatusType'] = this.patientStatusType; + data['ActualVisitStartTime'] = this.actualVisitStartTime; + data['ActualVisitEndTime'] = this.actualVisitEndTime; + data['IsReminderActivated'] = this.isReminderActivated; + data['ReminderDisplayInterval'] = this.reminderDisplayInterval; + data['ReminderDisplayIntervalUnit'] = this.reminderDisplayIntervalUnit; + data['MainAppointmentNo'] = this.mainAppointmentNo; + data['Notes'] = this.notes; + data['CompanyID'] = this.companyID; + data['DHCCPatApptRef'] = this.dHCCPatApptRef; + data['BookedBy'] = this.bookedBy; + data['BookedOn'] = this.bookedOn; + data['ConfirmedBy'] = this.confirmedBy; + data['ConfirmedOn'] = this.confirmedOn; + data['ArrivalChangedBy'] = this.arrivalChangedBy; + data['ArrivedOn'] = this.arrivedOn; + data['RescheduledBy'] = this.rescheduledBy; + data['RescheduledOn'] = this.rescheduledOn; + data['MRStatus'] = this.mRStatus; + data['MRSentBy'] = this.mRSentBy; + data['MRSentOn'] = this.mRSentOn; + data['MRReceiptBy'] = this.mRReceiptBy; + data['MRReceiptOn'] = this.mRReceiptOn; + data['IsDocumentScanned'] = this.isDocumentScanned; + data['DocumentScanDateTime'] = this.documentScanDateTime; + data['DocumentScannedUser'] = this.documentScannedUser; + data['EditedBy'] = this.editedBy; + data['EditedOn'] = this.editedOn; + data['IsRecordedByNurse'] = this.isRecordedByNurse; + data['IsCheckedByDoctor'] = this.isCheckedByDoctor; + data['IsVisitClosed'] = this.isVisitClosed; + data['IsRecurring'] = this.isRecurring; + data['IsPersonallyConfirmed'] = this.isPersonallyConfirmed; + data['ConfirmationBy'] = this.confirmationBy; + data['RelationId'] = this.relationId; + data['AppointmentDays'] = this.appointmentDays; + data['IsActive'] = this.isActive; + data['ActualDoctorRate'] = this.actualDoctorRate; + data['ClinicName'] = this.clinicName; + data['DoctorCases'] = this.doctorCases; + data['DoctorImageURL'] = this.doctorImageURL; + data['DoctorInfo'] = this.doctorInfo; + data['DoctorName'] = this.doctorName; + data['DoctorRate'] = this.doctorRate; + 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['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; + } +} + +class PatientDoctorAppointmentList{ + + String filterName =""; + List patientDoctorAppointmentList = List(); + + PatientDoctorAppointmentList({this.filterName,PatientDoctorAppointment patientDoctorAppointment}){ + patientDoctorAppointmentList.add(patientDoctorAppointment); + } + +} diff --git a/lib/core/model/doctor/reques_patient_doctor_appointmentt.dart b/lib/core/model/doctor/reques_patient_doctor_appointmentt.dart new file mode 100644 index 00000000..8ed90132 --- /dev/null +++ b/lib/core/model/doctor/reques_patient_doctor_appointmentt.dart @@ -0,0 +1,76 @@ +class RequestPatientDoctorAppointment { + int top; + double versionID; + int beforeDays; + int exludType; + int channel; + int languageID; + String iPAdress; + String generalid; + int patientOutSA; + String sessionID; + bool isDentalAllowedBackend; + int deviceTypeID; + int patientID; + String tokenID; + int patientTypeID; + int patientType; + + RequestPatientDoctorAppointment( + {this.top, + this.versionID, + this.beforeDays, + this.exludType, + this.channel, + this.languageID, + this.iPAdress, + this.generalid, + this.patientOutSA, + this.sessionID, + this.isDentalAllowedBackend, + this.deviceTypeID, + this.patientID, + this.tokenID, + this.patientTypeID, + this.patientType}); + + RequestPatientDoctorAppointment.fromJson(Map json) { + top = json['Top']; + versionID = json['VersionID']; + beforeDays = json['beforeDays']; + exludType = json['exludType']; + channel = json['Channel']; + languageID = json['LanguageID']; + iPAdress = json['IPAdress']; + generalid = json['generalid']; + patientOutSA = json['PatientOutSA']; + sessionID = json['SessionID']; + isDentalAllowedBackend = json['isDentalAllowedBackend']; + deviceTypeID = json['DeviceTypeID']; + patientID = json['PatientID']; + tokenID = json['TokenID']; + patientTypeID = json['PatientTypeID']; + patientType = json['PatientType']; + } + + Map toJson() { + final Map data = new Map(); + data['Top'] = this.top; + data['VersionID'] = this.versionID; + data['beforeDays'] = this.beforeDays; + data['exludType'] = this.exludType; + data['Channel'] = this.channel; + data['LanguageID'] = this.languageID; + data['IPAdress'] = this.iPAdress; + data['generalid'] = this.generalid; + data['PatientOutSA'] = this.patientOutSA; + data['SessionID'] = this.sessionID; + data['isDentalAllowedBackend'] = this.isDentalAllowedBackend; + data['DeviceTypeID'] = this.deviceTypeID; + data['PatientID'] = this.patientID; + data['TokenID'] = this.tokenID; + data['PatientTypeID'] = this.patientTypeID; + data['PatientType'] = this.patientType; + return data; + } +} diff --git a/lib/core/model/doctor/request_doctor_profile.dart b/lib/core/model/doctor/request_doctor_profile.dart new file mode 100644 index 00000000..80766b3f --- /dev/null +++ b/lib/core/model/doctor/request_doctor_profile.dart @@ -0,0 +1,72 @@ +class RequestDoctorProfile { + int doctorID; + bool license; + bool isRegistered; + int projectID; + int clinicID; + int patientID; + double versionID; + int channel; + int languageID; + String iPAdress; + String generalid; + int patientOutSA; + String sessionID; + bool isDentalAllowedBackend; + int deviceTypeID; + + RequestDoctorProfile( + {this.doctorID, + this.license, + this.isRegistered, + this.projectID, + this.clinicID, + this.patientID, + this.versionID, + this.channel, + this.languageID, + this.iPAdress, + this.generalid, + this.patientOutSA, + this.sessionID, + this.isDentalAllowedBackend, + this.deviceTypeID}); + + RequestDoctorProfile.fromJson(Map json) { + doctorID = json['doctorID']; + license = json['License']; + isRegistered = json['IsRegistered']; + projectID = json['ProjectID']; + clinicID = json['ClinicID']; + patientID = json['PatientID']; + versionID = json['VersionID']; + channel = json['Channel']; + languageID = json['LanguageID']; + iPAdress = json['IPAdress']; + generalid = json['generalid']; + patientOutSA = json['PatientOutSA']; + sessionID = json['SessionID']; + isDentalAllowedBackend = json['isDentalAllowedBackend']; + deviceTypeID = json['DeviceTypeID']; + } + + Map toJson() { + final Map data = new Map(); + data['doctorID'] = this.doctorID; + data['License'] = this.license; + data['IsRegistered'] = this.isRegistered; + data['ProjectID'] = this.projectID; + data['ClinicID'] = this.clinicID; + data['PatientID'] = this.patientID; + data['VersionID'] = this.versionID; + data['Channel'] = this.channel; + data['LanguageID'] = this.languageID; + data['IPAdress'] = this.iPAdress; + data['generalid'] = this.generalid; + data['PatientOutSA'] = this.patientOutSA; + data['SessionID'] = this.sessionID; + data['isDentalAllowedBackend'] = this.isDentalAllowedBackend; + data['DeviceTypeID'] = this.deviceTypeID; + return data; + } +} diff --git a/lib/core/model/doctor/request_doctor_rating.dart b/lib/core/model/doctor/request_doctor_rating.dart new file mode 100644 index 00000000..fcc9386b --- /dev/null +++ b/lib/core/model/doctor/request_doctor_rating.dart @@ -0,0 +1,52 @@ +class RequestDoctorRating { + double versionID; + int channel; + int languageID; + String iPAdress; + String generalid; + int patientOutSA; + String sessionID; + bool isDentalAllowedBackend; + int deviceTypeID; + int doctorID; + + RequestDoctorRating( + {this.versionID, + this.channel, + this.languageID, + this.iPAdress, + this.generalid, + this.patientOutSA, + this.sessionID, + this.isDentalAllowedBackend, + this.deviceTypeID, + this.doctorID}); + + RequestDoctorRating.fromJson(Map json) { + versionID = json['VersionID']; + channel = json['Channel']; + languageID = json['LanguageID']; + iPAdress = json['IPAdress']; + generalid = json['generalid']; + patientOutSA = json['PatientOutSA']; + sessionID = json['SessionID']; + isDentalAllowedBackend = json['isDentalAllowedBackend']; + deviceTypeID = json['DeviceTypeID']; + doctorID = json['DoctorID']; + } + + Map toJson() { + final Map data = new Map(); + data['VersionID'] = this.versionID; + data['Channel'] = this.channel; + data['LanguageID'] = this.languageID; + data['IPAdress'] = this.iPAdress; + data['generalid'] = this.generalid; + data['PatientOutSA'] = this.patientOutSA; + data['SessionID'] = this.sessionID; + data['isDentalAllowedBackend'] = this.isDentalAllowedBackend; + data['DeviceTypeID'] = this.deviceTypeID; + data['DoctorID'] = this.doctorID; + return data; + } +} diff --git a/lib/core/model/prescriptions/Prescriptions.dart b/lib/core/model/prescriptions/Prescriptions.dart new file mode 100644 index 00000000..1362f1c2 --- /dev/null +++ b/lib/core/model/prescriptions/Prescriptions.dart @@ -0,0 +1,155 @@ +import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; + +class Prescriptions { + String setupID; + int projectID; + int patientID; + int appointmentNo; + String appointmentDate; + String doctorName; + String clinicDescription; + String name; + int episodeID; + int actualDoctorRate; + int admission; + int clinicID; + String companyName; + String despensedStatus; + DateTime dischargeDate; + int dischargeNo; + int doctorID; + String doctorImageURL; + int doctorRate; + String doctorTitle; + int gender; + String genderDescription; + bool isActiveDoctorProfile; + bool isDoctorAllowVedioCall; + bool isExecludeDoctor; + bool isInOutPatient; + String isInOutPatientDescription; + String isInOutPatientDescriptionN; + bool isInsurancePatient; + String nationalityFlagURL; + int noOfPatientsRate; + String qR; + List speciality; + + Prescriptions( + {this.setupID, + this.projectID, + this.patientID, + this.appointmentNo, + this.appointmentDate, + this.doctorName, + this.clinicDescription, + this.name, + this.episodeID, + this.actualDoctorRate, + this.admission, + this.clinicID, + this.companyName, + this.despensedStatus, + this.dischargeDate, + this.dischargeNo, + this.doctorID, + this.doctorImageURL, + this.doctorRate, + this.doctorTitle, + this.gender, + this.genderDescription, + this.isActiveDoctorProfile, + this.isDoctorAllowVedioCall, + this.isExecludeDoctor, + this.isInOutPatient, + this.isInOutPatientDescription, + this.isInOutPatientDescriptionN, + this.isInsurancePatient, + this.nationalityFlagURL, + this.noOfPatientsRate, + this.qR, + this.speciality}); + + Prescriptions.fromJson(Map json) { + setupID = json['SetupID']; + projectID = json['ProjectID']; + patientID = json['PatientID']; + appointmentNo = json['AppointmentNo']; + appointmentDate = json['AppointmentDate']; + doctorName = json['DoctorName']; + clinicDescription = json['ClinicDescription']; + name = json['Name']; + episodeID = json['EpisodeID']; + actualDoctorRate = json['ActualDoctorRate']; + admission = json['Admission']; + clinicID = json['ClinicID']; + companyName = json['CompanyName']; + despensedStatus = json['Despensed_Status']; + dischargeDate = DateUtil.convertStringToDate(json['DischargeDate']); + dischargeNo = json['DischargeNo']; + doctorID = json['DoctorID']; + doctorImageURL = json['DoctorImageURL']; + doctorRate = json['DoctorRate']; + doctorTitle = json['DoctorTitle']; + gender = json['Gender']; + genderDescription = json['GenderDescription']; + isActiveDoctorProfile = json['IsActiveDoctorProfile']; + isDoctorAllowVedioCall = json['IsDoctorAllowVedioCall']; + isExecludeDoctor = json['IsExecludeDoctor']; + isInOutPatient = json['IsInOutPatient']; + isInOutPatientDescription = json['IsInOutPatientDescription']; + isInOutPatientDescriptionN = json['IsInOutPatientDescriptionN']; + isInsurancePatient = json['IsInsurancePatient']; + nationalityFlagURL = json['NationalityFlagURL']; + noOfPatientsRate = json['NoOfPatientsRate']; + qR = json['QR']; + // speciality = json['Speciality'].cast(); + } + + Map toJson() { + final Map data = new Map(); + data['SetupID'] = this.setupID; + data['ProjectID'] = this.projectID; + data['PatientID'] = this.patientID; + data['AppointmentNo'] = this.appointmentNo; + data['AppointmentDate'] = this.appointmentDate; + data['DoctorName'] = this.doctorName; + data['ClinicDescription'] = this.clinicDescription; + data['Name'] = this.name; + data['EpisodeID'] = this.episodeID; + data['ActualDoctorRate'] = this.actualDoctorRate; + data['Admission'] = this.admission; + data['ClinicID'] = this.clinicID; + data['CompanyName'] = this.companyName; + data['Despensed_Status'] = this.despensedStatus; + data['DischargeDate'] = this.dischargeDate; + data['DischargeNo'] = this.dischargeNo; + data['DoctorID'] = this.doctorID; + data['DoctorImageURL'] = this.doctorImageURL; + data['DoctorRate'] = this.doctorRate; + data['DoctorTitle'] = this.doctorTitle; + data['Gender'] = this.gender; + data['GenderDescription'] = this.genderDescription; + data['IsActiveDoctorProfile'] = this.isActiveDoctorProfile; + data['IsDoctorAllowVedioCall'] = this.isDoctorAllowVedioCall; + data['IsExecludeDoctor'] = this.isExecludeDoctor; + data['IsInOutPatient'] = this.isInOutPatient; + data['IsInOutPatientDescription'] = this.isInOutPatientDescription; + data['IsInOutPatientDescriptionN'] = this.isInOutPatientDescriptionN; + data['IsInsurancePatient'] = this.isInsurancePatient; + data['NationalityFlagURL'] = this.nationalityFlagURL; + data['NoOfPatientsRate'] = this.noOfPatientsRate; + data['QR'] = this.qR; + data['Speciality'] = this.speciality; + return data; + } +} + +class PrescriptionsList { + String filterName = ""; + List prescriptionsList = List(); + + PrescriptionsList({this.filterName, Prescriptions prescriptions}) { + prescriptionsList.add(prescriptions); + } +} diff --git a/lib/core/model/prescriptions/prescription_report.dart b/lib/core/model/prescriptions/prescription_report.dart new file mode 100644 index 00000000..51f5750f --- /dev/null +++ b/lib/core/model/prescriptions/prescription_report.dart @@ -0,0 +1,127 @@ +import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; + +class PrescriptionReport { + int patientID; + String patientName; + String patientAge; + String patientGender; + String address; + String phoneOffice; + String itemDescription; + int doseTimingID; + int frequencyID; + int routeID; + String clinic; + String doctorName; + String route; + String frequency; + String remarks; + String name; + int days; + String startDate; + String orderDate; + int doseDailyQuantity; + int itemID; + Null productImage; + String sKU; + String itemDescriptionN; + String routeN; + String frequencyN; + String imageSRCUrl; + String imageThumbUrl; + + PrescriptionReport( + {this.patientID, + this.patientName, + this.patientAge, + this.patientGender, + this.address, + this.phoneOffice, + this.itemDescription, + this.doseTimingID, + this.frequencyID, + this.routeID, + this.clinic, + this.doctorName, + this.route, + this.frequency, + this.remarks, + this.name, + this.days, + this.startDate, + this.orderDate, + this.doseDailyQuantity, + this.itemID, + this.productImage, + this.sKU, + this.itemDescriptionN, + this.routeN, + this.frequencyN, + this.imageSRCUrl, + this.imageThumbUrl}); + + PrescriptionReport.fromJson(Map json) { + patientID = json['PatientID']; + patientName = json['PatientName']; + patientAge = json['PatientAge']; + patientGender = json['PatientGender']; + address = json['Address']; + phoneOffice = json['PhoneOffice']; + itemDescription = json['ItemDescription']; + doseTimingID = json['DoseTimingID']; + frequencyID = json['FrequencyID']; + routeID = json['RouteID']; + clinic = json['Clinic']; + doctorName = json['DoctorName']; + route = json['Route']; + frequency = json['Frequency']; + remarks = json['Remarks']; + name = json['Name']; + days = json['Days']; + startDate = json['StartDate']; + orderDate = json['OrderDate']; + doseDailyQuantity = json['DoseDailyQuantity']; + itemID = json['ItemID']; + productImage = json['ProductImage']; + sKU = json['SKU']; + itemDescriptionN = json['ItemDescriptionN']; + routeN = json['RouteN']; + frequencyN = json['FrequencyN']; + imageSRCUrl = json['ImageSRCUrl']; + imageThumbUrl = json['ImageThumbUrl']; + } + + Map toJson() { + final Map data = new Map(); + data['PatientID'] = this.patientID; + data['PatientName'] = this.patientName; + data['PatientAge'] = this.patientAge; + data['PatientGender'] = this.patientGender; + data['Address'] = this.address; + data['PhoneOffice'] = this.phoneOffice; + data['ItemDescription'] = this.itemDescription; + data['DoseTimingID'] = this.doseTimingID; + data['FrequencyID'] = this.frequencyID; + data['RouteID'] = this.routeID; + data['Clinic'] = this.clinic; + data['DoctorName'] = this.doctorName; + data['Route'] = this.route; + data['Frequency'] = this.frequency; + data['Remarks'] = this.remarks; + data['Name'] = this.name; + data['Days'] = this.days; + data['StartDate'] = this.startDate; + data['OrderDate'] = this.orderDate; + data['DoseDailyQuantity'] = this.doseDailyQuantity; + data['ItemID'] = this.itemID; + data['ProductImage'] = this.productImage; + data['SKU'] = this.sKU; + data['ItemDescriptionN'] = this.itemDescriptionN; + data['RouteN'] = this.routeN; + data['FrequencyN'] = this.frequencyN; + data['ImageSRCUrl'] = this.imageSRCUrl; + data['ImageThumbUrl'] = this.imageThumbUrl; + data['hasPlan'] = false; + return data; + } +} diff --git a/lib/core/model/prescriptions/prescriptions_order.dart b/lib/core/model/prescriptions/prescriptions_order.dart new file mode 100644 index 00000000..db2b1855 --- /dev/null +++ b/lib/core/model/prescriptions/prescriptions_order.dart @@ -0,0 +1,134 @@ +import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; + +class PrescriptionsOrder { + int iD; + String patientID; + bool patientOutSA; + bool isOutPatient; + int projectID; + int nearestProjectID; + double longitude; + double latitude; + String appointmentNo; + String dischargeID; + int lineItemNo; + int status; + String description; + String descriptionN; + DateTime createdOn; + int serviceID; + int createdBy; + DateTime editedOn; + int editedBy; + int channel; + String clientRequestID; + bool returnedToQueue; + Null pickupDateTime; + Null pickupLocationName; + Null dropoffLocationName; + int realRRTHaveTransactions; + String nearestProjectDescription; + String nearestProjectDescriptionN; + String projectDescription; + String projectDescriptionN; + + PrescriptionsOrder( + {this.iD, + this.patientID, + this.patientOutSA, + this.isOutPatient, + this.projectID, + this.nearestProjectID, + this.longitude, + this.latitude, + this.appointmentNo, + this.dischargeID, + this.lineItemNo, + this.status, + this.description, + this.descriptionN, + this.createdOn, + this.serviceID, + this.createdBy, + this.editedOn, + this.editedBy, + this.channel, + this.clientRequestID, + this.returnedToQueue, + this.pickupDateTime, + this.pickupLocationName, + this.dropoffLocationName, + this.realRRTHaveTransactions, + this.nearestProjectDescription, + this.nearestProjectDescriptionN, + this.projectDescription, + this.projectDescriptionN}); + + PrescriptionsOrder.fromJson(Map json) { + iD = json['ID']; + patientID = json['PatientID']; + patientOutSA = json['PatientOutSA']; + isOutPatient = json['IsOutPatient']; + projectID = json['ProjectID']; + nearestProjectID = json['NearestProjectID']; + longitude = json['Longitude']; + latitude = json['Latitude']; + appointmentNo = json['AppointmentNo']; + dischargeID = json['DischargeID']; + lineItemNo = json['LineItemNo']; + status = json['Status']; + description = json['Description']; + descriptionN = json['DescriptionN']; + createdOn = DateUtil.convertStringToDate(json['CreatedOn']); + serviceID = json['ServiceID']; + createdBy = json['CreatedBy']; + editedOn = DateUtil.convertStringToDate(json['EditedOn']); + editedBy = json['EditedBy']; + channel = json['Channel']; + clientRequestID = json['ClientRequestID']; + returnedToQueue = json['ReturnedToQueue']; + pickupDateTime = json['PickupDateTime']; + pickupLocationName = json['PickupLocationName']; + dropoffLocationName = json['DropoffLocationName']; + realRRTHaveTransactions = json['RealRRT_HaveTransactions']; + nearestProjectDescription = json['NearestProjectDescription']; + nearestProjectDescriptionN = json['NearestProjectDescriptionN']; + projectDescription = json['ProjectDescription']; + projectDescriptionN = json['ProjectDescriptionN']; + } + + Map toJson() { + final Map data = new Map(); + data['ID'] = this.iD; + data['PatientID'] = this.patientID; + data['PatientOutSA'] = this.patientOutSA; + data['IsOutPatient'] = this.isOutPatient; + data['ProjectID'] = this.projectID; + data['NearestProjectID'] = this.nearestProjectID; + data['Longitude'] = this.longitude; + data['Latitude'] = this.latitude; + data['AppointmentNo'] = this.appointmentNo; + data['DischargeID'] = this.dischargeID; + data['LineItemNo'] = this.lineItemNo; + data['Status'] = this.status; + data['Description'] = this.description; + data['DescriptionN'] = this.descriptionN; + data['CreatedOn'] = this.createdOn; + data['ServiceID'] = this.serviceID; + data['CreatedBy'] = this.createdBy; + data['EditedOn'] = this.editedOn; + data['EditedBy'] = this.editedBy; + data['Channel'] = this.channel; + data['ClientRequestID'] = this.clientRequestID; + data['ReturnedToQueue'] = this.returnedToQueue; + data['PickupDateTime'] = this.pickupDateTime; + data['PickupLocationName'] = this.pickupLocationName; + data['DropoffLocationName'] = this.dropoffLocationName; + data['RealRRT_HaveTransactions'] = this.realRRTHaveTransactions; + data['NearestProjectDescription'] = this.nearestProjectDescription; + data['NearestProjectDescriptionN'] = this.nearestProjectDescriptionN; + data['ProjectDescription'] = this.projectDescription; + data['ProjectDescriptionN'] = this.projectDescriptionN; + return data; + } +} diff --git a/lib/core/model/prescriptions/request_prescription_report.dart b/lib/core/model/prescriptions/request_prescription_report.dart new file mode 100644 index 00000000..c8323740 --- /dev/null +++ b/lib/core/model/prescriptions/request_prescription_report.dart @@ -0,0 +1,88 @@ +class RequestPrescriptionReport { + double versionID; + int channel; + int languageID; + String iPAdress; + String generalid; + int patientOutSA; + String sessionID; + bool isDentalAllowedBackend; + int deviceTypeID; + int patientID; + String tokenID; + int patientTypeID; + int patientType; + int appointmentNo; + String setupID; + int episodeID; + int clinicID; + int projectID; + int dischargeNo; + + RequestPrescriptionReport( + {this.versionID, + this.channel, + this.languageID, + this.iPAdress, + this.generalid, + this.patientOutSA, + this.sessionID, + this.isDentalAllowedBackend, + this.deviceTypeID, + this.patientID, + this.tokenID, + this.patientTypeID, + this.patientType, + this.appointmentNo, + this.setupID, + this.episodeID, + this.clinicID, + this.projectID, + this.dischargeNo}); + + RequestPrescriptionReport.fromJson(Map json) { + versionID = json['VersionID']; + channel = json['Channel']; + languageID = json['LanguageID']; + iPAdress = json['IPAdress']; + generalid = json['generalid']; + patientOutSA = json['PatientOutSA']; + sessionID = json['SessionID']; + isDentalAllowedBackend = json['isDentalAllowedBackend']; + deviceTypeID = json['DeviceTypeID']; + patientID = json['PatientID']; + tokenID = json['TokenID']; + patientTypeID = json['PatientTypeID']; + patientType = json['PatientType']; + appointmentNo = json['AppointmentNo']; + setupID = json['SetupID']; + episodeID = json['EpisodeID']; + clinicID = json['ClinicID']; + projectID = json['ProjectID']; + dischargeNo = json['DischargeNo']; + } + + Map toJson() { + final Map data = new Map(); + data['VersionID'] = this.versionID; + data['Channel'] = this.channel; + data['LanguageID'] = this.languageID; + data['IPAdress'] = this.iPAdress; + data['generalid'] = this.generalid; + data['PatientOutSA'] = this.patientOutSA; + data['SessionID'] = this.sessionID; + data['isDentalAllowedBackend'] = this.isDentalAllowedBackend; + data['DeviceTypeID'] = this.deviceTypeID; + data['PatientID'] = this.patientID; + data['TokenID'] = this.tokenID; + data['PatientTypeID'] = this.patientTypeID; + data['PatientType'] = this.patientType; + data['AppointmentNo'] = this.appointmentNo; + data['SetupID'] = this.setupID; + data['EpisodeID'] = this.episodeID; + data['ClinicID'] = this.clinicID; + data['ProjectID'] = this.projectID; + data['DischargeNo'] = this.dischargeNo; + return data; + } +} diff --git a/lib/core/model/prescriptions/request_prescriptions.dart b/lib/core/model/prescriptions/request_prescriptions.dart new file mode 100644 index 00000000..abb39143 --- /dev/null +++ b/lib/core/model/prescriptions/request_prescriptions.dart @@ -0,0 +1,64 @@ +class RequestPrescriptions { + double versionID; + int channel; + int languageID; + String iPAdress; + String generalid; + int patientOutSA; + String sessionID; + bool isDentalAllowedBackend; + int deviceTypeID; + int patientID; + String tokenID; + int patientTypeID; + int patientType; + + RequestPrescriptions( + {this.versionID, + this.channel, + this.languageID, + this.iPAdress, + this.generalid, + this.patientOutSA, + this.sessionID, + this.isDentalAllowedBackend, + this.deviceTypeID, + this.patientID, + this.tokenID, + this.patientTypeID, + this.patientType}); + + RequestPrescriptions.fromJson(Map json) { + versionID = json['VersionID']; + channel = json['Channel']; + languageID = json['LanguageID']; + iPAdress = json['IPAdress']; + generalid = json['generalid']; + patientOutSA = json['PatientOutSA']; + sessionID = json['SessionID']; + isDentalAllowedBackend = json['isDentalAllowedBackend']; + deviceTypeID = json['DeviceTypeID']; + patientID = json['PatientID']; + tokenID = json['TokenID']; + patientTypeID = json['PatientTypeID']; + patientType = json['PatientType']; + } + + Map toJson() { + final Map data = new Map(); + data['VersionID'] = this.versionID; + data['Channel'] = this.channel; + data['LanguageID'] = this.languageID; + data['IPAdress'] = this.iPAdress; + data['generalid'] = this.generalid; + data['PatientOutSA'] = this.patientOutSA; + data['SessionID'] = this.sessionID; + data['isDentalAllowedBackend'] = this.isDentalAllowedBackend; + data['DeviceTypeID'] = this.deviceTypeID; + data['PatientID'] = this.patientID; + data['TokenID'] = this.tokenID; + data['PatientTypeID'] = this.patientTypeID; + data['PatientType'] = this.patientType; + return data; + } +} diff --git a/lib/core/model/prescriptions/request_prescriptions_orders.dart b/lib/core/model/prescriptions/request_prescriptions_orders.dart new file mode 100644 index 00000000..9aaab33d --- /dev/null +++ b/lib/core/model/prescriptions/request_prescriptions_orders.dart @@ -0,0 +1,52 @@ +class RequestPrescriptionsOrders { + int patientID; + int patientOutSA; + double versionID; + int channel; + int languageID; + String iPAdress; + String generalid; + String sessionID; + bool isDentalAllowedBackend; + int deviceTypeID; + + RequestPrescriptionsOrders( + {this.patientID, + this.patientOutSA, + this.versionID, + this.channel, + this.languageID, + this.iPAdress, + this.generalid, + this.sessionID, + this.isDentalAllowedBackend, + this.deviceTypeID}); + + RequestPrescriptionsOrders.fromJson(Map json) { + patientID = json['PatientID']; + patientOutSA = json['PatientOutSA']; + versionID = json['VersionID']; + channel = json['Channel']; + languageID = json['LanguageID']; + iPAdress = json['IPAdress']; + generalid = json['generalid']; + sessionID = json['SessionID']; + isDentalAllowedBackend = json['isDentalAllowedBackend']; + deviceTypeID = json['DeviceTypeID']; + } + + Map toJson() { + final Map data = new Map(); + data['PatientID'] = this.patientID; + data['PatientOutSA'] = this.patientOutSA; + data['VersionID'] = this.versionID; + data['Channel'] = this.channel; + data['LanguageID'] = this.languageID; + data['IPAdress'] = this.iPAdress; + data['generalid'] = this.generalid; + data['SessionID'] = this.sessionID; + data['isDentalAllowedBackend'] = this.isDentalAllowedBackend; + data['DeviceTypeID'] = this.deviceTypeID; + return data; + } +} diff --git a/lib/core/model/prescriptions/request_send_prescription_email.dart b/lib/core/model/prescriptions/request_send_prescription_email.dart new file mode 100644 index 00000000..2d1f3aa3 --- /dev/null +++ b/lib/core/model/prescriptions/request_send_prescription_email.dart @@ -0,0 +1,112 @@ +import 'package:diplomaticquarterapp/core/model/prescriptions/prescription_report.dart'; + +class RequestSendPrescriptionEmail { + String appointmentDate; + double versionID; + int channel; + int languageID; + String iPAdress; + String generalid; + int patientOutSA; + String sessionID; + bool isDentalAllowedBackend; + int deviceTypeID; + int patientID; + String tokenID; + int patientTypeID; + int patientType; + String to; + String dateofBirth; + String patientIditificationNum; + String patientMobileNumber; + String patientName; + String setupID; + String clinicName; + String doctorName; + int projectID; + List listPrescriptions; + + RequestSendPrescriptionEmail( + {this.appointmentDate, + this.versionID, + this.channel, + this.languageID, + this.iPAdress, + this.generalid, + this.patientOutSA, + this.sessionID, + this.isDentalAllowedBackend, + this.deviceTypeID, + this.patientID, + this.tokenID, + this.patientTypeID, + this.patientType, + this.to, + this.dateofBirth, + this.patientIditificationNum, + this.patientMobileNumber, + this.patientName, + this.setupID, + this.clinicName, + this.doctorName, + this.projectID}); + + RequestSendPrescriptionEmail.fromJson(Map json) { + appointmentDate = json['AppointmentDate']; + versionID = json['VersionID']; + channel = json['Channel']; + languageID = json['LanguageID']; + iPAdress = json['IPAdress']; + generalid = json['generalid']; + patientOutSA = json['PatientOutSA']; + sessionID = json['SessionID']; + isDentalAllowedBackend = json['isDentalAllowedBackend']; + deviceTypeID = json['DeviceTypeID']; + patientID = json['PatientID']; + tokenID = json['TokenID']; + patientTypeID = json['PatientTypeID']; + patientType = json['PatientType']; + to = json['To']; + dateofBirth = json['DateofBirth']; + patientIditificationNum = json['PatientIditificationNum']; + patientMobileNumber = json['PatientMobileNumber']; + patientName = json['PatientName']; + setupID = json['SetupID']; + clinicName = json['ClinicName']; + doctorName = json['DoctorName']; + projectID = json['ProjectID']; + } + + Map toJson() { + final Map data = new Map(); + data['AppointmentDate'] = this.appointmentDate; + data['VersionID'] = this.versionID; + data['Channel'] = this.channel; + data['LanguageID'] = this.languageID; + data['IPAdress'] = this.iPAdress; + data['generalid'] = this.generalid; + data['PatientOutSA'] = this.patientOutSA; + data['SessionID'] = this.sessionID; + data['isDentalAllowedBackend'] = this.isDentalAllowedBackend; + data['DeviceTypeID'] = this.deviceTypeID; + data['PatientID'] = this.patientID; + data['TokenID'] = this.tokenID; + data['PatientTypeID'] = this.patientTypeID; + data['PatientType'] = this.patientType; + data['To'] = this.to; + data['DateofBirth'] = this.dateofBirth; + data['PatientIditificationNum'] = this.patientIditificationNum; + data['PatientMobileNumber'] = this.patientMobileNumber; + data['PatientName'] = this.patientName; + data['SetupID'] = this.setupID; + if (this.listPrescriptions != null) { + data['ListPrescriptions'] = + this.listPrescriptions.map((v) => v.toJson()).toList(); + } + data['ClinicName'] = this.clinicName; + data['DoctorName'] = this.doctorName; + data['ProjectID'] = this.projectID; + + return data; + } +} diff --git a/lib/core/service/client/base_app_client.dart b/lib/core/service/client/base_app_client.dart index 57686824..57910888 100644 --- a/lib/core/service/client/base_app_client.dart +++ b/lib/core/service/client/base_app_client.dart @@ -43,6 +43,7 @@ class BaseAppClient { if (!parsed['IsAuthenticated']) { // await helpers.logout(); //helpers.showErrorToast('Your session expired Please login agian'); + var asd =""; // TODO create logout fun } else if (parsed['MessageStatus'] == 1) { onSuccess(parsed, statusCode); diff --git a/lib/core/service/medical/my_doctor_service.dart b/lib/core/service/medical/my_doctor_service.dart new file mode 100644 index 00000000..349d7ace --- /dev/null +++ b/lib/core/service/medical/my_doctor_service.dart @@ -0,0 +1,102 @@ +import 'package:diplomaticquarterapp/config/config.dart'; +import 'package:diplomaticquarterapp/core/model/doctor/doctor_profile.dart'; +import 'package:diplomaticquarterapp/core/model/doctor/doctor_rating.dart'; +import 'package:diplomaticquarterapp/core/model/doctor/patient_doctor_appointment.dart'; +import 'package:diplomaticquarterapp/core/model/doctor/reques_patient_doctor_appointmentt.dart'; +import 'package:diplomaticquarterapp/core/model/doctor/request_doctor_profile.dart'; +import 'package:diplomaticquarterapp/core/model/doctor/request_doctor_rating.dart'; +import 'package:diplomaticquarterapp/core/service/base_service.dart'; + +class MyDoctorService extends BaseService { + List patientDoctorAppointmentList = List(); + DoctorProfile doctorProfile; + DoctorRating doctorRating = DoctorRating(); + + RequestPatientDoctorAppointment patientDoctorAppointmentRequest = + RequestPatientDoctorAppointment( + top: 0, + versionID: 5.5, + beforeDays: 0, + exludType: 4, + channel: 3, + languageID: 2, + iPAdress: '10.20.10.20', + generalid: 'Cs2020@2016\$2958', + patientOutSA: 0, + sessionID: 'TMRhVmkGhOsvamErw', + isDentalAllowedBackend: false, + deviceTypeID: 1, + patientID: 1231755, + tokenID: '@dm!n', + patientType: 1, + patientTypeID: 1); + + RequestDoctorRating _requestDoctorRating = RequestDoctorRating( + channel: 3, + deviceTypeID: 2, + doctorID: 2477, + iPAdress: '10.20.10.20', + languageID: 2, + patientOutSA: 0, + sessionID: 'CvsUFeJkyLDnFQqw', + versionID: 5.5, + generalid: 'Cs2020@2016\$2958', + isDentalAllowedBackend: false); + + Future getPatientDoctorAppointmentList() async { + await baseAppClient.post(GET_MY_DOCTOR, + onSuccess: (dynamic response, int statusCode) { + patientDoctorAppointmentList.clear(); + response['PatientDoctorAppointmentResultList'].forEach((hospital) { + patientDoctorAppointmentList + .add(PatientDoctorAppointment.fromJson(hospital)); + }); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: patientDoctorAppointmentRequest.toJson()); + } + + RequestDoctorProfile _requestDoctorProfile = RequestDoctorProfile( + doctorID: 2477, + license: true, + isRegistered: true, + projectID: 12, + clinicID: 501, + patientID: 1231755, + versionID: 5.5, + channel: 3, + languageID: 2, + iPAdress: '10.20.10.20', + generalid: 'Cs2020@2016\$2958', + patientOutSA: 0, + sessionID: 'nstatCtNEmuwxeuVAOUmw', + isDentalAllowedBackend: false, + deviceTypeID: 2, + ); + + Future getDoctorProfileAndRating({int doctorId,int clinicID,int projectID }) async { + ///GET DOCTOR PROFILE + _requestDoctorProfile.doctorID = doctorId; + _requestDoctorProfile.clinicID = clinicID; + _requestDoctorProfile.patientID = projectID; + hasError = false; + await baseAppClient.post(GET_DOCTOR_PROFILE, + onSuccess: (dynamic response, int statusCode) { + doctorProfile = DoctorProfile.fromJson(response['DoctorProfileList'][0]); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: _requestDoctorProfile.toJson()); + + ///GET DOCTOR RATING + //_requestDoctorRating.doctorID = doctorId; + await baseAppClient.post(GET_DOCTOR_RATING, + onSuccess: (dynamic response, int statusCode) { + doctorRating = DoctorRating.fromJson(response['AvgDoctorRatingList'][0]); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: _requestDoctorRating.toJson()); + } +} diff --git a/lib/core/service/medical/prescriptions_service.dart b/lib/core/service/medical/prescriptions_service.dart new file mode 100644 index 00000000..3e7259f7 --- /dev/null +++ b/lib/core/service/medical/prescriptions_service.dart @@ -0,0 +1,149 @@ +import 'package:diplomaticquarterapp/config/config.dart'; +import 'package:diplomaticquarterapp/core/model/prescriptions/Prescriptions.dart'; +import 'package:diplomaticquarterapp/core/model/prescriptions/prescription_report.dart'; +import 'package:diplomaticquarterapp/core/model/prescriptions/prescriptions_order.dart'; +import 'package:diplomaticquarterapp/core/model/prescriptions/request_prescription_report.dart'; +import 'package:diplomaticquarterapp/core/model/prescriptions/request_prescriptions.dart'; +import 'package:diplomaticquarterapp/core/model/prescriptions/request_prescriptions_orders.dart'; +import 'package:diplomaticquarterapp/core/model/prescriptions/request_send_prescription_email.dart'; +import 'package:diplomaticquarterapp/core/service/base_service.dart'; + +class PrescriptionsService extends BaseService { + List prescriptionsList = List(); + RequestPrescriptions _requestPrescriptions = RequestPrescriptions( + versionID: 5.5, + channel: 3, + languageID: 2, + iPAdress: '10.20.10.20', + generalid: 'Cs2020@2016\$2958', + patientOutSA: 0, + sessionID: 'KIbLoqkytuKJEWECHQ', + isDentalAllowedBackend: false, + deviceTypeID: 2, + patientID: 1231755, + tokenID: '@dm!n', + patientTypeID: 1, + patientType: 1); + + List prescriptionsOrderList = List(); + RequestPrescriptionsOrders _requestPrescriptionsOrders = + RequestPrescriptionsOrders( + patientID: 1231755, + patientOutSA: 0, + versionID: 5.5, + channel: 3, + languageID: 1, + iPAdress: '10.20.10.20', + generalid: 'Cs2020@2016\$2958', + sessionID: 'KIbLoqkytuKJEWECHQ', + isDentalAllowedBackend: false, + deviceTypeID: 2); + + Future getPrescriptions() async { + hasError = false; + await baseAppClient.post(PRESCRIPTIONS, + onSuccess: (dynamic response, int statusCode) { + prescriptionsList.clear(); + response['PatientPrescriptionList'].forEach((prescriptions) { + prescriptionsList.add(Prescriptions.fromJson(prescriptions)); + }); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: _requestPrescriptions.toJson()); + } + + Future getPrescriptionsOrders() async { + await baseAppClient.post(GET_PRESCRIPTIONS_ALL_ORDERS, + onSuccess: (dynamic response, int statusCode) { + prescriptionsOrderList.clear(); + response['PatientER_GetPatientAllPresOrdersList'] + .forEach((prescriptionsOrder) { + prescriptionsOrderList + .add(PrescriptionsOrder.fromJson(prescriptionsOrder)); + }); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: _requestPrescriptionsOrders.toJson()); + } + + RequestPrescriptionReport _requestPrescriptionReport = + RequestPrescriptionReport( + appointmentNo: 0, + channel: 3, + clinicID: 4, + deviceTypeID: 2, + dischargeNo: 2018003246, + episodeID: 0, + iPAdress: '10.20.10.20', + languageID: 1, + patientID: 1231755, + patientOutSA: 0, + patientType: 1, + patientTypeID: 1, + projectID: 12, + sessionID: 'wgKuHpsPsEuLnlJhAYCQ', + tokenID: '@dm!n', + setupID: "91877", + versionID: 5.5, + generalid: 'Cs2020@2016\$2958', + isDentalAllowedBackend: false); + List prescriptionReportList = List(); + + Future getPrescriptionReport({int dischargeNo}) async { + hasError = false; + _requestPrescriptionReport.dischargeNo = dischargeNo; + await baseAppClient.post(GET_PRESCRIPTION_REPORT, + onSuccess: (dynamic response, int statusCode) { + prescriptionReportList.clear(); + response['INP_GetPrescriptionReport_List'].forEach((prescriptions) { + prescriptionReportList.add(PrescriptionReport.fromJson(prescriptions)); + }); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: _requestPrescriptionReport.toJson()); + } + + RequestSendPrescriptionEmail _requestSendPrescriptionEmail = + RequestSendPrescriptionEmail( + versionID: 5.5, + languageID: 2, + channel: 3, + iPAdress: '10.20.10.20', + generalid: 'Cs2020@2016\$2958', + patientOutSA: 0, + sessionID: 'twIUmHfOHqFdDfVcyw', + isDentalAllowedBackend: false, + deviceTypeID: 2, + tokenID: '@dm!n', + patientTypeID: 1, + patientType: 1, + to: 'aljammalzmohammad@outlook.com', + dateofBirth: '/Date(536743800000+0300)/', + patientIditificationNum: '2344670985', + patientMobileNumber: '537503378', + patientName: 'TAMER FANASHEH', + setupID: '91877'); + + Future sendPrescriptionEmail(String appointmentDate, int patientID, + String clinicName, String doctorName, int projectID) async { + _requestSendPrescriptionEmail.listPrescriptions = prescriptionReportList; + _requestSendPrescriptionEmail.appointmentDate = appointmentDate; + _requestSendPrescriptionEmail.patientID = patientID; + _requestSendPrescriptionEmail.clinicName = clinicName; + _requestSendPrescriptionEmail.doctorName = doctorName; + _requestSendPrescriptionEmail.projectID = projectID; + hasError = false; + await baseAppClient.post(SEND_PRESCRIPTION_EMAIL, + onSuccess: (dynamic response, int statusCode){ + var asd = ""; + + }, + onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: _requestSendPrescriptionEmail.toJson()); + } +} diff --git a/lib/core/viewModels/medical/my_doctor_view_model.dart b/lib/core/viewModels/medical/my_doctor_view_model.dart new file mode 100644 index 00000000..e04f9bdd --- /dev/null +++ b/lib/core/viewModels/medical/my_doctor_view_model.dart @@ -0,0 +1,97 @@ +import 'package:diplomaticquarterapp/core/enum/filter_type.dart'; +import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; +import 'package:diplomaticquarterapp/core/model/doctor/doctor_profile.dart'; +import 'package:diplomaticquarterapp/core/model/doctor/doctor_rating.dart'; +import 'package:diplomaticquarterapp/core/model/doctor/patient_doctor_appointment.dart'; +import 'package:diplomaticquarterapp/core/service/medical/my_doctor_service.dart'; + +import '../../../locator.dart'; +import '../base_view_model.dart'; + +class MyDoctorViewModel extends BaseViewModel { + FilterType filterType = FilterType.Clinic; + MyDoctorService _myDoctorService = locator(); + + List _patientDoctorAppointmentListClinic = + List(); + List _patientDoctorAppointmentListHospital = + List(); + + List get patientDoctorAppointmentList => + filterType == FilterType.Clinic + ? _patientDoctorAppointmentListClinic + : _patientDoctorAppointmentListHospital; + + DoctorProfile get doctorProfile => _myDoctorService.doctorProfile; + DoctorRating get doctorRating => _myDoctorService.doctorRating; + + void getMyDoctor() async { + setState(ViewState.Busy); + await _myDoctorService.getPatientDoctorAppointmentList(); + if (_myDoctorService.hasError) { + error = _myDoctorService.error; + setState(ViewState.Error); + } else { + _myDoctorService.patientDoctorAppointmentList.forEach((element) { + List doctorByClinic = + _patientDoctorAppointmentListClinic + .where((elementClinic) => + elementClinic.filterName == element.clinicName) + .toList(); + + if (doctorByClinic.length != 0) { + _patientDoctorAppointmentListClinic[ + _patientDoctorAppointmentListClinic + .indexOf(doctorByClinic[0])] + .patientDoctorAppointmentList + .add(element); + } else { + _patientDoctorAppointmentListClinic.add(PatientDoctorAppointmentList( + filterName: element.clinicName, + patientDoctorAppointment: element)); + } + + // doctor list sort via project + List doctorByHospital = + _patientDoctorAppointmentListHospital + .where( + (elementClinic) => + elementClinic.filterName == element.projectName, + ) + .toList(); + + if (doctorByHospital.length != 0) { + _patientDoctorAppointmentListHospital[ + _patientDoctorAppointmentListHospital + .indexOf(doctorByHospital[0])] + .patientDoctorAppointmentList + .add(element); + } else { + _patientDoctorAppointmentListHospital.add( + PatientDoctorAppointmentList( + filterName: element.projectName, + patientDoctorAppointment: element)); + } + }); + + setState(ViewState.Idle); + } + } + + setFilterType(FilterType filterType) { + this.filterType = filterType; + notifyListeners(); + } + + void getDoctorProfileAndRating({int doctorId,int clinicID,int projectID }) async { + setState(ViewState.Busy); + await _myDoctorService.getDoctorProfileAndRating(doctorId: doctorId,clinicID: clinicID,projectID: projectID); + if (_myDoctorService.hasError) { + error = _myDoctorService.error; + setState(ViewState.Error); + } else + setState(ViewState.Idle); + } + + +} diff --git a/lib/core/viewModels/medical/prescriptions_view_model.dart b/lib/core/viewModels/medical/prescriptions_view_model.dart new file mode 100644 index 00000000..75ff319f --- /dev/null +++ b/lib/core/viewModels/medical/prescriptions_view_model.dart @@ -0,0 +1,126 @@ +import 'package:diplomaticquarterapp/core/model/prescriptions/prescription_report.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; + +import '../../../core/enum/filter_type.dart'; +import '../../../core/enum/viewstate.dart'; +import '../../../core/model/prescriptions/Prescriptions.dart'; +import '../../../core/service/medical/prescriptions_service.dart'; + +import '../../../locator.dart'; +import '../base_view_model.dart'; + +class PrescriptionsViewModel extends BaseViewModel { + FilterType filterType = FilterType.Clinic; + PrescriptionsService _prescriptionsService = locator(); + + List _prescriptionsOrderListClinic = List(); + List _prescriptionsOrderListHospital = List(); + + List get prescriptionReportList => + _prescriptionsService.prescriptionReportList; + + List get prescriptionsList => + _prescriptionsService.prescriptionsList; + + List get prescriptionsOrderList => + filterType == FilterType.Clinic + ? _prescriptionsOrderListClinic + : _prescriptionsOrderListHospital; + + getPrescriptions() async { + setState(ViewState.Busy); + await _prescriptionsService.getPrescriptions(); + if (_prescriptionsService.hasError) { + error = _prescriptionsService.error; + setState(ViewState.Error); + } else { + _filterList(); + await _getPrescriptionsOrders(); + setState(ViewState.Idle); + } + } + + void _filterList() { + _prescriptionsService.prescriptionsList.forEach((element) { + /// PrescriptionsList list sort clinic + List prescriptionsByClinic = + _prescriptionsOrderListClinic + .where((elementClinic) => + elementClinic.filterName == element.clinicDescription) + .toList(); + + if (prescriptionsByClinic.length != 0) { + _prescriptionsOrderListClinic[ + _prescriptionsOrderListClinic.indexOf(prescriptionsByClinic[0])] + .prescriptionsList + .add(element); + } else { + _prescriptionsOrderListClinic.add(PrescriptionsList( + filterName: element.clinicDescription, prescriptions: element)); + } + + /// PrescriptionsList list sort via hospital + List prescriptionsByHospital = + _prescriptionsOrderListHospital + .where( + (elementClinic) => elementClinic.filterName == element.name, + ) + .toList(); + + if (prescriptionsByHospital.length != 0) { + _prescriptionsOrderListHospital[_prescriptionsOrderListHospital + .indexOf(prescriptionsByHospital[0])] + .prescriptionsList + .add(element); + } else { + _prescriptionsOrderListHospital.add(PrescriptionsList( + filterName: element.name, prescriptions: element)); + } + }); + } + + _getPrescriptionsOrders() async { + await _prescriptionsService.getPrescriptionsOrders(); + if (_prescriptionsService.hasError) { + error = _prescriptionsService.error; + setState(ViewState.ErrorLocal); + } else { + setState(ViewState.Idle); + } + } + + setFilterType(FilterType filterType) { + this.filterType = filterType; + notifyListeners(); + } + + getPrescriptionReport({int dischargeNo}) async { + setState(ViewState.Busy); + await _prescriptionsService.getPrescriptionReport(dischargeNo: dischargeNo); + if (_prescriptionsService.hasError) { + error = _prescriptionsService.error; + setState(ViewState.ErrorLocal); + } else { + setState(ViewState.Idle); + } + } + + sendPrescriptionEmail( + {String appointmentDate, + int patientID, + String clinicName, + String doctorName, + int projectID}) async { + setState(ViewState.BusyLocal); + await _prescriptionsService.sendPrescriptionEmail( + appointmentDate, patientID, clinicName, doctorName, projectID); + if (_prescriptionsService.hasError) { + error = _prescriptionsService.error; + setState(ViewState.ErrorLocal); + AppToast.showSuccessToast(message: error); + } else { + AppToast.showSuccessToast(message: 'A copy has been sent to the e-mail'); + setState(ViewState.Idle); + } + } +} diff --git a/lib/locator.dart b/lib/locator.dart index f6a76c1c..c1a2a170 100644 --- a/lib/locator.dart +++ b/lib/locator.dart @@ -1,7 +1,11 @@ import 'package:get_it/get_it.dart'; import 'core/service/hospital_service.dart'; +import 'core/service/medical/my_doctor_service.dart'; +import 'core/service/medical/prescriptions_service.dart'; import 'core/viewModels/hospital_view_model.dart'; +import 'core/viewModels/medical/my_doctor_view_model.dart'; +import 'core/viewModels/medical/prescriptions_view_model.dart'; import 'core/viewModels/pharmacies_view_model.dart'; import 'core/service/pharmacies_service.dart'; @@ -12,8 +16,12 @@ void setupLocator() { /// Services locator.registerLazySingleton(() => HospitalService()); locator.registerLazySingleton(() => PharmacyService()); + locator.registerLazySingleton(() => MyDoctorService()); + locator.registerLazySingleton(() => PrescriptionsService()); /// View Model locator.registerFactory(() => HospitalViewModel()); locator.registerFactory(() => PharmacyViewModel()); + locator.registerFactory(() => MyDoctorViewModel()); + locator.registerFactory(() => PrescriptionsViewModel()); } diff --git a/lib/pages/MyAppointments/AppointmentDetails.dart b/lib/pages/MyAppointments/AppointmentDetails.dart index ffb5f6be..07d13e9a 100644 --- a/lib/pages/MyAppointments/AppointmentDetails.dart +++ b/lib/pages/MyAppointments/AppointmentDetails.dart @@ -72,7 +72,7 @@ class _AppointmentDetailsState extends State with SingleTick margin: EdgeInsets.only(top: 5.0), alignment: Alignment.center, child: RatingBar.readOnly( - initialRating: 4.0, + initialRating: 3.5, size: 35.0, filledColor: Colors.yellow[700], emptyColor: Colors.grey[500], diff --git a/lib/pages/landing/landing_page.dart b/lib/pages/landing/landing_page.dart index 50c32c78..18dd45af 100644 --- a/lib/pages/landing/landing_page.dart +++ b/lib/pages/landing/landing_page.dart @@ -2,9 +2,10 @@ import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/model/auth/select_device_imei_res.dart'; import 'package:diplomaticquarterapp/pages/ToDoList/ToDo.dart'; import 'package:diplomaticquarterapp/pages/landing/replay_page.dart'; +import 'package:diplomaticquarterapp/pages/medical/prescriptions/prescriptions_home_page.dart'; import 'package:diplomaticquarterapp/providers/auth_provider.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/medicine_search_screen.dart'; -import 'package:diplomaticquarterapp/pages/medical/medical_page.dart'; +import 'package:diplomaticquarterapp/pages/medical/medical_profile_page.dart'; import 'package:diplomaticquarterapp/pages/medical/my_admissions_page.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/bottom_navigation/bottom_nav_bar.dart'; @@ -71,7 +72,7 @@ class _LandingPageState extends State { body: PageView( physics: NeverScrollableScrollPhysics(), controller: pageController, - children: [HomePage(), MedicineSearch(), MedicalPage(), MyAdmissionsPage()], + children: [Container(), MedicalProfilePage(), MyAdmissionsPage(), ToDo()], ), bottomNavigationBar: BottomNavBar(changeIndex: _changeCurrentTab), ); diff --git a/lib/pages/medical/doctor/doctor_home_page.dart b/lib/pages/medical/doctor/doctor_home_page.dart new file mode 100644 index 00000000..c9bce380 --- /dev/null +++ b/lib/pages/medical/doctor/doctor_home_page.dart @@ -0,0 +1,110 @@ +import 'package:diplomaticquarterapp/core/enum/filter_type.dart'; +import 'package:diplomaticquarterapp/core/model/doctor/patient_doctor_appointment.dart'; +import 'package:diplomaticquarterapp/core/viewModels/medical/my_doctor_view_model.dart'; +import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; +import 'package:diplomaticquarterapp/widgets/data_display/medical/doctor_card.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_expandable_notifier.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:intl/intl.dart'; + +import 'doctor_profile_page.dart'; + +class DoctorHomePage extends StatelessWidget { + @override + Widget build(BuildContext context) { + return BaseView( + onModelReady: (model) => model.getMyDoctor(), + builder: (context, MyDoctorViewModel model, widget) => AppScaffold( + baseViewModel: model, + isShowAppBar: true, + appBarTitle: 'My Doctors', + body: SingleChildScrollView( + physics: BouncingScrollPhysics(), + child: FractionallySizedBox( + widthFactor: 1.0, + child: Center( + child: Column( + children: [ + Row( + children: [ + Expanded( + flex: 1, + child: InkWell( + onTap: () => model.setFilterType(FilterType.Clinic), + child: ListTile( + title: const Text('Clinic'), + leading: Radio( + value: FilterType.Clinic, + groupValue: model.filterType, + activeColor: Colors.red[800], + onChanged: (FilterType value) { + model.setFilterType(value); + }, + ), + ), + ), + ), + Expanded( + flex: 1, + child: InkWell( + onTap: () => model.setFilterType(FilterType.Hospital), + child: ListTile( + title: const Text('Hospital'), + leading: Radio( + value: FilterType.Hospital, + groupValue: model.filterType, + activeColor: Colors.red[800], + onChanged: (FilterType value) => + model.setFilterType(value), + ), + ), + ), + ) + ], + ), + ...List.generate( + model.patientDoctorAppointmentList.length, + (index) => AppExpandableNotifier( + title: model + .patientDoctorAppointmentList[index].filterName, + bodyWidget: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: model.patientDoctorAppointmentList[index] + .patientDoctorAppointmentList + .map((doctor) { + return InkWell( + onTap: () { + Navigator.push( + context, + FadePage( + page: DoctorProfilePage( + patientDoctorAppointment: doctor, + ), + ), + ); + }, + child: DoctorCard( + name: doctor.doctorName, + profileUrl: doctor.doctorImageURL, + rat: doctor.doctorRate.toDouble(), + subName: DateUtil.getMonthDayYearDateFormatted( + doctor.appointmentDate), + ), + ); + }).toList(), + )), + ) + ], + ), + ), + ), + ), + ), + ); + } +} diff --git a/lib/pages/medical/doctor/doctor_information_page.dart b/lib/pages/medical/doctor/doctor_information_page.dart new file mode 100644 index 00000000..7634cde2 --- /dev/null +++ b/lib/pages/medical/doctor/doctor_information_page.dart @@ -0,0 +1,199 @@ +import 'package:diplomaticquarterapp/core/model/doctor/doctor_profile.dart'; +import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +class DoctorInformation extends StatefulWidget { + final DoctorProfile doctorProfile; + + const DoctorInformation({Key key, this.doctorProfile}) : super(key: key); + + @override + _DoctorInformationState createState() => _DoctorInformationState(); +} + +class _DoctorInformationState extends State { + bool _isShowInfo = true; + bool _isScientificQualification = true; + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.grey[200], + body: SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + margin: EdgeInsets.only(top: 10, right: 10, left: 10), + padding: EdgeInsets.all(10.0), + width: double.infinity, + //height: 250, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.all(Radius.circular(10.0)), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Icon( + Icons.person, + size: 25, + color: Colors.red[700], + ), + SizedBox( + width: 10, + ), + Expanded(child: Texts(widget.doctorProfile.doctorName)), + InkWell( + onTap: () { + setState(() { + _isShowInfo = !_isShowInfo; + }); + }, + child: Container( + margin: EdgeInsets.all(5), + decoration: + BoxDecoration(shape: BoxShape.circle, boxShadow: [ + BoxShadow( + color: Colors.red[700], + blurRadius: 1.0, + spreadRadius: 0.0, + ) + ]), + child: Icon( + _isShowInfo + ? Icons.keyboard_arrow_up + : Icons.keyboard_arrow_down , + size: 25, + color: Colors.white, + )), + ), + ], + ), + if (_isShowInfo) + AnimatedContainer( + duration: Duration(milliseconds: 7000), + margin: EdgeInsets.only(top: 20), + // height: 150, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Texts('Gender'), + Texts( + widget.doctorProfile.genderDescription, + variant: 'overline', + ), + ], + ), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Texts('Nationality'), + Texts( + widget.doctorProfile.nationalityName, + variant: 'overline', + ), + ], + ), + ], + ), + SizedBox( + height: 5, + ), + Divider( + height: 3, + color: Colors.grey, + ), + SizedBox( + height: 5, + ), + Texts('Clinic'), + Texts( + widget.doctorProfile.clinicDescription, + variant: 'overline', + ), + ], + ), + ) + ], + ), + ), + Container( + margin: EdgeInsets.only(top: 10, right: 10, left: 10), + padding: EdgeInsets.all(10.0), + width: double.infinity, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.all(Radius.circular(10.0)), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Icon( + Icons.local_play, + size: 25, + color: Colors.red[700], + ), + SizedBox( + width: 10, + ), + Expanded(child: Texts(widget.doctorProfile.doctorName)), + InkWell( + onTap: () { + setState(() { + _isScientificQualification = + !_isScientificQualification; + }); + }, + child: Container( + margin: EdgeInsets.all(5), + decoration: + BoxDecoration(shape: BoxShape.circle, boxShadow: [ + BoxShadow( + color: Colors.red[700], + blurRadius: 1.0, + spreadRadius: 0.0, + ) + ]), + child: Icon( + _isScientificQualification + ? Icons.keyboard_arrow_up + : Icons.keyboard_arrow_down, + size: 25, + color: Colors.white, + )), + ), + ], + ), + if (_isScientificQualification) + AnimatedContainer( + duration: Duration(milliseconds: 7000), + margin: EdgeInsets.only(top: 20), + // height: 150, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Texts(widget.doctorProfile.doctorProfileInfo,) + ], + ), + ) + ], + ), + ) + ], + ), + ), + ); + } +} diff --git a/lib/pages/medical/doctor/doctor_profile_page.dart b/lib/pages/medical/doctor/doctor_profile_page.dart new file mode 100644 index 00000000..61bfd804 --- /dev/null +++ b/lib/pages/medical/doctor/doctor_profile_page.dart @@ -0,0 +1,181 @@ +import 'package:diplomaticquarterapp/core/model/doctor/patient_doctor_appointment.dart'; +import 'package:diplomaticquarterapp/core/viewModels/medical/my_doctor_view_model.dart'; +import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:rating_bar/rating_bar.dart'; + +import 'doctor_information_page.dart'; + +class DoctorProfilePage extends StatefulWidget { + final PatientDoctorAppointment patientDoctorAppointment; + + DoctorProfilePage({this.patientDoctorAppointment}); + + @override + _DoctorProfilePageState createState() => + _DoctorProfilePageState(patientDoctorAppointment); +} + +class _DoctorProfilePageState extends State + with SingleTickerProviderStateMixin { + TabController _tabController; + final PatientDoctorAppointment patientDoctorAppointment; + + _DoctorProfilePageState(this.patientDoctorAppointment); + + @override + void initState() { + _tabController = new TabController(length: 2, vsync: this); + super.initState(); + } + + @override + Widget build(BuildContext context) { + return BaseView( + onModelReady: (model) => model.getDoctorProfileAndRating( + doctorId: widget.patientDoctorAppointment.doctorID, + clinicID: widget.patientDoctorAppointment.clinicID, + projectID: widget.patientDoctorAppointment.projectID), + builder: (context, model, widget) => AppScaffold( + isShowAppBar: true, + appBarTitle: 'Doctor Profile', + baseViewModel: model, + body: SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + color: Colors.white, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + margin: EdgeInsets.only(top: 20.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Container( + margin: EdgeInsets.all(5), + width: 50, + height: 50, + decoration: + BoxDecoration(shape: BoxShape.circle, + color: Colors.grey + ), + child: Icon( + Icons.calendar_view_day, + size: 25, + color: Colors.white, + )), + ClipRRect( + borderRadius: BorderRadius.circular(100.0), + child: Image.network( + patientDoctorAppointment.doctorImageURL, + fit: BoxFit.fill, + height: 120.0, + width: 120.0), + ), + Container( + margin: EdgeInsets.all(5), + width: 50, + height: 50, + decoration: + BoxDecoration(shape: BoxShape.circle, + color: Colors.grey + ), + child: Icon( + Icons.format_list_bulleted, + size: 25, + color: Colors.white, + )), + ], + ), + ), + Container( + margin: EdgeInsets.only(top: 10.0), + alignment: Alignment.center, + child: Text(patientDoctorAppointment.doctorName, + style: TextStyle( + fontSize: 20.0, + color: Colors.grey[900], + letterSpacing: 1.0)), + ), + Container( + margin: EdgeInsets.only(top: 10.0), + alignment: Alignment.center, + child: Text(patientDoctorAppointment.clinicName, + style: TextStyle( + fontSize: 12.0, + color: Colors.grey[900], + letterSpacing: 1.0)), + ), + Container( + margin: EdgeInsets.only(top: 5.0), + alignment: Alignment.center, + child: RatingBar.readOnly( + initialRating: + model.doctorRating.doctorRate.toDouble() ?? + 0.0, + size: 35.0, + filledColor: Colors.yellow[700], + emptyColor: Colors.grey[500], + isHalfAllowed: true, + halfFilledIcon: Icons.star_half, + filledIcon: Icons.star, + emptyIcon: Icons.star, + ), + ), + Container( + margin: EdgeInsets.only(top: 5.0), + alignment: Alignment.center, + child: Text( + "(${model.doctorRating.patientNumber ?? 0} Reviews)", + style: TextStyle( + fontSize: 14.0, + color: Colors.blue[800], + letterSpacing: 1.0, + decoration: TextDecoration.underline, + )), + ), + Container( + margin: EdgeInsets.only(top: 10.0), + child: Divider( + color: Colors.grey[500], + ), + ), + TabBar( + indicatorColor: Colors.red[800], + indicatorWeight: 3.0, + tabs: [ + Tab( + child: Text( + 'Doctor Information', + style: TextStyle(color: Colors.black))), + Tab( + child: Text( + TranslationBase.of(context).availableAppo, + style: TextStyle(color: Colors.black)), + ) + ], + controller: _tabController, + ), + Container( + height: MediaQuery.of(context).size.height * 0.8, + child: TabBarView( + physics: BouncingScrollPhysics(), + children: [DoctorInformation(doctorProfile: model.doctorProfile,), Container()], + controller: _tabController, + ), + ), + ], + ), + ), + ], + ), + ), + )); + } +} diff --git a/lib/pages/medical/medical_page.dart b/lib/pages/medical/medical_profile_page.dart similarity index 68% rename from lib/pages/medical/medical_page.dart rename to lib/pages/medical/medical_profile_page.dart index 049ba0bc..ceacaed4 100644 --- a/lib/pages/medical/medical_page.dart +++ b/lib/pages/medical/medical_profile_page.dart @@ -1,18 +1,21 @@ import 'dart:math'; +import 'package:diplomaticquarterapp/pages/medical/prescriptions/prescriptions_home_page.dart'; import 'package:diplomaticquarterapp/widgets/data_display/medical/medical_profile_item.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/others/sliver_app_bar_delegate.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -class MedicalPage extends StatefulWidget { - @override - _MedicalPageState createState() => _MedicalPageState(); +import 'doctor/doctor_home_page.dart'; +class MedicalProfilePage extends StatefulWidget { + @override + _MedicalProfilePageState createState() => _MedicalProfilePageState(); } -class _MedicalPageState extends State { +class _MedicalProfilePageState extends State { @override Widget build(BuildContext context) { return AppScaffold( @@ -39,23 +42,32 @@ class _MedicalPageState extends State { padding: EdgeInsets.symmetric(vertical: 12.0), child: Column( children: [ - Row( children: [ Expanded( flex: 1, - child: MedicalProfileItem( - title: 'My Doctor', - imagePath: 'doctor_icon.png', - subTitle: 'List', + child: InkWell( + onTap: (){ + Navigator.push(context, FadePage(page: DoctorHomePage())); + }, + child: MedicalProfileItem( + title: 'My Doctor', + imagePath: 'doctor_icon.png', + subTitle: 'List', + ), ), ), Expanded( flex: 1, - child: MedicalProfileItem( - title: 'Lab', - imagePath: 'lab_result_icon.png', - subTitle: 'Result', + child: InkWell( + onTap: (){ + + }, + child: MedicalProfileItem( + title: 'Lab', + imagePath: 'lab_result_icon.png', + subTitle: 'Result', + ), ), ) ], @@ -72,10 +84,16 @@ class _MedicalPageState extends State { ), Expanded( flex: 1, - child: MedicalProfileItem( - title: 'Medicines', - imagePath: 'prescription_icon.png', - subTitle: 'Prescriptions', + child: InkWell( + onTap: (){ + Navigator.push(context, FadePage(page: HomePrescriptionsPage())); + + }, + child: MedicalProfileItem( + title: 'Medicines', + imagePath: 'prescription_icon.png', + subTitle: 'Prescriptions', + ), ), ) ], @@ -114,7 +132,6 @@ class _MedicalPageState extends State { flex: 1, child: Container(), ) - ], ), ], @@ -123,10 +140,7 @@ class _MedicalPageState extends State { ), ), ], - ), ); } } - - diff --git a/lib/pages/medical/prescriptions/prescription_details_page.dart b/lib/pages/medical/prescriptions/prescription_details_page.dart new file mode 100644 index 00000000..35a9a307 --- /dev/null +++ b/lib/pages/medical/prescriptions/prescription_details_page.dart @@ -0,0 +1,175 @@ +import 'package:diplomaticquarterapp/core/model/prescriptions/prescription_report.dart'; +import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +class PrescriptionDetailsPage extends StatelessWidget { + final PrescriptionReport prescriptionReport; + + PrescriptionDetailsPage({Key key, this.prescriptionReport}); + + @override + Widget build(BuildContext context) { + return AppScaffold( + isShowAppBar: true, + appBarTitle: 'Prescription Details', + body: SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + width: double.infinity, + margin: EdgeInsets.only(top: 10, left: 10, right: 10), + padding: EdgeInsets.all(8.0), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.all( + Radius.circular(10.0), + ), + border: Border.all(color: Colors.grey[200], width: 0.5), + ), + child: Row( + children: [ + ClipRRect( + borderRadius: BorderRadius.all(Radius.circular(5)), + child: Image.network( + prescriptionReport.imageSRCUrl, + fit: BoxFit.cover, + width: 60, + height: 70, + ), + ), + Expanded( + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Center( + child: Texts(prescriptionReport.itemDescription)), + ), + ), + ], + ), + ), + Container( + margin: EdgeInsets.all(8), + child: InkWell( + onTap: () {}, + child: Center( + child: Column( + children: [ + Container( + width: 50, + decoration: BoxDecoration( + color: Colors.white, + shape: BoxShape.rectangle + ), + child: Column( + children: [ + Icon( + Icons.pin_drop, + color: Colors.red[800], + size: 55, + ), + ], + ), + ), + SizedBox(height: 5,), + Texts('Ports') + + ], + ), + )), + ), + Container( + margin: EdgeInsets.only(top: 10, left: 10, right: 10), + child: Table( + border: TableBorder.symmetric( + inside: BorderSide(width: 0.5), + outside: BorderSide(width: 0.5)), + children: [ + TableRow( + children: [ + Container( + color: Colors.white, + height: 30, + width: double.infinity, + child: Center(child: Texts('Way'))), + Container( + color: Colors.white, + height: 30, + width: double.infinity, + child: Center(child: Texts('Average'))), + Container( + color: Colors.white, + height: 30, + width: double.infinity, + child: Center(child: Texts('Daily doses'))), + Container( + color: Colors.white, + height: 30, + width: double.infinity, + child: Center(child: Texts('Period'))), + ], + ), + TableRow( + children: [ + Container( + color: Colors.white, + height: 50, + width: double.infinity, + child: + Center(child: Text(prescriptionReport.routeN))), + Container( + color: Colors.white, + height: 50, + width: double.infinity, + child: Center( + child: Text(prescriptionReport.frequencyN))), + Container( + color: Colors.white, + height: 50, + width: double.infinity, + child: Center( + child: Text( + '${prescriptionReport.doseDailyQuantity}'))), + Container( + color: Colors.white, + height: 50, + width: double.infinity, + child: + Center(child: Text('${prescriptionReport.days}'))) + ], + ), + ], + ), + ), + Container( + margin: EdgeInsets.only(top: 10, left: 10, right: 10), + width: double.infinity, + color: Colors.white, + padding: EdgeInsets.all(5), + child: Center( + child: Column( + children: [ + Texts('Notes'), + SizedBox( + height: 5, + ), + Divider( + height: 0.5, + color: Colors.grey[300], + ), + SizedBox( + height: 5, + ), + Texts(' '), + ], + ), + ), + ) + ], + ), + ), + ); + } +} diff --git a/lib/pages/medical/prescriptions/prescription_items_page.dart b/lib/pages/medical/prescriptions/prescription_items_page.dart new file mode 100644 index 00000000..c84be7bd --- /dev/null +++ b/lib/pages/medical/prescriptions/prescription_items_page.dart @@ -0,0 +1,112 @@ +import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; +import 'package:diplomaticquarterapp/core/model/prescriptions/Prescriptions.dart'; +import 'package:diplomaticquarterapp/core/viewModels/medical/prescriptions_view_model.dart'; +import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/pages/medical/prescriptions/prescription_details_page.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/button.dart'; +import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +class PrescriptionItemsPage extends StatelessWidget { + final Prescriptions prescriptions; + + PrescriptionItemsPage({Key key, this.prescriptions}); + + @override + Widget build(BuildContext context) { + return BaseView( + onModelReady: (model) => + model.getPrescriptionReport(dischargeNo: prescriptions.dischargeNo), + builder: (_, model, widget) => AppScaffold( + isShowAppBar: true, + appBarTitle: 'Items', + baseViewModel: model, + body: Container( + height: MediaQuery.of(context).size.height * 0.8, + child: ListView.builder( + itemBuilder: (context, index) => InkWell( + onTap: () => Navigator.push( + context, + FadePage( + page: PrescriptionDetailsPage( + prescriptionReport: model.prescriptionReportList[index], + ), + ), + ), + child: Container( + width: double.infinity, + margin: EdgeInsets.only(top: 10, left: 10, right: 10), + padding: EdgeInsets.all(8.0), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.all( + Radius.circular(10.0), + ), + border: Border.all(color: Colors.grey[200], width: 0.5), + ), + child: Row( + children: [ + ClipRRect( + borderRadius: BorderRadius.all(Radius.circular(5)), + child: Image.network( + model.prescriptionReportList[index].imageSRCUrl, + fit: BoxFit.cover, + width: 60, + height: 70, + ), + ), + Expanded( + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Center( + child: Texts(model + .prescriptionReportList[index].itemDescription)), + )), + Icon( + Icons.arrow_forward_ios, + size: 18, + color: Colors.grey[500], + ) + ], + ), + ), + ), + itemCount: model.prescriptionReportList.length, + ), + ), + bottomSheet: Container( + width: double.infinity, + height: MediaQuery.of(context).size.height * 0.2, + color: Colors.grey[100], + child: Column( + children: [ + Divider(), + Container( + width: MediaQuery.of(context).size.width * 0.8, + child: Button( + label: 'Send Copy', + onTap: () => model.sendPrescriptionEmail( + appointmentDate: prescriptions.appointmentDate, + patientID: prescriptions.patientID, + clinicName: prescriptions.companyName, + doctorName: prescriptions.doctorName, + projectID: prescriptions.projectID), + loading: model.state == ViewState.BusyLocal, + ), + ), + Container( + width: MediaQuery.of(context).size.width * 0.8, + child: Button( + label: 'Resend order & deliver', + backgroundColor: Colors.green[200], + )) + ], + ), + ), + ), + ); + } +} diff --git a/lib/pages/medical/prescriptions/prescriptions_history.dart b/lib/pages/medical/prescriptions/prescriptions_history.dart new file mode 100644 index 00000000..1df9a467 --- /dev/null +++ b/lib/pages/medical/prescriptions/prescriptions_history.dart @@ -0,0 +1,13 @@ +import 'package:flutter/cupertino.dart'; + +class PrescriptionsHistory extends StatefulWidget { + @override + _PrescriptionsHistoryState createState() => _PrescriptionsHistoryState(); +} + +class _PrescriptionsHistoryState extends State { + @override + Widget build(BuildContext context) { + return Container(); + } +} diff --git a/lib/pages/medical/prescriptions/prescriptions_home_page.dart b/lib/pages/medical/prescriptions/prescriptions_home_page.dart new file mode 100644 index 00000000..e4c6ca9f --- /dev/null +++ b/lib/pages/medical/prescriptions/prescriptions_home_page.dart @@ -0,0 +1,122 @@ +import 'dart:ui'; + +import 'package:diplomaticquarterapp/core/viewModels/medical/prescriptions_view_model.dart'; +import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/pages/medical/prescriptions/prescriptions_history.dart'; +import 'package:diplomaticquarterapp/pages/medical/prescriptions/prescriptions_page.dart'; +import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +class HomePrescriptionsPage extends StatefulWidget { + @override + _HomePrescriptionsPageState createState() => _HomePrescriptionsPageState(); +} + +class _HomePrescriptionsPageState extends State + with SingleTickerProviderStateMixin { + TabController _tabController; + + @override + void initState() { + super.initState(); + _tabController = TabController(length: 2, vsync: this); + } + + @override + void dispose() { + super.dispose(); + _tabController.dispose(); + } + + @override + Widget build(BuildContext context) { + return BaseView( + onModelReady: (model) => model.getPrescriptions(), + builder: (_, model, widget) => AppScaffold( + isShowAppBar: true, + appBarTitle: 'My Doctors', + body: Scaffold( + extendBodyBehindAppBar: true, + appBar: PreferredSize( + preferredSize: Size.fromHeight(65.0), + child: Stack( + children: [ + Positioned( + bottom: 1, + left: 0, + right: 0, + child: BackdropFilter( + filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10), + child: Container( + color: Theme.of(context) + .scaffoldBackgroundColor + .withOpacity(0.8), + height: 70.0, + ), + ), + ), + Center( + child: Container( + height: 60.0, + margin: EdgeInsets.only(top: 10.0), + width: MediaQuery.of(context).size.width * 0.9, + decoration: BoxDecoration( + border: Border( + bottom: BorderSide( + color: Theme.of(context).dividerColor, + width: 0.7), + ), + color: Colors.white), + child: Center( + child: TabBar( + isScrollable: true, + controller: _tabController, + indicatorWeight: 5.0, + indicatorSize: TabBarIndicatorSize.label, + indicatorColor: Colors.red[800], + labelColor: Theme.of(context).primaryColor, + labelPadding: + EdgeInsets.only(top: 4.0, left: 18.0, right: 18.0), + unselectedLabelColor: Colors.grey[800], + tabs: [ + Container( + width: MediaQuery.of(context).size.width * 0.30, + child: Center( + child: Texts('Prescriptions'), + ), + ), + Container( + width: MediaQuery.of(context).size.width * 0.30, + child: Center( + child: Texts('History'), + ), + ), + ], + ), + ), + ), + ), + ], + ), + ), + body: Column( + children: [ + Expanded( + child: TabBarView( + physics: BouncingScrollPhysics(), + controller: _tabController, + children: [ + PrescriptionsPage(prescriptionsViewModel: model,), + PrescriptionsHistory() + ], + ), + ) + ], + ), + ), + ), + ); + } +} diff --git a/lib/pages/medical/prescriptions/prescriptions_page.dart b/lib/pages/medical/prescriptions/prescriptions_page.dart new file mode 100644 index 00000000..e335f41c --- /dev/null +++ b/lib/pages/medical/prescriptions/prescriptions_page.dart @@ -0,0 +1,102 @@ +import 'package:diplomaticquarterapp/core/enum/filter_type.dart'; +import 'package:diplomaticquarterapp/core/viewModels/medical/prescriptions_view_model.dart'; +import 'package:diplomaticquarterapp/pages/medical/prescriptions/prescription_items_page.dart'; +import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; +import 'package:diplomaticquarterapp/widgets/data_display/medical/doctor_card.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_expandable_notifier.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +class PrescriptionsPage extends StatelessWidget { + final PrescriptionsViewModel prescriptionsViewModel; + + const PrescriptionsPage({Key key, this.prescriptionsViewModel}) + : super(key: key); + + @override + Widget build(BuildContext context) { + return AppScaffold( + baseViewModel: prescriptionsViewModel, + body: FractionallySizedBox( + widthFactor: 1.0, + child: ListView( + physics: BouncingScrollPhysics(), + children: [ + Row( + children: [ + Expanded( + flex: 1, + child: InkWell( + onTap: () => + prescriptionsViewModel.setFilterType(FilterType.Clinic), + child: ListTile( + title: const Text('Clinic'), + leading: Radio( + value: FilterType.Clinic, + groupValue: prescriptionsViewModel.filterType, + activeColor: Colors.red[800], + onChanged: (FilterType value) { + prescriptionsViewModel.setFilterType(value); + }, + ), + ), + ), + ), + Expanded( + flex: 1, + child: InkWell( + onTap: () => prescriptionsViewModel + .setFilterType(FilterType.Hospital), + child: ListTile( + title: const Text('Hospital'), + leading: Radio( + value: FilterType.Hospital, + groupValue: prescriptionsViewModel.filterType, + activeColor: Colors.red[800], + onChanged: (FilterType value) { + prescriptionsViewModel.setFilterType(value); + }, + ), + ), + ), + ) + ], + ), + ...List.generate( + prescriptionsViewModel.prescriptionsOrderList.length, + (index) => AppExpandableNotifier( + title: prescriptionsViewModel + .prescriptionsOrderList[index].filterName, + bodyWidget: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: prescriptionsViewModel + .prescriptionsOrderList[index].prescriptionsList + .map((prescriptions) { + return InkWell( + onTap: () => Navigator.push( + context, + FadePage( + page: PrescriptionItemsPage(prescriptions: prescriptions,), + ), + ), + child: DoctorCard( + name: prescriptions.doctorName, + profileUrl: prescriptions.doctorImageURL, + rat: prescriptions.doctorRate.toDouble(), + subName: prescriptions.name, + date: DateUtil.getMonthDayYearDateFormatted( + prescriptions.dischargeDate), + ), + ); + }).toList(), + )), + ) + ], + ), + ), + ); + } +} diff --git a/lib/widgets/buttons/button.dart b/lib/widgets/buttons/button.dart index d63babb5..f8aff960 100644 --- a/lib/widgets/buttons/button.dart +++ b/lib/widgets/buttons/button.dart @@ -13,6 +13,7 @@ class Button extends StatefulWidget { this.label: "", this.icon, this.onTap, + this.backgroundColor, this.loading: false, this.elevation: true}) : super(key: key); @@ -22,6 +23,7 @@ class Button extends StatefulWidget { final VoidCallback onTap; final bool loading; final bool elevation; + final Color backgroundColor; @override _ButtonState createState() => _ButtonState(); @@ -103,7 +105,7 @@ class _ButtonState extends State