From 5a08cb720c406f35fb4784ae29fe93ee76d1a5bd Mon Sep 17 00:00:00 2001 From: Sultan Khan Date: Wed, 22 Jul 2020 09:47:05 +0300 Subject: [PATCH] login changes --- android/app/src/main/AndroidManifest.xml | 3 + android/settings_aar.gradle | 1 + lib/config/config.dart | 9 +- lib/config/shared_pref_kay.dart | 4 + .../check_paitent_authentication_req.dart | 76 ++++++++++ lib/core/service/client/base_app_client.dart | 3 +- lib/pages/landing/landing_page.dart | 16 ++- lib/pages/login/login-type.dart | 135 ++++++++++-------- lib/pages/login/login.dart | 98 +++++++++++-- lib/providers/auth_provider.dart | 36 ++++- lib/uitl/utils.dart | 38 +++++ lib/widgets/input/text_field.dart | 6 +- lib/widgets/mobile-no/mobile_no.dart | 45 ++++-- 13 files changed, 374 insertions(+), 96 deletions(-) create mode 100644 android/settings_aar.gradle create mode 100644 lib/core/model/auth/check_paitent_authentication_req.dart diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index c5095d24..02c26fa6 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -33,6 +33,7 @@ android:name="io.flutter.embedding.android.SplashScreenDrawable" android:resource="@drawable/launch_background" /> + @@ -47,5 +48,7 @@ + + diff --git a/android/settings_aar.gradle b/android/settings_aar.gradle new file mode 100644 index 00000000..e7b4def4 --- /dev/null +++ b/android/settings_aar.gradle @@ -0,0 +1 @@ +include ':app' diff --git a/lib/config/config.dart b/lib/config/config.dart index 57695678..dd958c10 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -1,11 +1,14 @@ - const MAX_SMALL_SCREEN = 660; -const BASE_URL = 'https://uat.hmgwebservices.com/Services'; +const BASE_URL = 'https://hmgwebservices.com/Services'; const GET_PROJECT = '/Lists.svc/REST/GetProject'; - class AppGlobal { static var context; } + +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/shared_pref_kay.dart b/lib/config/shared_pref_kay.dart index 59f4f0ff..1e75a802 100644 --- a/lib/config/shared_pref_kay.dart +++ b/lib/config/shared_pref_kay.dart @@ -1,3 +1,7 @@ const TOKEN = 'token'; const APP_LANGUAGE = 'language'; const USER_PROFILE = 'user-profile'; +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'; diff --git a/lib/core/model/auth/check_paitent_authentication_req.dart b/lib/core/model/auth/check_paitent_authentication_req.dart new file mode 100644 index 00000000..2846c1fc --- /dev/null +++ b/lib/core/model/auth/check_paitent_authentication_req.dart @@ -0,0 +1,76 @@ +class CheckPatientAuthenticationReq { + int patientMobileNumber; + String zipCode; + bool isRegister; + String tokenID; + int searchType; + String patientIdentificationID; + int patientID; + double versionID; + int channel; + int languageID; + String iPAdress; + String generalid; + int patientOutSA; + Null sessionID; + bool isDentalAllowedBackend; + int deviceTypeID; + + CheckPatientAuthenticationReq( + {this.patientMobileNumber, + this.zipCode, + this.isRegister, + this.tokenID, + this.searchType, + this.patientIdentificationID, + this.patientID, + this.versionID, + this.channel, + this.languageID, + this.iPAdress, + this.generalid, + this.patientOutSA, + this.sessionID, + this.isDentalAllowedBackend, + this.deviceTypeID}); + + CheckPatientAuthenticationReq.fromJson(Map json) { + patientMobileNumber = json['PatientMobileNumber']; + zipCode = json['ZipCode']; + isRegister = json['isRegister']; + tokenID = json['TokenID']; + searchType = json['SearchType']; + patientIdentificationID = json['PatientIdentificationID']; + 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['PatientMobileNumber'] = this.patientMobileNumber; + data['ZipCode'] = this.zipCode; + data['isRegister'] = this.isRegister; + data['TokenID'] = this.tokenID; + data['SearchType'] = this.searchType; + data['PatientIdentificationID'] = this.patientIdentificationID; + 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/service/client/base_app_client.dart b/lib/core/service/client/base_app_client.dart index 72c38568..57686824 100644 --- a/lib/core/service/client/base_app_client.dart +++ b/lib/core/service/client/base_app_client.dart @@ -14,7 +14,7 @@ AppSharedPreferences sharedPref = new AppSharedPreferences(); /// body: null); class BaseAppClient { - post( + post( String endPoint, { Map body, Function(dynamic response, int statusCode) onSuccess, @@ -22,7 +22,6 @@ class BaseAppClient { }) async { String url = BASE_URL + endPoint; try { - //Map profile = await sharedPref.getObj(DOCTOR_PROFILE); // String token = await sharedPref.getString(TOKEN); diff --git a/lib/pages/landing/landing_page.dart b/lib/pages/landing/landing_page.dart index c7748b4c..7557d1a0 100644 --- a/lib/pages/landing/landing_page.dart +++ b/lib/pages/landing/landing_page.dart @@ -1,4 +1,7 @@ +import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:diplomaticquarterapp/core/model/auth/select_device_imei_res.dart'; import 'package:diplomaticquarterapp/pages/landing/replay_page.dart'; +import 'package:diplomaticquarterapp/providers/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'; @@ -16,6 +19,7 @@ class _LandingPageState extends State { int currentTab = 0; PageController pageController; final FirebaseMessaging _firebaseMessaging = FirebaseMessaging(); + final authService = new AuthProvider(); _changeCurrentTab(int tab) { setState(() { currentTab = tab; @@ -28,7 +32,11 @@ class _LandingPageState extends State { super.initState(); pageController = PageController(keepPage: true); _firebaseMessaging.getToken().then((String token) { - print(token); + sharedPref.setString(PUSH_TOKEN, token); + if (token != null) { + checkUserStatus(token); + } + //assert(token != null); }); } @@ -78,4 +86,10 @@ class _LandingPageState extends State { return TranslationBase.of(context).services; } } + + void checkUserStatus(token) { + authService + .selectDeviceImei(token) + .then((SelectDeviceIMEIRES value) => print(value)); + } } diff --git a/lib/pages/login/login-type.dart b/lib/pages/login/login-type.dart index e22ce297..c0697099 100644 --- a/lib/pages/login/login-type.dart +++ b/lib/pages/login/login-type.dart @@ -38,69 +38,82 @@ class LoginType extends StatelessWidget { Row( mainAxisAlignment: MainAxisAlignment.center, children: [ - InkWell( - onTap: () => { - LoginType.loginType = 2, - Navigator.of(context) - .pushNamed(LOGIN_PAGE) - }, - 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: 60, - width: 70, - ), - SizedBox( - height: 20, - ), - AppText( - TranslationBase.of(context) - .nationalID, - fontSize: - SizeConfig.textMultiplier * 3, - ) - ], - ), - ))), - InkWell( - onTap: () => { - LoginType.loginType = 1, - Navigator.of(context) - .pushNamed(LOGIN_PAGE) - }, - 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: 60, - width: 70, + Expanded( + child: InkWell( + onTap: () => { + LoginType.loginType = 1, + Navigator.of(context) + .pushNamed(LOGIN_PAGE) + }, + 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, + ) + ], ), - SizedBox( - height: 20, + )))), + Expanded( + child: InkWell( + onTap: () => { + LoginType.loginType = 2, + Navigator.of(context) + .pushNamed(LOGIN_PAGE) + }, + 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, + ) + ], ), - AppText( - TranslationBase.of(context).fileNo, - fontSize: - SizeConfig.textMultiplier * 3, - ) - ], - ), - ))) + )))) ], ), Divider( diff --git a/lib/pages/login/login.dart b/lib/pages/login/login.dart index 1cd6fa11..7bb61da5 100644 --- a/lib/pages/login/login.dart +++ b/lib/pages/login/login.dart @@ -1,6 +1,12 @@ +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/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/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/card/rounded_container.dart'; import 'package:diplomaticquarterapp/widgets/input/text_field.dart'; @@ -16,10 +22,14 @@ class Login extends StatefulWidget { } class _Login extends State { - final TextEditingController nationalIDorFile = null; + final util = Utils(); + final nationalIDorFile = TextEditingController(); final int loginType = LoginType.loginType; - final TextEditingController mobileNo = null; - + String mobileNo; + String countryCode = '966'; + bool isButtonDisabled = true; + final authService = new AuthProvider(); + var sharedPref = new AppSharedPreferences(); @override Widget build(BuildContext context) { return AppScaffold( @@ -43,20 +53,24 @@ class _Login extends State { child: Column( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ - MobileNo(controller: mobileNo), + MobileNo( + onNumberChange: (value) => + {mobileNo = value, validateForm()}, + onCountryChange: (value) => countryCode = value), Container( child: TextFields( controller: nationalIDorFile, + onChanged: (value) => {validateForm()}, prefixIcon: Icon( loginType == 1 - ? Icons.receipt - : Icons.chrome_reader_mode, + ? 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).fileNo - : TranslationBase.of(context).nationalID, + ? TranslationBase.of(context).nationalID + : TranslationBase.of(context).fileNo, )) ], ), @@ -70,10 +84,12 @@ class _Login extends State { children: [ Expanded( child: RaisedButton( - color: Colors.grey, + color: isButtonDisabled == true + ? Colors.grey + : Colors.grey[600], textColor: Colors.white, child: Text(TranslationBase.of(context).login), - onPressed: () => {}, + onPressed: () => {this.startLogin()}, )) ], ), @@ -82,4 +98,66 @@ class _Login extends State { ]), ))); } + + startLogin() { + if (isButtonDisabled == false) { + checkUserAuthentication(); + } + } + + void validateForm() { + if (validateIDBox(nationalIDorFile.text) == true && + mobileNo != null && + util.isSAUDIIDValid(nationalIDorFile.text) == true) { + setState(() { + isButtonDisabled = false; + }); + } else { + setState(() { + isButtonDisabled = true; + }); + } + } + + bool validateIDBox(String value) { + Pattern pattern = loginIDPattern(); //r'^\d+(?:\.\d+)?$'; + + RegExp regex = new RegExp(pattern); + return regex.hasMatch(value); + } + + String loginIDPattern() { + var length = loginType == 1 ? 10 : 7; + return "([0-9]{" + length.toString() + "})"; + } + + checkUserAuthentication() { + var request = CheckPatientAuthenticationReq(); + request.isRegister = false; + request.patientMobileNumber = int.parse(mobileNo); + request.zipCode = countryCode; + request.searchType = this.loginType; + request.deviceTypeID = this.loginType; + if (this.loginType == 1) { + request.patientIdentificationID = this.nationalIDorFile.text; + request.patientID = 0; + } else { + request.patientIdentificationID = ''; + request.patientID = int.parse(nationalIDorFile.text); + } + sharedPref.setObject(REGISTER_DATA_FOR_REGISTER, request); + authService.checkPatientAuthentication(request).then((value) => { + if (value.isSMSSent) + { + sharedPref.setString(LOGIN_TOKEN_ID, value.LogInTokenID), + sharedPref.setObject(REGISTER_DATA_FOR_LOGIIN, request), + } + else + { + if (value.IsAuthenticated) {this.checkActivationCode()} + } + }); + } + + checkActivationCode() {} } diff --git a/lib/providers/auth_provider.dart b/lib/providers/auth_provider.dart index 09b880b9..3590355b 100644 --- a/lib/providers/auth_provider.dart +++ b/lib/providers/auth_provider.dart @@ -1,16 +1,21 @@ +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/core/service/client/base_app_client.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:flutter/cupertino.dart'; // SharedPreferences sharedPref = new SharedPreferences(); enum APP_STATUS { LOADING, UNAUTHENTICATED, AUTHENTICATED } AppSharedPreferences sharedPref = new AppSharedPreferences(); -const String INSERT_DEVICE_IMEI = - 'Services/Patients.svc/REST/Patient_INSERTDeviceIMEI'; +const String INSERT_DEVICE_IMEI = '/Patients.svc/REST/Patient_INSERTDeviceIMEI'; const String SELECT_DEVICE_IMEI = - 'Services/Patients.svc/REST/Patient_SELECTDeviceIMEIbyIMEI'; + '/Patients.svc/REST/Patient_SELECTDeviceIMEIbyIMEI'; +const String CHECK_PATIENT_AUTH = + '/Authentication.svc/REST/CheckPatientAuthentication'; class AuthProvider with ChangeNotifier { bool isLogin = false; @@ -78,7 +83,7 @@ class AuthProvider with ChangeNotifier { } } - Future selectDeviceImei(imei) async { + Future selectDeviceImei(imei) async { try { dynamic localRes; await new BaseAppClient().post(SELECT_DEVICE_IMEI, @@ -93,4 +98,27 @@ class AuthProvider with ChangeNotifier { throw error; } } + + Future checkPatientAuthentication( + CheckPatientAuthenticationReq 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(CHECK_PATIENT_AUTH, + 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/utils.dart b/lib/uitl/utils.dart index 1c2da2b6..ac586b7d 100644 --- a/lib/uitl/utils.dart +++ b/lib/uitl/utils.dart @@ -42,4 +42,42 @@ class Utils { static hideKeyboard(BuildContext context) { FocusScope.of(context).unfocus(); } + + bool isSAUDIIDValid(String id) { + if (id == null) { + return false; + } + try { + id = id.toString(); + id = id.trim(); + var returnValue = int.parse(id); + var sum = 0; + if (returnValue > 0) { + var type = int.parse(id[0]); + + if (id.length != 10) { + return false; + } + if (type != 2 && type != 1) { + return false; + } + + for (var i = 0; i < 10; i++) { + if (i % 2 == 0) { + var a = id[i]; + var x = int.parse(a) * 2; + var b = x.toString(); + if (b.length == 1) { + b = "0" + b; + } + sum += int.parse(b[0]) + int.parse(b[1]); + } else { + sum += int.parse(id[i]); + } + } + return sum % 10 == 0; + } + } catch (err) {} + return false; + } } diff --git a/lib/widgets/input/text_field.dart b/lib/widgets/input/text_field.dart index 94dfddba..5429dd39 100644 --- a/lib/widgets/input/text_field.dart +++ b/lib/widgets/input/text_field.dart @@ -46,7 +46,7 @@ class TextFields extends StatefulWidget { this.suffixIcon, this.autoFocus, this.onChanged, - this.initialValue, + // this.initialValue, this.minLines, this.maxLines, this.inputFormatters, @@ -75,7 +75,7 @@ class TextFields extends StatefulWidget { : super(key: key); final String hintText; - final String initialValue; + // final String initialValue; final String type; final bool autoFocus; final IconData suffixIcon; @@ -223,7 +223,7 @@ class _TextFieldsState extends State { minLines: widget.minLines ?? 1, maxLines: widget.maxLines ?? 1, maxLengthEnforced: widget.maxLengthEnforced, - initialValue: widget.initialValue, + // initialValue: widget.initialValue, onChanged: widget.onChanged, focusNode: _focusNode, maxLength: widget.maxLength ?? null, diff --git a/lib/widgets/mobile-no/mobile_no.dart b/lib/widgets/mobile-no/mobile_no.dart index a1304eff..2c17a669 100644 --- a/lib/widgets/mobile-no/mobile_no.dart +++ b/lib/widgets/mobile-no/mobile_no.dart @@ -9,21 +9,27 @@ import 'package:flutter/material.dart'; class MobileNo extends StatefulWidget { final bool disabled; // final String data; - final String countryCode; + final List countries = [ + new Countries(name: 'Saudi Arabia', code: '966'), + new Countries(name: 'Dubai', code: '971'), + ]; final double margin; final double marginTop; final double marginRight; final double marginBottom; final double marginLeft; final TextEditingController controller; + final Function onNumberChange; + final Function onCountryChange; MobileNo( {this.disabled = false, - this.countryCode = '966', this.marginTop = 0, this.marginRight = 0, this.marginBottom = 0, this.controller, this.marginLeft = 0, + this.onNumberChange, + this.onCountryChange, this.margin = 0}); @override @@ -31,8 +37,8 @@ class MobileNo extends StatefulWidget { } class _MobileNo extends State { - var _selectedType = 'Saudi Arabia'; - + var _selectedType = '966'; + String countryCode = '966'; @override Widget build(BuildContext context) { return Visibility( @@ -50,14 +56,18 @@ class _MobileNo extends State { value: _selectedType, iconSize: 40, elevation: 16, - onChanged: (newValue) => _selectedType = newValue, - items: [ - 'Saudi Arabia', - 'Dubai', - ].map>((String value) { + onChanged: (value) => { + widget.onCountryChange(value), + setState(() { + countryCode = value; + _selectedType = value; + }) + }, + items: widget.countries + .map>((Countries value) { return DropdownMenuItem( - value: value, - child: Text(value), + value: value.code, + child: Text(value.name), ); }).toList())))), ], @@ -77,7 +87,7 @@ class _MobileNo extends State { Expanded( flex: 1, child: Text( - widget.countryCode, + countryCode, overflow: TextOverflow.clip, )), Expanded( @@ -92,6 +102,11 @@ class _MobileNo extends State { left: widget.marginLeft), child: TextField( controller: widget.controller, + keyboardType: TextInputType.phone, + // onChanged: (value) { + // widget.controller.text = countryCode; + // }, + onChanged: (value) => widget.onNumberChange(value), decoration: InputDecoration( border: InputBorder.none, hintText: '5xxxxxxxx'), ), @@ -102,3 +117,9 @@ class _MobileNo extends State { ])); } } + +class Countries { + final String name; + final String code; + Countries({this.name, this.code}); +}