symptoms checker suggestions from infermedia inprogress

pull/327/head
faizatflutter 3 weeks ago
parent b77b4db2c8
commit 826d12e57d

@ -370,6 +370,12 @@
"clickHere": "انقر هنا", "clickHere": "انقر هنا",
"iAgreeToTheTermsAndConditions": "أوافق على الشروط والأحكام ", "iAgreeToTheTermsAndConditions": "أوافق على الشروط والأحكام ",
"iAgreeToTheTermsAndConditionsSubtitle": "أوافق على الشروط والأحكام ", "iAgreeToTheTermsAndConditionsSubtitle": "أوافق على الشروط والأحكام ",
"iAgreeAndAcceptTermsAndConditions": "أوافق وأقبل ",
"termsAndConditions": "الشروط والأحكام",
"iAgreeHealthInfoCanBeUsed": "أوافق على استخدام معلوماتي الصحية للمقابلة. مزيد من المعلومات في ",
"privacyPolicyText": "سياسة الخصوصية",
"outPatient": "العيادات الخارجيه",
"thisInvoiceIsNotEligibleForRefund": "هذه الفاتورة غير مؤهلة لاسترداد الأموال",
"save": "حفظ", "save": "حفظ",
"userAgreement": "اتفاقية المستخدم", "userAgreement": "اتفاقية المستخدم",
"updateSuccessfully": "تم التحديث بنجاح", "updateSuccessfully": "تم التحديث بنجاح",
@ -1893,5 +1899,6 @@
"referenceNo": "رقم المرجع", "referenceNo": "رقم المرجع",
"advanceNumber": "رقم الدفعة المقدمة", "advanceNumber": "رقم الدفعة المقدمة",
"amountOnly": "المبلغ", "amountOnly": "المبلغ",
"invoiceHistory": "سجل الفواتير" "invoiceHistory": "سجل الفواتير",
"refund": "استرداد"
} }

@ -366,6 +366,12 @@
"clickHere": "Click here", "clickHere": "Click here",
"iAgreeToTheTermsAndConditions": "I agree to the terms and conditions ", "iAgreeToTheTermsAndConditions": "I agree to the terms and conditions ",
"iAgreeToTheTermsAndConditionsSubtitle": "I agree to the terms and conditions ", "iAgreeToTheTermsAndConditionsSubtitle": "I agree to the terms and conditions ",
"iAgreeAndAcceptTermsAndConditions": "I agree and accept ",
"termsAndConditions": "Terms and Conditions",
"iAgreeHealthInfoCanBeUsed": "I agree that my health information can be used for the interview. More information in the ",
"privacyPolicyText": "Privacy Policy",
"outPatient": "Out Patient",
"thisInvoiceIsNotEligibleForRefund": "This invoice is not eligible for refund",
"save": "Save", "save": "Save",
"userAgreement": "User Agreement", "userAgreement": "User Agreement",
"updateSuccessfully": "Update Successfully", "updateSuccessfully": "Update Successfully",
@ -1887,7 +1893,6 @@
"advanceNumber": "Advance Number", "advanceNumber": "Advance Number",
"amountOnly": "Amount", "amountOnly": "Amount",
"invoiceHistory": "Invoice History" "invoiceHistory": "Invoice History"
} }

@ -255,7 +255,7 @@ class ApiClientImp implements ApiClient {
body: requestBody, body: requestBody,
headers: headers, headers: headers,
); );
log("response: ${response.body.toString()}"); // log("response: ${response.body.toString()}");
} on SocketException catch (e) { } on SocketException catch (e) {
final message = e.message.contains('Connection reset by peer') ? LocaleKeys.networkConnectionReset.tr() : LocaleKeys.networkErrorMessage.tr(); final message = e.message.contains('Connection reset by peer') ? LocaleKeys.networkConnectionReset.tr() : LocaleKeys.networkErrorMessage.tr();
onFailure(message, -1, failureType: ConnectivityFailure(message)); onFailure(message, -1, failureType: ConnectivityFailure(message));

@ -4,7 +4,7 @@ import 'package:hmg_patient_app_new/core/enums.dart';
class ApiConsts { class ApiConsts {
static const maxSmallScreen = 660; static const maxSmallScreen = 660;
static AppEnvironmentTypeEnum appEnvironmentType = AppEnvironmentTypeEnum.prod; static AppEnvironmentTypeEnum appEnvironmentType = AppEnvironmentTypeEnum.uat;
// static String baseUrl = 'https://uat.hmgwebservices.com/'; // HIS API URL UAT // static String baseUrl = 'https://uat.hmgwebservices.com/'; // HIS API URL UAT
@ -1011,33 +1011,9 @@ class ApiKeyConstants {
static final String googleMapsApiKey = 'AIzaSyB6TERnxIr0yJ3qG4ULBZbu0sAD4tGqtng'; static final String googleMapsApiKey = 'AIzaSyB6TERnxIr0yJ3qG4ULBZbu0sAD4tGqtng';
} }
//flutter: URL : https://hmgwebservices.com/Services/H2ORemainder.svc/REST/H2O_InsertUserActivity class AppUrls {
// flutter: {"IdentificationNo":"2530976584","MobileNumber":"504278212","QuantityIntake":200,"VersionID":20.0,"Channel":3,"LanguageID":2,"IPAdress":"10.20.10.20","generalid":"Cs2020@2016$2958","PatientOutSA":0,"SessionID":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlblR5cGUiOjIsIm9iaiI6eyJUaW1lIjoiMjAyNS0xMi0yOFQwODozNjo0My45MTY0MzRaIiwiUGF0aWVudElEIjoiNDUxNTY5NyIsIlBhdGllbnRNZXJnZWRJRHMiOiI0NTE1Njk3IiwiUGF0aWVudE91dFNBIjpmYWxzZX0sImV4cCI6MTc2Njk2NjQwMH0.l1rCcs2OAU5u2J-iZMiO7NX6shGzLJV0hlYtVh2JeqY","isDentalAllowedBackend":false,"DeviceTypeID":1,"PatientID":4515697,"TokenID":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlblR5cGUiOjIsIm9iaiI6eyJUaW1lIjoiMjAyNS0xMi0yOFQwODozNjo0My45MTY0MzRaIiwiUGF0aWVudElEIjoiNDUxNTY5NyIsIlBhdGllbnRNZXJnZWRJRHMiOiI0NTE1Njk3IiwiUGF0aWVudE91dFNBIjpmYWxzZX0sImV4cCI6MTc2Njk2NjQwMH0.l1rCcs2OAU5u2J-iZMiO7NX6shGzLJV0hlYtVh2JeqY","PatientTypeID":1,"PatientType":1,"Latitude":37.785834,"Longitude":-122.406417} static final hmgTermsUrlEn = 'https://hmg.com/en/Pages/Terms.aspx';
// flutter: response.body: static final hmgPrivacyUrlEn = 'https://hmg.com/en/Pages/Privacy.aspx';
// flutter: {"Date":null,"LanguageID":0,"ServiceName":0,"Time":null,"AndroidLink":null,"AuthenticationTokenID":null,"Data":null,"Dataw":false,"DietType":0,"DietTypeID":0,"ErrorCode":null,"ErrorEndUserMessage":null,"ErrorEndUserMessageN":null,"ErrorMessage":null,"ErrorStatusCode":0,"ErrorType":0,"FoodCategory":0,"IOSLink":null,"IsAuthenticated":true,"MealOrderStatus":0,"MealType":0,"MessageStatus":1,"NumberOfResultRecords":0,"PatientBlodType":null,"SuccessMsg":null,"SuccessMsgN":null,"VidaUpdatedResponse":null,"IsHMGPatient":false,"LogInTokenID":null,"PhysicalActivityData":null,"RowExists":0,"UserDetailData":null,"UserDetailData_New":null,"UserProgressForMonthData":null,"UserProgressForTodayData":[{"QuantityConsumed":200.00,"PercentageConsumed":9.41,"PercentageLeft":90.59,"QuantityLimit":2125.00}],"UserProgressForWeekData":null,"UserProgressHistoryData":[{"Quantity":200.000,"CreatedDate":"\/Date(1766911222217+0300)\/"}],"VerificationCode":null,"isSMSSent":false} static final hmgTermsUrlAr = 'https://hmg.com/ar/Pages/Terms.aspx';
static final hmgPrivacyUrlAr = 'https://hmg.com/ar/Pages/Privacy.aspx';
// URL : https://hmgwebservices.com/Services/H2ORemainder.svc/REST/H2o_UndoUserActivity }
// flutter: {"Progress":1,"MobileNumber":"504278212","IdentificationNo":"2530976584","VersionID":20.0,"Channel":3,"LanguageID":2,"IPAdress":"10.20.10.20","generalid":"Cs2020@2016$2958","PatientOutSA":0,"SessionID":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlblR5cGUiOjIsIm9iaiI6eyJUaW1lIjoiMjAyNS0xMi0yOFQwODozNjo0My45MTY0MzRaIiwiUGF0aWVudElEIjoiNDUxNTY5NyIsIlBhdGllbnRNZXJnZWRJRHMiOiI0NTE1Njk3IiwiUGF0aWVudE91dFNBIjpmYWxzZX0sImV4cCI6MTc2Njk2NjQwMH0.l1rCcs2OAU5u2J-iZMiO7NX6shGzLJV0hlYtVh2JeqY","isDentalAllowedBackend":false,"DeviceTypeID":1,"PatientID":4515697,"TokenID":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlblR5cGUiOjIsIm9iaiI6eyJUaW1lIjoiMjAyNS0xMi0yOFQwODozNjo0My45MTY0MzRaIiwiUGF0aWVudElEIjoiNDUxNTY5NyIsIlBhdGllbnRNZXJnZWRJRHMiOiI0NTE1Njk3IiwiUGF0aWVudE91dFNBIjpmYWxzZX0sImV4cCI6MTc2Njk2NjQwMH0.l1rCcs2OAU5u2J-iZMiO7NX6shGzLJV0hlYtVh2JeqY","PatientTypeID":1,"PatientType":1,"Latitude":37.785834,"Longitude":-122.406417}
// flutter: response.body:
// flutter: {"Date":null,"LanguageID":0,"ServiceName":0,"Time":null,"AndroidLink":null,"AuthenticationTokenID":null,"Data":null,"Dataw":false,"DietType":0,"DietTypeID":0,"ErrorCode":null,"ErrorEndUserMessage":null,"ErrorEndUserMessageN":null,"ErrorMessage":null,"ErrorStatusCode":0,"ErrorType":0,"FoodCategory":0,"IOSLink":null,"IsAuthenticated":false,"MealOrderStatus":0,"MealType":0,"MessageStatus":1,"NumberOfResultRecords":0,"PatientBlodType":null,"SuccessMsg":null,"SuccessMsgN":null,"VidaUpdatedResponse":null,"IsHMGPatient":false,"LogInTokenID":null,"PhysicalActivityData":null,"RowExists":0,"UserDetailData":null,"UserDetailData_New":null,"UserProgressForMonthData":null,"UserProgressForTodayData":[{"QuantityConsumed":0.00,"PercentageConsumed":0.00,"PercentageLeft":100.00,"QuantityLimit":2125.00}],"UserProgressForWeekData":null,"UserProgressHistoryData":[],"VerificationCode":null,"isSMSSent":false}
// Progress":2 means weekly data
// flutter: URL : https://hmgwebservices.com/Services/H2ORemainder.svc/REST/H2O_GetUserProgress
// flutter: {"Progress":2,"MobileNumber":"504278212","IdentificationNo":"2530976584","VersionID":20.0,"Channel":3,"LanguageID":2,"IPAdress":"10.20.10.20","generalid":"Cs2020@2016$2958","PatientOutSA":0,"SessionID":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlblR5cGUiOjIsIm9iaiI6eyJUaW1lIjoiMjAyNS0xMi0yOFQwODozNjo0My45MTY0MzRaIiwiUGF0aWVudElEIjoiNDUxNTY5NyIsIlBhdGllbnRNZXJnZWRJRHMiOiI0NTE1Njk3IiwiUGF0aWVudE91dFNBIjpmYWxzZX0sImV4cCI6MTc2Njk2NjQwMH0.l1rCcs2OAU5u2J-iZMiO7NX6shGzLJV0hlYtVh2JeqY","isDentalAllowedBackend":false,"DeviceTypeID":1,"PatientID":4515697,"TokenID":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlblR5cGUiOjIsIm9iaiI6eyJUaW1lIjoiMjAyNS0xMi0yOFQwODozNjo0My45MTY0MzRaIiwiUGF0aWVudElEIjoiNDUxNTY5NyIsIlBhdGllbnRNZXJnZWRJRHMiOiI0NTE1Njk3IiwiUGF0aWVudE91dFNBIjpmYWxzZX0sImV4cCI6MTc2Njk2NjQwMH0.l1rCcs2OAU5u2J-iZMiO7NX6shGzLJV0hlYtVh2JeqY","PatientTypeID":1,"PatientType":1,"Latitude":37.785834,"Longitude":-122.406417}
// flutter: response.body:
// [log] {"Date":null,"LanguageID":0,"ServiceName":0,"Time":null,"AndroidLink":null,"AuthenticationTokenID":null,"Data":null,"Dataw":false,"DietType":0,"DietTypeID":0,"ErrorCode":null,"ErrorEndUserMessage":null,"ErrorEndUserMessageN":null,"ErrorMessage":null,"ErrorStatusCode":0,"ErrorType":0,"FoodCategory":0,"IOSLink":null,"IsAuthenticated":false,"MealOrderStatus":0,"MealType":0,"MessageStatus":1,"NumberOfResultRecords":0,"PatientBlodType":null,"SuccessMsg":null,"SuccessMsgN":null,"VidaUpdatedResponse":null,"IsHMGPatient":false,"LogInTokenID":null,"PhysicalActivityData":null,"RowExists":0,"UserDetailData":null,"UserDetailData_New":null,"UserProgressForMonthData":null,"UserProgressForTodayData":null,"UserProgressForWeekData":[{"DayNumber":1,"DayDate":null,"DayName":"Sunday","PercentageConsumed":0},{"DayNumber":7,"DayDate":null,"DayName":"Saturday","PercentageConsumed":0},{"DayNumber":6,"DayDate":null,"DayName":"Friday","PercentageConsumed":0},{"DayNumber":5,"DayDate":null,"DayName":"Thursday","PercentageConsumed":0},{"DayNumber":4,"DayDate":null,"DayName":"Wednesday","PercentageConsumed":0},{"DayNumber":3,"DayDate":null,"DayName":"Tuesday","PercentageConsumed":0},{"DayNumber":2,"DayDate":null,"DayName":"Monday","PercentageConsumed":0}],"UserProgressHistoryData":[],"VerificationCode":null,"isSMSSent":false}
// Progress":1 means daily data
//URL : https://hmgwebservices.com/Services/H2ORemainder.svc/REST/H2O_GetUserProgress
// flutter: {"Progress":1,"MobileNumber":"504278212","IdentificationNo":"2530976584","VersionID":20.0,"Channel":3,"LanguageID":2,"IPAdress":"10.20.10.20","generalid":"Cs2020@2016$2958","PatientOutSA":0,"SessionID":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlblR5cGUiOjIsIm9iaiI6eyJUaW1lIjoiMjAyNS0xMi0yOFQwODozNjo0My45MTY0MzRaIiwiUGF0aWVudElEIjoiNDUxNTY5NyIsIlBhdGllbnRNZXJnZWRJRHMiOiI0NTE1Njk3IiwiUGF0aWVudE91dFNBIjpmYWxzZX0sImV4cCI6MTc2Njk2NjQwMH0.l1rCcs2OAU5u2J-iZMiO7NX6shGzLJV0hlYtVh2JeqY","isDentalAllowedBackend":false,"DeviceTypeID":1,"PatientID":4515697,"TokenID":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlblR5cGUiOjIsIm9iaiI6eyJUaW1lIjoiMjAyNS0xMi0yOFQwODozNjo0My45MTY0MzRaIiwiUGF0aWVudElEIjoiNDUxNTY5NyIsIlBhdGllbnRNZXJnZWRJRHMiOiI0NTE1Njk3IiwiUGF0aWVudE91dFNBIjpmYWxzZX0sImV4cCI6MTc2Njk2NjQwMH0.l1rCcs2OAU5u2J-iZMiO7NX6shGzLJV0hlYtVh2JeqY","PatientTypeID":1,"PatientType":1,"Latitude":37.785834,"Longitude":-122.406417}
// flutter: response.body:
// flutter: {"Date":null,"LanguageID":0,"ServiceName":0,"Time":null,"AndroidLink":null,"AuthenticationTokenID":null,"Data":null,"Dataw":false,"DietType":0,"DietTypeID":0,"ErrorCode":null,"ErrorEndUserMessage":null,"ErrorEndUserMessageN":null,"ErrorMessage":null,"ErrorStatusCode":0,"ErrorType":0,"FoodCategory":0,"IOSLink":null,"IsAuthenticated":false,"MealOrderStatus":0,"MealType":0,"MessageStatus":1,"NumberOfResultRecords":0,"PatientBlodType":null,"SuccessMsg":null,"SuccessMsgN":null,"VidaUpdatedResponse":null,"IsHMGPatient":false,"LogInTokenID":null,"PhysicalActivityData":null,"RowExists":0,"UserDetailData":null,"UserDetailData_New":null,"UserProgressForMonthData":null,"UserProgressForTodayData":[{"QuantityConsumed":0.00,"PercentageConsumed":0.00,"PercentageLeft":100.00,"QuantityLimit":2125.00}],"UserProgressForWeekData":null,"UserProgressHistoryData":[],"VerificationCode":null,"isSMSSent":false}
// Progress":1 means monthly data
// flutter: URL : https://hmgwebservices.com/Services/H2ORemainder.svc/REST/H2O_GetUserProgress
// flutter: {"Progress":3,"MobileNumber":"504278212","IdentificationNo":"2530976584","VersionID":20.0,"Channel":3,"LanguageID":2,"IPAdress":"10.20.10.20","generalid":"Cs2020@2016$2958","PatientOutSA":0,"SessionID":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlblR5cGUiOjIsIm9iaiI6eyJUaW1lIjoiMjAyNS0xMi0yOFQwODozNjo0My45MTY0MzRaIiwiUGF0aWVudElEIjoiNDUxNTY5NyIsIlBhdGllbnRNZXJnZWRJRHMiOiI0NTE1Njk3IiwiUGF0aWVudE91dFNBIjpmYWxzZX0sImV4cCI6MTc2Njk2NjQwMH0.l1rCcs2OAU5u2J-iZMiO7NX6shGzLJV0hlYtVh2JeqY","isDentalAllowedBackend":false,"DeviceTypeID":1,"PatientID":4515697,"TokenID":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlblR5cGUiOjIsIm9iaiI6eyJUaW1lIjoiMjAyNS0xMi0yOFQwODozNjo0My45MTY0MzRaIiwiUGF0aWVudElEIjoiNDUxNTY5NyIsIlBhdGllbnRNZXJnZWRJRHMiOiI0NTE1Njk3IiwiUGF0aWVudE91dFNBIjpmYWxzZX0sImV4cCI6MTc2Njk2NjQwMH0.l1rCcs2OAU5u2J-iZMiO7NX6shGzLJV0hlYtVh2JeqY","PatientTypeID":1,"PatientType":1,"Latitude":37.785834,"Longitude":-122.406417}
// flutter: response.body:
// [log] {"Date":null,"LanguageID":0,"ServiceName":0,"Time":null,"AndroidLink":null,"AuthenticationTokenID":null,"Data":null,"Dataw":false,"DietType":0,"DietTypeID":0,"ErrorCode":null,"ErrorEndUserMessage":null,"ErrorEndUserMessageN":null,"ErrorMessage":null,"ErrorStatusCode":0,"ErrorType":0,"FoodCategory":0,"IOSLink":null,"IsAuthenticated":false,"MealOrderStatus":0,"MealType":0,"MessageStatus":1,"NumberOfResultRecords":0,"PatientBlodType":null,"SuccessMsg":null,"SuccessMsgN":null,"VidaUpdatedResponse":null,"IsHMGPatient":false,"LogInTokenID":null,"PhysicalActivityData":null,"RowExists":0,"UserDetailData":null,"UserDetailData_New":null,"UserProgressForMonthData":[{"MonthNumber":1,"MonthName":"January","PercentageConsumed":0},{"MonthNumber":2,"MonthName":"February","PercentageConsumed":0},{"MonthNumber":3,"MonthName":"March","PercentageConsumed":0},{"MonthNumber":4,"MonthName":"April","PercentageConsumed":0},{"MonthNumber":5,"MonthName":"May","PercentageConsumed":0},{"MonthNumber":6,"MonthName":"June","PercentageConsumed":0},{"MonthNumber":7,"MonthName":"July","PercentageConsumed":0},{"MonthNumber":8,"MonthName":"August","PercentageConsumed":0},{"MonthNumber":9,"MonthName":"September","PercentageConsumed":0},{"MonthNumber":10,"MonthName":"October","PercentageConsumed":0},{"MonthNumber":11,"MonthName":"November","PercentageConsumed":0},{"MonthNumber":12,"MonthName":"December","PercentageConsumed":0}],"UserProgressForTodayData":null,"UserProgressForWeekData":null,"UserProgressHistoryData":[],"VerificationCode":null,"isSMSSent":false}

@ -40,7 +40,7 @@ abstract class SymptomsCheckerRepo {
Future<Either<Failure, GenericApiModel<RiskAndSuggestionsResponseModel>>> getSuggestions({ Future<Either<Failure, GenericApiModel<RiskAndSuggestionsResponseModel>>> getSuggestions({
required int age, required int age,
required int gender, required int gender,
required List<String> evidenceIds, required List<Map<String, dynamic>> evidenceList,
required String language, required String language,
required String userSessionToken, required String userSessionToken,
required String sessionId, required String sessionId,
@ -49,7 +49,7 @@ abstract class SymptomsCheckerRepo {
Future<Either<Failure, GenericApiModel<TriageDataDetails>>> getDiagnosisForTriage({ Future<Either<Failure, GenericApiModel<TriageDataDetails>>> getDiagnosisForTriage({
required int age, required int age,
required int gender, required int gender,
required List<String> evidenceIds, required List<Map<String, dynamic>> initialEvidenceList,
List<Map<String, String>>? triageEvidence, List<Map<String, String>>? triageEvidence,
required String language, required String language,
required String userSessionToken, required String userSessionToken,
@ -201,12 +201,20 @@ class SymptomsCheckerRepoImp implements SymptomsCheckerRepo {
required String userSessionToken, required String userSessionToken,
required String sessionId, required String sessionId,
}) async { }) async {
// Build evidence list with "initial" source for symptoms
final List<Map<String, dynamic>> evidenceList = evidenceIds.map((id) {
return {
"id": id,
"source": "initial",
};
}).toList();
final Map<String, dynamic> body = { final Map<String, dynamic> body = {
"age": { "age": {
"value": age, "value": age,
}, },
"gender": gender, "gender": gender,
"evidence": evidenceIds.map((id) => {"id": id}).toList(), "evidence": evidenceList,
"language": language, "language": language,
"generalId": sessionId, "generalId": sessionId,
}; };
@ -265,21 +273,19 @@ class SymptomsCheckerRepoImp implements SymptomsCheckerRepo {
Future<Either<Failure, GenericApiModel<TriageDataDetails>>> getDiagnosisForTriage({ Future<Either<Failure, GenericApiModel<TriageDataDetails>>> getDiagnosisForTriage({
required int age, required int age,
required int gender, required int gender,
required List<String> evidenceIds, required List<Map<String, dynamic>> initialEvidenceList,
List<Map<String, String>>? triageEvidence, // Additional triage-specific evidence List<Map<String, String>>? triageEvidence, // Additional triage-specific evidence
required String language, required String language,
required String userSessionToken, required String userSessionToken,
required String sessionId, required String sessionId,
}) async { }) async {
// Build evidence list: combine initial symptoms with triage evidence // Build evidence list: combine initial evidence (with sources) with triage evidence
List<Map<String, dynamic>> evidenceList = []; List<Map<String, dynamic>> evidenceList = [];
// Add initial evidence as simple IDs // Add initial evidence (already has sources: initial, red_flags, suggest)
for (var id in evidenceIds) { evidenceList.addAll(initialEvidenceList);
evidenceList.add({"id": id});
}
// Add triage evidence with proper format (id, choice_id, source) // Add triage evidence with proper format (id, choice_id, source=triage)
if (triageEvidence != null && triageEvidence.isNotEmpty) { if (triageEvidence != null && triageEvidence.isNotEmpty) {
evidenceList.addAll(triageEvidence); evidenceList.addAll(triageEvidence);
} }
@ -351,7 +357,7 @@ class SymptomsCheckerRepoImp implements SymptomsCheckerRepo {
Future<Either<Failure, GenericApiModel<RiskAndSuggestionsResponseModel>>> getSuggestions({ Future<Either<Failure, GenericApiModel<RiskAndSuggestionsResponseModel>>> getSuggestions({
required int age, required int age,
required int gender, required int gender,
required List<String> evidenceIds, required List<Map<String, dynamic>> evidenceList,
required String language, required String language,
required String userSessionToken, required String userSessionToken,
required String sessionId, required String sessionId,
@ -361,7 +367,7 @@ class SymptomsCheckerRepoImp implements SymptomsCheckerRepo {
"value": age, "value": age,
}, },
"gender": gender, "gender": gender,
"evidence": evidenceIds.map((id) => {"id": id}).toList(), "evidence": evidenceList,
"language": language, "language": language,
"generalId": sessionId, "generalId": sessionId,
}; };

@ -87,6 +87,10 @@ class SymptomsCheckerViewModel extends ChangeNotifier {
String? _selectedSingleItemId; // Store which item was selected String? _selectedSingleItemId; // Store which item was selected
int? _selectedSingleChoiceIndex; // Store which choice was selected int? _selectedSingleChoiceIndex; // Store which choice was selected
// Triage question history tracking
final List<TriageDataDetails> _triageQuestionHistory = []; // Stack of previous questions
final List<List<Map<String, String>>> _triageEvidenceHistory = []; // Stack of evidence states at each question
// Selected risk factors tracking // Selected risk factors tracking
final Set<String> _selectedRiskFactorIds = {}; final Set<String> _selectedRiskFactorIds = {};
@ -178,6 +182,9 @@ class SymptomsCheckerViewModel extends ChangeNotifier {
/// Get the number of triage questions answered /// Get the number of triage questions answered
int get triageQuestionCount => _triageQuestionCount; int get triageQuestionCount => _triageQuestionCount;
/// Check if this is the first triage question (no history)
bool get isFirstTriageQuestion => _triageQuestionHistory.isEmpty;
List<GetClinicDetailsResponseModel> clinicDetailsList = []; List<GetClinicDetailsResponseModel> clinicDetailsList = [];
/// Get choice index for a specific item /// Get choice index for a specific item
@ -745,6 +752,44 @@ class SymptomsCheckerViewModel extends ChangeNotifier {
return evidenceIds; return evidenceIds;
} }
/// Get all evidence with their sources based on selection step
/// Source values:
/// - "initial" for symptoms (used in GetRiskFactors)
/// - "red_flags" for risk factors (used in GetSuggestions)
/// - "suggest" for suggestions (used in GetDiagnosis)
List<Map<String, dynamic>> getAllEvidenceWithSources({String defaultSource = "initial"}) {
List<Map<String, dynamic>> evidenceList = [];
// Add selected symptoms with source "initial"
final selectedSymptoms = getAllSelectedSymptoms();
for (var symptom in selectedSymptoms.where((s) => s.id != null)) {
evidenceList.add({
"id": symptom.id!,
"source": "initial",
});
}
// Add selected risk factors with source "red_flags" (excluding "not_applicable")
final selectedRiskFactors = getAllSelectedRiskFactors();
for (var riskFactor in selectedRiskFactors.where((rf) => rf.id != null && rf.id != "not_applicable")) {
evidenceList.add({
"id": riskFactor.id!,
"source": "red_flags",
});
}
// Add selected suggestions with source "suggest" (excluding "not_applicable")
final selectedSuggestions = getAllSelectedSuggestions();
for (var suggestion in selectedSuggestions.where((s) => s.id != null && s.id != "not_applicable")) {
evidenceList.add({
"id": suggestion.id!,
"source": "suggest",
});
}
return evidenceList;
}
/// Fetch risk factors based on selected symptoms /// Fetch risk factors based on selected symptoms
Future<void> fetchSuggestions({ Future<void> fetchSuggestions({
Function()? onSuccess, Function()? onSuccess,
@ -768,21 +813,30 @@ class SymptomsCheckerViewModel extends ChangeNotifier {
return; return;
} }
// Extract symptom IDs // Build evidence list with proper sources
List<String> evidenceIds = selectedSymptoms.where((s) => s.id != null).map((s) => s.id!).toList(); List<Map<String, dynamic>> evidenceList = [];
// Get all selected symptoms // Add selected symptoms with source "initial"
final selectedRisks = getAllSelectedRiskFactors(); for (var symptom in selectedSymptoms.where((s) => s.id != null)) {
evidenceList.add({
"id": symptom.id!,
"source": "initial",
});
}
if (selectedRisks.isNotEmpty) { // Get selected risk factors and add with source "red_flags"
List<String> evidenceRisksIds = selectedRisks.where((s) => s.id != null && s.id != "not_applicable").map((s) => s.id!).toList(); final selectedRisks = getAllSelectedRiskFactors();
evidenceIds.addAll(evidenceRisksIds); for (var riskFactor in selectedRisks.where((rf) => rf.id != null && rf.id != "not_applicable")) {
evidenceList.add({
"id": riskFactor.id!,
"source": "red_flags",
});
} }
await getSuggestions( await getSuggestions(
age: _selectedAge!, age: _selectedAge!,
gender: _getGenderAsInt(_selectedGender), gender: _getGenderAsInt(_selectedGender),
evidenceIds: evidenceIds, evidenceList: evidenceList,
language: appState.isArabic() ? 'ar' : 'en', language: appState.isArabic() ? 'ar' : 'en',
onSuccess: (response) { onSuccess: (response) {
if (onSuccess != null) { if (onSuccess != null) {
@ -801,7 +855,7 @@ class SymptomsCheckerViewModel extends ChangeNotifier {
Future<void> getSuggestions({ Future<void> getSuggestions({
required int age, required int age,
required int gender, required int gender,
required List<String> evidenceIds, required List<Map<String, dynamic>> evidenceList,
required String language, required String language,
Function(RiskAndSuggestionsResponseModel)? onSuccess, Function(RiskAndSuggestionsResponseModel)? onSuccess,
Function(String)? onError, Function(String)? onError,
@ -812,7 +866,7 @@ class SymptomsCheckerViewModel extends ChangeNotifier {
final result = await symptomsCheckerRepo.getSuggestions( final result = await symptomsCheckerRepo.getSuggestions(
age: age, age: age,
gender: gender, gender: gender,
evidenceIds: evidenceIds, evidenceList: evidenceList,
language: language, language: language,
sessionId: currentSessionId, sessionId: currentSessionId,
userSessionToken: currentSessionAuthToken, userSessionToken: currentSessionAuthToken,
@ -863,19 +917,27 @@ class SymptomsCheckerViewModel extends ChangeNotifier {
Future<void> getDiagnosisForTriage({ Future<void> getDiagnosisForTriage({
required int age, required int age,
required int gender, required int gender,
required List<String> evidenceIds, required List<Map<String, dynamic>> initialEvidenceList, // Evidence with sources (initial, red_flags, suggest)
List<Map<String, String>>? triageEvidence, List<Map<String, String>>? triageEvidence, // Triage-specific evidence (id, choice_id, source=triage)
required String language, required String language,
Function(TriageDataDetails)? onSuccess, Function(TriageDataDetails)? onSuccess,
Function(String)? onError, Function(String)? onError,
bool isGoingBack = false, // Flag to indicate if we're going back in history
}) async { }) async {
// Save current question and evidence to history BEFORE making new API call
// (but only if we're moving forward, not going back)
if (!isGoingBack && triageDataDetails != null) {
_triageQuestionHistory.add(triageDataDetails!);
_triageEvidenceHistory.add(List<Map<String, String>>.from(_triageEvidenceList));
}
isTriageDiagnosisLoading = true; isTriageDiagnosisLoading = true;
notifyListeners(); notifyListeners();
final result = await symptomsCheckerRepo.getDiagnosisForTriage( final result = await symptomsCheckerRepo.getDiagnosisForTriage(
age: age, age: age,
gender: gender, gender: gender,
evidenceIds: evidenceIds, initialEvidenceList: initialEvidenceList,
triageEvidence: triageEvidence, triageEvidence: triageEvidence,
language: language, language: language,
sessionId: currentSessionId, sessionId: currentSessionId,
@ -923,10 +985,10 @@ class SymptomsCheckerViewModel extends ChangeNotifier {
return; return;
} }
// Get all evidence IDs // Get all evidence with sources
final evidenceIds = getAllEvidenceIds(); final evidenceList = getAllEvidenceWithSources();
if (evidenceIds.isEmpty) { if (evidenceList.isEmpty) {
if (onError != null) { if (onError != null) {
onError('No evidence selected'); onError('No evidence selected');
} }
@ -936,7 +998,7 @@ class SymptomsCheckerViewModel extends ChangeNotifier {
await getDiagnosisForTriage( await getDiagnosisForTriage(
age: _selectedAge!, age: _selectedAge!,
gender: _getGenderAsInt(_selectedGender), gender: _getGenderAsInt(_selectedGender),
evidenceIds: evidenceIds, initialEvidenceList: evidenceList,
language: appState.isArabic() ? 'ar' : 'en', language: appState.isArabic() ? 'ar' : 'en',
onSuccess: (response) { onSuccess: (response) {
if (onSuccess != null) { if (onSuccess != null) {
@ -993,7 +1055,7 @@ class SymptomsCheckerViewModel extends ChangeNotifier {
_triageEvidenceList.add({ _triageEvidenceList.add({
"id": itemId, "id": itemId,
"choice_id": choiceId, "choice_id": choiceId,
"source": "triage", "source": "suggest",
}); });
notifyListeners(); notifyListeners();
} }
@ -1009,6 +1071,39 @@ class SymptomsCheckerViewModel extends ChangeNotifier {
notifyListeners(); notifyListeners();
} }
/// Go back to previous triage question
/// Returns true if successfully went back, false if already at first question
bool goBackToPreviousTriageQuestion() {
if (_triageQuestionHistory.isEmpty) {
return false; // Already at first question
}
// Pop the last question from history
final previousQuestion = _triageQuestionHistory.removeLast();
final previousEvidence = _triageEvidenceHistory.removeLast();
// Restore the previous question
triageDataDetails = previousQuestion;
// Restore the previous evidence state
_triageEvidenceList.clear();
_triageEvidenceList.addAll(previousEvidence);
// Decrement question count
if (_triageQuestionCount > 0) {
_triageQuestionCount--;
}
// Clear current selections
_selectedTriageChoiceIndex = null;
_selectedTriageChoicesByItemId.clear();
_selectedSingleItemId = null;
_selectedSingleChoiceIndex = null;
notifyListeners();
return true;
}
void reset() { void reset() {
_currentView = BodyView.front; _currentView = BodyView.front;
_selectedOrganIds.clear(); _selectedOrganIds.clear();
@ -1018,6 +1113,8 @@ class SymptomsCheckerViewModel extends ChangeNotifier {
_triageEvidenceList.clear(); _triageEvidenceList.clear();
_selectedTriageChoicesByItemId.clear(); _selectedTriageChoicesByItemId.clear();
_triageQuestionCount = 0; // Reset question count _triageQuestionCount = 0; // Reset question count
_triageQuestionHistory.clear(); // Clear question history
_triageEvidenceHistory.clear(); // Clear evidence history
_currentZoomScale = 1.0; // Reset zoom scale _currentZoomScale = 1.0; // Reset zoom scale
_symptomSearchQuery = ''; // Reset search query _symptomSearchQuery = ''; // Reset search query
_filteredOrganSymptomsResults.clear(); // Clear filtered results _filteredOrganSymptomsResults.clear(); // Clear filtered results
@ -1054,6 +1151,8 @@ class SymptomsCheckerViewModel extends ChangeNotifier {
_selectedRiskFactorIds.clear(); _selectedRiskFactorIds.clear();
_selectedSuggestionsIds.clear(); _selectedSuggestionsIds.clear();
_triageEvidenceList.clear(); _triageEvidenceList.clear();
_triageQuestionHistory.clear(); // Clear question history
_triageEvidenceHistory.clear(); // Clear evidence history
_selectedTriageChoicesByItemId.clear(); _selectedTriageChoicesByItemId.clear();
_selectedSingleItemId = null; _selectedSingleItemId = null;
_selectedSingleChoiceIndex = null; _selectedSingleChoiceIndex = null;
@ -1066,6 +1165,28 @@ class SymptomsCheckerViewModel extends ChangeNotifier {
notifyListeners(); notifyListeners();
} }
/// Clear selections when reaching possible conditions screen
/// This clears organs, symptoms, risk factors, suggestions, and questions
void clearSelectionsForPossibleConditions() {
_selectedOrganIds.clear();
_selectedSymptomsByOrgan.clear();
_selectedRiskFactorIds.clear();
_selectedSuggestionsIds.clear();
_triageEvidenceList.clear();
_triageQuestionHistory.clear();
_triageEvidenceHistory.clear();
_selectedTriageChoicesByItemId.clear();
_selectedSingleItemId = null;
_selectedSingleChoiceIndex = null;
_triageQuestionCount = 0;
_symptomSearchQuery = '';
_filteredOrganSymptomsResults.clear();
_isBottomSheetExpanded = false;
_tooltipTimer?.cancel();
_tooltipOrganId = null;
notifyListeners();
}
// User Info Flow Methods // User Info Flow Methods
/// Set current page in user info flow /// Set current page in user info flow
@ -1170,6 +1291,34 @@ class SymptomsCheckerViewModel extends ChangeNotifier {
}; };
} }
// User Consent Methods
bool isTermsAccepted = false;
bool isPrivacyAccepted = false;
/// Toggle terms acceptance
void toggleTermsAcceptance() {
isTermsAccepted = !isTermsAccepted;
notifyListeners();
}
/// Toggle privacy policy acceptance
void togglePrivacyAcceptance() {
isPrivacyAccepted = !isPrivacyAccepted;
notifyListeners();
}
void setTermsAcceptance(bool value) {
isTermsAccepted = value;
notifyListeners();
}
/// Toggle privacy policy acceptance
void setPrivacyAcceptance(bool value) {
isPrivacyAccepted = value;
notifyListeners();
}
Future<void> getSymptomsUserDetails({ Future<void> getSymptomsUserDetails({
required String userName, required String userName,
required String password, required String password,

File diff suppressed because it is too large Load Diff

@ -2,7 +2,7 @@
// ignore_for_file: constant_identifier_names // ignore_for_file: constant_identifier_names
abstract class LocaleKeys { abstract class LocaleKeys {
static const english = 'english'; static const english = 'english';
static const arabic = 'arabic'; static const arabic = 'arabic';
static const login = 'login'; static const login = 'login';
@ -371,6 +371,12 @@ abstract class LocaleKeys {
static const clickHere = 'clickHere'; static const clickHere = 'clickHere';
static const iAgreeToTheTermsAndConditions = 'iAgreeToTheTermsAndConditions'; static const iAgreeToTheTermsAndConditions = 'iAgreeToTheTermsAndConditions';
static const iAgreeToTheTermsAndConditionsSubtitle = 'iAgreeToTheTermsAndConditionsSubtitle'; static const iAgreeToTheTermsAndConditionsSubtitle = 'iAgreeToTheTermsAndConditionsSubtitle';
static const iAgreeAndAcceptTermsAndConditions = 'iAgreeAndAcceptTermsAndConditions';
static const termsAndConditions = 'termsAndConditions';
static const iAgreeHealthInfoCanBeUsed = 'iAgreeHealthInfoCanBeUsed';
static const privacyPolicyText = 'privacyPolicyText';
static const outPatient = 'outPatient';
static const thisInvoiceIsNotEligibleForRefund = 'thisInvoiceIsNotEligibleForRefund';
static const save = 'save'; static const save = 'save';
static const userAgreement = 'userAgreement'; static const userAgreement = 'userAgreement';
static const updateSuccessfully = 'updateSuccessfully'; static const updateSuccessfully = 'updateSuccessfully';
@ -1360,7 +1366,6 @@ abstract class LocaleKeys {
static const medicalFiles = 'medicalFiles'; static const medicalFiles = 'medicalFiles';
static const addANewFamilyMember = 'addANewFamilyMember'; static const addANewFamilyMember = 'addANewFamilyMember';
static const viewInvoiceDetails = 'viewInvoiceDetails'; static const viewInvoiceDetails = 'viewInvoiceDetails';
static const outPatient = 'outPatient';
static const invoiceDetails = 'invoiceDetails'; static const invoiceDetails = 'invoiceDetails';
static const sendingEmailPleaseWait = 'sendingEmailPleaseWait'; static const sendingEmailPleaseWait = 'sendingEmailPleaseWait';
static const emailSentSuccessfullyMessage = 'emailSentSuccessfullyMessage'; static const emailSentSuccessfullyMessage = 'emailSentSuccessfullyMessage';
@ -1851,7 +1856,7 @@ abstract class LocaleKeys {
static const invalidIbanFormat = 'invalidIbanFormat'; static const invalidIbanFormat = 'invalidIbanFormat';
static const refundHistory = 'refundHistory'; static const refundHistory = 'refundHistory';
static const noRefundHistoryFound = 'noRefundHistoryFound'; static const noRefundHistoryFound = 'noRefundHistoryFound';
static const selectProcedures = 'selectProcedures'; static const selectProcedure = 'selectProcedure';
static const noProceduresAvailableForRefund = 'noProceduresAvailableForRefund'; static const noProceduresAvailableForRefund = 'noProceduresAvailableForRefund';
static const selectAll = 'selectAll'; static const selectAll = 'selectAll';
static const selectRefundMethod = 'selectRefundMethod'; static const selectRefundMethod = 'selectRefundMethod';
@ -1866,18 +1871,19 @@ abstract class LocaleKeys {
static const refundReason5 = 'refundReason5'; static const refundReason5 = 'refundReason5';
static const refundReason6 = 'refundReason6'; static const refundReason6 = 'refundReason6';
static const refundReason7 = 'refundReason7'; static const refundReason7 = 'refundReason7';
static const selectProcedures = 'selectProcedures';
static const redeem = 'redeem'; static const redeem = 'redeem';
static const points = 'points'; static const points = 'points';
static const transactions = 'transactions'; static const transactions = 'transactions';
static const pharmacy = 'pharmacy'; static const pharmacy = 'pharmacy';
static const visitsOrders = 'visitsOrders'; static const visitsOrders = 'visitsOrders';
static const cannotOpenThisFile = 'cannotOpenThisFile'; static const cannotOpenThisFile = 'cannotOpenThisFile';
static const thisInvoiceIsNotEligibleForRefund = 'thisInvoiceIsNotEligibleForRefund';
static const refundDetails = 'refundDetails'; static const refundDetails = 'refundDetails';
static const requestNo = 'requestNo'; static const requestNo = 'requestNo';
static const referenceNo = 'referenceNo'; static const referenceNo = 'referenceNo';
static const refund = 'refund';
static const advanceNumber = 'advanceNumber'; static const advanceNumber = 'advanceNumber';
static const amountOnly = 'amountOnly'; static const amountOnly = 'amountOnly';
static const invoiceHistory = 'invoiceHistory'; static const invoiceHistory = 'invoiceHistory';
static const refund = 'refund';
} }

@ -1,6 +1,7 @@
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/gestures.dart'; import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:hmg_patient_app_new/core/api_consts.dart';
import 'package:hmg_patient_app_new/core/app_assets.dart'; import 'package:hmg_patient_app_new/core/app_assets.dart';
import 'package:hmg_patient_app_new/core/app_state.dart'; import 'package:hmg_patient_app_new/core/app_state.dart';
import 'package:hmg_patient_app_new/core/dependencies.dart'; import 'package:hmg_patient_app_new/core/dependencies.dart';
@ -95,7 +96,13 @@ class _RegisterNew extends State<RegisterNew> {
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Utils.showLottie(context: context, assetPath: 'assets/animations/lottie/register.json', width: 200.w, height: 200.h, fit: BoxFit.cover, repeat: true), Utils.showLottie(
context: context,
assetPath: 'assets/animations/lottie/register.json',
width: 200.w,
height: 200.h,
fit: BoxFit.cover,
repeat: true),
SizedBox(height: 16.h), SizedBox(height: 16.h),
LocaleKeys.prepareToElevate.tr(context: context).toText32(isBold: true), LocaleKeys.prepareToElevate.tr(context: context).toText32(isBold: true),
SizedBox(height: 24.h), SizedBox(height: 24.h),
@ -134,8 +141,10 @@ class _RegisterNew extends State<RegisterNew> {
padding: EdgeInsets.symmetric(vertical: 8.h), padding: EdgeInsets.symmetric(vertical: 8.h),
leadingIcon: AppAssets.student_card, leadingIcon: AppAssets.student_card,
fontFamily: "Poppins", fontFamily: "Poppins",
hasError: false, // Don't show individual field border hasError: false,
errorMessage: authVm.nationalIdError, // Show error message if exists // Don't show individual field border
errorMessage: authVm.nationalIdError,
// Show error message if exists
onChange: (value) { onChange: (value) {
// Clear error when user starts typing // Clear error when user starts typing
authVm.clearNationalIdError(); authVm.clearNationalIdError();
@ -162,8 +171,9 @@ class _RegisterNew extends State<RegisterNew> {
authVm.clearDobError(); authVm.clearDobError();
}, },
fontFamily: "Poppins", fontFamily: "Poppins",
hasError: false, // Don't show individual field border hasError: false,
errorMessage: authVm.dobError, // Show error message if exists // Don't show individual field border
errorMessage: authVm.dobError, // Show error message if exists
).withVerticalPadding(8), ).withVerticalPadding(8),
], ],
), ),
@ -202,7 +212,7 @@ class _RegisterNew extends State<RegisterNew> {
onTap: () { onTap: () {
// Navigate to terms and conditions page // Navigate to terms and conditions page
Utils.openWebView( Utils.openWebView(
url: 'https://hmg.com/en/Pages/Terms.aspx', url: AppUrls.hmgTermsUrlEn,
); );
}, },
child: Text( child: Text(

@ -1,5 +1,6 @@
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:hmg_patient_app_new/core/api_consts.dart';
import 'package:hmg_patient_app_new/core/app_assets.dart'; import 'package:hmg_patient_app_new/core/app_assets.dart';
import 'package:hmg_patient_app_new/core/app_state.dart'; import 'package:hmg_patient_app_new/core/app_state.dart';
import 'package:hmg_patient_app_new/core/dependencies.dart'; import 'package:hmg_patient_app_new/core/dependencies.dart';
@ -15,18 +16,13 @@ import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/presentation/blood_donation/widgets/select_blood_group_widget.dart'; import 'package:hmg_patient_app_new/presentation/blood_donation/widgets/select_blood_group_widget.dart';
import 'package:hmg_patient_app_new/presentation/blood_donation/widgets/select_city_widget.dart'; import 'package:hmg_patient_app_new/presentation/blood_donation/widgets/select_city_widget.dart';
import 'package:hmg_patient_app_new/presentation/blood_donation/widgets/select_gender_widget.dart'; import 'package:hmg_patient_app_new/presentation/blood_donation/widgets/select_gender_widget.dart';
import 'package:hmg_patient_app_new/presentation/book_appointment/select_clinic_page.dart';
import 'package:hmg_patient_app_new/presentation/home/navigation_screen.dart';
import 'package:hmg_patient_app_new/services/dialog_service.dart'; import 'package:hmg_patient_app_new/services/dialog_service.dart';
import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/theme/colors.dart';
import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart'; import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart';
import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart';
import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart'; import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart';
import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart';
import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart';
import 'package:lottie/lottie.dart'; import 'package:lottie/lottie.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:hmg_patient_app_new/presentation/appointments/widgets/hospital_bottom_sheet/hospital_bottom_sheet_body.dart';
class BloodDonationPage extends StatefulWidget { class BloodDonationPage extends StatefulWidget {
BloodDonationPage({super.key}); BloodDonationPage({super.key});
@ -60,7 +56,8 @@ class _BloodDonationPageState extends State<BloodDonationPage> {
onPressed: () { onPressed: () {
if (bloodDonationVM.isUserAuthanticated()) { if (bloodDonationVM.isUserAuthanticated()) {
bloodDonationVM.fetchHospitalsList().then((value) { bloodDonationVM.fetchHospitalsList().then((value) {
showCommonBottomSheetWithoutHeight(context, title: LocaleKeys.selectHospital.tr(context: context), isDismissible: false, child: Consumer<BloodDonationViewModel>(builder: (_, data, __) { showCommonBottomSheetWithoutHeight(context, title: LocaleKeys.selectHospital.tr(context: context), isDismissible: false,
child: Consumer<BloodDonationViewModel>(builder: (_, data, __) {
return HospitalBottomSheetBodySelection( return HospitalBottomSheetBodySelection(
isHideTitle: true, isHideTitle: true,
onUserHospitalSelection: (BdGetProjectsHaveBdClinic userChoice) { onUserHospitalSelection: (BdGetProjectsHaveBdClinic userChoice) {
@ -77,7 +74,8 @@ class _BloodDonationPageState extends State<BloodDonationPage> {
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
Lottie.asset(AppAnimations.errorAnimation, repeat: true, reverse: false, frameRate: FrameRate(60), width: 100.h, height: 100.h, fit: BoxFit.fill), Lottie.asset(AppAnimations.errorAnimation,
repeat: true, reverse: false, frameRate: FrameRate(60), width: 100.h, height: 100.h, fit: BoxFit.fill),
SizedBox(height: 8.h), SizedBox(height: 8.h),
(LocaleKeys.loginToUseService.tr()).toText16(color: AppColors.blackColor), (LocaleKeys.loginToUseService.tr()).toText16(color: AppColors.blackColor),
SizedBox(height: 16.h), SizedBox(height: 16.h),
@ -131,7 +129,8 @@ class _BloodDonationPageState extends State<BloodDonationPage> {
padding: EdgeInsets.all(24.w), padding: EdgeInsets.all(24.w),
child: SingleChildScrollView( child: SingleChildScrollView(
child: Container( child: Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r, hasShadow: false), decoration:
RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r, hasShadow: false),
child: Padding( child: Padding(
padding: EdgeInsets.all(16.h), padding: EdgeInsets.all(16.h),
child: Column( child: Column(
@ -150,7 +149,8 @@ class _BloodDonationPageState extends State<BloodDonationPage> {
LocaleKeys.city.tr().toText16(color: AppColors.textColor, isBold: true), LocaleKeys.city.tr().toText16(color: AppColors.textColor, isBold: true),
(appState.isArabic() (appState.isArabic()
? (bloodDonationVM.selectedCity?.descriptionN ?? LocaleKeys.selectBloodDonationCity.tr()) ? (bloodDonationVM.selectedCity?.descriptionN ?? LocaleKeys.selectBloodDonationCity.tr())
: bloodDonationVM.selectedCity?.description ?? LocaleKeys.selectBloodDonationCity.tr(context: context)) : bloodDonationVM.selectedCity?.description ??
LocaleKeys.selectBloodDonationCity.tr(context: context))
.toText14(color: AppColors.greyTextColor, isBold: true), .toText14(color: AppColors.greyTextColor, isBold: true),
], ],
), ),
@ -160,7 +160,10 @@ class _BloodDonationPageState extends State<BloodDonationPage> {
], ],
).onPress(() async { ).onPress(() async {
showCommonBottomSheetWithoutHeight(context, showCommonBottomSheetWithoutHeight(context,
title: LocaleKeys.selectCity.tr(context: context), isDismissible: true, child: SelectCityWidget(bloodDonationViewModel: bloodDonationVM), callBackFunc: () {}); title: LocaleKeys.selectCity.tr(context: context),
isDismissible: true,
child: SelectCityWidget(bloodDonationViewModel: bloodDonationVM),
callBackFunc: () {});
}), }),
SizedBox(height: 16.h), SizedBox(height: 16.h),
Divider(color: AppColors.borderOnlyColor.withValues(alpha: 0.1), height: 1.h), Divider(color: AppColors.borderOnlyColor.withValues(alpha: 0.1), height: 1.h),
@ -254,17 +257,17 @@ class _BloodDonationPageState extends State<BloodDonationPage> {
SizedBox(width: 12.w), SizedBox(width: 12.w),
Expanded( Expanded(
child: LocaleKeys.aboutBloodDonation.tr(context: context).toText16( child: LocaleKeys.aboutBloodDonation.tr(context: context).toText16(
color: AppColors.primaryRedColor, color: AppColors.primaryRedColor,
isBold: true, isBold: true,
), ),
), ),
], ],
), ),
SizedBox(height: 12.h), SizedBox(height: 12.h),
LocaleKeys.bloodDonationDescription.tr(context: context).toText14( LocaleKeys.bloodDonationDescription.tr(context: context).toText14(
color: AppColors.greyTextColor, color: AppColors.greyTextColor,
isBold: true, isBold: true,
), ),
SizedBox(height: 12.h), SizedBox(height: 12.h),
Row( Row(
children: [ children: [
@ -279,9 +282,9 @@ class _BloodDonationPageState extends State<BloodDonationPage> {
SizedBox(width: 8.w), SizedBox(width: 8.w),
Expanded( Expanded(
child: LocaleKeys.bloodDonationBenefit1.tr(context: context).toText13( child: LocaleKeys.bloodDonationBenefit1.tr(context: context).toText13(
color: AppColors.textColor, color: AppColors.textColor,
isBold: true, isBold: true,
), ),
), ),
], ],
), ),
@ -299,9 +302,9 @@ class _BloodDonationPageState extends State<BloodDonationPage> {
SizedBox(width: 8.w), SizedBox(width: 8.w),
Expanded( Expanded(
child: LocaleKeys.bloodDonationBenefit2.tr(context: context).toText13( child: LocaleKeys.bloodDonationBenefit2.tr(context: context).toText13(
color: AppColors.textColor, color: AppColors.textColor,
isBold: true, isBold: true,
), ),
), ),
], ],
), ),
@ -319,9 +322,9 @@ class _BloodDonationPageState extends State<BloodDonationPage> {
SizedBox(width: 8.w), SizedBox(width: 8.w),
Expanded( Expanded(
child: LocaleKeys.bloodDonationBenefit3.tr(context: context).toText13( child: LocaleKeys.bloodDonationBenefit3.tr(context: context).toText13(
color: AppColors.textColor, color: AppColors.textColor,
isBold: true, isBold: true,
), ),
), ),
], ],
), ),
@ -376,10 +379,10 @@ class _BloodDonationPageState extends State<BloodDonationPage> {
// Navigator.of(context).pushNamed('/terms'); // Navigator.of(context).pushNamed('/terms');
appState.isArabic() appState.isArabic()
? Utils.openWebView( ? Utils.openWebView(
url: 'https://hmg.com/ar/Pages/Terms.aspx', url: AppUrls.hmgTermsUrlAr,
) )
: Utils.openWebView( : Utils.openWebView(
url: 'https://hmg.com/en/Pages/Terms.aspx', url: AppUrls.hmgTermsUrlEn,
); );
}, },
child: Text( child: Text(
@ -419,7 +422,8 @@ class _BloodDonationPageState extends State<BloodDonationPage> {
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
Lottie.asset(AppAnimations.errorAnimation, repeat: true, reverse: false, frameRate: FrameRate(60), width: 100.h, height: 100.h, fit: BoxFit.fill), Lottie.asset(AppAnimations.errorAnimation,
repeat: true, reverse: false, frameRate: FrameRate(60), width: 100.h, height: 100.h, fit: BoxFit.fill),
SizedBox(height: 8.h), SizedBox(height: 8.h),
(LocaleKeys.loginToUseService.tr()).toText16(color: AppColors.blackColor), (LocaleKeys.loginToUseService.tr()).toText16(color: AppColors.blackColor),
SizedBox(height: 16.h), SizedBox(height: 16.h),

@ -1,6 +1,7 @@
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_staggered_animations/flutter_staggered_animations.dart'; import 'package:flutter_staggered_animations/flutter_staggered_animations.dart';
import 'package:hmg_patient_app_new/core/api_consts.dart';
import 'package:hmg_patient_app_new/core/app_assets.dart'; import 'package:hmg_patient_app_new/core/app_assets.dart';
import 'package:hmg_patient_app_new/core/app_export.dart'; import 'package:hmg_patient_app_new/core/app_export.dart';
import 'package:hmg_patient_app_new/core/app_state.dart'; import 'package:hmg_patient_app_new/core/app_state.dart';
@ -820,7 +821,7 @@ class _ServicesPageState extends State<ServicesPage> {
), ),
).onPress(() { ).onPress(() {
Utils.openWebView( Utils.openWebView(
url: 'https://hmg.com/en/Pages/Terms.aspx', url: AppUrls.hmgTermsUrlEn,
); );
}), }),
), ),
@ -845,7 +846,7 @@ class _ServicesPageState extends State<ServicesPage> {
), ),
).onPress(() { ).onPress(() {
Utils.openWebView( Utils.openWebView(
url: 'https://hmg.com/en/Pages/Privacy.aspx', url: AppUrls.hmgPrivacyUrlEn,
); );
}), }),
) )

@ -1,6 +1,7 @@
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:get_it/get_it.dart'; import 'package:get_it/get_it.dart';
import 'package:hmg_patient_app_new/core/api_consts.dart';
import 'package:hmg_patient_app_new/core/app_assets.dart'; import 'package:hmg_patient_app_new/core/app_assets.dart';
import 'package:hmg_patient_app_new/core/app_state.dart'; import 'package:hmg_patient_app_new/core/app_state.dart';
import 'package:hmg_patient_app_new/core/cache_consts.dart'; import 'package:hmg_patient_app_new/core/cache_consts.dart';
@ -82,7 +83,8 @@ class MonthlyReport extends StatelessWidget {
LocaleKeys.email.tr(context: context).toText12(color: AppColors.greyTextColor, isBold: true), LocaleKeys.email.tr(context: context).toText12(color: AppColors.greyTextColor, isBold: true),
SizedBox( SizedBox(
width: MediaQuery.of(context).size.width * 0.7, width: MediaQuery.of(context).size.width * 0.7,
child: "${appState.getAuthenticatedUser()!.emailAddress}".toText16(color: AppColors.textColor, isBold: true, maxlines: 2), child: "${appState.getAuthenticatedUser()!.emailAddress}"
.toText16(color: AppColors.textColor, isBold: true, maxlines: 2),
), ),
], ],
), ),
@ -98,7 +100,9 @@ class MonthlyReport extends StatelessWidget {
Utils.buildSvgWithAssets(icon: AppAssets.prescription_remarks_icon, width: 18.w, height: 18.h), Utils.buildSvgWithAssets(icon: AppAssets.prescription_remarks_icon, width: 18.w, height: 18.h),
SizedBox(width: 9.h), SizedBox(width: 9.h),
Expanded( Expanded(
child: LocaleKeys.monthlyHealthSummaryReportDisclaimer.tr(context: context).toText10(isBold: true, color: AppColors.greyTextColorLight), child: LocaleKeys.monthlyHealthSummaryReportDisclaimer
.tr(context: context)
.toText10(isBold: true, color: AppColors.greyTextColorLight),
), ),
], ],
), ),
@ -135,9 +139,11 @@ class MonthlyReport extends StatelessWidget {
), ),
SizedBox(width: 10.w), SizedBox(width: 10.w),
"I agree to the ".toText14(isBold: true, letterSpacing: -1.0), "I agree to the ".toText14(isBold: true, letterSpacing: -1.0),
"terms and conditions".toText14(isBold: true, letterSpacing: -1.0, color: AppColors.primaryRedColor, isUnderLine: true).onPress(() { "terms and conditions"
.toText14(isBold: true, letterSpacing: -1.0, color: AppColors.primaryRedColor, isUnderLine: true)
.onPress(() {
Utils.openWebView( Utils.openWebView(
url: 'https://hmg.com/en/Pages/Terms.aspx', url: AppUrls.hmgTermsUrlEn,
); );
}) })
], ],

@ -24,9 +24,9 @@ import 'package:provider/provider.dart';
class InvoiceListCard extends StatelessWidget { class InvoiceListCard extends StatelessWidget {
final GetInvoicesListResponseModel getInvoicesListResponseModel; final GetInvoicesListResponseModel getInvoicesListResponseModel;
Function? onTap; final Function? onTap;
InvoiceListCard({super.key, required this.getInvoicesListResponseModel, required this.onTap}); const InvoiceListCard({super.key, required this.getInvoicesListResponseModel, required this.onTap});
void _handleRefundInvoiceTap(BuildContext context) { void _handleRefundInvoiceTap(BuildContext context) {
final invoiceNo = getInvoicesListResponseModel.invoiceNo; final invoiceNo = getInvoicesListResponseModel.invoiceNo;
@ -70,7 +70,6 @@ class InvoiceListCard extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
AppState appState = getIt<AppState>();
return Container( return Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 20.h, hasShadow: true), decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 20.h, hasShadow: true),
child: Padding( child: Padding(
@ -91,7 +90,7 @@ class InvoiceListCard extends StatelessWidget {
textColor: AppColors.textColor, textColor: AppColors.textColor,
), ),
AppCustomChipWidget( AppCustomChipWidget(
labelText: appState.isArabic() ? "العيادات الخارجيه" : "Out Patient", labelText: LocaleKeys.outPatient.tr(context: context),
backgroundColor: AppColors.warningColorYellow.withValues(alpha: 0.1), backgroundColor: AppColors.warningColorYellow.withValues(alpha: 0.1),
textColor: AppColors.warningColorYellow, textColor: AppColors.warningColorYellow,
), ),

@ -4,6 +4,7 @@ import 'dart:io';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_swiper_view/flutter_swiper_view.dart'; import 'package:flutter_swiper_view/flutter_swiper_view.dart';
import 'package:hmg_patient_app_new/core/api_consts.dart';
import 'package:hmg_patient_app_new/core/app_assets.dart'; import 'package:hmg_patient_app_new/core/app_assets.dart';
import 'package:hmg_patient_app_new/core/app_export.dart'; import 'package:hmg_patient_app_new/core/app_export.dart';
import 'package:hmg_patient_app_new/core/app_state.dart'; import 'package:hmg_patient_app_new/core/app_state.dart';
@ -347,13 +348,13 @@ class ProfileSettingsState extends State<ProfileSettings> {
1.divider, 1.divider,
actionItem(AppAssets.privacy_terms, LocaleKeys.privacyPolicy.tr(context: context), () { actionItem(AppAssets.privacy_terms, LocaleKeys.privacyPolicy.tr(context: context), () {
Utils.openWebView( Utils.openWebView(
url: 'https://hmg.com/en/Pages/Privacy.aspx', url: AppUrls.hmgPrivacyUrlEn,
); );
}, isExternalLink: true), }, isExternalLink: true),
1.divider, 1.divider,
actionItem(AppAssets.privacy_terms, LocaleKeys.termsConditoins.tr(context: context), () { actionItem(AppAssets.privacy_terms, LocaleKeys.termsConditoins.tr(context: context), () {
Utils.openWebView( Utils.openWebView(
url: 'https://hmg.com/en/Pages/Terms.aspx', url: AppUrls.hmgTermsUrlEn,
); );
}, isExternalLink: true), }, isExternalLink: true),
1.divider, 1.divider,

@ -49,8 +49,8 @@ class _PossibleConditionsPageState extends State<PossibleConditionsPage> {
void initState() { void initState() {
super.initState(); super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) { WidgetsBinding.instance.addPostFrameCallback((_) {
// Clear selections once user reaches results page // Clear all selections (organs, symptoms, risk factors, suggestions, questions) once user reaches possible conditions screen
symptomsCheckerViewModel.clearSelectionsKeepResults(); symptomsCheckerViewModel.clearSelectionsForPossibleConditions();
}); });
} }

@ -157,7 +157,13 @@ class _TriagePageState extends State<TriagePage> {
} }
void _onPreviousPressed() { void _onPreviousPressed() {
context.pop(); // Try to go back to previous question
bool wentBack = viewModel.goBackToPreviousTriageQuestion();
if (!wentBack) {
// If already at first question, go back to suggestions screen
context.pop();
}
} }
void _onNextPressed() { void _onNextPressed() {
@ -224,15 +230,15 @@ class _TriagePageState extends State<TriagePage> {
} }
} }
// Get all evidence: initial symptoms + risk factors + suggestions + triage evidence // Get all evidence: initial symptoms + risk factors + suggestions (with sources) + triage evidence
List<String> initialEvidenceIds = viewModel.getAllEvidenceIds(); List<Map<String, dynamic>> initialEvidenceList = viewModel.getAllEvidenceWithSources();
List<Map<String, String>> triageEvidence = viewModel.getTriageEvidence(); List<Map<String, String>> triageEvidence = viewModel.getTriageEvidence();
// Call API with updated evidence // Call API with updated evidence
viewModel.getDiagnosisForTriage( viewModel.getDiagnosisForTriage(
age: viewModel.selectedAge!, age: viewModel.selectedAge!,
gender: viewModel.selectedGender!.toLowerCase() == "male" ? 1 : 2, gender: viewModel.selectedGender!.toLowerCase() == "male" ? 1 : 2,
evidenceIds: initialEvidenceIds, initialEvidenceList: initialEvidenceList,
triageEvidence: triageEvidence, triageEvidence: triageEvidence,
language: viewModel.appState.isArabic() ? 'ar' : 'en', language: viewModel.appState.isArabic() ? 'ar' : 'en',
onSuccess: (response) { onSuccess: (response) {
@ -536,7 +542,7 @@ class _TriagePageState extends State<TriagePage> {
children: [ children: [
RichText( RichText(
text: TextSpan( text: TextSpan(
text: "${LocaleKeys.possibleSymptom.tr(context: context)} ", text: "${LocaleKeys.possibleConditions.tr(context: context)} ",
style: TextStyle( style: TextStyle(
color: AppColors.greyTextColor, fontWeight: FontWeight.w600, fontSize: 14.f, fontFamily: isArabic ? 'CairoArabic' : 'Poppins'), color: AppColors.greyTextColor, fontWeight: FontWeight.w600, fontSize: 14.f, fontFamily: isArabic ? 'CairoArabic' : 'Poppins'),
children: [ children: [
@ -586,8 +592,8 @@ class _TriagePageState extends State<TriagePage> {
Expanded( Expanded(
child: CustomButton( child: CustomButton(
text: LocaleKeys.previous.tr(context: context), text: LocaleKeys.previous.tr(context: context),
onPressed: isFirstQuestion ? () {} : _onPreviousPressed, onPressed: _onPreviousPressed,
isDisabled: isFirstQuestion || viewModel.isTriageDiagnosisLoading, isDisabled: viewModel.isTriageDiagnosisLoading,
backgroundColor: AppColors.primaryRedColor.withValues(alpha: 0.11), backgroundColor: AppColors.primaryRedColor.withValues(alpha: 0.11),
borderColor: Colors.transparent, borderColor: Colors.transparent,
textColor: AppColors.primaryRedColor, textColor: AppColors.primaryRedColor,

@ -0,0 +1,231 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:hmg_patient_app_new/core/api_consts.dart';
import 'package:hmg_patient_app_new/core/app_export.dart';
import 'package:hmg_patient_app_new/core/app_state.dart';
import 'package:hmg_patient_app_new/core/dependencies.dart';
import 'package:hmg_patient_app_new/core/utils/utils.dart';
import 'package:hmg_patient_app_new/extensions/route_extensions.dart';
import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
import 'package:hmg_patient_app_new/extensions/widget_extensions.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/theme/colors.dart';
import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart';
import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart';
// Before using the checkup, please read the Terms of Service and remember:
//
// Checkup isn't a diagnosis. It's only for your information and not a qualified medical opinion.
// Checkup isn't for emergencies. Call your local emergency number right away when there's a health emergency.
// Your data is safe. Privacy measures ensure the information you share is protected.
class UserConsentScreen extends StatefulWidget {
const UserConsentScreen({super.key});
@override
State<UserConsentScreen> createState() => _UserConsentScreenState();
}
class _UserConsentScreenState extends State<UserConsentScreen> {
bool _isTermsAccepted = false;
bool _isPrivacyAccepted = false;
void _onTermsAndConditionsAgreed() {
setState(() {
_isTermsAccepted = !_isTermsAccepted;
});
}
void _onPrivacyPolicyAgreed() {
setState(() {
_isPrivacyAccepted = !_isPrivacyAccepted;
});
}
bool get _canProceed => _isTermsAccepted && _isPrivacyAccepted;
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: AppColors.bgScaffoldColor,
body: Column(
children: [
Expanded(
child: CollapsingListView(
title: LocaleKeys.termsService.tr(),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
"Before using the checkup, please read the Terms of Service and remember:".toText14(),
SizedBox(height: 44.h),
"• Checkup isn't a diagnosis. It's only for your information and not a qualified medical opinion.".toText14(),
SizedBox(height: 12.h),
"• Checkup isn't for emergencies. Call your local emergency number right away when there's a health emergency.".toText14(),
SizedBox(height: 12.h),
"• Your data is safe. Privacy measures ensure the information you share is protected.".toText14(),
SizedBox(height: 24.h),
GestureDetector(
onTap: _onTermsAndConditionsAgreed,
child: Container(
margin: EdgeInsets.only(bottom: 12.h),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
AnimatedContainer(
duration: const Duration(milliseconds: 300),
curve: Curves.easeInOut,
width: 24.w,
height: 24.w,
decoration: BoxDecoration(
color: _isTermsAccepted ? AppColors.primaryRedColor : Colors.transparent,
borderRadius: BorderRadius.circular(5.r),
border: Border.all(
color: _isTermsAccepted ? AppColors.primaryRedColor : AppColors.checkBoxBorderColor,
width: 1.w,
),
),
child: _isTermsAccepted ? Icon(Icons.check, size: 16.f, color: AppColors.whiteColor) : null,
),
SizedBox(width: 12.w),
Expanded(
child: RichText(
text: TextSpan(
text: LocaleKeys.iAgreeAndAcceptTermsAndConditions.tr(context: context),
style: TextStyle(
fontSize: 16.f,
fontFamily: getIt.get<AppState>().isArabic() ? 'CairoArabic' : 'Poppins',
fontWeight: FontWeight.w500,
color: AppColors.textColor,
),
children: [
WidgetSpan(
child: GestureDetector(
onTap: () {
AppState appState = getIt.get<AppState>();
Utils.openWebView(
url: appState.isArabic() ? AppUrls.hmgTermsUrlAr : AppUrls.hmgTermsUrlEn,
);
},
child: Text(
LocaleKeys.termsAndConditions.tr(context: context),
style: TextStyle(
fontSize: 16.f,
fontFamily: getIt.get<AppState>().isArabic() ? 'CairoArabic' : 'Poppins',
fontWeight: FontWeight.w500,
color: AppColors.primaryRedColor,
decoration: TextDecoration.underline,
decorationColor: AppColors.primaryRedColor,
),
),
),
),
],
),
),
),
],
),
),
),
SizedBox(
height: 16.h,
),
GestureDetector(
onTap: _onPrivacyPolicyAgreed,
child: Container(
margin: EdgeInsets.only(bottom: 12.h),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
AnimatedContainer(
duration: const Duration(milliseconds: 300),
curve: Curves.easeInOut,
width: 24.w,
height: 24.w,
decoration: BoxDecoration(
color: _isPrivacyAccepted ? AppColors.primaryRedColor : Colors.transparent,
borderRadius: BorderRadius.circular(5.r),
border: Border.all(
color: _isPrivacyAccepted ? AppColors.primaryRedColor : AppColors.checkBoxBorderColor,
width: 1.w,
),
),
child: _isPrivacyAccepted ? Icon(Icons.check, size: 16.f, color: AppColors.whiteColor) : null,
),
SizedBox(width: 12.w),
Expanded(
child: RichText(
text: TextSpan(
text: LocaleKeys.iAgreeHealthInfoCanBeUsed.tr(context: context),
style: TextStyle(
fontSize: 16.f,
fontFamily: getIt.get<AppState>().isArabic() ? 'CairoArabic' : 'Poppins',
fontWeight: FontWeight.w500,
color: AppColors.textColor,
),
children: [
WidgetSpan(
child: GestureDetector(
onTap: () {
AppState appState = getIt.get<AppState>();
Utils.openWebView(
url: appState.isArabic() ? AppUrls.hmgPrivacyUrlAr : AppUrls.hmgPrivacyUrlEn,
);
},
child: Text(
LocaleKeys.privacyPolicyText.tr(context: context),
style: TextStyle(
fontSize: 16.f,
fontFamily: getIt.get<AppState>().isArabic() ? 'CairoArabic' : 'Poppins',
fontWeight: FontWeight.w500,
color: AppColors.primaryRedColor,
decorationColor: AppColors.primaryRedColor,
),
),
),
),
],
),
),
),
],
),
),
),
],
).paddingAll(24.w),
),
),
_buildStickyBottomCard(context),
],
),
);
}
Widget _buildStickyBottomCard(BuildContext context) {
return Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
SizedBox(height: 16.h),
Row(
children: [
Expanded(
child: CustomButton(
text: LocaleKeys.next.tr(context: context),
onPressed: _canProceed ? () => context.navigateWithName(AppRoutes.userInfoSelection) : null,
isDisabled: !_canProceed,
backgroundColor: AppColors.primaryRedColor,
borderColor: AppColors.primaryRedColor,
textColor: AppColors.whiteColor,
fontSize: 16.f,
),
),
],
),
SizedBox(height: 24.h),
],
).paddingSymmetrical(24.w, 0),
);
}
}

@ -17,14 +17,14 @@ import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart';
import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
class UserInfoSelectionPage extends StatefulWidget { class UserInfoSelectionScreen extends StatefulWidget {
const UserInfoSelectionPage({super.key}); const UserInfoSelectionScreen({super.key});
@override @override
State<UserInfoSelectionPage> createState() => _UserInfoSelectionPageState(); State<UserInfoSelectionScreen> createState() => _UserInfoSelectionScreenState();
} }
class _UserInfoSelectionPageState extends State<UserInfoSelectionPage> { class _UserInfoSelectionScreenState extends State<UserInfoSelectionScreen> {
@override @override
void initState() { void initState() {
super.initState(); super.initState();
@ -202,10 +202,15 @@ class _UserInfoSelectionPageState extends State<UserInfoSelectionPage> {
padding: EdgeInsets.symmetric(vertical: 24.h, horizontal: 16.w), padding: EdgeInsets.symmetric(vertical: 24.h, horizontal: 16.w),
child: Column( child: Column(
children: [ children: [
LocaleKeys.helloIsYourInformationUpToDate.tr(namedArgs: {'name': name}).toText16( LocaleKeys.helloIsYourInformationUpToDate
weight: FontWeight.w600, .tr(namedArgs: {'name': name})
color: AppColors.textColor, .toText16(
), weight: FontWeight.w600,
color: AppColors.textColor,
)
.onPress(() {
context.navigateWithName(AppRoutes.userConsentScreen);
}),
SizedBox(height: 32.h), SizedBox(height: 32.h),
_buildEditInfoTile( _buildEditInfoTile(
context: context, context: context,

@ -1,6 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:hmg_patient_app_new/core/enums.dart'; import 'package:hmg_patient_app_new/core/enums.dart';
import 'package:hmg_patient_app_new/features/my_invoices/models/get_invoices_list_response_model.dart'; import 'package:hmg_patient_app_new/features/my_invoices/models/get_invoices_list_response_model.dart';
import 'package:hmg_patient_app_new/features/refund_request/models/resp_models/refund_request_list_response_model.dart';
import 'package:hmg_patient_app_new/presentation/authentication/login.dart'; import 'package:hmg_patient_app_new/presentation/authentication/login.dart';
import 'package:hmg_patient_app_new/presentation/authentication/register.dart'; import 'package:hmg_patient_app_new/presentation/authentication/register.dart';
import 'package:hmg_patient_app_new/presentation/authentication/register_step2.dart'; import 'package:hmg_patient_app_new/presentation/authentication/register_step2.dart';
@ -24,7 +25,6 @@ import 'package:hmg_patient_app_new/presentation/my_family/my_family.dart';
import 'package:hmg_patient_app_new/presentation/parking/paking_page.dart'; import 'package:hmg_patient_app_new/presentation/parking/paking_page.dart';
import 'package:hmg_patient_app_new/presentation/refund_request/refund_request_create_page.dart'; import 'package:hmg_patient_app_new/presentation/refund_request/refund_request_create_page.dart';
import 'package:hmg_patient_app_new/presentation/refund_request/refund_request_detail_screen.dart'; import 'package:hmg_patient_app_new/presentation/refund_request/refund_request_detail_screen.dart';
import 'package:hmg_patient_app_new/features/refund_request/models/resp_models/refund_request_list_response_model.dart';
import 'package:hmg_patient_app_new/presentation/service_price/services_price_list_page.dart'; import 'package:hmg_patient_app_new/presentation/service_price/services_price_list_page.dart';
import 'package:hmg_patient_app_new/presentation/smartwatches/smartwatch_home_page.dart'; import 'package:hmg_patient_app_new/presentation/smartwatches/smartwatch_home_page.dart';
import 'package:hmg_patient_app_new/presentation/symptoms_checker/organ_selector_screen.dart'; import 'package:hmg_patient_app_new/presentation/symptoms_checker/organ_selector_screen.dart';
@ -33,8 +33,9 @@ import 'package:hmg_patient_app_new/presentation/symptoms_checker/risk_factors_s
import 'package:hmg_patient_app_new/presentation/symptoms_checker/suggestions_screen.dart'; import 'package:hmg_patient_app_new/presentation/symptoms_checker/suggestions_screen.dart';
import 'package:hmg_patient_app_new/presentation/symptoms_checker/symptoms_selector_screen.dart'; import 'package:hmg_patient_app_new/presentation/symptoms_checker/symptoms_selector_screen.dart';
import 'package:hmg_patient_app_new/presentation/symptoms_checker/triage_screen.dart'; import 'package:hmg_patient_app_new/presentation/symptoms_checker/triage_screen.dart';
import 'package:hmg_patient_app_new/presentation/symptoms_checker/user_info_selection.dart'; import 'package:hmg_patient_app_new/presentation/symptoms_checker/user_consent_screen.dart';
import 'package:hmg_patient_app_new/presentation/symptoms_checker/user_info_selection/user_info_flow_manager.dart'; import 'package:hmg_patient_app_new/presentation/symptoms_checker/user_info_selection/user_info_flow_manager.dart';
import 'package:hmg_patient_app_new/presentation/symptoms_checker/user_info_selection_screen.dart';
import 'package:hmg_patient_app_new/presentation/tele_consultation/zoom/call_screen.dart'; import 'package:hmg_patient_app_new/presentation/tele_consultation/zoom/call_screen.dart';
import 'package:hmg_patient_app_new/presentation/vital_sign/vital_sign_page.dart'; import 'package:hmg_patient_app_new/presentation/vital_sign/vital_sign_page.dart';
import 'package:hmg_patient_app_new/presentation/water_monitor/water_consumption_page.dart'; import 'package:hmg_patient_app_new/presentation/water_monitor/water_consumption_page.dart';
@ -85,6 +86,7 @@ class AppRoutes {
static const String possibleConditionsPage = '/possibleConditionsScreen'; static const String possibleConditionsPage = '/possibleConditionsScreen';
static const String triagePage = '/triageProgressScreen'; static const String triagePage = '/triageProgressScreen';
static const String userInfoSelection = '/userInfoSelection'; static const String userInfoSelection = '/userInfoSelection';
static const String userConsentScreen = '/userConsentScreen';
static const String userInfoFlowManager = '/userInfoFlowManager'; static const String userInfoFlowManager = '/userInfoFlowManager';
static const String monthlyReports = '/monthlyReportsPage'; static const String monthlyReports = '/monthlyReportsPage';
static const String qrParking = '/qrParkingPage'; static const String qrParking = '/qrParkingPage';
@ -132,7 +134,8 @@ class AppRoutes {
bloodDonationPage: (context) => BloodDonationPage(), bloodDonationPage: (context) => BloodDonationPage(),
myChildVaccine: (context) => MyChildVaccinePage(), myChildVaccine: (context) => MyChildVaccinePage(),
bookAppointmentPage: (context) => BookAppointmentPage(), bookAppointmentPage: (context) => BookAppointmentPage(),
userInfoSelection: (context) => UserInfoSelectionPage(), userInfoSelection: (context) => UserInfoSelectionScreen(),
userConsentScreen: (context) => UserConsentScreen(),
userInfoFlowManager: (context) => UserInfoFlowManager(), userInfoFlowManager: (context) => UserInfoFlowManager(),
smartWatches: (context) => SmartwatchHomePage(), smartWatches: (context) => SmartwatchHomePage(),
// huaweiHealthExample: (context) => HuaweiHealthExample(), // huaweiHealthExample: (context) => HuaweiHealthExample(),

@ -177,3 +177,4 @@ flutter:
# SA8345000000815089206001
Loading…
Cancel
Save