login changes

merge-requests/250/head
Sultan Khan 5 years ago
parent 71c4d48cca
commit 40e9ab864a

@ -44,6 +44,7 @@ android {
versionCode flutterVersionCode.toInteger() versionCode flutterVersionCode.toInteger()
versionName flutterVersionName versionName flutterVersionName
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
multiDexEnabled true
} }
buildTypes { buildTypes {
@ -72,9 +73,10 @@ dependencies {
implementation 'com.opentok.android:opentok-android-sdk:2.16.5' implementation 'com.opentok.android:opentok-android-sdk:2.16.5'
//permissions //permissions
implementation 'pub.devrel:easypermissions:0.4.0' implementation 'pub.devrel:easypermissions:0.4.0'
implementation 'com.google.firebase:firebase-core:9.6.1'
//retrofit //retrofit
implementation 'com.squareup.retrofit2:retrofit:2.6.2' implementation 'com.squareup.retrofit2:retrofit:2.6.2'
implementation 'com.squareup.retrofit2:converter-gson:2.6.2' implementation 'com.squareup.retrofit2:converter-gson:2.6.2'
implementation 'com.squareup.okhttp3:logging-interceptor:3.14.1' implementation 'com.squareup.okhttp3:logging-interceptor:3.14.1'
apply plugin: 'com.google.gms.google-services'
} }

@ -0,0 +1,39 @@
{
"project_info": {
"project_number": "1008895414777",
"project_id": "doctorapp-9f172",
"storage_bucket": "doctorapp-9f172.appspot.com"
},
"client": [
{
"client_info": {
"mobilesdk_app_id": "1:1008895414777:android:d00fe21d6955c21b1f6d28",
"android_client_info": {
"package_name": "com.example.doctor_app_flutter"
}
},
"oauth_client": [
{
"client_id": "1008895414777-3mg88j5ocs5r1au7rf4sh3f4pgsri2f2.apps.googleusercontent.com",
"client_type": 3
}
],
"api_key": [
{
"current_key": "AIzaSyCNncEIj8ehVUSxV89rx0x1NaWp8t1YVkw"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": [
{
"client_id": "1008895414777-3mg88j5ocs5r1au7rf4sh3f4pgsri2f2.apps.googleusercontent.com",
"client_type": 3
}
]
}
}
}
],
"configuration_version": "1"
}

@ -8,6 +8,7 @@ buildscript {
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:3.5.0' classpath 'com.android.tools.build:gradle:3.5.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'com.google.gms:google-services:4.3.2'
} }
} }

@ -0,0 +1,39 @@
{
"project_info": {
"project_number": "1008895414777",
"project_id": "doctorapp-9f172",
"storage_bucket": "doctorapp-9f172.appspot.com"
},
"client": [
{
"client_info": {
"mobilesdk_app_id": "1:1008895414777:android:d00fe21d6955c21b1f6d28",
"android_client_info": {
"package_name": "com.example.doctor_app_flutter"
}
},
"oauth_client": [
{
"client_id": "1008895414777-3mg88j5ocs5r1au7rf4sh3f4pgsri2f2.apps.googleusercontent.com",
"client_type": 3
}
],
"api_key": [
{
"current_key": "AIzaSyCNncEIj8ehVUSxV89rx0x1NaWp8t1YVkw"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": [
{
"client_id": "1008895414777-3mg88j5ocs5r1au7rf4sh3f4pgsri2f2.apps.googleusercontent.com",
"client_type": 3
}
]
}
}
}
],
"configuration_version": "1"
}

@ -1,4 +1,5 @@
org.gradle.jvmargs=-Xmx1536M
android.enableR8=true android.enableR8=true
android.useAndroidX=true android.useAndroidX=true
android.enableJetifier=true android.enableJetifier=true
org.gradle.jvmargs=-Xmx4608m

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 488 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

@ -42,8 +42,7 @@ class BaseAppClient {
DoctorProfileModel doctorProfile = DoctorProfileModel.fromJson(profile); DoctorProfileModel doctorProfile = DoctorProfileModel.fromJson(profile);
if (body['DoctorID'] == null) if (body['DoctorID'] == null)
body['DoctorID'] = doctorProfile?.doctorID; body['DoctorID'] = doctorProfile?.doctorID;
if (body['DoctorID'] == "") if (body['DoctorID'] == "") body['DoctorID'] = null;
body['DoctorID'] = null;
body['EditedBy'] = doctorProfile?.doctorID; body['EditedBy'] = doctorProfile?.doctorID;
if (body['ProjectID'] == null) { if (body['ProjectID'] == null) {
body['ProjectID'] = doctorProfile?.projectID; body['ProjectID'] = doctorProfile?.projectID;
@ -51,7 +50,7 @@ class BaseAppClient {
if (body['ClinicID'] == null) if (body['ClinicID'] == null)
body['ClinicID'] = doctorProfile?.clinicID; body['ClinicID'] = doctorProfile?.clinicID;
} }
body['TokenID'] = token ?? ''; body['TokenID'] = token ?? '@dm!n';
String lang = await sharedPref.getString(APP_Language); String lang = await sharedPref.getString(APP_Language);
if (lang != null && lang == 'ar') if (lang != null && lang == 'ar')
body['LanguageID'] = 1; body['LanguageID'] = 1;
@ -66,8 +65,8 @@ class BaseAppClient {
body['IsLoginForDoctorApp'] = IS_LOGIN_FOR_DOCTOR_APP; body['IsLoginForDoctorApp'] = IS_LOGIN_FOR_DOCTOR_APP;
body['PatientOutSA'] = 0; // PATIENT_OUT_SA; body['PatientOutSA'] = 0; // PATIENT_OUT_SA;
body['VidaAuthTokenID'] = await sharedPref.getString(VIDA_AUTH_TOKEN_ID); body['VidaAuthTokenID'] = await sharedPref.getString(VIDA_AUTH_TOKEN_ID);
body['VidaRefreshTokenID'] = await sharedPref.getString(VIDA_REFRESH_TOKEN_ID); body['VidaRefreshTokenID'] =
await sharedPref.getString(VIDA_REFRESH_TOKEN_ID);
print("URL : $url"); print("URL : $url");
print("Body : ${json.encode(body)}"); print("Body : ${json.encode(body)}");
@ -87,8 +86,7 @@ class BaseAppClient {
if (!parsed['IsAuthenticated']) { if (!parsed['IsAuthenticated']) {
await helpers.logout(); await helpers.logout();
helpers.showErrorToast('Your session expired Please login agian'); helpers.showErrorToast('Your session expired Please login agian');
} else } else if (parsed['MessageStatus'] == 1) {
if (parsed['MessageStatus'] == 1) {
if (!parsed['IsAuthenticated']) if (!parsed['IsAuthenticated'])
onFailure(getError(parsed), statusCode); onFailure(getError(parsed), statusCode);
else else
@ -123,7 +121,7 @@ class BaseAppClient {
} }
} }
} }
if(error == null || error == "null" || error == "null\n"){ if (error == null || error == "null" || error == "null\n") {
return "This server not work probably in this time"; return "This server not work probably in this time";
} }
return error; return error;

@ -78,9 +78,13 @@ const GET_PATIENT_LAB_RESULTS =
'Services/DoctorApplication.svc/REST/GetPatientLabResults'; 'Services/DoctorApplication.svc/REST/GetPatientLabResults';
const LOGIN_URL = 'Services/Sentry.svc/REST/MemberLogIN_New'; const LOGIN_URL = 'Services/Sentry.svc/REST/MemberLogIN_New';
const INSERT_DEVICE_IMEI = const INSERT_DEVICE_IMEI =
'Services/Sentry.svc/REST/DoctorApplication_INSERTDeviceIMEI'; 'Services/DoctorApplication.svc/REST/DoctorApp_InsertOrUpdateDeviceDetails';
// 'Services/Sentry.svc/REST/DoctorApplication_INSERTDeviceIMEI';
// const SELECT_DEVICE_IMEI =
// 'Services/Sentry.svc/REST/DoctorApplication_SELECTDeviceIMEIbyIMEI';
const SELECT_DEVICE_IMEI = const SELECT_DEVICE_IMEI =
'Services/Sentry.svc/REST/DoctorApplication_SELECTDeviceIMEIbyIMEI'; 'Services/DoctorApplication.svc/REST/DoctorApp_GetDeviceDetailsByIMEI';
const SEND_ACTIVATION_CODE_BY_OTP_NOTIFICATION_TYPE = const SEND_ACTIVATION_CODE_BY_OTP_NOTIFICATION_TYPE =
'Services/Sentry.svc/REST/DoctorApplication_SendActivationCodebyOTPNotificationType'; 'Services/Sentry.svc/REST/DoctorApplication_SendActivationCodebyOTPNotificationType';
@ -216,6 +220,8 @@ var SERVICES_PATIANT_HEADER_AR = [
//****************** //******************
// Colors ////// by : ibrahim // Colors ////// by : ibrahim
var DEVICE_TOKEN = "";
const PRIMARY_COLOR = 0xff515B5D; const PRIMARY_COLOR = 0xff515B5D;
const TRANSACTION_NO = 0; const TRANSACTION_NO = 0;

@ -536,4 +536,39 @@ const Map<String, Map<String, String>> localizedValues = {
'en': "There is no Chief Complaint", 'en': "There is no Chief Complaint",
'ar': "ليس هناك شكوى رئيس" 'ar': "ليس هناك شكوى رئيس"
}, },
"more-verify": {
"en": "More Verification Options",
"ar": "المزيد من خيارات التحقق"
},
"welcome-back": {"en": "Welcome back!", "ar": "مرحبا بعودتك!"},
"account-info": {
"en": "Would you like to login with current username?",
"ar": "هل ترغب في تسجيل الدخول باسم المستخدم الحالي؟"
},
"another-acc": {"en": "Use Another Account", "ar": "استخدم حسابا آخر"},
"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": "نوع التحقق:"},
"verify-fingerprint": {
"en":
"To activate the fingerprint login service, please verify data by using one of the following options.",
"ar":
"لتفعيل خدمة الدخول بالبصمة، يرجى اختيار احدى القنوات التالية للتحقق من البيانات"
},
"verification_message": {
"en": "Please enter the Verification Code sent to",
"ar": "الرجاء ادخال رمز التحقق الذي تم إرساله إلى"
},
"validation_message": {
"en": "The verification code expires in",
"ar": "تنتهي صلاحية رمز التحقق خلال"
},
}; };

@ -10,3 +10,5 @@ final DOCTOR_PROFILE = 'doctorProfile';
final LIVE_CARE_PATIENT = 'livecare-patient-profile'; final LIVE_CARE_PATIENT = 'livecare-patient-profile';
final LOGGED_IN_USER = 'loggedUser'; final LOGGED_IN_USER = 'loggedUser';
final DASHBOARD_DATA = 'dashboard-data'; final DASHBOARD_DATA = 'dashboard-data';
final OTP_TYPE = 'otp-type';
final LAST_LOGIN_USER = 'last-login-user';

@ -0,0 +1,88 @@
class GetIMEIDetailsModel {
String iMEI;
int logInTypeID;
bool outSA;
String mobile;
String identificationNo;
int doctorID;
String doctorName;
String doctorNameN;
int clinicID;
String clinicDescription;
String clnicDescriptionN;
String projectName;
String genderDescription;
String genderDescriptionN;
String titleDescription;
String titleDescriptionN;
bool biometricEnabled;
int preferredLanguage;
bool isActive;
GetIMEIDetailsModel(
{this.iMEI,
this.logInTypeID,
this.outSA,
this.mobile,
this.identificationNo,
this.doctorID,
this.doctorName,
this.doctorNameN,
this.clinicID,
this.clinicDescription,
this.clnicDescriptionN,
this.projectName,
this.genderDescription,
this.genderDescriptionN,
this.titleDescription,
this.titleDescriptionN,
this.biometricEnabled,
this.preferredLanguage,
this.isActive});
GetIMEIDetailsModel.fromJson(Map<String, dynamic> json) {
iMEI = json['IMEI'];
logInTypeID = json['LogInTypeID'];
outSA = json['OutSA'];
mobile = json['Mobile'];
identificationNo = json['IdentificationNo'];
doctorID = json['DoctorID'];
doctorName = json['DoctorName'];
doctorNameN = json['DoctorNameN'];
clinicID = json['ClinicID'];
clinicDescription = json['ClinicDescription'];
clnicDescriptionN = json['ClnicDescriptionN'];
projectName = json['ProjectName'];
genderDescription = json['Gender_Description'];
genderDescriptionN = json['Gender_DescriptionN'];
titleDescription = json['Title_Description'];
titleDescriptionN = json['Title_DescriptionN'];
biometricEnabled = json['BiometricEnabled'];
preferredLanguage = json['PreferredLanguage'];
isActive = json['IsActive'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['IMEI'] = this.iMEI;
data['LogInTypeID'] = this.logInTypeID;
data['OutSA'] = this.outSA;
data['Mobile'] = this.mobile;
data['IdentificationNo'] = this.identificationNo;
data['DoctorID'] = this.doctorID;
data['DoctorName'] = this.doctorName;
data['DoctorNameN'] = this.doctorNameN;
data['ClinicID'] = this.clinicID;
data['ClinicDescription'] = this.clinicDescription;
data['ClnicDescriptionN'] = this.clnicDescriptionN;
data['ProjectName'] = this.projectName;
data['Gender_Description'] = this.genderDescription;
data['Gender_DescriptionN'] = this.genderDescriptionN;
data['Title_Description'] = this.titleDescription;
data['Title_DescriptionN'] = this.titleDescriptionN;
data['BiometricEnabled'] = this.biometricEnabled;
data['PreferredLanguage'] = this.preferredLanguage;
data['IsActive'] = this.isActive;
return data;
}
}

@ -0,0 +1,92 @@
class InsertIMEIDetailsModel {
String iMEI;
int logInTypeID;
bool outSA;
String mobileNo;
String identificationNo;
int doctorID;
String doctorName;
String doctorNameN;
int clinicID;
String clinicDescription;
String clinicDescriptionN;
String projectName;
int projectID;
String genderDescription;
String genderDescriptionN;
String titleDescription;
String titleDescriptionN;
bool bioMetricEnabled;
int preferredLanguage;
bool isActive;
InsertIMEIDetailsModel(
{this.iMEI,
this.logInTypeID,
this.outSA,
this.mobileNo,
this.identificationNo,
this.doctorID,
this.doctorName,
this.doctorNameN,
this.clinicID,
this.clinicDescription,
this.clinicDescriptionN,
this.projectName,
this.projectID,
this.genderDescription,
this.genderDescriptionN,
this.titleDescription,
this.titleDescriptionN,
this.bioMetricEnabled,
this.preferredLanguage,
this.isActive});
InsertIMEIDetailsModel.fromJson(Map<String, dynamic> json) {
iMEI = json['IMEI'];
logInTypeID = json['LogInTypeID'];
outSA = json['OutSA'];
mobileNo = json['MobileNo'];
identificationNo = json['IdentificationNo'];
doctorID = json['DoctorID'];
doctorName = json['DoctorName'];
doctorNameN = json['DoctorNameN'];
clinicID = json['ClinicID'];
clinicDescription = json['ClinicDescription'];
clinicDescriptionN = json['ClinicDescriptionN'];
projectName = json['ProjectName'];
projectID = json['ProjectID'];
genderDescription = json['GenderDescription'];
genderDescriptionN = json['GenderDescriptionN'];
titleDescription = json['TitleDescription'];
titleDescriptionN = json['TitleDescriptionN'];
bioMetricEnabled = json['BioMetricEnabled'];
preferredLanguage = json['PreferredLanguage'];
isActive = json['IsActive'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['IMEI'] = this.iMEI;
data['LogInTypeID'] = this.logInTypeID;
data['OutSA'] = this.outSA;
data['MobileNo'] = this.mobileNo;
data['IdentificationNo'] = this.identificationNo;
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['ProjectName'] = this.projectName;
data['ProjectID'] = this.projectID;
data['GenderDescription'] = this.genderDescription;
data['GenderDescriptionN'] = this.genderDescriptionN;
data['TitleDescription'] = this.titleDescription;
data['TitleDescriptionN'] = this.titleDescriptionN;
data['BioMetricEnabled'] = this.bioMetricEnabled;
data['PreferredLanguage'] = this.preferredLanguage;
data['IsActive'] = this.isActive;
return data;
}
}

@ -0,0 +1,29 @@
import 'package:doctor_app_flutter/config/config.dart';
import 'package:doctor_app_flutter/core/model/imei_details.dart';
import 'package:doctor_app_flutter/core/service/base/base_service.dart';
import 'package:doctor_app_flutter/models/dashboard/dashboard_model.dart';
class AuthService extends BaseService {
List<GetIMEIDetailsModel> _imeiDetails = [];
List<GetIMEIDetailsModel> get dashboardItemsList => _imeiDetails;
Future selectDeviceImei(imei) async {
try {
// dynamic localRes;
await baseAppClient.post(SELECT_DEVICE_IMEI,
onSuccess: (dynamic response, int statusCode) {
_imeiDetails = [];
response['List_DoctorDeviceDetails'].forEach((v) {
_imeiDetails.add(GetIMEIDetailsModel.fromJson(v));
});
}, onFailure: (String error, int statusCode) {
hasError = true;
super.error = error;
}, body: {"IMEI": imei, "TokenID": "@dm!n"});
//return Future.value(localRes);
} catch (error) {
hasError = true;
super.error = error;
}
}
}

@ -14,7 +14,6 @@ class MedicineService extends BaseService {
PharmaciesItemsRequestModel(); PharmaciesItemsRequestModel();
PharmaciesListRequestModel _listRequestModel = PharmaciesListRequestModel(); PharmaciesListRequestModel _listRequestModel = PharmaciesListRequestModel();
Future getMedicineItem(String itemName) async { Future getMedicineItem(String itemName) async {
_itemsRequestModel.pHRItemName = itemName; _itemsRequestModel.pHRItemName = itemName;
await baseAppClient.post( await baseAppClient.post(

@ -1,4 +1,10 @@
import 'package:doctor_app_flutter/client/base_app_client.dart'; import 'package:doctor_app_flutter/client/base_app_client.dart';
import 'package:doctor_app_flutter/core/enum/viewstate.dart';
import 'package:doctor_app_flutter/core/model/imei_details.dart';
import 'package:doctor_app_flutter/core/model/insert_imei_model.dart';
import 'package:doctor_app_flutter/core/service/auth_service.dart';
import 'package:doctor_app_flutter/core/viewModel/base_view_model.dart';
import 'package:doctor_app_flutter/locator.dart';
import 'package:doctor_app_flutter/models/auth/activation_Code_req_model.dart'; import 'package:doctor_app_flutter/models/auth/activation_Code_req_model.dart';
import 'package:doctor_app_flutter/models/auth/check_activation_code_request_model.dart'; import 'package:doctor_app_flutter/models/auth/check_activation_code_request_model.dart';
import 'package:doctor_app_flutter/models/doctor/clinic_model.dart'; import 'package:doctor_app_flutter/models/doctor/clinic_model.dart';
@ -12,8 +18,9 @@ import '../../models/doctor/user_model.dart';
DrAppSharedPreferances sharedPref = new DrAppSharedPreferances(); DrAppSharedPreferances sharedPref = new DrAppSharedPreferances();
enum APP_STATUS { LOADING, UNAUTHENTICATED, AUTHENTICATED } enum APP_STATUS { LOADING, UNAUTHENTICATED, AUTHENTICATED }
class AuthViewModel with ChangeNotifier { class AuthViewModel extends BaseViewModel {
List<ClinicModel> doctorsClinicList = []; List<ClinicModel> doctorsClinicList = [];
String selectedClinicName; String selectedClinicName;
bool isLogin = false; bool isLogin = false;
bool isLoading = true; bool isLoading = true;
@ -71,35 +78,29 @@ class AuthViewModel with ChangeNotifier {
} }
} }
Future<dynamic> insertDeviceImei(imei) async { Future insertDeviceImei(request) async {
try { var loggedIn = await sharedPref.getObj(LOGGED_IN_USER);
dynamic localRes;
await baseAppClient.post(INSERT_DEVICE_IMEI, request['IMEI'] = DEVICE_TOKEN;
onSuccess: (dynamic response, int statusCode) { request['LogInTypeID'] = await sharedPref.getInt(OTP_TYPE);
localRes = response; request['BioMetricEnabled'] = true;
}, onFailure: (String error, int statusCode) { request['MobileNo'] = loggedIn['MobileNumber'];
throw error; InsertIMEIDetailsModel nRequest = InsertIMEIDetailsModel.fromJson(request);
}, body: imei); nRequest.genderDescription = request['Gender_Description'];
return Future.value(localRes); nRequest.genderDescriptionN = request['Gender_DescriptionN'];
} catch (error) { nRequest.genderDescriptionN = request['Gender_DescriptionN'];
print(error); nRequest.titleDescription = request['Title_Description'];
throw error; nRequest.titleDescriptionN = request['Title_DescriptionN'];
} nRequest.projectID = await sharedPref.getInt(PROJECT_ID);
}
Future<dynamic> selectDeviceImei(imei) async {
try { try {
dynamic localRes; var localRes;
await baseAppClient.post(SELECT_DEVICE_IMEI, await baseAppClient.post(INSERT_DEVICE_IMEI,
onSuccess: (dynamic response, int statusCode) { onSuccess: (dynamic response, int statusCode) {
localRes = response; localRes = response;
}, onFailure: (String error, int statusCode) { }, onFailure: (String error, int statusCode) {}, body: nRequest.toJson());
throw error;
}, body: imei);
return Future.value(localRes); return Future.value(localRes);
} catch (error) { } catch (error) {
print(error);
throw error; throw error;
} }
} }
@ -120,7 +121,8 @@ class AuthViewModel with ChangeNotifier {
} }
} }
Future sendActivationCodeForDoctorApp(ActivationCodeModel activationCodeModel) async { Future sendActivationCodeForDoctorApp(
ActivationCodeModel activationCodeModel) async {
try { try {
var localRes; var localRes;
await baseAppClient.post(SEND_ACTIVATION_CODE_FOR_DOCTOR_APP, await baseAppClient.post(SEND_ACTIVATION_CODE_FOR_DOCTOR_APP,
@ -158,8 +160,8 @@ class AuthViewModel with ChangeNotifier {
} }
} }
Future<dynamic> checkActivationCodeForDoctorApp(
Future<dynamic> checkActivationCodeForDoctorApp(CheckActivationCodeRequestModel checkActivationCodeRequestModel) async { CheckActivationCodeRequestModel checkActivationCodeRequestModel) async {
try { try {
dynamic localRes; dynamic localRes;
await baseAppClient.post(CHECK_ACTIVATION_CODE_FOR_DOCTOR_APP, await baseAppClient.post(CHECK_ACTIVATION_CODE_FOR_DOCTOR_APP,

@ -0,0 +1,21 @@
import 'package:doctor_app_flutter/client/base_app_client.dart';
import 'package:doctor_app_flutter/core/enum/viewstate.dart';
import 'package:doctor_app_flutter/core/model/imei_details.dart';
import 'package:doctor_app_flutter/core/service/auth_service.dart';
import 'package:doctor_app_flutter/core/viewModel/base_view_model.dart';
import 'package:doctor_app_flutter/locator.dart';
class IMEIViewModel extends BaseViewModel {
AuthService _authService = locator<AuthService>();
List<GetIMEIDetailsModel> get imeiDetails => _authService.dashboardItemsList;
Future selectDeviceImei(imei) async {
setState(ViewState.Busy);
await _authService.selectDeviceImei(imei);
if (_authService.hasError) {
error = _authService.error;
setState(ViewState.Error);
} else
setState(ViewState.Idle);
}
}

@ -24,6 +24,7 @@ class ProjectViewModel with ChangeNotifier {
List<ClinicModel> doctorClinicsList = []; List<ClinicModel> doctorClinicsList = [];
bool isLoading = false; bool isLoading = false;
bool isError = false; bool isError = false;
bool isLogin = false;
String error = ''; String error = '';
BaseAppClient baseAppClient = BaseAppClient(); BaseAppClient baseAppClient = BaseAppClient();
@ -56,7 +57,9 @@ class ProjectViewModel with ChangeNotifier {
currentLanguage = await sharedPref.getString(APP_Language); currentLanguage = await sharedPref.getString(APP_Language);
_appLocale = Locale(currentLanguage ?? 'en'); _appLocale = Locale(currentLanguage ?? 'en');
_isArabic = currentLanguage != null _isArabic = currentLanguage != null
? currentLanguage == 'ar' ? true : false ? currentLanguage == 'ar'
? true
: false
: false; : false;
notifyListeners(); notifyListeners();
} }

@ -1,10 +1,13 @@
import 'package:doctor_app_flutter/core/service/auth_service.dart';
import 'package:doctor_app_flutter/core/service/dasboard_service.dart'; import 'package:doctor_app_flutter/core/service/dasboard_service.dart';
import 'package:doctor_app_flutter/core/service/medical_file_service.dart'; import 'package:doctor_app_flutter/core/service/medical_file_service.dart';
import 'package:doctor_app_flutter/core/service/patient_service.dart'; import 'package:doctor_app_flutter/core/service/patient_service.dart';
import 'package:doctor_app_flutter/core/service/prescription_service.dart'; import 'package:doctor_app_flutter/core/service/prescription_service.dart';
import 'package:doctor_app_flutter/core/service/procedure_service.dart'; import 'package:doctor_app_flutter/core/service/procedure_service.dart';
import 'package:doctor_app_flutter/core/service/sickleave_service.dart'; import 'package:doctor_app_flutter/core/service/sickleave_service.dart';
import 'package:doctor_app_flutter/core/viewModel/auth_view_model.dart';
import 'package:doctor_app_flutter/core/viewModel/dashboard_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/dashboard_view_model.dart';
import 'package:doctor_app_flutter/core/viewModel/imei_view_model.dart';
import 'package:doctor_app_flutter/core/viewModel/medical_file_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/medical_file_view_model.dart';
import 'package:doctor_app_flutter/core/viewModel/patient_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/patient_view_model.dart';
import 'package:doctor_app_flutter/core/viewModel/prescription_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/prescription_view_model.dart';
@ -54,9 +57,11 @@ void setupLocator() {
locator.registerLazySingleton(() => MedicalFileService()); locator.registerLazySingleton(() => MedicalFileService());
locator.registerLazySingleton(() => AdmissionRequestService()); locator.registerLazySingleton(() => AdmissionRequestService());
locator.registerLazySingleton(() => UcafService()); locator.registerLazySingleton(() => UcafService());
locator.registerLazySingleton(() => AuthService());
/// View Model /// View Model
locator.registerFactory(() => DoctorReplayViewModel()); locator.registerFactory(() => DoctorReplayViewModel());
locator.registerFactory(() => IMEIViewModel());
locator.registerFactory(() => ScheduleViewModel()); locator.registerFactory(() => ScheduleViewModel());
locator.registerFactory(() => ReferralPatientViewModel()); locator.registerFactory(() => ReferralPatientViewModel());
locator.registerFactory(() => ReferredPatientViewModel()); locator.registerFactory(() => ReferredPatientViewModel());

@ -41,7 +41,7 @@ class MyApp extends StatelessWidget {
), ),
], ],
child: Consumer<ProjectViewModel>( child: Consumer<ProjectViewModel>(
builder: (context,projectProvider,child) => MaterialApp( builder: (context, projectProvider, child) => MaterialApp(
showSemanticsDebugger: false, showSemanticsDebugger: false,
title: 'Flutter Demo', title: 'Flutter Demo',
locale: projectProvider.appLocal, locale: projectProvider.appLocal,
@ -60,13 +60,12 @@ class MyApp extends StatelessWidget {
buttonColor: HexColor('#B8382C'), buttonColor: HexColor('#B8382C'),
fontFamily: 'WorkSans', fontFamily: 'WorkSans',
dividerColor: Colors.grey[350], dividerColor: Colors.grey[350],
backgroundColor: Color.fromRGBO(255,255,255, 1), backgroundColor: Color.fromRGBO(255, 255, 255, 1),
), ),
initialRoute: INIT_ROUTE, initialRoute: INIT_ROUTE,
routes: routes, routes: routes,
debugShowCheckedModeBanner: false, debugShowCheckedModeBanner: false,
) )),
),
); );
}); });
}, },

@ -8,7 +8,7 @@ class ActivationCodeModel {
String password; String password;
int facilityId; int facilityId;
String generalid; String generalid;
String otpSendType;
ActivationCodeModel( ActivationCodeModel(
{this.mobileNumber, {this.mobileNumber,
this.zipCode, this.zipCode,
@ -18,6 +18,7 @@ class ActivationCodeModel {
this.memberID, this.memberID,
this.password, this.password,
this.facilityId, this.facilityId,
this.otpSendType,
this.generalid}); this.generalid});
ActivationCodeModel.fromJson(Map<String, dynamic> json) { ActivationCodeModel.fromJson(Map<String, dynamic> json) {
@ -29,6 +30,7 @@ class ActivationCodeModel {
memberID = json['MemberID']; memberID = json['MemberID'];
password = json['Password']; password = json['Password'];
facilityId = json['facilityId']; facilityId = json['facilityId'];
otpSendType = json['OTP_SendType'];
generalid = json['generalid']; generalid = json['generalid'];
} }
@ -42,6 +44,7 @@ class ActivationCodeModel {
data['MemberID'] = this.memberID; data['MemberID'] = this.memberID;
data['Password'] = this.password; data['Password'] = this.password;
data['facilityId'] = this.facilityId; data['facilityId'] = this.facilityId;
data['OTP_SendType'] = otpSendType;
data['generalid'] = this.generalid; data['generalid'] = this.generalid;
return data; return data;
} }

@ -12,7 +12,7 @@ class CheckActivationCodeRequestModel {
String activationCode; String activationCode;
String vidaAuthTokenID; String vidaAuthTokenID;
String vidaRefreshTokenID; String vidaRefreshTokenID;
int oTPSendType;
CheckActivationCodeRequestModel( CheckActivationCodeRequestModel(
{this.mobileNumber, {this.mobileNumber,
this.zipCode, this.zipCode,
@ -26,7 +26,8 @@ class CheckActivationCodeRequestModel {
this.logInTokenID, this.logInTokenID,
this.activationCode, this.activationCode,
this.vidaAuthTokenID, this.vidaAuthTokenID,
this.vidaRefreshTokenID}); this.vidaRefreshTokenID,
this.oTPSendType});
CheckActivationCodeRequestModel.fromJson(Map<String, dynamic> json) { CheckActivationCodeRequestModel.fromJson(Map<String, dynamic> json) {
mobileNumber = json['MobileNumber']; mobileNumber = json['MobileNumber'];
@ -42,6 +43,7 @@ class CheckActivationCodeRequestModel {
activationCode = json['activationCode']; activationCode = json['activationCode'];
vidaAuthTokenID = json['VidaAuthTokenID']; vidaAuthTokenID = json['VidaAuthTokenID'];
vidaRefreshTokenID = json['VidaRefreshTokenID']; vidaRefreshTokenID = json['VidaRefreshTokenID'];
oTPSendType = json['OTP_SendType'];
} }
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
@ -59,6 +61,7 @@ class CheckActivationCodeRequestModel {
data['activationCode'] = this.activationCode; data['activationCode'] = this.activationCode;
data['VidaAuthTokenID'] = this.vidaAuthTokenID; data['VidaAuthTokenID'] = this.vidaAuthTokenID;
data['VidaRefreshTokenID'] = this.vidaRefreshTokenID; data['VidaRefreshTokenID'] = this.vidaRefreshTokenID;
data['OTP_SendType'] = this.oTPSendType;
return data; return data;
} }
} }

@ -1,7 +1,17 @@
import 'dart:async'; import 'dart:async';
import 'dart:io';
import 'package:doctor_app_flutter/config/config.dart'; import 'package:doctor_app_flutter/config/config.dart';
import 'package:doctor_app_flutter/config/shared_pref_kay.dart';
import 'package:doctor_app_flutter/core/service/auth_service.dart';
import 'package:doctor_app_flutter/core/viewModel/auth_view_model.dart';
import 'package:doctor_app_flutter/core/viewModel/imei_view_model.dart';
import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart';
import 'package:doctor_app_flutter/screens/auth/verification_methods_screen.dart';
import 'package:doctor_app_flutter/screens/base/base_view.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
import '../../lookups/auth_lookup.dart'; import '../../lookups/auth_lookup.dart';
@ -23,21 +33,48 @@ class _LoginsreenState extends State<Loginsreen> {
Future<SharedPreferences> _prefs = SharedPreferences.getInstance(); Future<SharedPreferences> _prefs = SharedPreferences.getInstance();
String platformImei; String platformImei;
Future<String> platformImeiFuture; // Future<String> platformImeiFuture;
final FirebaseMessaging _firebaseMessaging = FirebaseMessaging();
bool _isLoading = true;
ProjectViewModel projectViewModel;
AuthService authService = AuthService();
@override
void initState() {
super.initState();
bool _isLoading = false; _firebaseMessaging.setAutoInitEnabled(true);
if (Platform.isIOS) {
_firebaseMessaging.requestNotificationPermissions();
}
_firebaseMessaging.getToken().then((String token) async {
if (DEVICE_TOKEN == "" && projectViewModel.isLogin == false) {
DEVICE_TOKEN = token;
changeLoadingStata(true);
authService.selectDeviceImei(DEVICE_TOKEN).then((value) {
print(authService.dashboardItemsList);
Future<void> getSharedPref() async { if (authService.dashboardItemsList.length > 0) {
sharedPref.getString('platformImei').then((imei) { sharedPref.setObj(
platformImei = imei; LAST_LOGIN_USER, authService.dashboardItemsList[0]);
Navigator.of(context).pushReplacement(MaterialPageRoute(
builder: (BuildContext context) => VerificationMethodsScreen(
password: null,
)));
} else {
changeLoadingStata(false);
}
//changeLoadingStata(false);
}); });
} else {
changeLoadingStata(false);
} }
@override // else if (projectViewModel.isLogin) {
void initState() { // getNotificationCount(token);
super.initState(); // }
platformImeiFuture = _prefs.then((SharedPreferences prefs) { }).catchError((err) {
return (prefs.getString('platformImei')); print(err);
}); });
} }
@ -56,54 +93,46 @@ class _LoginsreenState extends State<Loginsreen> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
getSharedPref(); projectViewModel = Provider.of<ProjectViewModel>(context);
return AppScaffold(
isLoading: _isLoading, return BaseView<IMEIViewModel>(
onModelReady: (model) => {},
builder: (_, model, w) => AppScaffold(
baseViewModel: model,
isShowAppBar: false, isShowAppBar: false,
body: SafeArea( body: SafeArea(
child: ListView(children: <Widget>[ child: (_isLoading == false)
FutureBuilder( ? ListView(children: <Widget>[
future: platformImeiFuture, Container(
builder: (BuildContext context, AsyncSnapshot<String> snapshot) { margin:
switch (snapshot.connectionState) { EdgeInsetsDirectional.fromSTEB(30, 0, 30, 30),
case ConnectionState.waiting:
return DrAppCircularProgressIndeicator();
default:
if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
} else {
return Container(
margin: EdgeInsetsDirectional.fromSTEB(30, 0, 30, 30),
alignment: Alignment.topLeft, alignment: Alignment.topLeft,
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[ children: <Widget>[
(platformImei == null) Column(
? Column(
crossAxisAlignment: crossAxisAlignment:
CrossAxisAlignment.start, CrossAxisAlignment.start,
children: <Widget>[ children: <Widget>[
AuthHeader(loginType.knownUser), AuthHeader(loginType.knownUser),
LoginForm( LoginForm(
changeLoadingStata: changeLoadingStata: changeLoadingStata,
changeLoadingStata,
), ),
], ],
) )
: Column(
crossAxisAlignment: // : Column(
CrossAxisAlignment.start, // crossAxisAlignment:
children: <Widget>[ // CrossAxisAlignment.start,
AuthHeader(loginType.unknownUser), // children: <Widget>[
KnownUserLogin(), // AuthHeader(loginType.unknownUser),
], // KnownUserLogin(),
), // ],
])); // ),
} ]))
} ])
}), : Center(child: CircularProgressIndicator()),
]),
), ),
); ));
} }
} }

@ -1,3 +1,4 @@
import 'package:doctor_app_flutter/config/config.dart';
import 'package:doctor_app_flutter/config/shared_pref_kay.dart'; import 'package:doctor_app_flutter/config/shared_pref_kay.dart';
import 'package:doctor_app_flutter/config/size_config.dart'; import 'package:doctor_app_flutter/config/size_config.dart';
import 'package:doctor_app_flutter/core/viewModel/dashboard_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/dashboard_view_model.dart';
@ -58,6 +59,14 @@ class _DashboardScreenState extends State<DashboardScreen> {
if (_isInit) { if (_isInit) {
projectsProvider = Provider.of<ProjectViewModel>(context); projectsProvider = Provider.of<ProjectViewModel>(context);
projectsProvider.getDoctorClinicsList(); projectsProvider.getDoctorClinicsList();
if (DEVICE_TOKEN != '') {
var request = await sharedPref.getObj(DOCTOR_PROFILE);
authProvider.insertDeviceImei(request).then((value) {
print(value['ReturnValue']);
changeIsLoading(false);
});
}
} }
_isInit = false; _isInit = false;
} }

@ -792,7 +792,7 @@ class _RescheduleLeaveScreen extends State<RescheduleLeaveScreen> {
"doctorId": this.profile['DoctorID'], "doctorId": this.profile['DoctorID'],
"dateTimeFrom": fromDate, "dateTimeFrom": fromDate,
"dateTimeTo": toDate, "dateTimeTo": toDate,
"date": df.format(DateTime.now()), "date": offTime == '1' ? fromDate : df.format(DateTime.now()),
"reasonId": reason == null ? model.allOffTime[0]['code'] : reason, "reasonId": reason == null ? model.allOffTime[0]['code'] : reason,
"coveringDoctorId": "coveringDoctorId":
doctorID == null ? model.coveringDoctors[0]['doctorID'] : doctorID, doctorID == null ? model.coveringDoctors[0]['doctorID'] : doctorID,
@ -846,7 +846,7 @@ class _RescheduleLeaveScreen extends State<RescheduleLeaveScreen> {
"doctorId": this.profile['DoctorID'], "doctorId": this.profile['DoctorID'],
"dateTimeFrom": fromDate, "dateTimeFrom": fromDate,
"dateTimeTo": toDate, "dateTimeTo": toDate,
"date": df.format(DateTime.now()), "date": offTime == '1' ? fromDate : df.format(DateTime.now()),
"reasonId": reason == null ? model.allOffTime[0]['code'] : reason, "reasonId": reason == null ? model.allOffTime[0]['code'] : reason,
"coveringDoctorId": "coveringDoctorId":
doctorID == null ? model.coveringDoctors[0]['doctorID'] : doctorID, doctorID == null ? model.coveringDoctors[0]['doctorID'] : doctorID,

@ -346,10 +346,12 @@ class Helpers {
} }
logout() async { logout() async {
DEVICE_TOKEN = "";
String lang = await sharedPref.getString(APP_Language); String lang = await sharedPref.getString(APP_Language);
await clearSharedPref(); await clearSharedPref();
sharedPref.setString(APP_Language, lang); sharedPref.setString(APP_Language, lang);
Navigator.of(AppGlobal.CONTEX).pushReplacementNamed(LOGIN); Navigator.of(AppGlobal.CONTEX).pushReplacementNamed(LOGIN);
// TODO Fix it // TODO Fix it
// Navigator.of(AppGlobal.CONTEX).popUntil((ModalRoute.withName(LOGIN))); // Navigator.of(AppGlobal.CONTEX).popUntil((ModalRoute.withName(LOGIN)));
} }
@ -394,7 +396,8 @@ class Helpers {
} }
static BoxDecoration containerBorderDecoration( static BoxDecoration containerBorderDecoration(
Color containerColor, Color borderColor, {double borderWidth = -1}) { Color containerColor, Color borderColor,
{double borderWidth = -1}) {
return BoxDecoration( return BoxDecoration(
color: containerColor, color: containerColor,
shape: BoxShape.rectangle, shape: BoxShape.rectangle,

@ -544,15 +544,60 @@ class TranslationBase {
localizedValues['referralEmptyMsg'][locale.languageCode]; localizedValues['referralEmptyMsg'][locale.languageCode];
String get referralSuccessMsg => String get referralSuccessMsg =>
localizedValues['referralSuccessMsg'][locale.languageCode]; localizedValues['referralSuccessMsg'][locale.languageCode];
String get diagnoseType => localizedValues['diagnoseType'][locale.languageCode]; String get diagnoseType =>
localizedValues['diagnoseType'][locale.languageCode];
String get condition => localizedValues['condition'][locale.languageCode]; String get condition => localizedValues['condition'][locale.languageCode];
String get id => localizedValues['id'][locale.languageCode]; String get id => localizedValues['id'][locale.languageCode];
String get quantity => localizedValues['quantity'][locale.languageCode]; String get quantity => localizedValues['quantity'][locale.languageCode];
String get codeNo => localizedValues['codeNo'][locale.languageCode]; String get codeNo => localizedValues['codeNo'][locale.languageCode];
String get covered => localizedValues['covered'][locale.languageCode]; String get covered => localizedValues['covered'][locale.languageCode];
String get approvalRequired => localizedValues['approvalRequired'][locale.languageCode]; String get approvalRequired =>
String get uncoveredByDoctor => localizedValues['uncoveredByDoctor'][locale.languageCode]; localizedValues['approvalRequired'][locale.languageCode];
String get chiefComplaintEmptyMsg => localizedValues['chiefComplaintEmptyMsg'][locale.languageCode]; String get uncoveredByDoctor =>
localizedValues['uncoveredByDoctor'][locale.languageCode];
String get chiefComplaintEmptyMsg =>
localizedValues['chiefComplaintEmptyMsg'][locale.languageCode];
String get moreVerification =>
localizedValues['more-verify'][locale.languageCode];
String get welcomeBack =>
localizedValues['welcome-back'][locale.languageCode];
String get accountInfo =>
localizedValues['account-info'][locale.languageCode];
String get useAnotherAccount =>
localizedValues['another-acc'][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];
String get verifyFingerprint2 =>
localizedValues['verify-fingerprint'][locale.languageCode];
String get verificationMessage =>
localizedValues['verification_message'][locale.languageCode];
String get validationMessage =>
localizedValues['validation_message'][locale.languageCode];
} }
class TranslationBaseDelegate extends LocalizationsDelegate<TranslationBase> { class TranslationBaseDelegate extends LocalizationsDelegate<TranslationBase> {

@ -70,8 +70,8 @@ class _KnownUserLoginState extends State<KnownUserLogin> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
AuthViewModel authProv = Provider.of<AuthViewModel>(context); AuthViewModel authProv = Provider.of<AuthViewModel>(context);
var imeiModel = {'IMEI': _platformImei}; // var imeiModel = {'IMEI': _platformImei};
_loginTypeFuture = authProv.selectDeviceImei(imeiModel); // _loginTypeFuture = authProv.selectDeviceImei(imeiModel);
return FutureBuilder( return FutureBuilder(
future: Future.wait([_loggedUserFuture, _loginTypeFuture]), future: Future.wait([_loggedUserFuture, _loginTypeFuture]),
builder: (BuildContext context, AsyncSnapshot snapshot) { builder: (BuildContext context, AsyncSnapshot snapshot) {

@ -224,26 +224,29 @@ class _LoginFormState extends State<LoginForm> {
} }
login(context, AuthViewModel authProv, Function changeLoadingStata) { login(context, AuthViewModel authProv, Function changeLoadingStata) {
FocusScopeNode currentFocus = FocusScope.of(context); showLoading();
changeLoadingStata(true);
if (loginFormKey.currentState.validate()) { if (loginFormKey.currentState.validate()) {
loginFormKey.currentState.save(); loginFormKey.currentState.save();
sharedPref.setInt(PROJECT_ID, userInfo.projectID); sharedPref.setInt(PROJECT_ID, userInfo.projectID);
authProv.login(userInfo).then((res) { authProv.login(userInfo).then((res) {
changeLoadingStata(false); //changeLoadingStata(false);
hideLoading();
if (res['MessageStatus'] == 1) { if (res['MessageStatus'] == 1) {
// insertDeviceImei(res, authProv); // insertDeviceImei(res, authProv);
saveObjToString(LOGGED_IN_USER, res); saveObjToString(LOGGED_IN_USER, res);
sharedPref.remove(LAST_LOGIN_USER);
sharedPref.setString(TOKEN, res['LogInTokenID']); sharedPref.setString(TOKEN, res['LogInTokenID']);
print("token" + res['LogInTokenID']); print("token" + res['LogInTokenID']);
Navigator.of(context).pushReplacement(MaterialPageRoute(builder: (BuildContext context) => VerificationMethodsScreen(password: userInfo.password,))); Navigator.of(context).pushReplacement(MaterialPageRoute(
builder: (BuildContext context) => VerificationMethodsScreen(
password: userInfo.password,
)));
} else { } else {
// handel error // handel error
helpers.showErrorToast(res['ErrorEndUserMessage']); helpers.showErrorToast(res['ErrorEndUserMessage']);
} }
}).catchError((err) { }).catchError((err) {
print('$err'); hideLoading();
changeLoadingStata(false); changeLoadingStata(false);
helpers.showErrorToast(err); helpers.showErrorToast(err);
}); });
@ -273,7 +276,11 @@ class _LoginFormState extends State<LoginForm> {
if (res['MessageStatus'] == 1) { if (res['MessageStatus'] == 1) {
setSharedPref('platformImei', _platformImei); setSharedPref('platformImei', _platformImei);
saveObjToString(LOGGED_IN_USER, preRes); saveObjToString(LOGGED_IN_USER, preRes);
Navigator.of(context).pushReplacement(MaterialPageRoute(builder: (BuildContext context) => VerificationMethodsScreen(password: userInfo.password,)));
Navigator.of(context).pushReplacement(MaterialPageRoute(
builder: (BuildContext context) => VerificationMethodsScreen(
password: userInfo.password,
)));
// save imei on shared preferance // save imei on shared preferance
} else { } else {
@ -350,4 +357,18 @@ class _LoginFormState extends State<LoginForm> {
primaryFocus.unfocus(); primaryFocus.unfocus();
} }
showLoading() {
showDialog(
context: context,
builder: (BuildContext context) {
return Center(
child: CircularProgressIndicator(),
);
});
}
hideLoading() {
Navigator.pop(context);
}
} }

@ -1,11 +1,22 @@
import 'dart:io' show Platform; import 'dart:io' show Platform;
import 'package:doctor_app_flutter/config/shared_pref_kay.dart'; import 'package:doctor_app_flutter/config/shared_pref_kay.dart';
import 'package:doctor_app_flutter/core/model/imei_details.dart';
import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart';
import 'package:doctor_app_flutter/models/auth/activation_Code_req_model.dart'; import 'package:doctor_app_flutter/models/auth/activation_Code_req_model.dart';
import 'package:doctor_app_flutter/screens/auth/verification_methods_screen.dart'; import 'package:doctor_app_flutter/models/auth/check_activation_code_request_model.dart';
import 'package:doctor_app_flutter/models/doctor/clinic_model.dart';
import 'package:doctor_app_flutter/models/doctor/doctor_profile_model.dart';
import 'package:doctor_app_flutter/models/doctor/profile_req_Model.dart';
import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart';
import 'package:doctor_app_flutter/widgets/otp/sms-popup.dart';
import 'package:doctor_app_flutter/widgets/shared/app_button.dart';
import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart';
import 'package:doctor_app_flutter/widgets/shared/rounded_container_widget.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:hexcolor/hexcolor.dart'; import 'package:flutter/services.dart';
import 'package:intl/intl.dart';
import 'package:local_auth/local_auth.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import '../../config/size_config.dart'; import '../../config/size_config.dart';
@ -40,6 +51,17 @@ class _VerificationMethodsState extends State<VerificationMethods> {
Future _loggedUserFuture; Future _loggedUserFuture;
var _loggedUser; var _loggedUser;
var verificationMethod; var verificationMethod;
GetIMEIDetailsModel user;
final LocalAuthentication auth = LocalAuthentication();
var _availableBiometrics;
ProjectViewModel projectsProvider;
var isMoreOption = false;
var onlySMSBox = false;
static BuildContext _context;
var loginTokenID;
bool authenticated;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
@ -50,6 +72,13 @@ class _VerificationMethodsState extends State<VerificationMethods> {
sharedPref.getObj(LOGGED_IN_USER).then((userInfo) { sharedPref.getObj(LOGGED_IN_USER).then((userInfo) {
_loggedUser = userInfo; _loggedUser = userInfo;
}); });
sharedPref.getObj(LAST_LOGIN_USER).then((lastLogin) {
if (lastLogin != null) {
user = GetIMEIDetailsModel.fromJson(lastLogin);
}
});
print(user);
} }
@override @override
@ -63,6 +92,7 @@ class _VerificationMethodsState extends State<VerificationMethods> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
AuthViewModel authProv = Provider.of<AuthViewModel>(context); AuthViewModel authProv = Provider.of<AuthViewModel>(context);
projectsProvider = Provider.of<ProjectViewModel>(context);
return FutureBuilder( return FutureBuilder(
future: Future.wait([_loggedUserFuture]), future: Future.wait([_loggedUserFuture]),
builder: (BuildContext context, AsyncSnapshot snapshot) { builder: (BuildContext context, AsyncSnapshot snapshot) {
@ -75,186 +105,212 @@ class _VerificationMethodsState extends State<VerificationMethods> {
return Text('Error: ${snapshot.error}'); return Text('Error: ${snapshot.error}');
} else { } else {
return Container( return Container(
width: SizeConfig.realScreenWidth * 0.80, width: SizeConfig.realScreenWidth,
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[ children: <Widget>[
Text(
hideSilentMethods()
? TranslationBase.of(context).firstStep
: TranslationBase.of(context).pleaseChoose,
style: TextStyle(
fontSize: 3.5 * SizeConfig.textMultiplier,
),
),
SizedBox(
height: 20,
),
Container( Container(
height: SizeConfig.realScreenHeight * 0.6, height: SizeConfig.realScreenHeight * 0.6,
child: CustomScrollView( child: Column(
primary: false, children: <Widget>[
slivers: <Widget>[ user != null && isMoreOption == false
SliverPadding( ? Column(
padding: const EdgeInsets.all(0), mainAxisAlignment:
sliver: SliverGrid.count( MainAxisAlignment.spaceEvenly,
// childAspectRatio: 0.7, crossAxisAlignment:
crossAxisSpacing: 0, CrossAxisAlignment.start,
mainAxisSpacing: 5,
crossAxisCount: 2,
children: <Widget>[ children: <Widget>[
Visibility( AppText(
visible: hideSilentMethods() ? false : true, TranslationBase.of(context)
child: buildFingerprintMethod( .welcomeBack +
context, authProv), ' ' +
replacement: user.doctorName,
buildWhatsAppMethod(context, authProv), fontSize:
SizeConfig.textMultiplier * 3.5,
), ),
Visibility( SizedBox(
visible: hideSilentMethods() ? false : true, height: 20,
child: buildFaceIDMethod(context, authProv),
replacement:
buildSMSMethod(context, authProv),
), ),
Visibility( AppText(
visible: TranslationBase.of(context)
hideSilentMethods() ? false : true, .accountInfo,
child: buildWhatsAppMethod( fontSize:
context, authProv)), SizeConfig.textMultiplier * 2.5,
Visibility(
visible: hideSilentMethods() ? false : true,
child: buildSMSMethod(context, authProv),
), ),
], SizedBox(
height: 20,
), ),
Card(
color: Colors.grey[300],
child: Row(
children: <Widget>[
Flexible(
child: ListTile(
title: Text(
TranslationBase.of(context)
.lastLoginAt,
textAlign: TextAlign.center,
overflow:
TextOverflow.ellipsis,
), ),
subtitle: Text(
// user. != null
// ? formatDate(Helpers
// .convertStringToDate(
// user
// .))
// : user !=
// null
// ? formatDate(Helpers
// .convertStringToDate(user
// .createdOn))
//:
'--',
overflow:
TextOverflow.ellipsis,
textAlign:
TextAlign.center),
)),
Flexible(
child: ListTile(
title: Text(
TranslationBase.of(
context)
.lastLoginWith,
overflow:
TextOverflow.ellipsis,
textAlign:
TextAlign.center),
subtitle: Text(
getType(user.logInTypeID,
context),
overflow:
TextOverflow.ellipsis,
textAlign:
TextAlign.center),
))
], ],
), )),
// height: 500,
),
SizedBox(
// height: 20,
)
], ],
)
: Column(
mainAxisAlignment:
MainAxisAlignment.spaceEvenly,
crossAxisAlignment:
CrossAxisAlignment.start,
children: <Widget>[
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.start,
), ),
); ]),
} user != null && isMoreOption == false
} ? Column(
}); mainAxisAlignment:
} MainAxisAlignment.start,
crossAxisAlignment:
/* CrossAxisAlignment.start,
*@author: Elham Rababah children: <Widget>[
*@Date:28/5/2020 Row(
*@param: BuildContext context, AuthProvider authProv mainAxisAlignment:
*@return: Center widget MainAxisAlignment.center,
*@desc: buildSMSMethod Methods widget children: <Widget>[
*/ Expanded(
Center buildSMSMethod(BuildContext context, AuthViewModel authProv) {
return buildVerificationMethod(
context,
'assets/images/verification_sms_icon.png',
TranslationBase.of(context).sms, () {
sendActivationCodeByOtpNotificationType(1, authProv);
});
}
/*
*@author: Elham Rababah
*@Date:28/5/2020
*@param: BuildContext context, AuthProvider authProv
*@return: Center widget
*@desc: build WhatsApp Methods widget
*/
Center buildWhatsAppMethod(BuildContext context, AuthViewModel authProv) {
return buildVerificationMethod(
context,
'assets/images/verification_whatsapp_icon.png',
TranslationBase.of(context).whatsApp, () {
sendActivationCodeByOtpNotificationType(2, authProv);
});
}
/*
*@author: Elham Rababah
*@Date:28/5/2020
*@param: BuildContext context, AuthProvider authProv
*@return: Center widget
*@desc: build FaceID Methods widget
*/
Center buildFaceIDMethod(BuildContext context, AuthViewModel authProv) {
return buildVerificationMethod(
context,
'assets/images/verification_faceid_icon.png',
TranslationBase.of(context).faceId, () {
sendActivationCodeByOtpNotificationType(3, authProv);
});
}
/*
*@author: Elham Rababah
*@Date:28/5/2020
*@param: BuildContext context, AuthProvider authProv
*@return: Center widget
*@desc: build Fingerprint Methods widget
*/
Center buildFingerprintMethod(BuildContext context, AuthViewModel authProv) {
return buildVerificationMethod(
context,
'assets/images/verification_fingerprint_icon.png',
TranslationBase.of(context).fingerprint, () {
sendActivationCodeByOtpNotificationType(4, authProv);
});
}
/*
*@author: Elham Rababah
*@Date:28/5/2020
*@param: BuildContext context, AuthProvider authProv
*@return: Center widget
*@desc: build Verification Methods widget
*/
Center buildVerificationMethod(context, url, dec, Function fun) {
return Center(
child: InkWell( child: InkWell(
onTap: fun, onTap: () => {
child: Container( authenticateUser(
// height: SizeConfig.heightMultiplier *2, 3,
height: SizeConfig.heightMultiplier * 19, BiometricType
width: SizeConfig.widthMultiplier * 37, .face
.index,
padding: EdgeInsets.all(10), authProv)
decoration: BoxDecoration( },
border: Border.all( child: getButton(
width: 1, user.logInTypeID,
color: HexColor( authProv))),
'#CCCCCC') // <--- border width here Expanded(
child:
getButton(5, authProv))
])
])
: Column(
mainAxisAlignment:
MainAxisAlignment.start,
crossAxisAlignment:
CrossAxisAlignment.start,
children: <Widget>[
onlySMSBox == false
? Row(
mainAxisAlignment:
MainAxisAlignment.center,
children: <Widget>[
Expanded(
child: getButton(
3, authProv)),
Expanded(
child: getButton(
2, authProv))
],
)
: SizedBox(),
Row(
mainAxisAlignment:
MainAxisAlignment.center,
children: <Widget>[
Expanded(
child:
getButton(1, authProv)),
Expanded(
child: getButton(4, authProv))
],
), ),
borderRadius: BorderRadius.all(Radius.circular(10))), ]),
Expanded(
flex: 1,
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[ children: <Widget>[
Container( user != null
margin: EdgeInsetsDirectional.only( ? Row(
top: SizeConfig.heightMultiplier * 0.5), children: <Widget>[
child: Image.asset( Expanded(
url, child: Button(
height: SizeConfig.heightMultiplier * 10, title:
fit: BoxFit.cover, TranslationBase.of(context)
), .useAnotherAccount,
), onTap: () {
SizedBox( Navigator.of(context)
height: 10, .pushNamed(LOGIN);
), },
Text( )),
dec, ],
style: TextStyle(fontSize: SizeConfig.textMultiplier * 2),
) )
: SizedBox(),
], ],
), ),
), )
],
))
],
), ),
); );
} }
}
});
}
bool hideSilentMethods() { bool hideSilentMethods() {
return verificationMethod == 4 || verificationMethod == 3 ? true : false; return verificationMethod == 4 || verificationMethod == 3 ? true : false;
@ -267,25 +323,33 @@ class _VerificationMethodsState extends State<VerificationMethods> {
*@return: *@return:
*@desc: send Activation Code By Otp Notification Type *@desc: send Activation Code By Otp Notification Type
*/ */
sendActivationCodeByOtpNotificationType(oTPSendType, AuthViewModel authProv) async { sendActivationCodeByOtpNotificationType(
oTPSendType, AuthViewModel authProv) async {
// TODO : build enum for verfication method // TODO : build enum for verfication method
if (oTPSendType == 1 || oTPSendType == 2) { if (oTPSendType == 1 || oTPSendType == 2) {
widget.changeLoadingStata(true); widget.changeLoadingStata(true);
int projectID = await sharedPref.getInt(PROJECT_ID); int projectID = await sharedPref.getInt(PROJECT_ID);
ActivationCodeModel activationCodeModel = ActivationCodeModel( ActivationCodeModel activationCodeModel = ActivationCodeModel(
// facilityId: projectID != null ? projectID : 15, //user.projectID,
// generalid: "Cs2020@2016\$2958",
// memberID: _loggedUser != null
// ? _loggedUser['List_MemberInformation'][0]['MemberID']
// : user.doctorID,
// zipCode: _loggedUser != null
// ? _loggedUser['ZipCode']
// : user.outSA == true
// ? '966'
// : '971',
// mobileNumber:
// _loggedUser != null ? _loggedUser['MobileNumber'] : user.mobile,
facilityId: projectID, facilityId: projectID,
generalid: "Cs2020@2016\$2958", generalid: "Cs2020@2016\$2958",
memberID: _loggedUser['List_MemberInformation'][0]['MemberID'], memberID: _loggedUser['List_MemberInformation'][0]['MemberID'],
zipCode: _loggedUser['ZipCode'], zipCode: _loggedUser['ZipCode'],
mobileNumber: _loggedUser['MobileNumber'], mobileNumber: _loggedUser['MobileNumber'],
otpSendType: oTPSendType.toString(),
password: widget.password); password: widget.password);
Map<String, dynamic> model = {
"OTP_SendType": oTPSendType
};
try { try {
authProv authProv
.sendActivationCodeForDoctorApp(activationCodeModel) .sendActivationCodeForDoctorApp(activationCodeModel)
@ -293,38 +357,439 @@ class _VerificationMethodsState extends State<VerificationMethods> {
widget.changeLoadingStata(false); widget.changeLoadingStata(false);
if (res['MessageStatus'] == 1) { if (res['MessageStatus'] == 1) {
print("VerificationCode : "+ res["VerificationCode"]); print("VerificationCode : " + res["VerificationCode"]);
sharedPref.setString(VIDA_AUTH_TOKEN_ID, res["VidaAuthTokenID"]); sharedPref.setString(VIDA_AUTH_TOKEN_ID, res["VidaAuthTokenID"]);
sharedPref.setString(VIDA_REFRESH_TOKEN_ID, res["VidaRefreshTokenID"]); sharedPref.setString(
VIDA_REFRESH_TOKEN_ID, res["VidaRefreshTokenID"]);
sharedPref.setString(LOGIN_TOKEN_ID, res["LogInTokenID"]); sharedPref.setString(LOGIN_TOKEN_ID, res["LogInTokenID"]);
Navigator.of(context).pushReplacementNamed(VERIFY_ACCOUNT, this.startSMSService(oTPSendType, authProv);
arguments: {'model': model});
} else { } else {
print(res['ErrorEndUserMessage']); print(res['ErrorEndUserMessage']);
helpers.showErrorToast(res['ErrorEndUserMessage']); helpers.showErrorToast(res['ErrorEndUserMessage']);
} }
}) }).catchError((err) {
.catchError((err) {
print('$err'); print('$err');
widget.changeLoadingStata(false); widget.changeLoadingStata(false);
helpers.showErrorToast(); helpers.showErrorToast();
}); });
} catch (e) {} } catch (e) {}
} else { } else {
// TODO route to this page with parameters to inicate we should present 2 option // TODO route to this page with parameters to inicate we should present 2 option
if (Platform.isAndroid && oTPSendType == 3) { if (Platform.isAndroid && oTPSendType == 3) {
helpers.showErrorToast('Your device not support this feature'); helpers.showErrorToast('Your device not support this feature');
} else { } else {
Navigator.of(context).push(MaterialPageRoute( // Navigator.of(context).push(MaterialPageRoute(
builder: (BuildContext context) => // builder: (BuildContext context) =>
VerificationMethodsScreen(password: widget.password,))); // VerificationMethodsScreen(password: widget.password,)));
// Navigator.of(context).pushNamed(VERIFICATION_METHODS, // Navigator.of(context).pushNamed(VERIFICATION_METHODS,
// arguments: {'verificationMethod': oTPSendType}); // arguments: {'verificationMethod': oTPSendType});
} }
} }
} }
Widget getButton(flag, authProv) {
switch (flag) {
case 2:
return InkWell(
onTap: () => {authenticateUser(2, true, authProv)},
child: RoundedContainer(
borderColor: Colors.grey,
showBorder: true,
child: Padding(
padding: EdgeInsets.fromLTRB(30, 15, 30, 15),
child: Column(
children: <Widget>[
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,
textAlign: TextAlign.center,
)
],
),
)));
break;
case 1:
return InkWell(
onTap: () => {authenticateUser(1, true, authProv)},
child: RoundedContainer(
borderColor: Colors.grey,
showBorder: true,
child: Padding(
padding: EdgeInsets.fromLTRB(5, 15, 5, 15),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Image.asset(
'assets/images/login/103.png',
height: SizeConfig.imageSizeMultiplier * 13,
width: SizeConfig.imageSizeMultiplier * 16,
),
projectsProvider.isArabic
? SizedBox(
height: 20,
)
: SizedBox(
height: 20,
),
AppText(
TranslationBase.of(context).verifySMS,
fontSize: projectsProvider.isArabic
? SizeConfig.textMultiplier * 1.8
: SizeConfig.textMultiplier * 2,
textAlign: TextAlign.center,
)
],
),
)));
break;
case 3:
return InkWell(
onTap: () => {
authenticateUser(3, BiometricType.fingerprint.index, authProv)
},
child: RoundedContainer(
backgroundColor: BiometricType.fingerprint.index == 1
? Colors.white
: Colors.white.withOpacity(.7),
borderColor: Colors.grey,
showBorder: true,
child: Padding(
padding: EdgeInsets.fromLTRB(5, 15, 5, 15),
child: Column(
children: <Widget>[
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,
textAlign: TextAlign.center,
)
],
),
)));
break;
case 4:
return InkWell(
onTap: () =>
{authenticateUser(4, BiometricType.face.index, authProv)},
child: RoundedContainer(
backgroundColor: checkIfBiometricAvailable(BiometricType.face)
? Colors.white
: Colors.white.withOpacity(.7),
borderColor: Colors.grey,
showBorder: true,
child: Padding(
padding: EdgeInsets.fromLTRB(5, 15, 5, 15),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
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,
textAlign: TextAlign.center,
)
],
),
)));
break;
default:
return InkWell(
onTap: () => {
setState(() {
isMoreOption = true;
})
},
child: RoundedContainer(
backgroundColor: BiometricType.fingerprint.index == 1
? Colors.white
: Colors.white.withOpacity(.7),
borderColor: Colors.grey,
showBorder: true,
child: Padding(
padding: EdgeInsets.fromLTRB(5, 0, 5, 5),
child: Column(
children: <Widget>[
Image.asset(
'assets/images/login/more_icon.png',
height: SizeConfig.imageSizeMultiplier * 13,
width: SizeConfig.imageSizeMultiplier * 16,
),
projectsProvider.isArabic
? SizedBox(
height: 15,
)
: SizedBox(
height: 10,
),
AppText(
TranslationBase.of(context).moreVerification,
fontSize: SizeConfig.textMultiplier * 2,
textAlign: TextAlign.center,
)
],
),
)));
}
}
getType(type, context) {
switch (type) {
case 1:
return TranslationBase.of(context).verifySMS;
break;
case 3:
return TranslationBase.of(context).verifyFingerprint;
break;
case 4:
return TranslationBase.of(context).verifyFaceID;
break;
case 2:
return TranslationBase.of(context).verifyWhatsApp;
break;
default:
return TranslationBase.of(context).verifySMS;
break;
}
}
bool checkIfBiometricAvailable(BiometricType biometricType) {
bool isAvailable = false;
if (_availableBiometrics != null) {
for (var i = 0; i < _availableBiometrics.length; i++) {
if (biometricType == _availableBiometrics[i]) isAvailable = true;
}
}
return isAvailable;
}
formatDate(date) {
return DateFormat('MMM dd, yyy, kk:mm').format(date);
}
authenticateUser(type, isActive, authProv) {
//GifLoaderDialogUtils.showMyDialog(context);
// if (type == 2 || type == 3) {
// fingrePrintBefore = type;
// }
//this.selectedOption = fingrePrintBefore != null ? fingrePrintBefore : type;
switch (type) {
case 1:
this.loginWithSMS(1, isActive, authProv);
break;
case 2:
this.loginWithSMS(2, isActive, authProv);
break;
case 3:
this.loginWithFingurePrintFace(3, isActive, authProv);
break;
case 4:
this.loginWithFingurePrintFace(4, isActive, authProv);
break;
default:
break;
}
// sharedPref.setInt(LAST_LOGIN,
// this.selectedOption); //this.cs.sharedService.setStorage(this.selectedOption, AuthenticationService.LAST_LOGIN);
}
loginWithSMS(type, isActive, authProv) {
this.sendActivationCode(type, authProv);
// //if (!el.disabled) {
// if (this.user != null) {
// this.checkUserAuthentication(type);
// } else {
// // if (this.loginTokenID != null) {
// this.sendActivationCode(type, authProv);
// // } else {
// //this.checkUserAuthentication(type);
// // }
// }
}
// checkUserAuthentication(type) {
// // showLoader(true);
// // var req = getCommonRequest(type: type);
// // req.logInTokenID = "";
// // var request = CheckPatientAuthenticationReq.fromJson(req.toJson());
// // sharedPref.setObject(REGISTER_DATA_FOR_REGISTER, request);
// // authService
// // .checkPatientAuthentication(request)
// // .then((value) => {
// // GifLoaderDialogUtils.hideDialog(context),
// // if (value['isSMSSent'])
// // {
// // sharedPref.setString(LOGIN_TOKEN_ID, value['LogInTokenID']),
// // this.loginTokenID = value['LogInTokenID'],
// // sharedPref.setObject(REGISTER_DATA_FOR_LOGIIN, request),
// // // Future.delayed(Duration(seconds: 1), () {
// // this.sendActivationCode(type)
// // // })
// // }
// // else
// // {
// // if (value['IsAuthenticated']) {this.checkActivationCode()}
// // }
// // })
// // .catchError((err) {
// // print(err);
// // GifLoaderDialogUtils.hideDialog(context);
// // });
// }
Future<void> _getAvailableBiometrics() async {
var availableBiometrics;
try {
availableBiometrics = await auth.getAvailableBiometrics();
} on PlatformException catch (e) {
print(e);
}
if (!mounted) return;
setState(() {
_availableBiometrics = availableBiometrics;
});
}
sendActivationCode(type, authProv) async {
sendActivationCodeByOtpNotificationType(type, authProv);
}
startSMSService(type, authProv) {
sharedPref.setInt(OTP_TYPE, type);
new SMSOTP(
context,
type,
_loggedUser['MobileNumber'],
(value) {
showDialog(
context: context,
builder: (BuildContext context) {
return Center(
child: CircularProgressIndicator(),
);
});
this.checkActivationCode(authProv, value: value);
},
() => {
Navigator.pop(context),
print('Faild..'),
},
).displayDialog(context);
}
loginWithFingurePrintFace(type, isActive, authProv) async {
if (isActive == 1) {
// this.startBiometricLoginIfAvailable();
authenticated = await auth.authenticateWithBiometrics(
localizedReason: 'Scan your fingerprint to authenticate',
useErrorDialogs: true,
stickyAuth: true);
if (user.logInTypeID == 1 || user.logInTypeID == 2) {
this.onlySMSBox = true;
} else {
this.checkActivationCode(authProv);
}
// if (authenticated == true) {
// if (user != null && (user.logInTypeID == 4 || user.logInTypeID == 3)) {
// //this.checkActivationCode();
// } else {
// // var request = this.getCommonRequest(type: type);
// // this.getMobileInfo(request);
// }
// }
}
}
checkActivationCode(AuthViewModel authProv, {value}) async {
CheckActivationCodeRequestModel checkActivationCodeForDoctorApp =
new CheckActivationCodeRequestModel(
zipCode: _loggedUser['ZipCode'],
mobileNumber: _loggedUser['MobileNumber'],
projectID: await sharedPref.getInt(PROJECT_ID),
logInTokenID: await sharedPref.getString(LOGIN_TOKEN_ID),
activationCode: value,
oTPSendType: await sharedPref.getInt(OTP_TYPE),
generalid: "Cs2020@2016\$2958");
authProv
.checkActivationCodeForDoctorApp(checkActivationCodeForDoctorApp)
.then((res) async {
widget.changeLoadingStata(false);
if (res['MessageStatus'] == 1) {
sharedPref.setString(TOKEN, res['AuthenticationTokenID']);
if (res['List_DoctorProfile'] != null) {
loginProcessCompleted(res['List_DoctorProfile'][0], authProv);
} else {
ClinicModel clinic =
ClinicModel.fromJson(res['List_DoctorsClinic'][0]);
getDocProfiles(clinic, authProv);
}
} else {
//changeLoadingStata(false);
helpers.showErrorToast(res['ErrorEndUserMessage']);
}
}).catchError((err) {
//changeLoadingStata(false);
helpers.showErrorToast(err);
});
}
loginProcessCompleted(Map<String, dynamic> profile, authProv) {
var doctor = DoctorProfileModel.fromJson(profile);
authProv.setDoctorProfile(doctor);
sharedPref.setObj(DOCTOR_PROFILE, profile);
projectsProvider.isLogin = true;
Navigator.of(context).pushReplacementNamed(HOME);
}
getDocProfiles(ClinicModel clinicInfo, authProv) {
ProfileReqModel docInfo = new ProfileReqModel(
doctorID: clinicInfo.doctorID,
clinicID: clinicInfo.clinicID,
license: true,
projectID: clinicInfo.projectID,
tokenID: '',
languageID: 2);
authProv.getDocProfiles(docInfo.toJson()).then((res) {
if (res['MessageStatus'] == 1) {
loginProcessCompleted(res['DoctorProfileList'][0], authProv);
} else {
// changeLoadingStata(false);
helpers.showErrorToast(res['ErrorEndUserMessage']);
}
}).catchError((err) {
// changeLoadingStata(false);
helpers.showErrorToast(err);
});
}
} }

@ -0,0 +1,346 @@
import 'dart:async';
import 'package:doctor_app_flutter/config/size_config.dart';
import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart';
import 'package:doctor_app_flutter/util/translations_delegate_base.dart';
import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart';
import 'package:flutter/material.dart';
import 'dart:math';
import 'package:provider/provider.dart';
class SMSOTP {
final type;
final mobileNo;
final Function onSuccess;
final Function onFailure;
final context;
int remainingTime = 600;
Future<Null> timer;
static BuildContext _context;
static bool _loading;
SMSOTP(
this.context,
this.type,
this.mobileNo,
this.onSuccess,
this.onFailure,
);
final verifyAccountForm = GlobalKey<FormState>();
TextEditingController digit1 = TextEditingController(text: "");
TextEditingController digit2 = TextEditingController(text: "");
TextEditingController digit3 = TextEditingController(text: "");
TextEditingController digit4 = TextEditingController(text: "");
Map verifyAccountFormValue = {
'digit1': '',
'digit2': '',
'digit3': '',
'digit4': '',
};
final focusD1 = FocusNode();
final focusD2 = FocusNode();
final focusD3 = FocusNode();
final focusD4 = FocusNode();
String errorMsg;
ProjectViewModel projectProvider;
String displayTime = '';
displayDialog(BuildContext context) async {
return showDialog(
context: context,
builder: (context) {
projectProvider = Provider.of(context);
return AlertDialog(
title: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
IconButton(
icon: Icon(Icons.close),
onPressed: () {
Navigator.pop(context);
this.onFailure();
},
)
],
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(10.0))),
content: StatefulBuilder(builder: (context, setState) {
if (displayTime == '') {
startTimer(setState);
}
return Container(
color: Colors.white,
height: SizeConfig.realScreenHeight * 0.5,
width: SizeConfig.realScreenWidth * 0.8,
child: Center(
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
type == 1
? Image.asset('assets/images/login/103.png')
: Image.asset('assets/images/login/104.png'),
Padding(
padding: EdgeInsets.only(top: 5),
child: AppText(
TranslationBase.of(context).verificationMessage +
' XXXXXX' +
mobileNo
.toString()
.substring(mobileNo.toString().length - 3),
textAlign: TextAlign.center,
)),
Form(
key: verifyAccountForm,
child: Padding(
padding: EdgeInsets.only(top: 20),
child: Directionality(
textDirection: TextDirection.ltr,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Container(
width: SizeConfig.realScreenWidth * 0.15,
child: TextFormField(
textInputAction: TextInputAction.next,
style: buildTextStyle(),
autofocus: true,
maxLength: 1,
controller: digit1,
textAlign: TextAlign.center,
keyboardType: TextInputType.number,
decoration: buildInputDecoration(context),
onSaved: (val) {},
validator: validateCodeDigit,
onFieldSubmitted: (_) {
FocusScope.of(context)
.requestFocus(focusD2);
},
onChanged: (val) {
if (val.length == 1) {
FocusScope.of(context)
.requestFocus(focusD2);
verifyAccountFormValue['digit1'] =
val.trim();
checkValue();
}
},
),
),
Container(
width: SizeConfig.realScreenWidth * 0.15,
child: TextFormField(
focusNode: focusD2,
textInputAction: TextInputAction.next,
maxLength: 1,
controller: digit2,
textAlign: TextAlign.center,
style: buildTextStyle(),
keyboardType: TextInputType.number,
decoration: buildInputDecoration(context),
onSaved: (val) {},
onFieldSubmitted: (_) {
FocusScope.of(context)
.requestFocus(focusD3);
},
onChanged: (val) {
if (val.length == 1) {
FocusScope.of(context)
.requestFocus(focusD3);
verifyAccountFormValue['digit2'] =
val.trim();
checkValue();
}
},
validator: validateCodeDigit),
),
Container(
width: SizeConfig.realScreenWidth * 0.15,
child: TextFormField(
focusNode: focusD3,
textInputAction: TextInputAction.next,
maxLength: 1,
controller: digit3,
textAlign: TextAlign.center,
style: buildTextStyle(),
keyboardType: TextInputType.number,
decoration:
buildInputDecoration(context),
onSaved: (val) {},
onFieldSubmitted: (_) {
FocusScope.of(context)
.requestFocus(focusD4);
},
onChanged: (val) {
if (val.length == 1) {
FocusScope.of(context)
.requestFocus(focusD4);
verifyAccountFormValue['digit3'] =
val.trim();
checkValue();
}
},
validator: validateCodeDigit)),
Container(
width: SizeConfig.realScreenWidth * 0.15,
child: TextFormField(
focusNode: focusD4,
maxLength: 1,
textAlign: TextAlign.center,
style: buildTextStyle(),
controller: digit4,
keyboardType: TextInputType.number,
decoration:
buildInputDecoration(context),
onFieldSubmitted: (_) {
FocusScope.of(context)
.requestFocus(focusD4);
},
onChanged: (val) {
if (val.length == 1) {
verifyAccountFormValue['digit4'] =
val.trim();
checkValue();
}
},
validator: validateCodeDigit)),
],
)),
),
),
Padding(
padding: EdgeInsets.only(top: 10),
child: AppText(
TranslationBase.of(context).validationMessage +
' ' +
displayTime,
color: Colors.red,
textAlign: TextAlign.center,
))
],
))),
);
}),
);
});
}
TextStyle buildTextStyle() {
return TextStyle(
fontSize: SizeConfig.textMultiplier * 3,
);
}
InputDecoration buildInputDecoration(BuildContext context) {
return InputDecoration(
counterText: " ",
// 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 ' ';
} else if (value.length == 3) {
print(value);
} else {
return null;
}
}
checkValue() {
//print(verifyAccountFormValue);
if (verifyAccountForm.currentState.validate()) {
onSuccess(digit1.text.toString() +
digit2.text.toString() +
digit3.text.toString() +
digit4.text.toString());
}
}
getSecondsAsDigitalClock(int inputSeconds) {
var sec_num =
int.parse(inputSeconds.toString()); // don't forget the second param
var hours = (sec_num / 3600).floor();
var minutes = ((sec_num - hours * 3600) / 60).floor();
var seconds = sec_num - hours * 3600 - minutes * 60;
var minutesString = "";
var secondsString = "";
minutesString =
minutes < 10 ? "0" + minutes.toString() : minutes.toString();
secondsString =
seconds < 10 ? "0" + seconds.toString() : seconds.toString();
return minutesString + ":" + secondsString;
}
startTimer(setState) {
this.remainingTime--;
setState(() {
displayTime = this.getSecondsAsDigitalClock(this.remainingTime);
});
timer = Future.delayed(Duration(seconds: 1), () {
if (this.remainingTime > 0) {
startTimer(setState);
} else {
Navigator.pop(context);
}
});
}
static void showLoadingDialog(BuildContext context, bool _loading) async {
_context = context;
if (_loading == false) {
Navigator.of(context).pop();
return;
}
_loading = true;
await showDialog(
context: _context,
barrierDismissible: false,
builder: (BuildContext context) {
return SimpleDialog(
elevation: 0.0,
backgroundColor: Colors.transparent,
children: <Widget>[
Center(
child: CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(Colors.black),
),
)
],
);
});
}
static void hideSMSBox(context) {
Navigator.pop(context);
}
}

@ -316,6 +316,34 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "5.2.1" version: "5.2.1"
firebase_core:
dependency: transitive
description:
name: firebase_core
url: "https://pub.dartlang.org"
source: hosted
version: "0.5.3"
firebase_core_platform_interface:
dependency: transitive
description:
name: firebase_core_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
firebase_core_web:
dependency: transitive
description:
name: firebase_core_web
url: "https://pub.dartlang.org"
source: hosted
version: "0.2.1+1"
firebase_messaging:
dependency: "direct main"
description:
name: firebase_messaging
url: "https://pub.dartlang.org"
source: hosted
version: "7.0.3"
fixnum: fixnum:
dependency: transitive dependency: transitive
description: description:

@ -59,6 +59,8 @@ dependencies:
#Dependency Injection #Dependency Injection
get_it: ^4.0.2 get_it: ^4.0.2
#firebase
firebase_messaging: ^7.0.0
#Autocomplete TextField #Autocomplete TextField
autocomplete_textfield: ^1.7.3 autocomplete_textfield: ^1.7.3
@ -93,7 +95,7 @@ flutter:
assets: assets:
- assets/images/ - assets/images/
- assets/images/dashboard/ - assets/images/dashboard/
- assets/images/login/
# An image asset can refer to one or more resolution-specific "variants", see # An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.dev/assets-and-images/#resolution-aware. # https://flutter.dev/assets-and-images/#resolution-aware.

Loading…
Cancel
Save