Merge branch 'register_patient_services' into 'development'

Register patient services

See merge request Cloud_Solution/doctor_app_flutter!879
merge-requests/880/merge
Elham Ali 4 years ago
commit 26ffd7cb7a

@ -27,7 +27,7 @@ class BaseAppClient {
Function(String error, int statusCode) onFailure, Function(String error, int statusCode) onFailure,
bool isAllowAny = false, bool isAllowAny = false,
bool isLiveCare = false, bool isLiveCare = false,
bool isFallLanguage=false}) async { bool isFallLanguage = false}) async {
String url; String url;
if (isLiveCare) if (isLiveCare)
url = BASE_URL_LIVE_CARE + endPoint; url = BASE_URL_LIVE_CARE + endPoint;
@ -40,14 +40,17 @@ class BaseAppClient {
String token = await sharedPref.getString(TOKEN); String token = await sharedPref.getString(TOKEN);
if (profile != null) { if (profile != null) {
DoctorProfileModel doctorProfile = DoctorProfileModel.fromJson(profile); DoctorProfileModel doctorProfile = DoctorProfileModel.fromJson(profile);
if (body['DoctorID'] == null) body['DoctorID'] = doctorProfile?.doctorID; if (body['DoctorID'] == null)
body['DoctorID'] = doctorProfile?.doctorID;
if (body['DoctorID'] == "") body['DoctorID'] = null; if (body['DoctorID'] == "") body['DoctorID'] = null;
if (body['EditedBy'] == null) body['EditedBy'] = doctorProfile?.doctorID; if (body['EditedBy'] == null)
body['EditedBy'] = doctorProfile?.doctorID;
if (body['ProjectID'] == null) { if (body['ProjectID'] == null) {
body['ProjectID'] = doctorProfile?.projectID; body['ProjectID'] = doctorProfile?.projectID;
} }
if (body['ClinicID'] == null) body['ClinicID'] = doctorProfile?.clinicID; if (body['ClinicID'] == null)
body['ClinicID'] = doctorProfile?.clinicID;
} }
if (body['DoctorID'] == '') { if (body['DoctorID'] == '') {
body['DoctorID'] = null; body['DoctorID'] = null;
@ -59,7 +62,7 @@ class BaseAppClient {
body['TokenID'] = token ?? ''; body['TokenID'] = token ?? '';
} }
// body['TokenID'] = "@dm!n" ?? ''; // body['TokenID'] = "@dm!n" ?? '';
if(!isFallLanguage) { if (!isFallLanguage) {
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;
@ -69,22 +72,29 @@ class BaseAppClient {
body['stamp'] = DateTime.now().toIso8601String(); body['stamp'] = DateTime.now().toIso8601String();
// if(!body.containsKey("IPAdress")) // if(!body.containsKey("IPAdress"))
body['IPAdress'] = IP_ADDRESS; body['IPAdress'] = IP_ADDRESS;
body['VersionID'] = VERSION_ID; if (body['VersionID'] == null) {
body['Channel'] = CHANNEL; body['VersionID'] = VERSION_ID;
}
if (body['Channel'] == null) {
body['Channel'] = CHANNEL;
}
body['SessionID'] = SESSION_ID; body['SessionID'] = SESSION_ID;
body['IsLoginForDoctorApp'] = IS_LOGIN_FOR_DOCTOR_APP; body['IsLoginForDoctorApp'] = IS_LOGIN_FOR_DOCTOR_APP;
body['PatientOutSA'] = body['PatientOutSA'] ?? 0; // PATIENT_OUT_SA; body['PatientOutSA'] = body['PatientOutSA'] ?? 0; // PATIENT_OUT_SA;
if (body['VidaAuthTokenID'] == null) { if (body['VidaAuthTokenID'] == null) {
body['VidaAuthTokenID'] = await sharedPref.getString(VIDA_AUTH_TOKEN_ID); body['VidaAuthTokenID'] =
await sharedPref.getString(VIDA_AUTH_TOKEN_ID);
} }
if (body['VidaRefreshTokenID'] == null) { if (body['VidaRefreshTokenID'] == null) {
body['VidaRefreshTokenID'] = await sharedPref.getString(VIDA_REFRESH_TOKEN_ID); body['VidaRefreshTokenID'] =
await sharedPref.getString(VIDA_REFRESH_TOKEN_ID);
} }
int projectID = await sharedPref.getInt(PROJECT_ID); int projectID = await sharedPref.getInt(PROJECT_ID);
if (projectID == 2 || projectID == 3) if (projectID == 2 || projectID == 3)
body['PatientOutSA'] = true; body['PatientOutSA'] = true;
else if ((body.containsKey('facilityId') && body['facilityId'] == 2 || body['facilityId'] == 3) || else if ((body.containsKey('facilityId') && body['facilityId'] == 2 ||
body['facilityId'] == 3) ||
body['ProjectID'] == 2 || body['ProjectID'] == 2 ||
body['ProjectID'] == 3) body['ProjectID'] == 3)
body['PatientOutSA'] = true; body['PatientOutSA'] = true;
@ -98,21 +108,28 @@ class BaseAppClient {
var asd2; var asd2;
if (await Helpers.checkConnection()) { if (await Helpers.checkConnection()) {
final response = await http.post(url, final response = await http.post(url,
body: json.encode(body), headers: {'Content-Type': 'application/json', 'Accept': 'application/json'}); body: json.encode(body),
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
});
final int statusCode = response.statusCode; final int statusCode = response.statusCode;
if (statusCode < 200 || statusCode >= 400) { if (statusCode < 200 || statusCode >= 400) {
onFailure(Helpers.generateContactAdminMsg(), statusCode); onFailure(Helpers.generateContactAdminMsg(), statusCode);
} else { } else {
var parsed = json.decode(response.body.toString()); var parsed = json.decode(response.body.toString());
if (parsed['ErrorType'] == 4) { if (parsed['ErrorType'] == 4) {
helpers.navigateToUpdatePage(parsed['ErrorEndUserMessage'], parsed['AndroidLink'], parsed['IOSLink']); helpers.navigateToUpdatePage(parsed['ErrorEndUserMessage'],
parsed['AndroidLink'], parsed['IOSLink']);
} }
if (parsed['IsAuthenticated'] != null && !parsed['IsAuthenticated']) { if (parsed['IsAuthenticated'] != null && !parsed['IsAuthenticated']) {
if (body['OTP_SendType'] != null) { if (body['OTP_SendType'] != null) {
onFailure(getError(parsed), statusCode); onFailure(getError(parsed), statusCode);
} else if (!isAllowAny) { } else if (!isAllowAny) {
await Provider.of<AuthenticationViewModel>(AppGlobal.CONTEX, listen: false).logout(); await Provider.of<AuthenticationViewModel>(AppGlobal.CONTEX,
listen: false)
.logout();
Helpers.showErrorToast('Your session expired Please login again'); Helpers.showErrorToast('Your session expired Please login again');
locator<NavigationService>().pushNamedAndRemoveUntil(ROOT); locator<NavigationService>().pushNamedAndRemoveUntil(ROOT);
@ -147,10 +164,14 @@ class BaseAppClient {
String url = BASE_URL + endPoint; String url = BASE_URL + endPoint;
try { try {
Map<String, String> headers = {'Content-Type': 'application/json', 'Accept': 'application/json'}; Map<String, String> headers = {
'Content-Type': 'application/json',
'Accept': 'application/json'
};
String token = await sharedPref.getString(TOKEN); String token = await sharedPref.getString(TOKEN);
var languageID = await sharedPref.getStringWithDefaultValue(APP_Language, 'en'); var languageID =
await sharedPref.getStringWithDefaultValue(APP_Language, 'en');
body['SetupID'] = body.containsKey('SetupID') body['SetupID'] = body.containsKey('SetupID')
? body['SetupID'] != null ? body['SetupID'] != null
? body['SetupID'] ? body['SetupID']
@ -170,11 +191,12 @@ class BaseAppClient {
: PATIENT_OUT_SA_PATIENT_REQ; : PATIENT_OUT_SA_PATIENT_REQ;
if (body.containsKey('isDentalAllowedBackend')) { if (body.containsKey('isDentalAllowedBackend')) {
body['isDentalAllowedBackend'] = body.containsKey('isDentalAllowedBackend') body['isDentalAllowedBackend'] =
? body['isDentalAllowedBackend'] != null body.containsKey('isDentalAllowedBackend')
? body['isDentalAllowedBackend'] ? body['isDentalAllowedBackend'] != null
: IS_DENTAL_ALLOWED_BACKEND ? body['isDentalAllowedBackend']
: IS_DENTAL_ALLOWED_BACKEND; : IS_DENTAL_ALLOWED_BACKEND
: IS_DENTAL_ALLOWED_BACKEND;
} }
body['DeviceTypeID'] = Platform.isAndroid ? 1 : 2; body['DeviceTypeID'] = Platform.isAndroid ? 1 : 2;
@ -196,7 +218,9 @@ class BaseAppClient {
: PATIENT_TYPE_ID; : PATIENT_TYPE_ID;
body['TokenID'] = body.containsKey('TokenID') ? body['TokenID'] : token; body['TokenID'] = body.containsKey('TokenID') ? body['TokenID'] : token;
body['PatientID'] = body['PatientID'] != null ? body['PatientID'] : patient.patientId ?? patient.patientMRN; body['PatientID'] = body['PatientID'] != null
? body['PatientID']
: patient.patientId ?? patient.patientMRN;
body['PatientOutSA'] = 0; //user['OutSA']; //TODO change it body['PatientOutSA'] = 0; //user['OutSA']; //TODO change it
body['SessionID'] = SESSION_ID; //getSe body['SessionID'] = SESSION_ID; //getSe
@ -209,9 +233,11 @@ class BaseAppClient {
print("URL : $url"); print("URL : $url");
print("Body : ${json.encode(body)}"); print("Body : ${json.encode(body)}");
var asd = json.encode(body);
var asd2;
if (await Helpers.checkConnection()) { if (await Helpers.checkConnection()) {
final response = await http.post(url.trim(), body: json.encode(body), headers: headers); final response = await http.post(url.trim(),
body: json.encode(body), headers: headers);
final int statusCode = response.statusCode; final int statusCode = response.statusCode;
print("statusCode :$statusCode"); print("statusCode :$statusCode");
if (statusCode < 200 || statusCode >= 400 || json == null) { if (statusCode < 200 || statusCode >= 400 || json == null) {
@ -223,7 +249,8 @@ class BaseAppClient {
onSuccess(parsed, statusCode); onSuccess(parsed, statusCode);
} else { } else {
if (parsed['ErrorType'] == 4) { if (parsed['ErrorType'] == 4) {
helpers.navigateToUpdatePage(parsed['ErrorEndUserMessage'], parsed['AndroidLink'], parsed['IOSLink']); helpers.navigateToUpdatePage(parsed['ErrorEndUserMessage'],
parsed['AndroidLink'], parsed['IOSLink']);
} }
if (parsed['IsAuthenticated'] == null) { if (parsed['IsAuthenticated'] == null) {
if (parsed['isSMSSent'] == true) { if (parsed['isSMSSent'] == true) {
@ -239,20 +266,28 @@ class BaseAppClient {
onFailure(getError(parsed), statusCode); onFailure(getError(parsed), statusCode);
} }
} }
} else if (parsed['MessageStatus'] == 1 || parsed['SMSLoginRequired'] == true) { } else if (parsed['MessageStatus'] == 1 ||
parsed['SMSLoginRequired'] == true) {
onSuccess(parsed, statusCode); onSuccess(parsed, statusCode);
} else if (parsed['MessageStatus'] == 2 && parsed['IsAuthenticated']) { } else if (parsed['MessageStatus'] == 2 &&
parsed['IsAuthenticated']) {
if (parsed['SameClinicApptList'] != null) { if (parsed['SameClinicApptList'] != null) {
onSuccess(parsed, statusCode); onSuccess(parsed, statusCode);
} else { } else {
if (parsed['message'] == null && parsed['ErrorEndUserMessage'] == null) { if (parsed['message'] == null &&
parsed['ErrorEndUserMessage'] == null) {
if (parsed['ErrorSearchMsg'] == null) { if (parsed['ErrorSearchMsg'] == null) {
onFailure("Server Error found with no available message", statusCode); onFailure("Server Error found with no available message",
statusCode);
} else { } else {
onFailure(parsed['ErrorSearchMsg'], statusCode); onFailure(parsed['ErrorSearchMsg'], statusCode);
} }
} else { } else {
onFailure(parsed['message'] ?? parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode); onFailure(
parsed['message'] ??
parsed['ErrorEndUserMessage'] ??
parsed['ErrorMessage'],
statusCode);
} }
} }
} else { } else {
@ -262,7 +297,9 @@ class BaseAppClient {
if (parsed['message'] != null) { if (parsed['message'] != null) {
onFailure(parsed['message'] ?? parsed['message'], statusCode); onFailure(parsed['message'] ?? parsed['message'], statusCode);
} else { } else {
onFailure(parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode); onFailure(
parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'],
statusCode);
} }
} }
} }
@ -285,8 +322,12 @@ class BaseAppClient {
if (parsed["ValidationErrors"]["ValidationErrors"] != null && if (parsed["ValidationErrors"]["ValidationErrors"] != null &&
parsed["ValidationErrors"]["ValidationErrors"].length != 0) { parsed["ValidationErrors"]["ValidationErrors"].length != 0) {
for (var i = 0; i < parsed["ValidationErrors"]["ValidationErrors"].length; i++) { for (var i = 0;
error = error + parsed["ValidationErrors"]["ValidationErrors"][i]["Messages"][0] + "\n"; i < parsed["ValidationErrors"]["ValidationErrors"].length;
i++) {
error = error +
parsed["ValidationErrors"]["ValidationErrors"][i]["Messages"][0] +
"\n";
} }
} }
} }

@ -373,8 +373,8 @@ const GET_ADMISSION_ORDERS =
///Patient Registration Services ///Patient Registration Services
const CHECK_PATIENT_FOR_REGISTRATION = const CHECK_PATIENT_FOR_REGISTRATION =
"Services/Authentication.svc/REST/CheckPatientForRegisteration"; "Services/Authentication.svc/REST/CheckPatientForRegisteration";
const SEND_ACTIVATION_CODE_BY_OTP_NOT_TYPE = const SEND_ACTIVATION_CODE_BY_OTP_NOT_TYPE_FOR_REGISTRATION =
"Services/Authentication.svc/REST/SendActivationCodebyOTPNotificationType"; "Services/Authentication.svc/REST/SendActivationCodebyOTPNotificationTypeForRegistration";
const CHECK_ACTIVATION_CODE_FOR_PATIENT = const CHECK_ACTIVATION_CODE_FOR_PATIENT =
"Services/Authentication.svc/REST/CheckActivationCode"; "Services/Authentication.svc/REST/CheckActivationCode";
const PATIENT_REGISTRATION = "Services/Authentication.svc/REST/PatientRegistration"; const PATIENT_REGISTRATION = "Services/Authentication.svc/REST/PatientRegistration";

@ -6,16 +6,20 @@ import 'package:doctor_app_flutter/core/model/PatientRegistration/GetPatientInfo
import 'package:doctor_app_flutter/core/model/PatientRegistration/PatientRegistrationModel.dart'; import 'package:doctor_app_flutter/core/model/PatientRegistration/PatientRegistrationModel.dart';
import 'package:doctor_app_flutter/core/model/PatientRegistration/SendActivationCodebyOTPNotificationTypeForRegistrationModel.dart'; import 'package:doctor_app_flutter/core/model/PatientRegistration/SendActivationCodebyOTPNotificationTypeForRegistrationModel.dart';
import 'package:doctor_app_flutter/core/service/base/base_service.dart'; import 'package:doctor_app_flutter/core/service/base/base_service.dart';
import 'package:doctor_app_flutter/core/viewModel/PatientRegistrationViewModel.dart';
class PatientRegistrationService extends BaseService { class PatientRegistrationService extends BaseService {
GetPatientInfoResponseModel getPatientInfoResponseModel; GetPatientInfoResponseModel getPatientInfoResponseModel;
String logInTokenID;
checkPatientForRegistration( checkPatientForRegistration(
CheckPatientForRegistrationModel registrationModel) async { CheckPatientForRegistrationModel registrationModel) async {
hasError = false; hasError = false;
await baseAppClient.post(CHECK_PATIENT_FOR_REGISTRATION, await baseAppClient.post(CHECK_PATIENT_FOR_REGISTRATION,
onSuccess: (dynamic response, int statusCode) {}, onSuccess: (dynamic response, int statusCode) {
onFailure: (String error, int statusCode) { //TODO Elham* fix it
logInTokenID = "OjEi/qgRekGICZm5/a4jbQ=="; //response["LogInTokenID"];
}, onFailure: (String error, int statusCode) {
hasError = true; hasError = true;
super.error = error; super.error = error;
}, body: registrationModel.toJson()); }, body: registrationModel.toJson());
@ -35,12 +39,47 @@ class PatientRegistrationService extends BaseService {
} }
sendActivationCodeByOTPNotificationType( sendActivationCodeByOTPNotificationType(
SendActivationCodeByOTPNotificationTypeForRegistrationModel {SendActivationCodeByOTPNotificationTypeForRegistrationModel
registrationModel) async { registrationModel,
int otpType,
PatientRegistrationViewModel model,
CheckPatientForRegistrationModel
checkPatientForRegistrationModel}) async {
registrationModel =
SendActivationCodeByOTPNotificationTypeForRegistrationModel(
oTPSendType: otpType,
patientIdentificationID: checkPatientForRegistrationModel
.patientIdentificationID,
patientMobileNumber: checkPatientForRegistrationModel
.patientMobileNumber,
zipCode: checkPatientForRegistrationModel.zipCode,
patientOutSA: 0,
healthId: model.getPatientInfoResponseModel.healthId,
dOB: checkPatientForRegistrationModel.dOB,
isRegister: checkPatientForRegistrationModel.isRegister,
isHijri: checkPatientForRegistrationModel.isHijri,
sessionID: null,
generalid: GENERAL_ID,
isDentalAllowedBackend: false,
projectOutSA: 0,
searchType: 1,
versionID: 7.1,
channel: 3,
nationalID:
model.checkPatientForRegistrationModel.patientIdentificationID,
patientID: 0,
mobileNo: model.checkPatientForRegistrationModel.patientMobileNumber
.toString(),
loginType: otpType,
logInTokenID: logInTokenID);
hasError = false; hasError = false;
await baseAppClient.post(SEND_ACTIVATION_CODE_BY_OTP_NOT_TYPE, await baseAppClient.post(SEND_ACTIVATION_CODE_BY_OTP_NOT_TYPE_FOR_REGISTRATION,
onSuccess: (dynamic response, int statusCode) {}, onSuccess: (dynamic response, int statusCode) {
onFailure: (String error, int statusCode) { registrationModel =
SendActivationCodeByOTPNotificationTypeForRegistrationModel.fromJson(
response);
}, onFailure: (String error, int statusCode) {
hasError = true; hasError = true;
super.error = error; super.error = error;
}, body: registrationModel.toJson()); }, body: registrationModel.toJson());
@ -49,8 +88,9 @@ class PatientRegistrationService extends BaseService {
checkActivationCode(CheckActivationCodeModel registrationModel) async { checkActivationCode(CheckActivationCodeModel registrationModel) async {
hasError = false; hasError = false;
await baseAppClient.post(CHECK_ACTIVATION_CODE_FOR_PATIENT, await baseAppClient.post(CHECK_ACTIVATION_CODE_FOR_PATIENT,
onSuccess: (dynamic response, int statusCode) {}, onSuccess: (dynamic response, int statusCode) {
onFailure: (String error, int statusCode) { registrationModel = CheckActivationCodeModel.fromJson(response);
}, onFailure: (String error, int statusCode) {
hasError = true; hasError = true;
super.error = error; super.error = error;
}, body: registrationModel.toJson()); }, body: registrationModel.toJson());

@ -1,3 +1,4 @@
import 'package:doctor_app_flutter/config/config.dart';
import 'package:doctor_app_flutter/core/enum/viewstate.dart'; import 'package:doctor_app_flutter/core/enum/viewstate.dart';
import 'package:doctor_app_flutter/core/model/PatientRegistration/CheckActivationCodeModel.dart'; import 'package:doctor_app_flutter/core/model/PatientRegistration/CheckActivationCodeModel.dart';
import 'package:doctor_app_flutter/core/model/PatientRegistration/CheckPatientForRegistrationModel.dart'; import 'package:doctor_app_flutter/core/model/PatientRegistration/CheckPatientForRegistrationModel.dart';
@ -14,14 +15,17 @@ class PatientRegistrationViewModel extends BaseViewModel {
PatientRegistrationService _patientRegistrationService = PatientRegistrationService _patientRegistrationService =
locator<PatientRegistrationService>(); locator<PatientRegistrationService>();
GetPatientInfoResponseModel get getPatientInfoResponseModel =>
_patientRegistrationService.getPatientInfoResponseModel;
GetPatientInfoResponseModel get getPatientInfoResponseModel =>_patientRegistrationService.getPatientInfoResponseModel; CheckPatientForRegistrationModel checkPatientForRegistrationModel;
CheckPatientForRegistrationModel checkPatientForRegistrationModel ;
Future checkPatientForRegistration( Future checkPatientForRegistration(
CheckPatientForRegistrationModel registrationModel) async { CheckPatientForRegistrationModel registrationModel) async {
checkPatientForRegistrationModel = registrationModel;
checkPatientForRegistrationModel =CheckPatientForRegistrationModel.fromJson(registrationModel.toJson()); checkPatientForRegistrationModel =
CheckPatientForRegistrationModel.fromJson(registrationModel.toJson());
setState(ViewState.BusyLocal); setState(ViewState.BusyLocal);
await _patientRegistrationService await _patientRegistrationService
.checkPatientForRegistration(registrationModel); .checkPatientForRegistration(registrationModel);
@ -35,135 +39,170 @@ class PatientRegistrationViewModel extends BaseViewModel {
Future getPatientInfo( Future getPatientInfo(
GetPatientInfoRequestModel getPatientInfoRequestModel) async { GetPatientInfoRequestModel getPatientInfoRequestModel) async {
setState(ViewState.BusyLocal); setState(ViewState.BusyLocal);
/// TODO Elham* return call service when it working /// TODO Elham* return call service when it working
_patientRegistrationService.getPatientInfoResponseModel = GetPatientInfoResponseModel.fromJson({ _patientRegistrationService.getPatientInfoResponseModel =
"Date": null, GetPatientInfoResponseModel.fromJson({
"LanguageID": 0, "Date": null,
"ServiceName": 0, "LanguageID": 0,
"Time": null, "ServiceName": 0,
"AndroidLink": null, "Time": null,
"AuthenticationTokenID": null, "AndroidLink": null,
"Data": null, "AuthenticationTokenID": null,
"Dataw": false, "Data": null,
"DietType": 0, "Dataw": false,
"ErrorCode": null, "DietType": 0,
"ErrorEndUserMessage": null, "ErrorCode": null,
"ErrorEndUserMessageN": null, "ErrorEndUserMessage": null,
"ErrorMessage": null, "ErrorEndUserMessageN": null,
"ErrorType": 0, "ErrorMessage": null,
"FoodCategory": 0, "ErrorType": 0,
"IOSLink": null, "FoodCategory": 0,
"IsAuthenticated": false, "IOSLink": null,
"MealOrderStatus": 0, "IsAuthenticated": false,
"MealType": 0, "MealOrderStatus": 0,
"MessageStatus": 1, "MealType": 0,
"NumberOfResultRecords": 0, "MessageStatus": 1,
"PatientBlodType": null, "NumberOfResultRecords": 0,
"SuccessMsg": null, "PatientBlodType": null,
"SuccessMsgN": null, "SuccessMsg": null,
"VidaUpdatedResponse": null, "SuccessMsgN": null,
"AccessTokenObject": null, "VidaUpdatedResponse": null,
"Age": 33, "AccessTokenObject": null,
"ClientIdentifierId": null, "Age": 33,
"CreatedBy": 0, "ClientIdentifierId": null,
"DateOfBirth": "07/31/1988", "CreatedBy": 0,
"FirstNameAr": "سفيان", "DateOfBirth": "07/31/1988",
"FirstNameEn": "SUFIAN", "FirstNameAr": "سفيان",
"Gender": "M", "FirstNameEn": "SUFIAN",
"GenderAr": null, "Gender": "M",
"GenderEn": null, "GenderAr": null,
"HealthId": "30000018540264", "GenderEn": null,
"IdNumber": "1062938285", "HealthId": "30000018540264",
"IdType": "NationalId", "IdNumber": "1062938285",
"IsHijri": false, "IdType": "NationalId",
"IsInstertedOrUpdated": 0, "IsHijri": false,
"IsNull": 0, "IsInstertedOrUpdated": 0,
"IsPatientExistNHIC": 0, "IsNull": 0,
"IsRecordLockedByCurrentUser": false, "IsPatientExistNHIC": 0,
"LastNameAr": "عثمان", "IsRecordLockedByCurrentUser": false,
"LastNameEn": "OTHMAN", "LastNameAr": "عثمان",
"List_ActiveAccessToken": null, "LastNameEn": "OTHMAN",
"MaritalStatus": "غير معروف", "List_ActiveAccessToken": null,
"MaritalStatusCode": "U", "MaritalStatus": "غير معروف",
"NationalDateOfBirth": "18/12/1408", "MaritalStatusCode": "U",
"Nationality": "السعودية", "NationalDateOfBirth": "18/12/1408",
"NationalityCode": "SAU", "Nationality": "السعودية",
"Occupation": "طالب", "NationalityCode": "SAU",
"PCDTransactionDataResultList": null, "Occupation": "طالب",
"PCD_GetVidaPatientForManualVerificationList": null, "PCDTransactionDataResultList": null,
"PCD_NHIC_HMG_PatientDetailsMatchCalulationList": null, "PCD_GetVidaPatientForManualVerificationList": null,
"PCD_ReturnValue": 0, "PCD_NHIC_HMG_PatientDetailsMatchCalulationList": null,
"PatientStatus": "-", "PCD_ReturnValue": 0,
"PlaceofBirth": "فينا", "PatientStatus": "-",
"PractitionerStatusCode": null, "PlaceofBirth": "فينا",
"PractitionerStatusDescAr": null, "PractitionerStatusCode": null,
"PractitionerStatusDescEn": null, "PractitionerStatusDescAr": null,
"RowCount": 0, "PractitionerStatusDescEn": null,
"SecondNameAr": "عبدالهادي", "RowCount": 0,
"SecondNameEn": "ABDULHADI", "SecondNameAr": "عبدالهادي",
"ThirdNameAr": "احمد", "SecondNameEn": "ABDULHADI",
"ThirdNameEn": "A", "ThirdNameAr": "احمد",
"YakeenVidaPatientDataStatisticsByPatientIdList": null, "ThirdNameEn": "A",
"YakeenVidaPatientDataStatisticsList": null, "YakeenVidaPatientDataStatisticsByPatientIdList": null,
"YakeenVidaPatientDataStatisticsPrefferedList": null, "YakeenVidaPatientDataStatisticsList": null,
"accessToken": null, "YakeenVidaPatientDataStatisticsPrefferedList": null,
"categoryCode": 0, "accessToken": null,
"categoryNameAr": null, "categoryCode": 0,
"categoryNameEn": null, "categoryNameAr": null,
"constraintCode": 0, "categoryNameEn": null,
"constraintNameAr": null, "constraintCode": 0,
"constraintNameEn": null, "constraintNameAr": null,
"content": null, "constraintNameEn": null,
"errorList": null, "content": null,
"licenseExpiryDate": null, "errorList": null,
"licenseIssuedDate": null, "licenseExpiryDate": null,
"licenseStatusCode": null, "licenseIssuedDate": null,
"licenseStatusDescAr": null, "licenseStatusCode": null,
"licenseStatusDescEn": null, "licenseStatusDescAr": null,
"organizations": null, "licenseStatusDescEn": null,
"registrationNumber": null, "organizations": null,
"specialtyCode": 0, "registrationNumber": null,
"specialtyNameAr": null, "specialtyCode": 0,
"specialtyNameEn": null "specialtyNameAr": null,
}); "specialtyNameEn": null
});
// await _patientRegistrationService. // await _patientRegistrationService.
// getPatientInfo(getPatientInfoRequestModel); // getPatientInfo(getPatientInfoRequestModel);
// if (_patientRegistrationService.hasError) { // if (_patientRegistrationService.hasError) {
// error = _patientRegistrationService.error; // error = _patientRegistrationService.error;
// setState(ViewState.ErrorLocal); // setState(ViewState.ErrorLocal);
// } else // } else
// setState(ViewState.Idle); setState(ViewState.Idle);
} }
Future sendActivationCodeByOTPNotificationType( Future sendActivationCodeByOTPNotificationType(
SendActivationCodeByOTPNotificationTypeForRegistrationModel {SendActivationCodeByOTPNotificationTypeForRegistrationModel
registrationModel) async { registrationModel,
setState(ViewState.Busy); int otpType,
await _patientRegistrationService PatientRegistrationViewModel user}) async {
.sendActivationCodeByOTPNotificationType(registrationModel); setState(ViewState.BusyLocal);
print(checkPatientForRegistrationModel);
print(checkPatientForRegistrationModel);
await _patientRegistrationService.sendActivationCodeByOTPNotificationType(
otpType: otpType,
model: this,
checkPatientForRegistrationModel: checkPatientForRegistrationModel);
if (_patientRegistrationService.hasError) { if (_patientRegistrationService.hasError) {
error = _patientRegistrationService.error; error = _patientRegistrationService.error;
setState(ViewState.Error); setState(ViewState.ErrorLocal);
} else } else
setState(ViewState.Idle); setState(ViewState.Idle);
} }
Future checkActivationCode(CheckActivationCodeModel registrationModel) async { Future checkActivationCode(String code) async {
setState(ViewState.Busy); CheckActivationCodeModel model = CheckActivationCodeModel(
await _patientRegistrationService.checkActivationCode(registrationModel); activationCode: code,
patientIdentificationID:
checkPatientForRegistrationModel.patientIdentificationID,
patientMobileNumber: checkPatientForRegistrationModel.patientMobileNumber,
zipCode: checkPatientForRegistrationModel.zipCode,
patientOutSA: 0,
healthId: getPatientInfoResponseModel.healthId,
dOB: checkPatientForRegistrationModel.dOB,
isRegister: checkPatientForRegistrationModel.isRegister,
isHijri: checkPatientForRegistrationModel.isHijri,
sessionID: null,
generalid: GENERAL_ID,
forRegisteration: true,
isDentalAllowedBackend: false,
projectOutSA: 0,
searchType: 1,
versionID: 7.1,
channel: 3,
// TODO Elham* loginType
loginType: 4,
logInTokenID:_patientRegistrationService.logInTokenID ,
nationalID: checkPatientForRegistrationModel.patientIdentificationID,
patientID: 0,
mobileNo: checkPatientForRegistrationModel.patientMobileNumber.toString(),
);
setState(ViewState.BusyLocal);
await _patientRegistrationService.checkActivationCode(model);
if (_patientRegistrationService.hasError) { if (_patientRegistrationService.hasError) {
error = _patientRegistrationService.error; error = _patientRegistrationService.error;
setState(ViewState.Error); setState(ViewState.ErrorLocal);
} else } else
setState(ViewState.Idle); setState(ViewState.Idle);
} }
Future registrationPatient(PatientRegistrationModel registrationModel) async { Future registrationPatient(PatientRegistrationModel registrationModel) async {
setState(ViewState.Busy); setState(ViewState.BusyLocal);
await _patientRegistrationService.registrationPatient(registrationModel); await _patientRegistrationService.registrationPatient(registrationModel);
if (_patientRegistrationService.hasError) { if (_patientRegistrationService.hasError) {
error = _patientRegistrationService.error; error = _patientRegistrationService.error;
setState(ViewState.Error); setState(ViewState.ErrorLocal);
} else } else
setState(ViewState.Idle); setState(ViewState.Idle);
} }

@ -399,7 +399,8 @@ class _HomeScreenState extends State<HomeScreen> {
patientCards.add(HomePatientCard( patientCards.add(HomePatientCard(
backgroundColor: backgroundColors[colorIndex], backgroundColor: backgroundColors[colorIndex],
backgroundIconColor: backgroundIconColors[colorIndex], backgroundIconColor: backgroundIconColors[colorIndex],
cardIconImage: 'assets/images/patient_register.png', //TODO Elham* match the of the icon
cardIcon: DoctorApp.arrival_patients,
textColor: textColors[colorIndex], textColor: textColors[colorIndex],
text: TranslationBase.of(context).registerNewPatient, text: TranslationBase.of(context).registerNewPatient,
onTap: () { onTap: () {

@ -1,4 +1,5 @@
import 'package:doctor_app_flutter/icons_app/doctor_app_icons.dart'; import 'package:doctor_app_flutter/icons_app/doctor_app_icons.dart';
import 'package:doctor_app_flutter/util/translations_delegate_base.dart';
import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart';
import 'package:doctor_app_flutter/widgets/shared/text_fields/app-textfield-custom.dart'; import 'package:doctor_app_flutter/widgets/shared/text_fields/app-textfield-custom.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -8,13 +9,14 @@ class CustomEditableText extends StatefulWidget {
Key key, Key key,
@required this.controller, @required this.controller,
this.hint, this.hint,
this.isEditable = false, this.isEditable = false, this.isSubmitted,
}) : super(key: key); }) : super(key: key);
final TextEditingController controller; final TextEditingController controller;
final String hint; final String hint;
bool isEditable; bool isEditable;
final bool isSubmitted;
@override @override
_CustomEditableTextState createState() => _CustomEditableTextState(); _CustomEditableTextState createState() => _CustomEditableTextState();
@ -77,6 +79,12 @@ class _CustomEditableTextState extends State<CustomEditableText> {
hintText: widget.hint, hintText: widget.hint,
//TranslationBase.of(context).addoperationReports, //TranslationBase.of(context).addoperationReports,
controller: widget.controller, controller: widget.controller,
validationError: widget.controller
.text.isEmpty &&
widget.isSubmitted
? TranslationBase.of(context)
.emptyMessage
: null,
maxLines: 1, maxLines: 1,
minLines: 1, minLines: 1,
hasBorder: true, hasBorder: true,

@ -17,6 +17,7 @@ import 'package:doctor_app_flutter/models/operation_report/create_update_operati
import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart'; import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart';
import 'package:doctor_app_flutter/models/patient/progress_note_request.dart'; import 'package:doctor_app_flutter/models/patient/progress_note_request.dart';
import 'package:doctor_app_flutter/screens/patients/profile/soap_update/shared_soap_widgets/bottom_sheet_title.dart'; import 'package:doctor_app_flutter/screens/patients/profile/soap_update/shared_soap_widgets/bottom_sheet_title.dart';
import 'package:doctor_app_flutter/util/date-utils.dart';
import 'package:doctor_app_flutter/util/dr_app_toast_msg.dart'; import 'package:doctor_app_flutter/util/dr_app_toast_msg.dart';
import 'package:doctor_app_flutter/util/helpers.dart'; import 'package:doctor_app_flutter/util/helpers.dart';
import 'package:doctor_app_flutter/util/translations_delegate_base.dart'; import 'package:doctor_app_flutter/util/translations_delegate_base.dart';
@ -28,6 +29,8 @@ import 'package:doctor_app_flutter/widgets/shared/speech-text-popup.dart';
import 'package:doctor_app_flutter/widgets/shared/text_fields/app-textfield-custom.dart'; import 'package:doctor_app_flutter/widgets/shared/text_fields/app-textfield-custom.dart';
import 'package:doctor_app_flutter/widgets/shared/text_fields/text_fields_utils.dart'; import 'package:doctor_app_flutter/widgets/shared/text_fields/text_fields_utils.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:hijri/hijri_calendar.dart';
import 'package:intl/intl.dart';
import 'package:permission_handler/permission_handler.dart'; import 'package:permission_handler/permission_handler.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:speech_to_text/speech_recognition_error.dart'; import 'package:speech_to_text/speech_recognition_error.dart';
@ -38,13 +41,10 @@ import 'CustomEditableText.dart';
class RegisterConfirmationPatientPage extends StatefulWidget { class RegisterConfirmationPatientPage extends StatefulWidget {
final OperationReportViewModel operationReportViewModel; final OperationReportViewModel operationReportViewModel;
final PatiantInformtion patient; final PatiantInformtion patient;
final PatientRegistrationViewModel model; final PatientRegistrationViewModel model;
const RegisterConfirmationPatientPage( const RegisterConfirmationPatientPage(
{Key key, {Key key, this.operationReportViewModel, this.patient, this.model})
this.operationReportViewModel,
this.patient, this.model})
: super(key: key); : super(key: key);
@override @override
@ -56,23 +56,39 @@ class _RegisterConfirmationPatientPageState
extends State<RegisterConfirmationPatientPage> { extends State<RegisterConfirmationPatientPage> {
bool isSubmitted = false; bool isSubmitted = false;
ProjectViewModel projectViewModel; ProjectViewModel projectViewModel;
TextEditingController firstName; TextEditingController firstNameN;
TextEditingController middleName ; TextEditingController middleNameN;
TextEditingController lastName; TextEditingController lastNameN;
TextEditingController firstNameAr;
TextEditingController middleNameAr;
TextEditingController lastNameAr;
TextEditingController emailAddressController; TextEditingController emailAddressController;
TextEditingController langController = TextEditingController(
text: "English");
int selectedLang = 1;
@override @override
void initState() { void initState() {
firstName = TextEditingController(text: widget.model.getPatientInfoResponseModel.firstNameEn); firstNameN = TextEditingController(
middleName = TextEditingController(text: ""); text: widget.model.getPatientInfoResponseModel.firstNameEn);
lastName = TextEditingController(text: widget.model.getPatientInfoResponseModel.lastNameEn); middleNameN = TextEditingController(text: "");
lastNameN = TextEditingController(
text: widget.model.getPatientInfoResponseModel.lastNameEn);
firstNameAr = TextEditingController(
text: widget.model.getPatientInfoResponseModel.firstNameAr);
middleNameAr = TextEditingController(text: "");
lastNameAr = TextEditingController(
text: widget.model.getPatientInfoResponseModel.lastNameAr);
emailAddressController = TextEditingController(text: "");
super.initState(); super.initState();
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
projectViewModel = Provider.of(context); projectViewModel = Provider.of(context);
///TODO Elham* add translation
return AppScaffold( return AppScaffold(
isShowAppBar: false, isShowAppBar: false,
backgroundColor: Color(0xFFF8F8F8), backgroundColor: Color(0xFFF8F8F8),
@ -95,23 +111,49 @@ class _RegisterConfirmationPatientPageState
child: Column( child: Column(
children: [ children: [
CustomEditableText( CustomEditableText(
controller: firstName, controller: firstNameN,
isSubmitted: isSubmitted,
hint: TranslationBase.of(context).firstName), hint: TranslationBase.of(context).firstName),
SizedBox( SizedBox(
height: 4, height: 4,
), ),
CustomEditableText( CustomEditableText(
controller: middleName, controller: middleNameN,
isEditable: middleNameN.text.isEmpty,
isSubmitted: isSubmitted,
hint: TranslationBase.of(context).middleName), hint: TranslationBase.of(context).middleName),
SizedBox( SizedBox(
height: 4, height: 4,
), ),
CustomEditableText( CustomEditableText(
controller: lastName, controller: lastNameN,
isSubmitted: isSubmitted,
hint: TranslationBase.of(context).lastName), hint: TranslationBase.of(context).lastName),
SizedBox( SizedBox(
height: 20, height: 20,
), ),
CustomEditableText(
controller: firstNameAr,
isSubmitted: isSubmitted,
hint: "First Name Arabic"),
SizedBox(
height: 4,
),
CustomEditableText(
controller: middleNameAr,
isEditable: middleNameN.text.isEmpty,
isSubmitted: isSubmitted,
hint: "Middle Name Arabic"),
SizedBox(
height: 4,
),
CustomEditableText(
controller: lastNameAr,
isSubmitted: isSubmitted,
hint: "Last Name Arabic"),
SizedBox(
height: 20,
),
FractionallySizedBox( FractionallySizedBox(
widthFactor: .9, widthFactor: .9,
child: Center( child: Center(
@ -148,7 +190,6 @@ class _RegisterConfirmationPatientPageState
color: Colors.black), color: Colors.black),
AppText( AppText(
"${widget.model.getPatientInfoResponseModel.idNumber}", "${widget.model.getPatientInfoResponseModel.idNumber}",
fontSize: 12, fontSize: 12,
color: Colors.grey[600], color: Colors.grey[600],
), ),
@ -193,7 +234,6 @@ class _RegisterConfirmationPatientPageState
color: Colors.black), color: Colors.black),
AppText( AppText(
"${widget.model.getPatientInfoResponseModel.occupation}", "${widget.model.getPatientInfoResponseModel.occupation}",
fontSize: 12, fontSize: 12,
color: Colors.grey[600], color: Colors.grey[600],
), ),
@ -222,7 +262,6 @@ class _RegisterConfirmationPatientPageState
color: Colors.black), color: Colors.black),
AppText( AppText(
"${widget.model.checkPatientForRegistrationModel.patientMobileNumber}", "${widget.model.checkPatientForRegistrationModel.patientMobileNumber}",
fontSize: 12, fontSize: 12,
color: Colors.grey[600], color: Colors.grey[600],
), ),
@ -268,6 +307,7 @@ class _RegisterConfirmationPatientPageState
onClick: () { onClick: () {
openLangList(context); openLangList(context);
}, },
controller: langController,
hintText: TranslationBase.of(context).lanEnglish, hintText: TranslationBase.of(context).lanEnglish,
maxLines: 1, maxLines: 1,
minLines: 1, minLines: 1,
@ -289,6 +329,11 @@ class _RegisterConfirmationPatientPageState
maxLines: 1, maxLines: 1,
minLines: 1, minLines: 1,
hasBorder: true, hasBorder: true,
validationError:
emailAddressController.text.isEmpty &&
isSubmitted
? TranslationBase.of(context).emptyMessage
: null,
), ),
SizedBox( SizedBox(
height: 400, height: 400,
@ -341,32 +386,93 @@ class _RegisterConfirmationPatientPageState
fontColor: Colors.white, fontColor: Colors.white,
fontSize: 2.0, fontSize: 2.0,
onPressed: () async { onPressed: () async {
GifLoaderDialogUtils.showMyDialog(context); setState(() {
PatientRegistrationModel isSubmitted = true;
patientRegistrationModel = });
PatientRegistrationModel( if (isFormValid()) {
// patientIdentificationID: print(
// int.parse(_idController.text), widget.model.getPatientInfoResponseModel.dateOfBirth);
// patientMobileNumber:
// int.parse(_phoneController.text), var dateFormat = DateFormat('MM/dd/yyyy').parse(
// zipCode: _phoneCode.text, widget.model.getPatientInfoResponseModel.dateOfBirth);
isHijri: 0, String wellFormat =
isDentalAllowedBackend: false, "${dateFormat.day}\/${dateFormat.month}\/${dateFormat.year}";
patientOutSA: 0, print(dateFormat.toUtc().toString());
generalid: GENERAL_ID, HijriCalendar hijriDate = HijriCalendar.fromDate(
// dOB: new DateTime(dateFormat.year, dateFormat.month,
// "${AppDateUtils.convertStringToDateFormat(_birthDate.toString(), "yyyy/MM/dd")}" dateFormat.day));
); // return ;
await widget.model.registrationPatient(
patientRegistrationModel);
if(widget.model.state == ViewState.ErrorLocal){
Helpers.showErrorToast(widget.model.error);
} else {
Navigator.of(context).pop();
}
GifLoaderDialogUtils.hideDialog(context); GifLoaderDialogUtils.showMyDialog(context);
PatientRegistrationModel patientRegistrationModel =
PatientRegistrationModel(
patientobject: Patientobject(
tempValue: true,
patientIdentificationNo: widget
.model
.checkPatientForRegistrationModel
.patientIdentificationID
.toString(),
patientIdentificationType: 1,
firstName: firstNameAr.text,
firstNameN: firstNameN.text,
lastName: lastNameAr.text,
lastNameN: lastNameN.text,
middleName: middleNameAr.text,
middleNameN: middleNameN.text,
strDateofBirth: dateFormat.toUtc().toString(),
dateofBirth: AppDateUtils.convertToServerFormat(
widget.model.getPatientInfoResponseModel
.dateOfBirth,
'MM/dd/yyyy'),
dateofBirthN: '$hijriDate',
gender: (widget.model.getPatientInfoResponseModel.gender == "M")
? 1
: 2,
sourceType: "1",
patientOutSA: 0,
nationalityID: widget
.model
.getPatientInfoResponseModel
.nationalityCode,
//todo Elham* change static value to dynamic
preferredLanguage: selectedLang.toString(),
marital: "0",
eHealthIDField: widget.model
.getPatientInfoResponseModel.healthId,
emailAddress: emailAddressController.text,
mobileNumber: widget
.model
.checkPatientForRegistrationModel
.patientMobileNumber),
isHijri: 0,
logInTokenID: "zjgvKtLC/EK+saznJ/OkiA==",
isDentalAllowedBackend: false,
patientOutSA: 0,
sessionID: null,
patientMobileNumber: widget
.model
.checkPatientForRegistrationModel
.patientMobileNumber
.toString(),
healthId:
widget.model.getPatientInfoResponseModel.healthId,
generalid: GENERAL_ID,
patientIdentificationID: widget.model.checkPatientForRegistrationModel.patientIdentificationID.toString(),
dOB: wellFormat,
zipCode: widget.model.checkPatientForRegistrationModel.zipCode);
await widget.model
.registrationPatient(patientRegistrationModel);
if (widget.model.state == ViewState.ErrorLocal) {
Helpers.showErrorToast(widget.model.error);
} else {
DrAppToastMsg.showSuccesToast(
"Patient added Successfully");
Navigator.of(context).pop();
}
GifLoaderDialogUtils.hideDialog(context);
}
}, },
), ),
), ),
@ -413,7 +519,6 @@ class _RegisterConfirmationPatientPageState
), ),
], ],
), ),
SizedBox( SizedBox(
height: 10, height: 10,
), ),
@ -522,19 +627,20 @@ class _RegisterConfirmationPatientPageState
), ),
], ],
), ),
SizedBox( SizedBox(
height: 10, height: 10,
), ),
InkWell( InkWell(
onTap: () {}, onTap: () {
setSelectedLang(1);
},
child: Row( child: Row(
children: [ children: [
Radio( Radio(
value: 1, value: 1,
groupValue: 1, groupValue: selectedLang,
onChanged: (value) { onChanged: (value) {
setState(() {}); setSelectedLang(value);
}, },
activeColor: Colors.red, activeColor: Colors.red,
), ),
@ -548,14 +654,17 @@ class _RegisterConfirmationPatientPageState
), ),
), ),
InkWell( InkWell(
onTap: () {}, onTap: () {
setSelectedLang(2);
},
child: Row( child: Row(
children: [ children: [
Radio( Radio(
value: 1, value: 2,
groupValue: 1, groupValue: selectedLang,
onChanged: (value) { onChanged: (value) {
setState(() {}); setSelectedLang(value);
}, },
activeColor: Colors.red, activeColor: Colors.red,
), ),
@ -568,11 +677,28 @@ class _RegisterConfirmationPatientPageState
], ],
), ),
), ),
], ],
), ),
); );
}); });
} }
setSelectedLang(lang){
setState(() {
selectedLang = lang;
langController.text = lang==1?"English": "العربيه";
});
Navigator.of(context).pop();
}
bool isFormValid() {
if (middleNameAr.text != null &&
middleNameAr.text.isNotEmpty &&
middleNameN.text != null &&
middleNameN.text.isNotEmpty &&
emailAddressController.text != null &&
emailAddressController.text.isNotEmpty) {
return true;
}
return false;
}
} }

@ -3,6 +3,7 @@ import 'package:doctor_app_flutter/screens/base/base_view.dart';
import 'package:doctor_app_flutter/screens/patients/patient_search/patient_search_header.dart'; import 'package:doctor_app_flutter/screens/patients/patient_search/patient_search_header.dart';
import 'package:doctor_app_flutter/screens/patients/profile/UCAF/page-stepper-widget.dart'; import 'package:doctor_app_flutter/screens/patients/profile/UCAF/page-stepper-widget.dart';
import 'package:doctor_app_flutter/screens/patients/register_patient/RegisterConfirmationPatientPage.dart'; import 'package:doctor_app_flutter/screens/patients/register_patient/RegisterConfirmationPatientPage.dart';
import 'package:doctor_app_flutter/screens/patients/register_patient/VerifyMethodPage.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/shared/app_scaffold_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart';
import 'package:doctor_app_flutter/widgets/shared/buttons/app_buttons_widget.dart'; import 'package:doctor_app_flutter/widgets/shared/buttons/app_buttons_widget.dart';
@ -52,7 +53,7 @@ class _RegisterPatientPageState extends State<RegisterPatientPage>
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final screenSize = MediaQuery.of(context).size; final screenSize = MediaQuery.of(context).size;
///TODO Elham* Add Translation
return BaseView<PatientRegistrationViewModel>( return BaseView<PatientRegistrationViewModel>(
builder: (_, model, w) => AppScaffold( builder: (_, model, w) => AppScaffold(
baseViewModel: model, baseViewModel: model,
@ -72,6 +73,7 @@ class _RegisterPatientPageState extends State<RegisterPatientPage>
SizedBox( SizedBox(
height: 10, height: 10,
), ),
//TODO Elham* Fix overflow
PageStepperWidget( PageStepperWidget(
stepsCount: 3, stepsCount: 3,
currentStepIndex: _currentIndex + 1, currentStepIndex: _currentIndex + 1,
@ -98,9 +100,16 @@ class _RegisterPatientPageState extends State<RegisterPatientPage>
}, },
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
children: <Widget>[ children: <Widget>[
RegisterSearchPatientPage(changePageViewIndex: changePageViewIndex,model: model), RegisterSearchPatientPage(
RegisterConfirmationPatientPage(model: model,), changePageViewIndex: changePageViewIndex,
model: model),
ActivationPage(
model: model,
changePageViewIndex: changePageViewIndex,
),
RegisterConfirmationPatientPage(
model: model,
),
]), ]),
), ),
), ),

@ -36,13 +36,15 @@ class RegisterSearchPatientPage extends StatefulWidget {
class _RegisterSearchPatientPageState extends State<RegisterSearchPatientPage> { class _RegisterSearchPatientPageState extends State<RegisterSearchPatientPage> {
String countryError; String countryError;
dynamic _selectedCountry; dynamic _selectedCountry;
bool isSubmitted = false;
TextEditingController _phoneController = TextEditingController();
TextEditingController _phoneController = TextEditingController(text: "508079569");
TextEditingController _phoneCode = TextEditingController(text: "966"); TextEditingController _phoneCode = TextEditingController(text: "966");
String phoneError; String phoneError;
TextEditingController _idController = TextEditingController(); TextEditingController _idController = TextEditingController(text: "1062938285");
String idError; String idError;
DateTime _birthDate; DateTime _birthDate;
@ -51,6 +53,7 @@ class _RegisterSearchPatientPageState extends State<RegisterSearchPatientPage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final screenSize = MediaQuery.of(context).size; final screenSize = MediaQuery.of(context).size;
/// TODO Elham* add transaltion
return AppScaffold( return AppScaffold(
baseViewModel: widget.model, baseViewModel: widget.model,
@ -83,47 +86,32 @@ class _RegisterSearchPatientPageState extends State<RegisterSearchPatientPage> {
? _selectedCountry['nameEn'] ? _selectedCountry['nameEn']
: "Saudi Arabia", : "Saudi Arabia",
enabled: false, enabled: false,
/*onClick: widget.model.dietTypesList != null && widget.model.dietTypesList.length > 0
? () {
openListDialogField('nameEn', 'id', widget.model.dietTypesList, (selectedValue) {
setState(() {
_selectedCountry = selectedValue;
});
});
}
: () async {
GifLoaderDialogUtils.showMyDialog(context);
await model
.getDietTypes(patient.patientId)
.then((_) => GifLoaderDialogUtils.hideDialog(context));
if (widget.model.state == ViewState.Idle && widget.model.dietTypesList.length > 0) {
openListDialogField('nameEn', 'id', widget.model.dietTypesList, (selectedValue) {
setState(() {
_selectedCountry = selectedValue;
});
});
} else if (widget.model.state == ViewState.ErrorLocal) {
DrAppToastMsg.showErrorToast(widget.model.error);
} else {
DrAppToastMsg.showErrorToast("Empty List");
}
},*/
), ),
SizedBox( SizedBox(
height: 10, height: 10,
), ),
Row( Row(
children: [ children: [
Container( Column(
width: MediaQuery.of(context).size.width * 0.3, children: [
child: AppTextFieldCustom( Container(
height: screenSize.height * 0.075, width: MediaQuery.of(context).size.width * 0.28,
hintText: "Code", child: AppTextFieldCustom(
inputType: TextInputType.phone, height: screenSize.height * 0.075,
controller: _phoneCode, hintText: "Code",
validationError: phoneError, inputType: TextInputType.phone,
), controller: _phoneCode,
validationError: phoneError,
),
),
if(_phoneController
.text.isEmpty &&
isSubmitted
)
SizedBox(height: 35,)
],
), ),
SizedBox(width: 10,),
Expanded( Expanded(
child: Container( child: Container(
// width: MediaQuery.of(context).size.width*0.7, // width: MediaQuery.of(context).size.width*0.7,
@ -132,7 +120,12 @@ class _RegisterSearchPatientPageState extends State<RegisterSearchPatientPage> {
hintText: "Phone Number", hintText: "Phone Number",
inputType: TextInputType.phone, inputType: TextInputType.phone,
controller: _phoneController, controller: _phoneController,
validationError: phoneError, validationError: _phoneController
.text.isEmpty &&
isSubmitted
? TranslationBase.of(context)
.emptyMessage
: null,
), ),
), ),
), ),
@ -146,7 +139,12 @@ class _RegisterSearchPatientPageState extends State<RegisterSearchPatientPage> {
hintText: "ID Number", hintText: "ID Number",
inputType: TextInputType.phone, inputType: TextInputType.phone,
controller: _idController, controller: _idController,
validationError: idError, validationError: _idController
.text.isEmpty &&
isSubmitted
? TranslationBase.of(context)
.emptyMessage
: null,
), ),
SizedBox( SizedBox(
height: 12, height: 12,
@ -167,7 +165,11 @@ class _RegisterSearchPatientPageState extends State<RegisterSearchPatientPage> {
: null, : null,
enabled: false, enabled: false,
isTextFieldHasSuffix: true, isTextFieldHasSuffix: true,
validationError: birthdateError, validationError: _birthDate == null &&
isSubmitted
? TranslationBase.of(context)
.emptyMessage
: null,
suffixIcon: IconButton( suffixIcon: IconButton(
icon: Icon( icon: Icon(
Icons.calendar_today, Icons.calendar_today,
@ -230,45 +232,54 @@ class _RegisterSearchPatientPageState extends State<RegisterSearchPatientPage> {
fontColor: Colors.white, fontColor: Colors.white,
fontSize: 2.0, fontSize: 2.0,
onPressed: () async { onPressed: () async {
GifLoaderDialogUtils.showMyDialog(context); setState(() {
CheckPatientForRegistrationModel isSubmitted = true;
checkPatientForRegistrationModel = });
CheckPatientForRegistrationModel( if(isFormValid()) {
patientIdentificationID: GifLoaderDialogUtils.showMyDialog(context);
int.parse(_idController.text), CheckPatientForRegistrationModel
patientMobileNumber: checkPatientForRegistrationModel =
int.parse(_phoneController.text), CheckPatientForRegistrationModel(
zipCode: _phoneCode.text, patientIdentificationID:
int.parse(_idController.text),
patientMobileNumber:
int.parse(_phoneController.text),
zipCode: _phoneCode.text,
isHijri: 0,
patientID: 0,
isRegister: false,
isDentalAllowedBackend: false,
patientOutSA: 0,
generalid: GENERAL_ID,
dOB:
"${AppDateUtils.convertStringToDateFormat(_birthDate.toString(), "yyyy/MM/dd")}");
await widget.model.checkPatientForRegistration(
checkPatientForRegistrationModel);
GetPatientInfoRequestModel getPatientInfoRequestModel =
GetPatientInfoRequestModel(
//TODO Elham* this return the static to dynamic
patientIdentificationID:"1062938285", //_idController.text,
isHijri: 0, isHijri: 0,
patientID: 0,
isRegister: false,
isDentalAllowedBackend: false, isDentalAllowedBackend: false,
patientOutSA: 0, patientOutSA: 0,
generalid: GENERAL_ID, generalid: GENERAL_ID,
dOB: sessionID: null,
"${AppDateUtils.convertStringToDateFormat(_birthDate.toString(), "yyyy/MM/dd")}"); dOB:"31/07/1988",//"${AppDateUtils.convertStringToDateFormat(_birthDate.toString(), "dd/MM/yyyy")}"
await widget.model.checkPatientForRegistration(
checkPatientForRegistrationModel);
GetPatientInfoRequestModel getPatientInfoRequestModel =
GetPatientInfoRequestModel(
//TODO Elham* this return the static to dynamic
patientIdentificationID:"1062938285", //_idController.text,
isHijri: 0,
isDentalAllowedBackend: false,
patientOutSA: 0,
generalid: GENERAL_ID,
sessionID: null,
dOB:"31/07/1988",//"${AppDateUtils.convertStringToDateFormat(_birthDate.toString(), "dd/MM/yyyy")}"
); );
await widget.model.getPatientInfo(getPatientInfoRequestModel); if (widget.model.state == ViewState.ErrorLocal) {
if (widget.model.state == ViewState.ErrorLocal) { Helpers.showErrorToast(widget.model.error);
Helpers.showErrorToast(widget.model.error); } else {
} else { await widget.model.getPatientInfo(getPatientInfoRequestModel);
widget.changePageViewIndex(1); if (widget.model.state == ViewState.ErrorLocal) {
Helpers.showErrorToast(widget.model.error);
} else {
widget.changePageViewIndex(1);
}
}
GifLoaderDialogUtils.hideDialog(context);
} }
GifLoaderDialogUtils.hideDialog(context);
}, },
), ),
), ),
@ -279,6 +290,14 @@ class _RegisterSearchPatientPageState extends State<RegisterSearchPatientPage> {
); );
} }
isFormValid() {
if(_phoneController.text!=null &&_phoneController.text.isNotEmpty&& _idController.text!=null &&_idController.text.isNotEmpty &&_birthDate!=null) {
return true;
}
return false;
}
Future _selectDate(BuildContext context, DateTime dateTime, Future _selectDate(BuildContext context, DateTime dateTime,
Function(DateTime picked) updateDate) async { Function(DateTime picked) updateDate) async {
final DateTime picked = await showDatePicker( final DateTime picked = await showDatePicker(

@ -0,0 +1,48 @@
import 'package:doctor_app_flutter/config/size_config.dart';
import 'package:doctor_app_flutter/core/viewModel/PatientRegistrationViewModel.dart';
import 'package:doctor_app_flutter/screens/base/base_view.dart';
import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart';
import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart';
import 'package:flutter/material.dart';
class VerifyActivationCodePage extends StatefulWidget {
const VerifyActivationCodePage({Key key}) : super(key: key);
@override
_VerifyActivationCodePageState createState() =>
_VerifyActivationCodePageState();
}
class _VerifyActivationCodePageState extends State<VerifyActivationCodePage> {
@override
Widget build(BuildContext context) {
return BaseView<PatientRegistrationViewModel>(
builder: (_, model, w) => AppScaffold(
baseViewModel: model,
isShowAppBar: false,
body: Column(
children: [
Container(
width: double.infinity,
margin: EdgeInsets.all(16.0),
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
AppText(
"Please enter the verification code sent to 02221552",
fontFamily: 'Poppins',
fontSize: SizeConfig.textMultiplier * 2.2,
fontWeight: FontWeight.w800,
),
],
),
),
)
],
),
),
);
}
}

@ -0,0 +1,504 @@
import 'package:doctor_app_flutter/config/size_config.dart';
import 'package:doctor_app_flutter/core/enum/viewstate.dart';
import 'package:doctor_app_flutter/core/model/PatientRegistration/CheckPatientForRegistrationModel.dart';
import 'package:doctor_app_flutter/core/viewModel/PatientRegistrationViewModel.dart';
import 'package:doctor_app_flutter/screens/base/base_view.dart';
import 'package:doctor_app_flutter/util/helpers.dart';
import 'package:doctor_app_flutter/util/translations_delegate_base.dart';
import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart';
import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart';
import 'package:doctor_app_flutter/widgets/shared/buttons/app_buttons_widget.dart';
import 'package:doctor_app_flutter/widgets/shared/loader/gif_loader_dialog_utils.dart';
import 'package:flutter/material.dart';
import 'package:hexcolor/hexcolor.dart';
class ActivationPage extends StatefulWidget {
final PatientRegistrationViewModel model;
final Function changePageViewIndex;
ActivationPage({this.model, this.changePageViewIndex});
@override
_ActivationPageState createState() => _ActivationPageState();
}
class _ActivationPageState extends State<ActivationPage> {
bool isSendOtp = false;
final verifyAccountForm = GlobalKey<FormState>();
TextStyle buildTextStyle() {
return TextStyle(
fontSize: SizeConfig.textMultiplier * 3,
);
}
Map verifyAccountFormValue = {
'digit1': '',
'digit2': '',
'digit3': '',
'digit4': '',
};
final focusD1 = FocusNode();
final focusD2 = FocusNode();
final focusD3 = FocusNode();
final focusD4 = FocusNode();
TextEditingController digit1 = TextEditingController(text: "");
TextEditingController digit2 = TextEditingController(text: "");
TextEditingController digit3 = TextEditingController(text: "");
TextEditingController digit4 = TextEditingController(text: "");
@override
Widget build(BuildContext context) {
return AppScaffold(
baseViewModel: widget.model,
isShowAppBar: false,
body: Column(
children: [
Visibility(
//visible: isSendOtp,
child: !isSendOtp
? Container(
width: double.infinity,
margin: EdgeInsets.all(16.0),
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
AppText(
"Please select how you want to be verified",
fontFamily: 'Poppins',
fontSize: SizeConfig.textMultiplier * 2.2,
fontWeight: FontWeight.w800,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Expanded(
child: InkWell(
onTap: () async {
// setState(() {
// isSendOtp = true;
// });
//
// await widget.model
// .sendActivationCodeByOTPNotificationType(
// otpType: 1);
await sendActivationCode(1);
},
child: Container(
height:
MediaQuery.of(context).size.height *
0.233,
margin: EdgeInsets.all(10),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(
Radius.circular(10),
),
border: Border.all(
color: HexColor('#707070'),
width: 0.1),
),
child: Column(
children: [
Row(
children: [
Image.asset(
"assets/images/verify-sms.png",
height: MediaQuery.of(context)
.size
.height *
0.15,
width: MediaQuery.of(context)
.size
.width *
0.15,
),
],
),
SizedBox(
height: 20,
),
AppText(
"Verify through SMS",
fontSize: 14,
color: Color(0xFF2E303A),
fontWeight: FontWeight.bold,
)
],
),
),
),
),
Expanded(
child: InkWell(
onTap: () async {
await sendActivationCode(2);
},
child: Container(
height:
MediaQuery.of(context).size.height *
0.233,
margin: EdgeInsets.all(10),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(
Radius.circular(10),
),
border: Border.all(
color: HexColor('#707070'),
width: 0.1),
),
child: Column(
children: [
Row(
children: [
Image.asset(
"assets/images/verify-whtsapp.png",
height: MediaQuery.of(context)
.size
.height *
0.15,
width: MediaQuery.of(context)
.size
.width *
0.15,
),
],
),
SizedBox(
height: 20,
),
AppText(
"Verify through WhatsApp",
fontSize: 14,
color: Color(0xFF2E303A),
fontWeight: FontWeight.bold,
)
],
),
),
),
),
],
),
],
),
),
)
: Container(
width: double.infinity,
margin: EdgeInsets.all(16.0),
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
AppText(
"Please enter the verification code sent to 02221552",
fontFamily: 'Poppins',
fontSize: SizeConfig.textMultiplier * 2.2,
fontWeight: FontWeight.w800,
),
Row(
children: [
Center(
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Form(
key: verifyAccountForm,
child: Padding(
padding: EdgeInsets.only(top: 20),
child: Directionality(
textDirection: TextDirection.ltr,
child: Row(
mainAxisAlignment:
MainAxisAlignment.start,
children: <Widget>[
Container(
width: SizeConfig
.realScreenWidth *
0.16,
margin: EdgeInsets.all(5),
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.16,
margin: EdgeInsets.all(5),
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(
margin: EdgeInsets.all(5),
width: SizeConfig
.realScreenWidth *
0.16,
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(
margin: EdgeInsets.all(5),
width: SizeConfig
.realScreenWidth *
0.16,
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: const EdgeInsets.all(12.0),
child: Column(
mainAxisAlignment:
MainAxisAlignment.start,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
AppText(
TranslationBase.of(context)
.validationMessage +
' ',
fontWeight: FontWeight.w600,
fontSize: 14,
),
// AppText(
// displayTime,
// color: Colors.red,
// textAlign: TextAlign.start,
// fontWeight: FontWeight.bold,
// fontSize: 14,
// )
]),
)
],
))),
],
),
],
),
),
),
)
],
),
bottomSheet: isSendOtp
? Container(
height: 60,
margin: EdgeInsets.symmetric(vertical: 16, horizontal: 16),
child: Row(
children: [
Expanded(
child: Container(
child: AppButton(
title: TranslationBase.of(context).cancel,
hasBorder: true,
vPadding: 12,
hPadding: 8,
borderColor: Color(0xFFeaeaea),
color: Color(0xFFeaeaea),
fontColor: Colors.black,
fontSize: 2.2,
onPressed: () {
Navigator.of(context).pop();
},
),
),
),
SizedBox(
width: 8,
),
Expanded(
child: Container(
child: AppButton(
title: TranslationBase.of(context).next,
hasBorder: true,
vPadding: 12,
hPadding: 8,
borderColor: Color(0xFFB8382B),
color: Color(0xFFB8382B),
fontColor: Colors.white,
fontSize: 2.0,
onPressed: () async {
GifLoaderDialogUtils.showMyDialog(context);
await widget.model.checkActivationCode("${digit1.text}${digit2.text}${digit3.text}${digit4.text}");
if (widget.model.state == ViewState.ErrorLocal) {
Helpers.showErrorToast(widget.model.error);
//TODO Elham* remove this
widget.changePageViewIndex(2);
GifLoaderDialogUtils.hideDialog(context);
} else {
GifLoaderDialogUtils.hideDialog(context);
widget.changePageViewIndex(2);
}
},
),
),
),
],
),
)
: null);
}
sendActivationCode(type) async {
GifLoaderDialogUtils.showMyDialog(context);
await widget.model.sendActivationCodeByOTPNotificationType(otpType: type);
if (widget.model.state == ViewState.ErrorLocal) {
Helpers.showErrorToast(widget.model.error);
GifLoaderDialogUtils.hideDialog(context);
// TODO Elham* retuen the else
// } else {
setState(() {
isSendOtp = true;
});
}
}
InputDecoration buildInputDecoration(BuildContext context) {
return InputDecoration(
counterText: " ",
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(10)),
borderSide: BorderSide(color: Colors.grey[300]),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(10.0)),
borderSide: BorderSide(color: Colors.grey[300]),
),
errorBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(10.0)),
borderSide: BorderSide(color: Colors.grey[300]),
),
focusedErrorBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(10.0)),
borderSide: BorderSide(color: Theme.of(context).errorColor),
),
);
}
}

@ -24,6 +24,10 @@ class AppDateUtils {
return convertDateToFormat(dateTime, dateFormat); return convertDateToFormat(dateTime, dateFormat);
} }
static String convertToServerFormat(String date, String dateFormat){
return '/Date(${DateFormat(dateFormat).parse(date).millisecondsSinceEpoch})/';
}
static convertDateFromServerFormat(String str, dateFormat) { static convertDateFromServerFormat(String str, dateFormat) {
var date = getDateTimeFromServerFormat(str); var date = getDateTimeFromServerFormat(str);

@ -574,6 +574,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.6" version: "1.0.6"
hijri:
dependency: "direct main"
description:
name: hijri
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.3"
html: html:
dependency: "direct main" dependency: "direct main"
description: description:

@ -103,6 +103,11 @@ dependencies:
# Badges # Badges
badges: ^1.1.4 badges: ^1.1.4
# Hijri
hijri: ^2.0.0
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:
sdk: flutter sdk: flutter

Loading…
Cancel
Save