diff --git a/assets/images/svg/blood_type.svg b/assets/images/svg/blood_type.svg
new file mode 100644
index 0000000..5aded31
--- /dev/null
+++ b/assets/images/svg/blood_type.svg
@@ -0,0 +1,4 @@
+
diff --git a/assets/images/svg/genderInputIcon.svg b/assets/images/svg/genderInputIcon.svg
new file mode 100644
index 0000000..4482ae3
--- /dev/null
+++ b/assets/images/svg/genderInputIcon.svg
@@ -0,0 +1,5 @@
+
diff --git a/lib/core/api_consts.dart b/lib/core/api_consts.dart
index 1846d1e..c103291 100644
--- a/lib/core/api_consts.dart
+++ b/lib/core/api_consts.dart
@@ -848,6 +848,12 @@ class ApiConsts {
static String h2oUpdateUserDetail = "Services/H2ORemainder.svc/REST/H2O_UpdateUserDetails_New";
static String h2oUndoUserActivity = "Services/H2ORemainder.svc/REST/H2o_UndoUserActivity";
+ //Blood Donation
+ static String bloodGroupUpdate = "Services/PatientVarification.svc/REST/BloodDonation_RegisterBloodType";
+ static String userAgreementForBloodGroupUpdate = "Services/PatientVarification.svc/REST/AddUserAgreementForBloodDonation";
+ static String getProjectsHaveBDClinics = "Services/OUTPs.svc/REST/BD_getProjectsHaveBDClinics";
+ static String getClinicsBDFreeSlots = "Services/OUTPs.svc/REST/BD_GetFreeSlots";
+
// ************ static values for Api ****************
static final double appVersionID = 50.3;
static final int appChannelId = 3;
diff --git a/lib/core/app_assets.dart b/lib/core/app_assets.dart
index a581e78..9763758 100644
--- a/lib/core/app_assets.dart
+++ b/lib/core/app_assets.dart
@@ -218,6 +218,8 @@ class AppAssets {
static const String activity = '$svgBasePath/activity.svg';
static const String age = '$svgBasePath/age_icon.svg';
static const String gender = '$svgBasePath/gender_icon.svg';
+ static const String genderInputIcon = '$svgBasePath/genderInputIcon.svg';
+ static const String bloodType = '$svgBasePath/blood_type.svg';
static const String trade_down_yellow = '$svgBasePath/trade_down_yellow.svg';
static const String trade_down_red = '$svgBasePath/trade_down_red.svg';
diff --git a/lib/core/dependencies.dart b/lib/core/dependencies.dart
index ebf0a84..7db5d41 100644
--- a/lib/core/dependencies.dart
+++ b/lib/core/dependencies.dart
@@ -154,26 +154,20 @@ class AppDependencies {
() => RadiologyViewModel(radiologyRepo: getIt(), errorHandlerService: getIt(), navigationService: getIt()),
);
- getIt.registerLazySingleton(
- () => PrescriptionsViewModel(prescriptionsRepo: getIt(), errorHandlerService: getIt(), navServices: getIt()));
+ getIt.registerLazySingleton(() => PrescriptionsViewModel(prescriptionsRepo: getIt(), errorHandlerService: getIt(), navServices: getIt()));
getIt.registerLazySingleton(() => InsuranceViewModel(insuranceRepo: getIt(), errorHandlerService: getIt()));
- getIt.registerLazySingleton(
- () => MyAppointmentsViewModel(myAppointmentsRepo: getIt(), errorHandlerService: getIt(), appState: getIt()));
+ getIt.registerLazySingleton(() => MyAppointmentsViewModel(myAppointmentsRepo: getIt(), errorHandlerService: getIt(), appState: getIt()));
- getIt.registerLazySingleton(
- () => AppointmentRatingViewModel(myAppointmentsRepo: getIt(), errorHandlerService: getIt(), appState: getIt()));
+ getIt.registerLazySingleton(() => AppointmentRatingViewModel(myAppointmentsRepo: getIt(), errorHandlerService: getIt(), appState: getIt()));
getIt.registerLazySingleton(
() => PayfortViewModel(payfortRepo: getIt(), errorHandlerService: getIt()),
);
getIt.registerLazySingleton(
- () => HabibWalletViewModel(
- habibWalletRepo: getIt(),
- errorHandlerService: getIt()
- ),
+ () => HabibWalletViewModel(habibWalletRepo: getIt(), errorHandlerService: getIt()),
);
getIt.registerLazySingleton(
@@ -185,12 +179,7 @@ class AppDependencies {
getIt.registerLazySingleton(
() => BookAppointmentsViewModel(
- bookAppointmentsRepo: getIt(),
- errorHandlerService: getIt(),
- navigationService: getIt(),
- myAppointmentsViewModel: getIt(),
- locationUtils: getIt(),
- dialogService: getIt()),
+ bookAppointmentsRepo: getIt(), errorHandlerService: getIt(), navigationService: getIt(), myAppointmentsViewModel: getIt(), locationUtils: getIt(), dialogService: getIt()),
);
getIt.registerLazySingleton(
@@ -204,13 +193,7 @@ class AppDependencies {
getIt.registerLazySingleton(
() => AuthenticationViewModel(
- authenticationRepo: getIt(),
- cacheService: getIt(),
- navigationService: getIt(),
- dialogService: getIt(),
- appState: getIt(),
- errorHandlerService: getIt(),
- localAuthService: getIt()),
+ authenticationRepo: getIt(), cacheService: getIt(), navigationService: getIt(), dialogService: getIt(), appState: getIt(), errorHandlerService: getIt(), localAuthService: getIt()),
);
getIt.registerLazySingleton(() => ProfileSettingsViewModel());
@@ -271,6 +254,7 @@ class AppDependencies {
navigationService: getIt(),
dialogService: getIt(),
appState: getIt(),
+ navServices: getIt(),
),
);
diff --git a/lib/features/blood_donation/blood_donation_repo.dart b/lib/features/blood_donation/blood_donation_repo.dart
index dce0975..5643635 100644
--- a/lib/features/blood_donation/blood_donation_repo.dart
+++ b/lib/features/blood_donation/blood_donation_repo.dart
@@ -3,14 +3,26 @@ import 'package:hmg_patient_app_new/core/api/api_client.dart';
import 'package:hmg_patient_app_new/core/api_consts.dart';
import 'package:hmg_patient_app_new/core/common_models/generic_api_model.dart';
import 'package:hmg_patient_app_new/core/exceptions/api_failure.dart';
+import 'package:hmg_patient_app_new/features/blood_donation/models/blood_group_hospitals_model.dart';
import 'package:hmg_patient_app_new/features/blood_donation/models/blood_group_response_model.dart';
import 'package:hmg_patient_app_new/features/blood_donation/models/cities_model.dart';
+import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/hospital_model.dart';
import 'package:hmg_patient_app_new/services/logger_service.dart';
abstract class BloodDonationRepo {
Future>>> getAllCities();
+ Future>>> getProjectList();
+
+ Future>>> getBloodDonationProjectsList();
+
Future>> getPatientBloodGroupDetails();
+
+ Future>> updateBloodGroup({required Map request});
+
+ Future>> getFreeBloodDonationSlots({required Map request});
+
+ Future>> addUserAgreementForBloodDonation({required Map request});
}
class BloodDonationRepoImp implements BloodDonationRepo {
@@ -93,4 +105,186 @@ class BloodDonationRepoImp implements BloodDonationRepo {
return Left(UnknownFailure(e.toString()));
}
}
-}
\ No newline at end of file
+
+ @override
+ Future>>> getProjectList() async {
+ Map request = {};
+
+ try {
+ GenericApiModel>? apiResponse;
+ Failure? failure;
+ await apiClient.post(
+ GET_PROJECT_LIST,
+ body: request,
+ onFailure: (error, statusCode, {messageStatus, failureType}) {
+ failure = failureType;
+ },
+ onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
+ try {
+ final list = response['ListProject'];
+
+ final appointmentsList = list.map((item) => HospitalsModel.fromJson(item as Map)).toList().cast();
+
+ apiResponse = GenericApiModel>(
+ messageStatus: messageStatus,
+ statusCode: statusCode,
+ errorMessage: null,
+ data: appointmentsList,
+ );
+ } catch (e) {
+ failure = DataParsingFailure(e.toString());
+ }
+ },
+ );
+ if (failure != null) return Left(failure!);
+ if (apiResponse == null) return Left(ServerFailure("Unknown error"));
+ return Right(apiResponse!);
+ } catch (e) {
+ return Left(UnknownFailure(e.toString()));
+ }
+ }
+
+ @override
+ Future>>> getBloodDonationProjectsList() async {
+ Map request = {};
+
+ try {
+ GenericApiModel>? apiResponse;
+ Failure? failure;
+ await apiClient.post(
+ ApiConsts.getProjectsHaveBDClinics,
+ body: request,
+ onFailure: (error, statusCode, {messageStatus, failureType}) {
+ failure = failureType;
+ },
+ onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
+ try {
+ final listData = (response['BD_getProjectsHaveBDClinics'] as List);
+ final list = listData.map((item) => BdGetProjectsHaveBdClinic.fromJson(item as Map)).toList();
+ apiResponse = GenericApiModel>(
+ messageStatus: messageStatus,
+ statusCode: statusCode,
+ errorMessage: null,
+ data: list,
+ );
+ } catch (e) {
+ failure = DataParsingFailure(e.toString());
+ }
+ },
+ );
+ if (failure != null) return Left(failure!);
+ if (apiResponse == null) return Left(ServerFailure("Unknown error"));
+ return Right(apiResponse!);
+ } catch (e) {
+ return Left(UnknownFailure(e.toString()));
+ }
+ }
+
+ @override
+ Future>>> updateBloodGroup({required Map request}) async {
+ try {
+ GenericApiModel>? apiResponse;
+ Failure? failure;
+ await apiClient.post(
+ ApiConsts.bloodGroupUpdate,
+ body: request,
+ onFailure: (error, statusCode, {messageStatus, failureType}) {
+ failure = failureType;
+ },
+ onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
+ try {
+ // final list = response['ListProject'];
+
+ // final appointmentsList = list.map((item) => HospitalsModel.fromJson(item as Map)).toList().cast();
+
+ apiResponse = GenericApiModel>(
+ messageStatus: messageStatus,
+ statusCode: statusCode,
+ errorMessage: null,
+ data: response,
+ );
+ } catch (e) {
+ failure = DataParsingFailure(e.toString());
+ }
+ },
+ );
+ if (failure != null) return Left(failure!);
+ if (apiResponse == null) return Left(ServerFailure("Unknown error"));
+ return Right(apiResponse!);
+ } catch (e) {
+ return Left(UnknownFailure(e.toString()));
+ }
+ }
+
+ @override
+ Future>>> getFreeBloodDonationSlots({required Map request}) async {
+ try {
+ GenericApiModel>? apiResponse;
+ Failure? failure;
+ await apiClient.post(
+ ApiConsts.getClinicsBDFreeSlots,
+ body: request,
+ onFailure: (error, statusCode, {messageStatus, failureType}) {
+ failure = failureType;
+ },
+ onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
+ try {
+ // final list = response['ListProject'];
+
+ // final appointmentsList = list.map((item) => HospitalsModel.fromJson(item as Map)).toList().cast();
+
+ apiResponse = GenericApiModel>(
+ messageStatus: messageStatus,
+ statusCode: statusCode,
+ errorMessage: null,
+ data: response,
+ );
+ } catch (e) {
+ failure = DataParsingFailure(e.toString());
+ }
+ },
+ );
+ if (failure != null) return Left(failure!);
+ if (apiResponse == null) return Left(ServerFailure("Unknown error"));
+ return Right(apiResponse!);
+ } catch (e) {
+ return Left(UnknownFailure(e.toString()));
+ }
+ }
+
+ @override
+ Future>>> addUserAgreementForBloodDonation({required Map request}) async {
+ try {
+ GenericApiModel>? apiResponse;
+ Failure? failure;
+ await apiClient.post(
+ ApiConsts.userAgreementForBloodGroupUpdate,
+ body: request,
+ onFailure: (error, statusCode, {messageStatus, failureType}) {
+ failure = failureType;
+ },
+ onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
+ try {
+ // final list = response['ListProject'];
+
+ // final appointmentsList = list.map((item) => HospitalsModel.fromJson(item as Map)).toList().cast();
+
+ apiResponse = GenericApiModel>(
+ messageStatus: messageStatus,
+ statusCode: statusCode,
+ errorMessage: null,
+ data: response,
+ );
+ } catch (e) {
+ failure = DataParsingFailure(e.toString());
+ }
+ },
+ );
+ if (failure != null) return Left(failure!);
+ if (apiResponse == null) return Left(ServerFailure("Unknown error"));
+ return Right(apiResponse!);
+ } catch (e) {
+ return Left(UnknownFailure(e.toString()));
+ }
+ }
+}
diff --git a/lib/features/blood_donation/blood_donation_view_model.dart b/lib/features/blood_donation/blood_donation_view_model.dart
index b8f0e9c..8325cf7 100644
--- a/lib/features/blood_donation/blood_donation_view_model.dart
+++ b/lib/features/blood_donation/blood_donation_view_model.dart
@@ -1,15 +1,25 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.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/enums.dart';
+import 'package:hmg_patient_app_new/core/utils/doctor_response_mapper.dart';
import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
+import 'package:hmg_patient_app_new/features/authentication/authentication_view_model.dart';
import 'package:hmg_patient_app_new/features/blood_donation/blood_donation_repo.dart';
+import 'package:hmg_patient_app_new/features/blood_donation/models/blood_group_hospitals_model.dart';
import 'package:hmg_patient_app_new/features/blood_donation/models/blood_group_list_model.dart';
import 'package:hmg_patient_app_new/features/blood_donation/models/blood_group_response_model.dart';
import 'package:hmg_patient_app_new/features/blood_donation/models/cities_model.dart';
+import 'package:hmg_patient_app_new/features/book_appointments/book_appointments_view_model.dart';
+import 'package:hmg_patient_app_new/features/my_appointments/models/facility_selection.dart';
+import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/doctor_list_api_response.dart';
+import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/hospital_model.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/services/dialog_service.dart';
import 'package:hmg_patient_app_new/services/error_handler_service.dart';
import 'package:hmg_patient_app_new/services/navigation_service.dart';
+import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart';
class BloodDonationViewModel extends ChangeNotifier {
final DialogService dialogService;
@@ -17,8 +27,21 @@ class BloodDonationViewModel extends ChangeNotifier {
ErrorHandlerService errorHandlerService;
final NavigationService navigationService;
final AppState appState;
+ bool isTermsAccepted = false;
+ BdGetProjectsHaveBdClinic? selectedHospital;
+ CitiesModel? selectedCity;
+ BloodGroupListModel? selectedBloodGroup;
+ int _selectedHospitalIndex = 0;
+ int _selectedBloodTypeIndex = 0;
+ GenderTypeEnum? selectedGender;
+ String? selectedBloodType;
+ final NavigationService navServices;
+
+ List hospitalList = [];
List citiesList = [];
+ List_BloodGroupDetailsModel patientBloodGroupDetailsModel = List_BloodGroupDetailsModel();
+
List bloodGroupList = [
BloodGroupListModel("O+", 0),
BloodGroupListModel("O-", 1),
@@ -30,35 +53,34 @@ class BloodDonationViewModel extends ChangeNotifier {
BloodGroupListModel("B-", 7),
];
- List genderList = [
- BloodGroupListModel(LocaleKeys.malE.tr(), 1),
- BloodGroupListModel("Female".needTranslation.tr(), 2),
- ];
-
- late CitiesModel selectedCity;
- late BloodGroupListModel selectedBloodGroup;
- int _selectedHospitalIndex = 0;
- int _selectedBloodTypeIndex = 0;
- String selectedBloodType = '';
-
- List_BloodGroupDetailsModel patientBloodGroupDetailsModel = List_BloodGroupDetailsModel();
-
- BloodDonationViewModel({required this.bloodDonationRepo, required this.errorHandlerService, required this.navigationService, required this.dialogService, required this.appState});
+ BloodDonationViewModel({
+ required this.bloodDonationRepo,
+ required this.errorHandlerService,
+ required this.navigationService,
+ required this.dialogService,
+ required this.appState,
+ required this.navServices,
+ });
setSelectedCity(CitiesModel city) {
selectedCity = city;
notifyListeners();
}
+ void onGenderChange(String? status) {
+ selectedGender = GenderTypeExtension.fromType(status)!;
+ notifyListeners();
+ }
+
setSelectedBloodGroup(BloodGroupListModel bloodGroup) {
selectedBloodGroup = bloodGroup;
- selectedBloodType = selectedBloodGroup.name;
+ selectedBloodType = selectedBloodGroup!.name;
notifyListeners();
}
Future getRegionSelectedClinics({Function(dynamic)? onSuccess, Function(String)? onError}) async {
citiesList.clear();
- selectedCity = CitiesModel();
+ selectedCity = null;
notifyListeners();
final result = await bloodDonationRepo.getAllCities();
@@ -71,6 +93,7 @@ class BloodDonationViewModel extends ChangeNotifier {
onError!(apiResponse.errorMessage ?? 'An unexpected error occurred');
} else if (apiResponse.messageStatus == 1) {
citiesList = apiResponse.data!;
+ citiesList.sort((a, b) => a.description!.compareTo(b.description!));
notifyListeners();
if (onSuccess != null) {
onSuccess(apiResponse);
@@ -100,7 +123,7 @@ class BloodDonationViewModel extends ChangeNotifier {
citiesModel.descriptionN = citiesList[_selectedHospitalIndex].descriptionN;
selectedCity = citiesModel;
selectedBloodType = patientBloodGroupDetailsModel.bloodGroup!;
- _selectedBloodTypeIndex = getBloodIndex(selectedBloodType);
+ _selectedBloodTypeIndex = getBloodIndex(selectedBloodType ?? '');
notifyListeners();
if (onSuccess != null) {
@@ -113,11 +136,11 @@ class BloodDonationViewModel extends ChangeNotifier {
int getSelectedCityID() {
int cityID = 1;
- citiesList.forEach((element) {
+ for (var element in citiesList) {
if (element.description == patientBloodGroupDetailsModel.city) {
cityID = element.iD!;
}
- });
+ }
return cityID;
}
@@ -144,4 +167,120 @@ class BloodDonationViewModel extends ChangeNotifier {
return 0;
}
}
+
+ void onTermAccepted() {
+ isTermsAccepted = !isTermsAccepted;
+ notifyListeners();
+ }
+
+ bool isUserAuthanticated() {
+ print("the app state is ${appState.isAuthenticated}");
+ if (!appState.isAuthenticated) {
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ Future fetchHospitalsList() async {
+ // hospitalList.clear();
+ notifyListeners();
+ final result = await bloodDonationRepo.getBloodDonationProjectsList();
+
+ result.fold(
+ (failure) async => await errorHandlerService.handleError(failure: failure),
+ (apiResponse) async {
+ if (apiResponse.messageStatus == 2) {
+ } else if (apiResponse.messageStatus == 1) {
+ hospitalList = apiResponse.data!;
+ hospitalList.sort((a, b) => a.projectName!.compareTo(b.projectName!));
+ notifyListeners();
+ }
+ },
+ );
+ }
+
+ Future getFreeBloodDonationSlots({required Map request}) async {
+ final result = await bloodDonationRepo.getFreeBloodDonationSlots(request: request);
+
+ result.fold(
+ (failure) async => await errorHandlerService.handleError(failure: failure),
+ (apiResponse) async {
+ if (apiResponse.messageStatus == 2) {
+ } else if (apiResponse.messageStatus == 1) {
+ // TODO: Handle free slots data
+ print(apiResponse.data['BD_FreeSlots']);
+ notifyListeners();
+ }
+ },
+ );
+ }
+
+ bool isLocationEnabled() {
+ return appState.userLong != 0.0 && appState.userLong != 0.0;
+ }
+
+ setSelectedHospital(BdGetProjectsHaveBdClinic hospital) {
+ selectedHospital = hospital;
+ notifyListeners();
+ }
+
+ Future validateSelections() async {
+ if (selectedCity == null) {
+ await dialogService.showErrorBottomSheet(
+ message: "Please choose city",
+ );
+ return false;
+ }
+
+ if (selectedBloodGroup == null) {
+ await dialogService.showErrorBottomSheet(
+ message: "Please choose Gender",
+ );
+ return false;
+ }
+
+ if (selectedBloodType == null) {
+ await dialogService.showErrorBottomSheet(
+ message: "Please choose Blood Group",
+ );
+ return false;
+ }
+
+ if (!isTermsAccepted) {
+ await dialogService.showErrorBottomSheet(
+ message: "Please accept Terms and Conditions to continue",
+ );
+ return false;
+ }
+ return true;
+ }
+
+ Future updateBloodGroup() async {
+ LoaderBottomSheet.showLoader();
+ // body['City'] = detailsModel.city;
+ // body['cityCode'] = detailsModel.cityCode;
+ // body['Gender'] = detailsModel.gender;
+ // body['BloodGroup'] = detailsModel.bloodGroup;
+ // body['CellNumber'] = user.mobileNumber;
+ // body['LanguageID'] = languageID;
+ // body['NationalID'] = user.nationalityID;
+ // body['ZipCode'] = user.zipCode ?? "+966";
+ // body['isDentalAllowedBackend'] = false;
+ Map payload = {
+ "City": selectedCity?.description,
+ "cityCode": selectedCity?.iD,
+ "Gender": selectedGender?.value,
+ "isDentalAllowedBackend": false
+ // "Gender": selectedGender?.value,
+ };
+ await bloodDonationRepo.updateBloodGroup(request: payload);
+ await addUserAgreementForBloodDonation();
+ LoaderBottomSheet.hideLoader();
+ }
+
+ Future addUserAgreementForBloodDonation() async {
+ Map payload = {"IsAgreed": true};
+ await bloodDonationRepo.addUserAgreementForBloodDonation(request: payload);
+ }
}
diff --git a/lib/features/blood_donation/models/blood_group_hospitals_model.dart b/lib/features/blood_donation/models/blood_group_hospitals_model.dart
new file mode 100644
index 0000000..10b4e67
--- /dev/null
+++ b/lib/features/blood_donation/models/blood_group_hospitals_model.dart
@@ -0,0 +1,81 @@
+import 'dart:convert';
+
+class BdProjectsHaveBdClinicsModel {
+ List? bdGetProjectsHaveBdClinics;
+
+ BdProjectsHaveBdClinicsModel({
+ this.bdGetProjectsHaveBdClinics,
+ });
+
+ factory BdProjectsHaveBdClinicsModel.fromRawJson(String str) => BdProjectsHaveBdClinicsModel.fromJson(json.decode(str));
+
+ String toRawJson() => json.encode(toJson());
+
+ factory BdProjectsHaveBdClinicsModel.fromJson(Map json) => BdProjectsHaveBdClinicsModel(
+ bdGetProjectsHaveBdClinics: json["BD_getProjectsHaveBDClinics"] == null ? [] : List.from(json["BD_getProjectsHaveBDClinics"]!.map((x) => BdGetProjectsHaveBdClinic.fromJson(x))),
+ );
+
+ Map toJson() => {
+ "BD_getProjectsHaveBDClinics": bdGetProjectsHaveBdClinics == null ? [] : List.from(bdGetProjectsHaveBdClinics!.map((x) => x.toJson())),
+ };
+}
+
+class BdGetProjectsHaveBdClinic {
+ int? rowId;
+ int? id;
+ int? projectId;
+ int? numberOfRooms;
+ bool? isActive;
+ int? createdBy;
+ String? createdOn;
+ dynamic editedBy;
+ dynamic editedOn;
+ String? projectName;
+ dynamic projectNameN;
+
+ BdGetProjectsHaveBdClinic({
+ this.rowId,
+ this.id,
+ this.projectId,
+ this.numberOfRooms,
+ this.isActive,
+ this.createdBy,
+ this.createdOn,
+ this.editedBy,
+ this.editedOn,
+ this.projectName,
+ this.projectNameN,
+ });
+
+ factory BdGetProjectsHaveBdClinic.fromRawJson(String str) => BdGetProjectsHaveBdClinic.fromJson(json.decode(str));
+
+ String toRawJson() => json.encode(toJson());
+
+ factory BdGetProjectsHaveBdClinic.fromJson(Map json) => BdGetProjectsHaveBdClinic(
+ rowId: json["RowID"],
+ id: json["ID"],
+ projectId: json["ProjectID"],
+ numberOfRooms: json["NumberOfRooms"],
+ isActive: json["IsActive"],
+ createdBy: json["CreatedBy"],
+ createdOn: json["CreatedOn"],
+ editedBy: json["EditedBy"],
+ editedOn: json["EditedON"],
+ projectName: json["ProjectName"],
+ projectNameN: json["ProjectNameN"],
+ );
+
+ Map toJson() => {
+ "RowID": rowId,
+ "ID": id,
+ "ProjectID": projectId,
+ "NumberOfRooms": numberOfRooms,
+ "IsActive": isActive,
+ "CreatedBy": createdBy,
+ "CreatedOn": createdOn,
+ "EditedBy": editedBy,
+ "EditedON": editedOn,
+ "ProjectName": projectName,
+ "ProjectNameN": projectNameN,
+ };
+}
diff --git a/lib/features/blood_donation/widgets/hospital_selection.dart b/lib/features/blood_donation/widgets/hospital_selection.dart
new file mode 100644
index 0000000..288ac34
--- /dev/null
+++ b/lib/features/blood_donation/widgets/hospital_selection.dart
@@ -0,0 +1,86 @@
+import 'package:flutter/material.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/dependencies.dart';
+import 'package:hmg_patient_app_new/core/utils/size_utils.dart';
+import 'package:hmg_patient_app_new/core/utils/utils.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/features/blood_donation/blood_donation_view_model.dart';
+import 'package:hmg_patient_app_new/features/blood_donation/models/blood_group_hospitals_model.dart';
+import 'package:hmg_patient_app_new/theme/colors.dart' show AppColors;
+import 'package:provider/provider.dart';
+
+class HospitalBottomSheetBodySelection extends StatelessWidget {
+ final Function(BdGetProjectsHaveBdClinic userSelection) onUserHospitalSelection;
+
+ const HospitalBottomSheetBodySelection({super.key, required this.onUserHospitalSelection(BdGetProjectsHaveBdClinic userSelection)});
+
+ @override
+ Widget build(BuildContext context) {
+ final bloodDonationVm = Provider.of(context, listen: false);
+ AppState appState = getIt.get();
+ return Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Text(
+ "Please select the hospital you want to make an appointment.".needTranslation,
+ style: TextStyle(
+ fontSize: 16,
+ fontWeight: FontWeight.w500,
+ color: AppColors.greyTextColor,
+ ),
+ ),
+ SizedBox(height: 16.h),
+ SizedBox(
+ height: MediaQuery.sizeOf(context).height * .4,
+ child: ListView.separated(
+ itemBuilder: (_, index) {
+ return DecoratedBox(
+ decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
+ color: AppColors.whiteColor,
+ borderRadius: 20.h,
+ hasShadow: false,
+ ),
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Expanded(
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ spacing: 8.h,
+ children: [
+ hospitalName(bloodDonationVm.hospitalList[index]).onPress(() {
+ onUserHospitalSelection(bloodDonationVm.hospitalList[index]);
+ Navigator.of(context).pop();
+ })
+ ],
+ ),
+ ),
+ Transform.flip(
+ flipX: appState.isArabic(),
+ child: Utils.buildSvgWithAssets(icon: AppAssets.forward_arrow_icon, iconColor: AppColors.blackColor, width: 40.h, height: 40.h, fit: BoxFit.contain),
+ ),
+ ],
+ ).paddingSymmetrical(16.h, 16.h),
+ ).onPress(() {
+ bloodDonationVm.setSelectedHospital(bloodDonationVm.hospitalList[index]);
+ Navigator.of(context).pop();
+ });
+ },
+ separatorBuilder: (_, __) => SizedBox(height: 16.h),
+ itemCount: bloodDonationVm.hospitalList.length),
+ )
+ ],
+ );
+ }
+
+ Widget hospitalName(dynamic hospital) => Row(
+ children: [
+ Utils.buildSvgWithAssets(icon: AppAssets.hmg).paddingOnly(right: 10),
+ Expanded(
+ child: Text(hospital.projectName ?? "", style: TextStyle(fontWeight: FontWeight.w600, fontSize: 16, color: AppColors.blackColor)),
+ )
+ ],
+ );
+}
diff --git a/lib/features/book_appointments/book_appointments_view_model.dart b/lib/features/book_appointments/book_appointments_view_model.dart
index cbed940..380d2db 100644
--- a/lib/features/book_appointments/book_appointments_view_model.dart
+++ b/lib/features/book_appointments/book_appointments_view_model.dart
@@ -49,6 +49,7 @@ class BookAppointmentsViewModel extends ChangeNotifier {
bool isLiveCareSchedule = false;
bool isGetDocForHealthCal = false;
+ bool showSortFilterButtons = false;
int? calculationID = 0;
bool isSortByClinic = true;
@@ -200,8 +201,10 @@ class BookAppointmentsViewModel extends ChangeNotifier {
void filterClinics(String? query) {
if (query!.isEmpty) {
_filteredClinicsList = List.from(clinicsList);
+ showSortFilterButtons = false;
} else {
_filteredClinicsList = clinicsList.where((clinic) => clinic.clinicDescription?.toLowerCase().contains(query!.toLowerCase()) ?? false).toList();
+ showSortFilterButtons = query.length >= 3;
}
notifyListeners();
}
diff --git a/lib/features/medical_file/medical_file_repo.dart b/lib/features/medical_file/medical_file_repo.dart
index 2f5cae6..09856ca 100644
--- a/lib/features/medical_file/medical_file_repo.dart
+++ b/lib/features/medical_file/medical_file_repo.dart
@@ -293,14 +293,13 @@ class MedicalFileRepoImp implements MedicalFileRepo {
Failure? failure;
await apiClient.post(
ApiConsts.getAllSharedRecordsByStatus,
- body: {if (status != null) "Status": status, "PatientID": patientID},
+ body: {if (status != null) "Status": status, "PatientID": patientID.toString()},
onFailure: (error, statusCode, {messageStatus, failureType}) {
failure = failureType;
},
onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
try {
- final list = response['GetAllSharedRecordsByStatusList'];
-
+ final list = response['GetAllSharedRecordsByStatusList'] ?? [];
final familyLists = list.map((item) => FamilyFileResponseModelLists.fromJson(item as Map)).toList().cast();
@@ -336,7 +335,7 @@ class MedicalFileRepoImp implements MedicalFileRepo {
},
onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
try {
- final list = response['GetAllPendingRecordsList'];
+ final list = response['GetAllPendingRecordsList'] ?? [];
final familyLists = list.map((item) => FamilyFileResponseModelLists.fromJson(item as Map)).toList().cast();
apiResponse = GenericApiModel>(
diff --git a/lib/presentation/blood_donation/blood_donation_page.dart b/lib/presentation/blood_donation/blood_donation_page.dart
index 5f3fa86..a987220 100644
--- a/lib/presentation/blood_donation/blood_donation_page.dart
+++ b/lib/presentation/blood_donation/blood_donation_page.dart
@@ -7,16 +7,26 @@ import 'package:hmg_patient_app_new/core/utils/size_utils.dart';
import 'package:hmg_patient_app_new/core/utils/utils.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/features/authentication/authentication_view_model.dart';
import 'package:hmg_patient_app_new/features/blood_donation/blood_donation_view_model.dart';
+import 'package:hmg_patient_app_new/features/blood_donation/models/blood_group_hospitals_model.dart';
+import 'package:hmg_patient_app_new/features/blood_donation/widgets/hospital_selection.dart';
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_city_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/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';
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:provider/provider.dart';
+import 'package:hmg_patient_app_new/presentation/appointments/widgets/hospital_bottom_sheet/hospital_bottom_sheet_body.dart';
class BloodDonationPage extends StatelessWidget {
BloodDonationPage({super.key});
@@ -25,7 +35,7 @@ class BloodDonationPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
- appState = getIt.get();
+ appState = getIt();
return Scaffold(
backgroundColor: AppColors.bgScaffoldColor,
body: Consumer(builder: (context, bloodDonationVM, child) {
@@ -34,15 +44,83 @@ class BloodDonationPage extends StatelessWidget {
Expanded(
child: CollapsingListView(
title: LocaleKeys.bloodDonation.tr(),
+ trailing: CustomButton(
+ text: "Book",
+ onPressed: () {
+ // if (bloodDonationVM.isUserAuthanticated()) {
+ bloodDonationVM.fetchHospitalsList().then((value) {
+ showCommonBottomSheetWithoutHeight(context, title: "Select Hospital", isDismissible: false, child: Consumer(builder: (_, data, __) {
+ return HospitalBottomSheetBodySelection(
+ onUserHospitalSelection: (BdGetProjectsHaveBdClinic userChoice) {
+ print("============User Choice===============");
+
+ bloodDonationVM.getFreeBloodDonationSlots(request: {"ClinicID": 134, "ProjectID": userChoice.projectId});
+ },
+ );
+ }), callBackFunc: () {});
+ });
+ // } else {
+ // return showCommonBottomSheetWithoutHeight(
+ // context,
+ // title: LocaleKeys.notice.tr(context: context),
+ // child: Column(
+ // mainAxisAlignment: MainAxisAlignment.center,
+ // crossAxisAlignment: CrossAxisAlignment.center,
+ // children: [
+ // Lottie.asset(AppAnimations.errorAnimation, repeat: true, reverse: false, frameRate: FrameRate(60), width: 100.h, height: 100.h, fit: BoxFit.fill),
+ // SizedBox(height: 8.h),
+ // (LocaleKeys.loginToUseService.tr()).toText16(color: AppColors.blackColor),
+ // SizedBox(height: 16.h),
+ // Row(
+ // children: [
+ // Expanded(
+ // child: CustomButton(
+ // text: LocaleKeys.cancel.tr(),
+ // onPressed: () {
+ // Navigator.of(context).pop();
+ // },
+ // backgroundColor: AppColors.secondaryLightRedColor,
+ // borderColor: AppColors.secondaryLightRedColor,
+ // textColor: AppColors.primaryRedColor,
+ // icon: AppAssets.cancel,
+ // iconColor: AppColors.primaryRedColor,
+ // ),
+ // ),
+ // SizedBox(width: 8.h),
+ // Expanded(
+ // child: CustomButton(
+ // text: LocaleKeys.confirm.tr(),
+ // onPressed: () async {
+ // Navigator.of(context).pop();
+ // // Navigator.pushAndRemoveUntil(context, CustomPageRoute(page: LandingNavigation()), (r) => false);
+ // await getIt().onLoginPressed();
+ // },
+ // backgroundColor: AppColors.bgGreenColor,
+ // borderColor: AppColors.bgGreenColor,
+ // textColor: Colors.white,
+ // icon: AppAssets.confirm,
+ // ),
+ // ),
+ // ],
+ // ),
+ // SizedBox(height: 16.h),
+ // ],
+ // ).center,
+ // callBackFunc: () {},
+ // isFullScreen: false,
+ // isCloseButtonVisible: true,
+ // );
+ // }
+ },
+ backgroundColor: AppColors.bgRedLightColor,
+ borderColor: AppColors.bgRedLightColor,
+ textColor: AppColors.primaryRedColor,
+ padding: EdgeInsetsGeometry.symmetric(vertical: 0.h, horizontal: 20.h)),
child: Padding(
padding: EdgeInsets.all(24.w),
child: SingleChildScrollView(
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(
padding: EdgeInsets.all(16.h),
child: Column(
@@ -60,8 +138,8 @@ class BloodDonationPage extends StatelessWidget {
children: [
LocaleKeys.city.tr().toText16(color: AppColors.textColor, weight: FontWeight.w500),
(appState.isArabic()
- ? (bloodDonationVM.selectedCity.descriptionN ?? LocaleKeys.select.tr())
- : bloodDonationVM.selectedCity.description ?? LocaleKeys.select.tr(context: context))
+ ? (bloodDonationVM.selectedCity?.descriptionN ?? LocaleKeys.select.tr())
+ : bloodDonationVM.selectedCity?.description ?? LocaleKeys.select.tr(context: context))
.toText14(color: AppColors.greyTextColor, weight: FontWeight.w500),
],
),
@@ -71,12 +149,7 @@ class BloodDonationPage extends StatelessWidget {
],
).onPress(() async {
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),
Divider(color: AppColors.borderOnlyColor.withValues(alpha: 0.1), height: 1.h),
@@ -86,13 +159,16 @@ class BloodDonationPage extends StatelessWidget {
children: [
Row(
children: [
- Utils.buildSvgWithAssets(icon: AppAssets.my_account_icon, width: 40.h, height: 40.h),
+ Utils.buildSvgWithAssets(icon: AppAssets.genderInputIcon, width: 40.h, height: 40.h),
SizedBox(width: 12.w),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
LocaleKeys.gender.tr().toText16(color: AppColors.textColor, weight: FontWeight.w500),
- "Male".toText14(color: AppColors.greyTextColor, weight: FontWeight.w500),
+ (appState.isArabic()
+ ? (bloodDonationVM.selectedGender?.typeAr ?? LocaleKeys.select.tr())
+ : bloodDonationVM.selectedGender?.type ?? LocaleKeys.select.tr(context: context))
+ .toText14(color: AppColors.greyTextColor, weight: FontWeight.w500),
],
),
],
@@ -103,10 +179,7 @@ class BloodDonationPage extends StatelessWidget {
showCommonBottomSheetWithoutHeight(context,
title: LocaleKeys.selectGender.tr(context: context),
isDismissible: true,
- child: SelectGenderWidget(
- isArabic: appState.isArabic(),
- bloodDonationViewModel: bloodDonationVM,
- ),
+ child: SelectGenderWidget(isArabic: appState.isArabic(), bloodDonationViewModel: bloodDonationVM),
callBackFunc: () {});
}),
SizedBox(height: 16.h),
@@ -117,13 +190,17 @@ class BloodDonationPage extends StatelessWidget {
children: [
Row(
children: [
- Utils.buildSvgWithAssets(icon: AppAssets.my_account_icon, width: 40.h, height: 40.h),
+ Utils.buildSvgWithAssets(icon: AppAssets.bloodType, width: 40.h, height: 40.h),
SizedBox(width: 12.w),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
LocaleKeys.bloodType.tr().toText16(color: AppColors.textColor, weight: FontWeight.w500),
- bloodDonationVM.selectedBloodType.toText14(color: AppColors.greyTextColor, weight: FontWeight.w500),
+ // bloodDonationVM.selectedBloodType?.toText14(color: AppColors.greyTextColor, weight: FontWeight.w500),
+ (appState.isArabic()
+ ? (bloodDonationVM.selectedBloodType ?? LocaleKeys.select.tr())
+ : bloodDonationVM.selectedBloodType ?? LocaleKeys.select.tr(context: context))
+ .toText14(color: AppColors.greyTextColor, weight: FontWeight.w500)
],
),
],
@@ -134,10 +211,7 @@ class BloodDonationPage extends StatelessWidget {
showCommonBottomSheetWithoutHeight(context,
title: LocaleKeys.select.tr(context: context),
isDismissible: true,
- child: SelectBloodGroupWidget(
- isArabic: appState.isArabic(),
- bloodDonationViewModel: bloodDonationVM,
- ),
+ child: SelectBloodGroupWidget(isArabic: appState.isArabic(), bloodDonationViewModel: bloodDonationVM),
callBackFunc: () {});
}),
],
@@ -149,19 +223,73 @@ class BloodDonationPage extends StatelessWidget {
),
),
Container(
- decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
- color: AppColors.whiteColor,
- borderRadius: 24.r,
- hasShadow: true,
- ),
+ decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r, hasShadow: true),
child: SizedBox(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
+ GestureDetector(
+ onTap: bloodDonationVM.onTermAccepted,
+ child: Row(
+ children: [
+ Selector(
+ selector: (_, viewModel) => viewModel.isTermsAccepted,
+ shouldRebuild: (previous, next) => previous != next,
+ builder: (context, isTermsAccepted, child) {
+ return AnimatedContainer(
+ duration: const Duration(milliseconds: 200),
+ height: 24.h,
+ width: 24.h,
+ decoration: BoxDecoration(
+ color: isTermsAccepted ? AppColors.primaryRedColor : Colors.transparent,
+ borderRadius: BorderRadius.circular(6),
+ border: Border.all(color: isTermsAccepted ? AppColors.primaryRedBorderColor : AppColors.greyColor, width: 2.h),
+ ),
+ child: isTermsAccepted ? Icon(Icons.check, size: 16.f, color: Colors.white) : null,
+ );
+ },
+ ),
+ SizedBox(width: 12.h),
+ Row(
+ children: [
+ Text(
+ LocaleKeys.iAcceptThe.tr(),
+ style: context.dynamicTextStyle(fontSize: 14.f, fontWeight: FontWeight.w500, color: Color(0xFF2E3039)),
+ ),
+ GestureDetector(
+ onTap: () {
+ // Navigate to terms and conditions page
+ Navigator.of(context).pushNamed('/terms');
+ },
+ child: Text(
+ LocaleKeys.termsConditoins.tr(),
+ style: context.dynamicTextStyle(
+ fontSize: 14.f,
+ fontWeight: FontWeight.w500,
+ color: AppColors.primaryRedColor,
+ decoration: TextDecoration.underline,
+ decorationColor: AppColors.primaryRedBorderColor,
+ ),
+ ),
+ ),
+ ],
+ ),
+ // Expanded(
+ // child: Text(
+ // LocaleKeys.iAcceptTermsConditions.tr().split("the").first,
+ // style: context.dynamicTextStyle(fontSize: 14.fSize, fontWeight: FontWeight.w500, color: Color(0xFF2E3039)),
+ // ),
+ // ),
+ ],
+ ),
+ ).paddingOnly(left: 16.h, right: 16.h, top: 24.h),
CustomButton(
text: LocaleKeys.save.tr(),
- onPressed: () {
- // openDoctorScheduleCalendar();
+ onPressed: () async {
+ DialogService dialogService = getIt.get();
+ if (await bloodDonationVM.validateSelections()) {
+ bloodDonationVM.updateBloodGroup();
+ }
},
backgroundColor: AppColors.primaryRedColor,
borderColor: AppColors.primaryRedColor,
diff --git a/lib/presentation/blood_donation/widgets/select_city_widget.dart b/lib/presentation/blood_donation/widgets/select_city_widget.dart
index 8e2f9a0..bf5992d 100644
--- a/lib/presentation/blood_donation/widgets/select_city_widget.dart
+++ b/lib/presentation/blood_donation/widgets/select_city_widget.dart
@@ -26,9 +26,7 @@ class SelectCityWidget extends StatelessWidget {
Navigator.of(context).pop();
});
},
- separatorBuilder: (_, __) => SizedBox(
- height: 8.h,
- ),
+ separatorBuilder: (_, __) => SizedBox(height: 8.h),
itemCount: bloodDonationViewModel.citiesList.length),
)
],
diff --git a/lib/presentation/blood_donation/widgets/select_gender_widget.dart b/lib/presentation/blood_donation/widgets/select_gender_widget.dart
index 67cd4bb..0d360a8 100644
--- a/lib/presentation/blood_donation/widgets/select_gender_widget.dart
+++ b/lib/presentation/blood_donation/widgets/select_gender_widget.dart
@@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:hmg_patient_app_new/core/app_assets.dart';
+import 'package:hmg_patient_app_new/core/enums.dart';
import 'package:hmg_patient_app_new/core/utils/size_utils.dart';
import 'package:hmg_patient_app_new/core/utils/utils.dart';
import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
@@ -8,10 +9,10 @@ import 'package:hmg_patient_app_new/features/blood_donation/blood_donation_view_
import 'package:hmg_patient_app_new/theme/colors.dart';
class SelectGenderWidget extends StatelessWidget {
- SelectGenderWidget({super.key, required this.bloodDonationViewModel, required this.isArabic});
+ const SelectGenderWidget({super.key, required this.bloodDonationViewModel, required this.isArabic});
- BloodDonationViewModel bloodDonationViewModel;
- bool isArabic;
+ final BloodDonationViewModel bloodDonationViewModel;
+ final bool isArabic;
@override
Widget build(BuildContext context) {
@@ -20,46 +21,45 @@ class SelectGenderWidget extends StatelessWidget {
children: [
SizedBox(height: 8.h),
SizedBox(
- height: MediaQuery.sizeOf(context).height * .4,
- child: ListView.separated(
- itemBuilder: (_, index) {
- return DecoratedBox(
- decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
- color: AppColors.whiteColor,
- borderRadius: 20.h,
- hasShadow: false,
- ),
- child: Row(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- children: [
- Expanded(
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- spacing: 8.h,
- children: [bloodDonationViewModel.genderList[index].name.toText16(color: AppColors.textColor, isBold: true)],
+ height: MediaQuery.sizeOf(context).height * .4,
+ child: ListView.separated(
+ itemBuilder: (_, index) {
+ return DecoratedBox(
+ decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
+ color: AppColors.whiteColor,
+ borderRadius: 20.h,
+ hasShadow: false,
+ ),
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Expanded(
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ spacing: 8.h,
+ children: [GenderTypeEnum.values[index].name.toCamelCase.toText16(color: AppColors.textColor, isBold: true)],
+ ),
),
- ),
- Transform.flip(
- flipX: isArabic,
- child: Utils.buildSvgWithAssets(
- icon: AppAssets.forward_arrow_icon,
- iconColor: AppColors.blackColor,
- width: 40.h,
- height: 40.h,
- fit: BoxFit.contain,
+ Transform.flip(
+ flipX: isArabic,
+ child: Utils.buildSvgWithAssets(
+ icon: AppAssets.forward_arrow_icon,
+ iconColor: AppColors.blackColor,
+ width: 40.h,
+ height: 40.h,
+ fit: BoxFit.contain,
+ ),
),
- ),
- ],
- ).paddingSymmetrical(16.h, 16.h).onPress(() {
- // bloodDonationViewModel.setSelectedCity(bloodDonationViewModel.citiesList[index]);
- Navigator.of(context).pop();
- }));
- },
- separatorBuilder: (_, __) => SizedBox(
- height: 8.h,
- ),
- itemCount: bloodDonationViewModel.genderList.length),
- )
+ ],
+ ).paddingSymmetrical(16.h, 16.h).onPress(() {
+ bloodDonationViewModel.onGenderChange(GenderTypeEnum.values[index].name.toCamelCase);
+ Navigator.of(context).pop();
+ }));
+ },
+ separatorBuilder: (_, __) => SizedBox(
+ height: 8.h,
+ ),
+ itemCount: GenderTypeEnum.values.length))
],
);
}
diff --git a/lib/presentation/book_appointment/book_appointment_page.dart b/lib/presentation/book_appointment/book_appointment_page.dart
index 76dc1be..bcb2131 100644
--- a/lib/presentation/book_appointment/book_appointment_page.dart
+++ b/lib/presentation/book_appointment/book_appointment_page.dart
@@ -112,10 +112,7 @@ class _BookAppointmentPageState extends State {
fit: BoxFit.cover,
).circle(100).toShimmer2(isShow: true, radius: 50.r),
SizedBox(height: 8.h),
- ("Dr. John Smith Smith Smith")
- .toString()
- .toText12(fontWeight: FontWeight.w500, isCenter: true, maxLine: 2)
- .toShimmer2(isShow: true),
+ ("Dr. John Smith Smith Smith").toString().toText12(fontWeight: FontWeight.w500, isCenter: true, maxLine: 2).toShimmer2(isShow: true),
],
)
: myAppointmentsVM.patientMyDoctorsList.isEmpty
@@ -241,10 +238,7 @@ class _BookAppointmentPageState extends State {
),
],
),
- Transform.flip(
- flipX: appState.isArabic(),
- child: Utils.buildSvgWithAssets(
- icon: AppAssets.forward_arrow_icon, iconColor: AppColors.textColor, width: 40.h, height: 40.h)),
+ Transform.flip(flipX: appState.isArabic(), child: Utils.buildSvgWithAssets(icon: AppAssets.forward_arrow_icon, iconColor: AppColors.textColor, width: 40.h, height: 40.h)),
],
).onPress(() {
bookAppointmentsViewModel.setIsClinicsListLoading(true);
@@ -276,10 +270,7 @@ class _BookAppointmentPageState extends State {
),
],
),
- Transform.flip(
- flipX: appState.isArabic(),
- child: Utils.buildSvgWithAssets(
- icon: AppAssets.forward_arrow_icon, iconColor: AppColors.textColor, width: 40.h, height: 40.h)),
+ Transform.flip(flipX: appState.isArabic(), child: Utils.buildSvgWithAssets(icon: AppAssets.forward_arrow_icon, iconColor: AppColors.textColor, width: 40.h, height: 40.h)),
],
).onPress(() {
bookAppointmentsViewModel.setIsDoctorSearchByNameStarted(false);
@@ -309,10 +300,7 @@ class _BookAppointmentPageState extends State {
),
],
),
- Transform.flip(
- flipX: appState.isArabic(),
- child: Utils.buildSvgWithAssets(
- icon: AppAssets.forward_arrow_icon, iconColor: AppColors.textColor, width: 40.h, height: 40.h)),
+ Transform.flip(flipX: appState.isArabic(), child: Utils.buildSvgWithAssets(icon: AppAssets.forward_arrow_icon, iconColor: AppColors.textColor, width: 40.h, height: 40.h)),
],
).onPress(() {
bookAppointmentsViewModel.setProjectID(null);
@@ -332,124 +320,115 @@ class _BookAppointmentPageState extends State {
Column(
children: [
Container(
- decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
- color: AppColors.whiteColor,
- borderRadius: 24.h,
- hasShadow: false,
- ),
- child: Padding(
- padding: EdgeInsets.all(16.h),
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Row(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- children: [
- Row(
- children: [
- Utils.buildSvgWithAssets(icon: AppAssets.search_by_clinic_icon, width: 40.h, height: 40.h),
- SizedBox(width: 12.h),
- Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- "Immediate Consultation".needTranslation.toText14(color: AppColors.textColor, weight: FontWeight.w500),
- "Tap to select clinic".needTranslation.toText12(color: AppColors.primaryRedColor, fontWeight: FontWeight.w500),
- ],
- ),
- ],
- ),
- Transform.flip(
- flipX: appState.isArabic(),
- child: Utils.buildSvgWithAssets(
- icon: AppAssets.forward_arrow_icon, iconColor: AppColors.textColor, width: 40.h, height: 40.h)),
- ],
- ).onPress(() async {
- //TODO Implement API to check for existing LiveCare Requests
+ decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
+ color: AppColors.whiteColor,
+ borderRadius: 24.h,
+ hasShadow: false,
+ ),
+ child: Padding(
+ padding: EdgeInsets.all(16.h),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Row(
+ children: [
+ Utils.buildSvgWithAssets(icon: AppAssets.search_by_clinic_icon, width: 40.h, height: 40.h),
+ SizedBox(width: 12.h),
+ Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ "Immediate Consultation".needTranslation.toText14(color: AppColors.textColor, weight: FontWeight.w500),
+ "Tap to select clinic".needTranslation.toText12(color: AppColors.primaryRedColor, fontWeight: FontWeight.w500),
+ ],
+ ),
+ ],
+ ),
+ Transform.flip(flipX: appState.isArabic(), child: Utils.buildSvgWithAssets(icon: AppAssets.forward_arrow_icon, iconColor: AppColors.textColor, width: 40.h, height: 40.h)),
+ ],
+ ).onPress(() async {
+ //TODO Implement API to check for existing LiveCare Requests
- LoaderBottomSheet.showLoader();
- await immediateLiveCareViewModel.getPatientLiveCareHistory();
- LoaderBottomSheet.hideLoader();
+ LoaderBottomSheet.showLoader();
+ await immediateLiveCareViewModel.getPatientLiveCareHistory();
+ LoaderBottomSheet.hideLoader();
- if (immediateLiveCareViewModel.patientHasPendingLiveCareRequest) {
- Navigator.of(context).push(
- CustomPageRoute(
- page: ImmediateLiveCarePendingRequestPage(),
- ),
- );
- } else {
- Navigator.of(context).push(
- CustomPageRoute(
- page: SelectImmediateLiveCareClinicPage(),
- ),
- );
- }
- }),
- SizedBox(height: 16.h),
- Divider(color: AppColors.borderOnlyColor.withValues(alpha: 0.1), height: 1.h),
- SizedBox(height: 16.h),
- Row(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- children: [
- Row(
- children: [
- Utils.buildSvgWithAssets(icon: AppAssets.search_by_doctor_icon, width: 40.h, height: 40.h),
- SizedBox(width: 12.h),
- Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- "Scheduled Consultation".needTranslation.toText14(color: AppColors.textColor, weight: FontWeight.w500),
- "Tap to select clinic".needTranslation.toText12(color: AppColors.primaryRedColor, fontWeight: FontWeight.w500),
- ],
- ),
- ],
- ),
- Transform.flip(
- flipX: appState.isArabic(),
- child: Utils.buildSvgWithAssets(
- icon: AppAssets.forward_arrow_icon, iconColor: AppColors.textColor, width: 40.h, height: 40.h)),
- ],
- ).onPress(() {
- bookAppointmentsViewModel.setIsClinicsListLoading(true);
- bookAppointmentsViewModel.setIsLiveCareSchedule(true);
- Navigator.of(context).push(
- CustomPageRoute(
- page: SelectClinicPage(),
- ),
- );
- }),
- SizedBox(height: 16.h),
- Divider(color: AppColors.borderOnlyColor.withValues(alpha: 0.1), height: 1.h),
- SizedBox(height: 16.h),
- Row(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- children: [
- Row(
- children: [
- Utils.buildSvgWithAssets(icon: AppAssets.search_by_region_icon, width: 40.h, height: 40.h),
- SizedBox(width: 12.h),
- Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- "Pharma LiveCare".needTranslation.toText14(color: AppColors.textColor, weight: FontWeight.w500),
- "".needTranslation.toText12(color: AppColors.primaryRedColor, fontWeight: FontWeight.w500),
- ],
- ),
- ],
- ),
- Transform.flip(
- flipX: appState.isArabic(),
- child: Utils.buildSvgWithAssets(
- icon: AppAssets.forward_arrow_icon, iconColor: AppColors.textColor, width: 40.h, height: 40.h)),
- ],
- ).onPress(() {
- openRegionListBottomSheet(context, RegionBottomSheetType.FOR_REGION);
- }),
- ],
- ),
- ),
- ),
- ],
- ).paddingSymmetrical(24.h, 0.h)
+ if (immediateLiveCareViewModel.patientHasPendingLiveCareRequest) {
+ Navigator.of(context).push(
+ CustomPageRoute(
+ page: ImmediateLiveCarePendingRequestPage(),
+ ),
+ );
+ } else {
+ Navigator.of(context).push(
+ CustomPageRoute(
+ page: SelectImmediateLiveCareClinicPage(),
+ ),
+ );
+ }
+ }),
+ SizedBox(height: 16.h),
+ Divider(color: AppColors.borderOnlyColor.withValues(alpha: 0.1), height: 1.h),
+ SizedBox(height: 16.h),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Row(
+ children: [
+ Utils.buildSvgWithAssets(icon: AppAssets.search_by_doctor_icon, width: 40.h, height: 40.h),
+ SizedBox(width: 12.h),
+ Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ "Scheduled Consultation".needTranslation.toText14(color: AppColors.textColor, weight: FontWeight.w500),
+ "Tap to select clinic".needTranslation.toText12(color: AppColors.primaryRedColor, fontWeight: FontWeight.w500),
+ ],
+ ),
+ ],
+ ),
+ Transform.flip(flipX: appState.isArabic(), child: Utils.buildSvgWithAssets(icon: AppAssets.forward_arrow_icon, iconColor: AppColors.textColor, width: 40.h, height: 40.h)),
+ ],
+ ).onPress(() {
+ bookAppointmentsViewModel.setIsClinicsListLoading(true);
+ bookAppointmentsViewModel.setIsLiveCareSchedule(true);
+ Navigator.of(context).push(
+ CustomPageRoute(
+ page: SelectClinicPage(),
+ ),
+ );
+ }),
+ SizedBox(height: 16.h),
+ Divider(color: AppColors.borderOnlyColor.withValues(alpha: 0.1), height: 1.h),
+ SizedBox(height: 16.h),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Row(
+ children: [
+ Utils.buildSvgWithAssets(icon: AppAssets.search_by_region_icon, width: 40.h, height: 40.h),
+ SizedBox(width: 12.h),
+ Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ "Pharma LiveCare".needTranslation.toText14(color: AppColors.textColor, weight: FontWeight.w500),
+ "".needTranslation.toText12(color: AppColors.primaryRedColor, fontWeight: FontWeight.w500),
+ ],
+ ),
+ ],
+ ),
+ Transform.flip(flipX: appState.isArabic(), child: Utils.buildSvgWithAssets(icon: AppAssets.forward_arrow_icon, iconColor: AppColors.textColor, width: 40.h, height: 40.h)),
+ ],
+ ).onPress(() {
+ openRegionListBottomSheet(context, RegionBottomSheetType.FOR_REGION);
+ }),
+ ],
+ ),
+ ),
+ ),
+ ],
+ ).paddingSymmetrical(24.h, 0.h)
// : getLiveCareNotLoggedInUI()
;
default:
@@ -493,10 +472,8 @@ class _BookAppointmentPageState extends State {
regionalViewModel.flush();
regionalViewModel.setBottomSheetType(type);
// AppointmentViaRegionViewmodel? viewmodel = null;
- showCommonBottomSheetWithoutHeight(context,
- title: "",
- titleWidget: Consumer(builder: (_, data, __) => getTitle(data)),
- isDismissible: false, child: Consumer(builder: (_, data, __) {
+ showCommonBottomSheetWithoutHeight(context, title: "", titleWidget: Consumer(builder: (_, data, __) => getTitle(data)), isDismissible: false,
+ child: Consumer(builder: (_, data, __) {
return getRegionalSelectionWidget(data);
}), callBackFunc: () {});
}
@@ -582,9 +559,7 @@ class _BookAppointmentPageState extends State {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
"Immediate service".needTranslation.toText18(color: AppColors.textColor, isBold: true),
- "No need to wait, you will get medical consultation immediately via video call"
- .needTranslation
- .toText14(color: AppColors.greyTextColor, weight: FontWeight.w500),
+ "No need to wait, you will get medical consultation immediately via video call".needTranslation.toText14(color: AppColors.greyTextColor, weight: FontWeight.w500),
],
),
),
@@ -616,9 +591,7 @@ class _BookAppointmentPageState extends State {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
"Doctor will contact".needTranslation.toText18(color: AppColors.textColor, isBold: true),
- "A specialised doctor will contact you and will be able to view your medical history"
- .needTranslation
- .toText14(color: AppColors.greyTextColor, weight: FontWeight.w500),
+ "A specialised doctor will contact you and will be able to view your medical history".needTranslation.toText14(color: AppColors.greyTextColor, weight: FontWeight.w500),
],
),
),
@@ -634,9 +607,7 @@ class _BookAppointmentPageState extends State {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
"Free medicine delivery".needTranslation.toText18(color: AppColors.textColor, isBold: true),
- "Offers free medicine delivery for the LiveCare appointment"
- .needTranslation
- .toText14(color: AppColors.greyTextColor, weight: FontWeight.w500),
+ "Offers free medicine delivery for the LiveCare appointment".needTranslation.toText14(color: AppColors.greyTextColor, weight: FontWeight.w500),
],
),
),
diff --git a/lib/presentation/book_appointment/laser/laser_appointment.dart b/lib/presentation/book_appointment/laser/laser_appointment.dart
index 19a3800..aae7990 100644
--- a/lib/presentation/book_appointment/laser/laser_appointment.dart
+++ b/lib/presentation/book_appointment/laser/laser_appointment.dart
@@ -1,6 +1,7 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:hmg_patient_app_new/core/utils/size_utils.dart';
+import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
import 'package:hmg_patient_app_new/extensions/string_extensions.dart' show CapExtension;
import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
import 'package:hmg_patient_app_new/extensions/widget_extensions.dart';
diff --git a/lib/presentation/book_appointment/select_clinic_page.dart b/lib/presentation/book_appointment/select_clinic_page.dart
index 48c0cd5..15c8654 100644
--- a/lib/presentation/book_appointment/select_clinic_page.dart
+++ b/lib/presentation/book_appointment/select_clinic_page.dart
@@ -1211,9 +1211,7 @@ class _SelectClinicPageState extends State {
bookAppointmentsViewModel.setIsContinueDentalPlan(true);
Navigator.of(context).pop();
Navigator.of(context).push(
- CustomPageRoute(
- page: SelectDoctorPage(),
- ),
+ CustomPageRoute(page: SelectDoctorPage()),
);
},
backgroundColor: AppColors.bgGreenColor,
diff --git a/lib/presentation/book_appointment/select_doctor_page.dart b/lib/presentation/book_appointment/select_doctor_page.dart
index d77e152..569e8ac 100644
--- a/lib/presentation/book_appointment/select_doctor_page.dart
+++ b/lib/presentation/book_appointment/select_doctor_page.dart
@@ -40,9 +40,7 @@ class _SelectDoctorPageState extends State {
late AppState appState;
late BookAppointmentsViewModel bookAppointmentsViewModel;
- // Scroll controller to control page scrolling when a group expands
late ScrollController _scrollController;
- // Map of keys for each item to allow scrolling to them
final Map _itemKeys = {};
@override
@@ -79,6 +77,20 @@ class _SelectDoctorPageState extends State {
backgroundColor: AppColors.bgScaffoldColor,
body: CollapsingListView(
title: "Choose Doctor".needTranslation,
+ // bottomChild: Container(
+ // decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, customBorder: BorderRadius.only(topLeft: Radius.circular(24.r), topRight: Radius.circular(24.r))),
+ // padding: EdgeInsets.symmetric(vertical: 20.h, horizontal: 20.h),
+ // child: CustomButton(
+ // text: LocaleKeys.search.tr(),
+ // onPressed: () {
+ // },
+ // icon: null,
+ // fontSize: 16.f,
+ // backgroundColor: AppColors.primaryRedColor,
+ // borderColor: AppColors.primaryRedColor,
+ // borderRadius: 12.r,
+ // fontWeight: FontWeight.w500),
+ // ),
child: SingleChildScrollView(
controller: _scrollController,
child: Padding(
@@ -124,40 +136,42 @@ class _SelectDoctorPageState extends State {
],
),
SizedBox(height: 16.h),
- Row(
- children: [
- CustomButton(
- text: LocaleKeys.byClinic.tr(context: context),
- onPressed: () {
- bookAppointmentsVM.setIsSortByClinic(true);
- },
- backgroundColor: bookAppointmentsVM.isSortByClinic ? AppColors.bgRedLightColor : AppColors.whiteColor,
- borderColor: bookAppointmentsVM.isSortByClinic ? AppColors.primaryRedColor : AppColors.textColor.withOpacity(0.2),
- textColor: bookAppointmentsVM.isSortByClinic ? AppColors.primaryRedColor : AppColors.blackColor,
- fontSize: 12,
- fontWeight: FontWeight.w500,
- borderRadius: 10,
- padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
- height: 40.h,
- ),
- SizedBox(width: 8.h),
- CustomButton(
- text: LocaleKeys.byHospital.tr(context: context),
- onPressed: () {
- bookAppointmentsVM.setIsSortByClinic(false);
- },
- backgroundColor: bookAppointmentsVM.isSortByClinic ? AppColors.whiteColor : AppColors.bgRedLightColor,
- borderColor: bookAppointmentsVM.isSortByClinic ? AppColors.textColor.withOpacity(0.2) : AppColors.primaryRedColor,
- textColor: bookAppointmentsVM.isSortByClinic ? AppColors.blackColor : AppColors.primaryRedColor,
- fontSize: 12,
- fontWeight: FontWeight.w500,
- borderRadius: 10,
- padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
- height: 40.h,
- ),
- ],
- ).paddingSymmetrical(0.h, 0.h),
- SizedBox(height: 16.h),
+ if (bookAppointmentsViewModel.isGetDocForHealthCal && bookAppointmentsVM.showSortFilterButtons)
+ Row(
+ children: [
+ CustomButton(
+ text: LocaleKeys.byClinic.tr(context: context),
+ onPressed: () {
+ bookAppointmentsVM.setIsSortByClinic(true);
+ },
+ backgroundColor: bookAppointmentsVM.isSortByClinic ? AppColors.bgRedLightColor : AppColors.whiteColor,
+ borderColor: bookAppointmentsVM.isSortByClinic ? AppColors.primaryRedColor : AppColors.textColor.withOpacity(0.2),
+ textColor: bookAppointmentsVM.isSortByClinic ? AppColors.primaryRedColor : AppColors.blackColor,
+ fontSize: 12,
+ fontWeight: FontWeight.w500,
+ borderRadius: 10,
+ padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
+ height: 40.h,
+ ),
+ SizedBox(width: 8.h),
+ CustomButton(
+ text: LocaleKeys.byHospital.tr(context: context),
+ onPressed: () {
+ bookAppointmentsVM.setIsSortByClinic(false);
+ },
+ backgroundColor: bookAppointmentsVM.isSortByClinic ? AppColors.whiteColor : AppColors.bgRedLightColor,
+ borderColor: bookAppointmentsVM.isSortByClinic ? AppColors.textColor.withOpacity(0.2) : AppColors.primaryRedColor,
+ textColor: bookAppointmentsVM.isSortByClinic ? AppColors.blackColor : AppColors.primaryRedColor,
+ fontSize: 12,
+ fontWeight: FontWeight.w500,
+ borderRadius: 10,
+ padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
+ height: 40.h,
+ ),
+ ],
+ ).paddingSymmetrical(0.h, 0.h),
+ if (bookAppointmentsViewModel.isGetDocForHealthCal && bookAppointmentsVM.showSortFilterButtons)
+ SizedBox(height: 16.h),
Row(
mainAxisSize: MainAxisSize.max,
children: [