LiveCare shcedule implementation contd.

pull/62/head
haroon amjad 1 month ago
parent 938d95cb06
commit a711d3a6dd

@ -176,8 +176,8 @@ class ApiClientImp implements ApiClient {
body[_appState.isAuthenticated ? 'TokenID' : 'LogInTokenID'] = _appState.appAuthToken; body[_appState.isAuthenticated ? 'TokenID' : 'LogInTokenID'] = _appState.appAuthToken;
} }
// body['TokenID'] = "@dm!n"; body['TokenID'] = "@dm!n";
// body['PatientID'] = 3628599; body['PatientID'] = 4767477;
} }
body.removeWhere((key, value) => value == null); body.removeWhere((key, value) => value == null);

@ -727,7 +727,7 @@ const FAMILY_FILES= 'Services/Authentication.svc/REST/GetAllSharedRecordsByStatu
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

@ -365,7 +365,7 @@ extension DynamicTextStyleExtension on BuildContext {
TextBaseline? textBaseline, TextBaseline? textBaseline,
FontStyle? fontStyle, FontStyle? fontStyle,
bool isLanguageSwitcher = false}) { bool isLanguageSwitcher = false}) {
final family = FontUtils.getFontFamilyForLanguage(true); final family = FontUtils.getFontFamilyForLanguage(false); // TODO: @Aamir make it dynamic based on app language
return TextStyle( return TextStyle(
fontFamily: family, fontFamily: family,
fontSize: fontSize, fontSize: fontSize,

@ -7,6 +7,7 @@ import 'package:hmg_patient_app_new/core/utils/date_util.dart';
import 'package:hmg_patient_app_new/features/book_appointments/models/resp_models/doctor_profile_response_model.dart'; import 'package:hmg_patient_app_new/features/book_appointments/models/resp_models/doctor_profile_response_model.dart';
import 'package:hmg_patient_app_new/features/book_appointments/models/resp_models/doctors_list_response_model.dart'; import 'package:hmg_patient_app_new/features/book_appointments/models/resp_models/doctors_list_response_model.dart';
import 'package:hmg_patient_app_new/features/book_appointments/models/resp_models/get_clinic_list_response_model.dart'; import 'package:hmg_patient_app_new/features/book_appointments/models/resp_models/get_clinic_list_response_model.dart';
import 'package:hmg_patient_app_new/features/book_appointments/models/resp_models/get_livecare_clinics_response_model.dart';
import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/hospital_model.dart'; import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/hospital_model.dart';
import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/patient_appointment_history_response_model.dart'; import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/patient_appointment_history_response_model.dart';
import 'package:hmg_patient_app_new/services/logger_service.dart'; import 'package:hmg_patient_app_new/services/logger_service.dart';
@ -45,6 +46,13 @@ abstract class BookAppointmentsRepo {
Future<Either<Failure, GenericApiModel<List<HospitalsModel>>>> getProjectList(); Future<Either<Failure, GenericApiModel<List<HospitalsModel>>>> getProjectList();
Future<Either<Failure, GenericApiModel<List<GetClinicsListResponseModel>>>> getClinicsWithRespectToClinicId(String projectID); Future<Either<Failure, GenericApiModel<List<GetClinicsListResponseModel>>>> getClinicsWithRespectToClinicId(String projectID);
Future<Either<Failure, GenericApiModel<List<GetLiveCareClinicsResponseModel>>>> getLiveCareScheduleClinics(int age, int genderID);
Future<Either<Failure, GenericApiModel<List<DoctorsListResponseModel>>>> getLiveCareDoctorsList(int serviceID, int age, int genderID, {Function(dynamic)? onSuccess, Function(String)? onError});
Future<Either<Failure, GenericApiModel<dynamic>>> getLiveCareDoctorFreeSlots(int clinicID, int serviceID, int projectID, int doctorId, bool isBookingForLiveCare,
{Function(dynamic)? onSuccess, Function(String)? onError});
} }
class BookAppointmentsRepoImp implements BookAppointmentsRepo { class BookAppointmentsRepoImp implements BookAppointmentsRepo {
@ -443,4 +451,133 @@ class BookAppointmentsRepoImp implements BookAppointmentsRepo {
return Left(UnknownFailure(e.toString())); return Left(UnknownFailure(e.toString()));
} }
} }
@override
Future<Either<Failure, GenericApiModel<List<GetLiveCareClinicsResponseModel>>>> getLiveCareScheduleClinics(int age, int genderID) async {
Map<String, dynamic> mapDevice = {"Age": age, "Gender": genderID};
try {
GenericApiModel<List<GetLiveCareClinicsResponseModel>>? apiResponse;
Failure? failure;
await apiClient.post(
GET_LIVECARE_SCHEDULE_CLINICS,
body: mapDevice,
onFailure: (error, statusCode, {messageStatus, failureType}) {
failure = failureType;
},
onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
try {
final list = response['ClinicsHaveScheduleList'];
// if (list == null || list.isEmpty) {
// throw Exception("lab list is empty");
// }
final clinicsList = list.map((item) => GetLiveCareClinicsResponseModel.fromJson(item as Map<String, dynamic>)).toList().cast<GetLiveCareClinicsResponseModel>();
apiResponse = GenericApiModel<List<GetLiveCareClinicsResponseModel>>(
messageStatus: messageStatus,
statusCode: statusCode,
errorMessage: null,
data: clinicsList,
);
} 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<Either<Failure, GenericApiModel<List<DoctorsListResponseModel>>>> getLiveCareDoctorsList(int serviceID, int age, int genderID,
{Function(dynamic)? onSuccess, Function(String)? onError}) async {
Map<String, dynamic> mapDevice = {
"ServiceID": serviceID,
"Age": age,
"Gender": genderID,
};
try {
GenericApiModel<List<DoctorsListResponseModel>>? apiResponse;
Failure? failure;
await apiClient.post(
GET_LIVECARE_SCHEDULE_CLINIC_DOCTOR_LIST,
body: mapDevice,
onFailure: (error, statusCode, {messageStatus, failureType}) {
failure = failureType;
onError!(error);
},
onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
try {
final list = response['DoctorByClinicIDList'];
final doctorsList = list.map((item) => DoctorsListResponseModel.fromJson(item as Map<String, dynamic>)).toList().cast<DoctorsListResponseModel>();
apiResponse = GenericApiModel<List<DoctorsListResponseModel>>(
messageStatus: messageStatus,
statusCode: statusCode,
errorMessage: null,
data: doctorsList,
);
} 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<Either<Failure, GenericApiModel>> getLiveCareDoctorFreeSlots(int clinicID, int serviceID, int projectID, int doctorId, bool isBookingForLiveCare,
{Function(dynamic)? onSuccess, Function(String)? onError}) async {
Map<String, dynamic> mapDevice = {
"DoctorID": doctorId,
"IsBookingForLiveCare": true,
"ClinicID": clinicID,
"ServiceID": serviceID,
"ProjectID": projectID,
"OriginalClinicID": clinicID,
"days": 50,
"isReschadual": false,
};
try {
GenericApiModel<dynamic>? apiResponse;
Failure? failure;
await apiClient.post(
GET_LIVECARE_SCHEDULE_DOCTOR_TIME_SLOTS,
body: mapDevice,
onFailure: (error, statusCode, {messageStatus, failureType}) {
failure = failureType;
},
onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
try {
apiResponse = GenericApiModel<dynamic>(
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()));
}
}
} }

@ -29,6 +29,8 @@ import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart';
import 'package:hmg_patient_app_new/widgets/transitions/fade_page.dart'; import 'package:hmg_patient_app_new/widgets/transitions/fade_page.dart';
import 'package:location/location.dart' show Location; import 'package:location/location.dart' show Location;
import 'models/resp_models/get_livecare_clinics_response_model.dart';
class BookAppointmentsViewModel extends ChangeNotifier { class BookAppointmentsViewModel extends ChangeNotifier {
int selectedTabIndex = 0; int selectedTabIndex = 0;
@ -37,6 +39,8 @@ class BookAppointmentsViewModel extends ChangeNotifier {
bool isDoctorProfileLoading = false; bool isDoctorProfileLoading = false;
bool isDoctorSearchByNameStarted = false; bool isDoctorSearchByNameStarted = false;
bool isLiveCareSchedule = false;
int initialSlotDuration = 0; int initialSlotDuration = 0;
LocationUtils locationUtils; LocationUtils locationUtils;
@ -44,12 +48,17 @@ class BookAppointmentsViewModel extends ChangeNotifier {
List<GetClinicsListResponseModel> clinicsList = []; List<GetClinicsListResponseModel> clinicsList = [];
List<GetClinicsListResponseModel> _filteredClinicsList = []; List<GetClinicsListResponseModel> _filteredClinicsList = [];
List<GetLiveCareClinicsResponseModel> liveCareClinicsList = [];
List<GetClinicsListResponseModel> get filteredClinicsList => _filteredClinicsList; List<GetClinicsListResponseModel> get filteredClinicsList => _filteredClinicsList;
List<DoctorsListResponseModel> doctorsList = []; List<DoctorsListResponseModel> doctorsList = [];
List<DoctorsListResponseModel> liveCareDoctorsList = [];
GetClinicsListResponseModel selectedClinic = GetClinicsListResponseModel(); GetClinicsListResponseModel selectedClinic = GetClinicsListResponseModel();
DoctorsListResponseModel selectedDoctor = DoctorsListResponseModel(); DoctorsListResponseModel selectedDoctor = DoctorsListResponseModel();
GetLiveCareClinicsResponseModel selectedLiveCareClinic = GetLiveCareClinicsResponseModel();
late DoctorsProfileResponseModel doctorsProfileResponseModel; late DoctorsProfileResponseModel doctorsProfileResponseModel;
@ -78,7 +87,9 @@ class BookAppointmentsViewModel extends ChangeNotifier {
bool shouldLoadSpecificClinic = false; bool shouldLoadSpecificClinic = false;
String? currentlySelectedHospitalFromRegionFlow; String? currentlySelectedHospitalFromRegionFlow;
BookAppointmentsViewModel({required this.bookAppointmentsRepo, required this.errorHandlerService, required this.navigationService, required this.myAppointmentsViewModel, required this.locationUtils}) {; BookAppointmentsViewModel(
{required this.bookAppointmentsRepo, required this.errorHandlerService, required this.navigationService, required this.myAppointmentsViewModel, required this.locationUtils}) {
;
initBookAppointmentViewModel(); initBookAppointmentViewModel();
} }
@ -101,8 +112,10 @@ class BookAppointmentsViewModel extends ChangeNotifier {
isClinicsListLoading = true; isClinicsListLoading = true;
isDoctorsListLoading = true; isDoctorsListLoading = true;
isDoctorProfileLoading = true; isDoctorProfileLoading = true;
isLiveCareSchedule = false;
clinicsList.clear(); clinicsList.clear();
doctorsList.clear(); doctorsList.clear();
liveCareClinicsList.clear();
// getLocation(); // getLocation();
notifyListeners(); notifyListeners();
} }
@ -154,6 +167,16 @@ class BookAppointmentsViewModel extends ChangeNotifier {
notifyListeners(); notifyListeners();
} }
setIsLiveCareSchedule(bool value) {
isLiveCareSchedule = value;
notifyListeners();
}
setLiveCareSelectedClinic(GetLiveCareClinicsResponseModel clinic) {
selectedLiveCareClinic = clinic;
notifyListeners();
}
void onTabChanged(int index) { void onTabChanged(int index) {
selectedTabIndex = index; selectedTabIndex = index;
notifyListeners(); notifyListeners();
@ -161,10 +184,11 @@ class BookAppointmentsViewModel extends ChangeNotifier {
/// this function will decide which clinic api to be called /// this function will decide which clinic api to be called
/// either api for region flow or the select clinic api /// either api for region flow or the select clinic api
Future<void> getClinics() async Future<void> getClinics() async {
{ if (shouldLoadSpecificClinic) {
if(shouldLoadSpecificClinic) {
getRegionSelectedClinics(); getRegionSelectedClinics();
} else if (isLiveCareSchedule) {
getLiveCareScheduleClinics();
} else { } else {
getAllClinics(); getAllClinics();
} }
@ -191,11 +215,58 @@ class BookAppointmentsViewModel extends ChangeNotifier {
); );
} }
Future<void> getLiveCareScheduleClinics({Function(dynamic)? onSuccess, Function(String)? onError}) async {
liveCareClinicsList.clear();
final result = await bookAppointmentsRepo.getLiveCareScheduleClinics(_appState.getAuthenticatedUser()!.age!, _appState.getAuthenticatedUser()!.gender!);
result.fold(
(failure) async => await errorHandlerService.handleError(failure: failure),
(apiResponse) {
if (apiResponse.messageStatus == 2) {
// dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {});
} else if (apiResponse.messageStatus == 1) {
liveCareClinicsList = apiResponse.data!;
isClinicsListLoading = false;
initializeFilteredList();
notifyListeners();
if (onSuccess != null) {
onSuccess(apiResponse);
}
}
},
);
}
Future<void> getLiveCareDoctorsList({Function(dynamic)? onSuccess, Function(String)? onError}) async {
doctorsList.clear();
final result =
await bookAppointmentsRepo.getLiveCareDoctorsList(selectedLiveCareClinic.serviceID!, _appState.getAuthenticatedUser()!.age!, _appState.getAuthenticatedUser()!.gender!, onError: onError);
result.fold(
(failure) async {
onError!("No doctors found for the search criteria".needTranslation);
},
(apiResponse) {
if (apiResponse.messageStatus == 2) {
// dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {});
} else if (apiResponse.messageStatus == 1) {
liveCareDoctorsList = apiResponse.data!;
isDoctorsListLoading = false;
// initializeFilteredList();
notifyListeners();
if (onSuccess != null) {
onSuccess(apiResponse);
}
}
},
);
}
//TODO: Make the API dynamic with parameters for ProjectID, isNearest, languageID, doctorId, doctorName //TODO: Make the API dynamic with parameters for ProjectID, isNearest, languageID, doctorId, doctorName
Future<void> getDoctorsList( Future<void> getDoctorsList(
{int projectID = 0, bool isNearest = false, int doctorId = 0, String doctorName = "", isContinueDentalPlan = false, Function(dynamic)? onSuccess, Function(String)? onError}) async { {int projectID = 0, bool isNearest = false, int doctorId = 0, String doctorName = "", isContinueDentalPlan = false, Function(dynamic)? onSuccess, Function(String)? onError}) async {
doctorsList.clear(); doctorsList.clear();
projectID = currentlySelectedHospitalFromRegionFlow != null?int.parse(currentlySelectedHospitalFromRegionFlow!):projectID; projectID = currentlySelectedHospitalFromRegionFlow != null ? int.parse(currentlySelectedHospitalFromRegionFlow!) : projectID;
final result = await bookAppointmentsRepo.getDoctorsList(selectedClinic.clinicID ?? 0, projectID, isNearest, doctorId, doctorName); final result = await bookAppointmentsRepo.getDoctorsList(selectedClinic.clinicID ?? 0, projectID, isNearest, doctorId, doctorName);
result.fold( result.fold(
@ -238,7 +309,6 @@ class BookAppointmentsViewModel extends ChangeNotifier {
); );
} }
//TODO: Handle the cases for LiveCare Schedule
Future<void> getDoctorFreeSlots({bool isBookingForLiveCare = false, Function(dynamic)? onSuccess, Function(String)? onError}) async { Future<void> getDoctorFreeSlots({bool isBookingForLiveCare = false, Function(dynamic)? onSuccess, Function(String)? onError}) async {
docFreeSlots.clear(); docFreeSlots.clear();
DateTime date; DateTime date;
@ -281,6 +351,50 @@ class BookAppointmentsViewModel extends ChangeNotifier {
); );
} }
Future<void> getLiveCareDoctorFreeSlots({bool isBookingForLiveCare = false, Function(dynamic)? onSuccess, Function(String)? onError}) async {
docFreeSlots.clear();
DateTime date;
final DateFormat formatter = DateFormat('HH:mm');
final DateFormat dateFormatter = DateFormat('yyyy-MM-dd');
Map<DateTime, List> _eventsParsed;
final result = await bookAppointmentsRepo.getLiveCareDoctorFreeSlots(
selectedDoctor.clinicID ?? 0, selectedLiveCareClinic.serviceID ?? 0, selectedDoctor.projectID ?? 0, selectedDoctor.doctorID ?? 0, isBookingForLiveCare,
onError: onError);
result.fold(
(failure) async {
print(failure);
},
(apiResponse) {
if (apiResponse.messageStatus == 2) {
onError!(apiResponse.errorMessage ?? "Unknown error occurred");
// dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {});
} else if (apiResponse.messageStatus == 1) {
if (apiResponse.data['PatientER_DoctorFreeSlots'] == null || apiResponse.data['PatientER_DoctorFreeSlots'].isEmpty) {
onError!("No free slots available".tr());
return;
}
initialSlotDuration = apiResponse.data["InitialSlotDuration"];
freeSlotsResponse = apiResponse.data['PatientER_DoctorFreeSlots'];
freeSlotsResponse.forEach((element) {
// date = (isLiveCareSchedule != null && isLiveCareSchedule)
// ? DateUtil.convertStringToDate(element)
// :
date = DateUtil.convertStringToDateSaudiTimezone(element, int.parse(selectedDoctor.projectID.toString()));
slotsList.add(FreeSlot(date, ['slot']));
docFreeSlots.add(TimeSlot(isoTime: formatter.format(date), start: new DateTime(date.year, date.month, date.day, 0, 0, 0, 0), end: date, vidaDate: element));
});
notifyListeners();
if (onSuccess != null) {
onSuccess(apiResponse);
}
}
},
);
}
Future<void> cancelAppointment({required PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel, Function(dynamic)? onSuccess, Function(String)? onError}) async { Future<void> cancelAppointment({required PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel, Function(dynamic)? onSuccess, Function(String)? onError}) async {
final result = await bookAppointmentsRepo.cancelAppointment(patientAppointmentHistoryResponseModel: patientAppointmentHistoryResponseModel); final result = await bookAppointmentsRepo.cancelAppointment(patientAppointmentHistoryResponseModel: patientAppointmentHistoryResponseModel);
@ -419,22 +533,21 @@ class BookAppointmentsViewModel extends ChangeNotifier {
final result = await bookAppointmentsRepo.getProjectList(); final result = await bookAppointmentsRepo.getProjectList();
result.fold( result.fold(
(failure) async => (failure) async => await errorHandlerService.handleError(failure: failure),
await errorHandlerService.handleError(failure: failure), (apiResponse) async {
(apiResponse) async {
if (apiResponse.messageStatus == 2) { if (apiResponse.messageStatus == 2) {
// dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {}); // dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {});
} else if (apiResponse.messageStatus == 1) { } else if (apiResponse.messageStatus == 1) {
var projectList = apiResponse.data!; var projectList = apiResponse.data!;
hospitalList = await DoctorMapper.getMappedHospitals(projectList, hospitalList = await DoctorMapper.getMappedHospitals(
projectList,
isArabic: _appState.isArabic(), isArabic: _appState.isArabic(),
lat: _appState.userLat, lat: _appState.userLat,
lng: _appState.userLong, lng: _appState.userLong,
); );
var isLocationEnabled = (_appState.userLat != 0) && (_appState.userLong != 0); var isLocationEnabled = (_appState.userLat != 0) && (_appState.userLong != 0);
hospitalList = hospitalList = await DoctorMapper.sortList(isLocationEnabled, hospitalList!);
await DoctorMapper.sortList(isLocationEnabled, hospitalList!);
isRegionListLoading = false; isRegionListLoading = false;
filteredHospitalList = hospitalList; filteredHospitalList = hospitalList;
@ -450,22 +563,21 @@ class BookAppointmentsViewModel extends ChangeNotifier {
} }
void filterHospitalListByString(String? value, String? selectedRegionId, bool isHMG) { void filterHospitalListByString(String? value, String? selectedRegionId, bool isHMG) {
if(value ==null || value.isEmpty){ if (value == null || value.isEmpty) {
filteredHospitalList = hospitalList; filteredHospitalList = hospitalList;
} else { } else {
filteredHospitalList = RegionList(); filteredHospitalList = RegionList();
var list = isHMG var list = isHMG ? hospitalList?.registeredDoctorMap![selectedRegionId]!.hmgDoctorList : hospitalList?.registeredDoctorMap![selectedRegionId]!.hmcDoctorList;
? hospitalList?.registeredDoctorMap![selectedRegionId]!.hmgDoctorList
: hospitalList?.registeredDoctorMap![selectedRegionId]!.hmcDoctorList;
if(list != null && list.isEmpty){ notifyListeners(); return;} if (list != null && list.isEmpty) {
notifyListeners();
return;
}
var filteredList = list!.where((element) => var filteredList = list!.where((element) => element.filterName!.toLowerCase().contains(value.toLowerCase())).toList();
element.filterName!.toLowerCase().contains(value.toLowerCase())
).toList();
var regionData = PatientDoctorAppointmentListByRegion(); var regionData = PatientDoctorAppointmentListByRegion();
if(isHMG){ if (isHMG) {
regionData.hmgDoctorList = filteredList; regionData.hmgDoctorList = filteredList;
regionData.hmgSize = filteredList.length; regionData.hmgSize = filteredList.length;
} else { } else {
@ -473,9 +585,7 @@ class BookAppointmentsViewModel extends ChangeNotifier {
regionData.hmcSize = filteredList.length; regionData.hmcSize = filteredList.length;
} }
filteredHospitalList?.registeredDoctorMap = { filteredHospitalList?.registeredDoctorMap = {selectedRegionId!: regionData};
selectedRegionId! : regionData
};
} }
notifyListeners(); notifyListeners();
} }
@ -498,12 +608,12 @@ class BookAppointmentsViewModel extends ChangeNotifier {
currentlySelectedHospitalFromRegionFlow = mainProjectID; currentlySelectedHospitalFromRegionFlow = mainProjectID;
} }
Future<void> getRegionSelectedClinics() async{ Future<void> getRegionSelectedClinics() async {
final result = await bookAppointmentsRepo.getClinicsWithRespectToClinicId(currentlySelectedHospitalFromRegionFlow??""); final result = await bookAppointmentsRepo.getClinicsWithRespectToClinicId(currentlySelectedHospitalFromRegionFlow ?? "");
result.fold( result.fold(
(failure) async => await errorHandlerService.handleError(failure: failure), (failure) async => await errorHandlerService.handleError(failure: failure),
(apiResponse) { (apiResponse) {
if (apiResponse.messageStatus == 2) { if (apiResponse.messageStatus == 2) {
// dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {}); // dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {});
} else if (apiResponse.messageStatus == 1) { } else if (apiResponse.messageStatus == 1) {
@ -515,12 +625,12 @@ class BookAppointmentsViewModel extends ChangeNotifier {
}, },
); );
} }
void resetFilterList(){
void resetFilterList() {
filteredHospitalList = hospitalList; filteredHospitalList = hospitalList;
} }
void getLocation() {
void getLocation(){
locationUtils.getLocation(); locationUtils.getLocation();
} }
} }

@ -12,8 +12,8 @@ class GetClinicsListResponseModel {
GetClinicsListResponseModel.fromJson(Map<String, dynamic> json) { GetClinicsListResponseModel.fromJson(Map<String, dynamic> json) {
clinicID = json['ClinicID']; clinicID = json['ClinicID'];
clinicDescription = json['ClinicDescription']; clinicDescription = json['ClinicDescription'] ?? "LiveCare Clinic";
clinicDescriptionN = json['ClinicDescriptionN']; clinicDescriptionN = json['ClinicDescriptionN'] ?? "LiveCare Clinic";
age = json['Age']; age = json['Age'];
gender = json['Gender']; gender = json['Gender'];
isLiveCareClinicAndOnline = json['IsLiveCareClinicAndOnline']; isLiveCareClinicAndOnline = json['IsLiveCareClinicAndOnline'];

@ -0,0 +1,33 @@
class GetLiveCareClinicsResponseModel {
int? clinicID;
int? serviceID;
int? projectID;
String? clinicDesc;
String? clinicDescN;
String? projectDesc;
String? projectDescN;
GetLiveCareClinicsResponseModel({this.clinicID, this.serviceID, this.projectID, this.clinicDesc, this.clinicDescN, this.projectDesc, this.projectDescN});
GetLiveCareClinicsResponseModel.fromJson(Map<String, dynamic> json) {
clinicID = json['ClinicID'];
serviceID = json['ServiceID'];
projectID = json['ProjectID'];
clinicDesc = json['ClinicDesc'] ?? "LiveCare Clinic";
clinicDescN = json['ClinicDescN'];
projectDesc = json['ProjectDesc'];
projectDescN = json['ProjectDescN'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['ClinicID'] = this.clinicID;
data['ServiceID'] = this.serviceID;
data['ProjectID'] = this.projectID;
data['ClinicDesc'] = this.clinicDesc;
data['ClinicDescN'] = this.clinicDescN;
data['ProjectDesc'] = this.projectDesc;
data['ProjectDescN'] = this.projectDescN;
return data;
}
}

@ -42,6 +42,7 @@ class _BookAppointmentPageState extends State<BookAppointmentPage> {
@override @override
void initState() { void initState() {
scheduleMicrotask(() { scheduleMicrotask(() {
bookAppointmentsViewModel.selectedTabIndex = 0;
bookAppointmentsViewModel.initBookAppointmentViewModel(); bookAppointmentsViewModel.initBookAppointmentViewModel();
bookAppointmentsViewModel.getLocation(); bookAppointmentsViewModel.getLocation();
}); });
@ -123,6 +124,7 @@ class _BookAppointmentPageState extends State<BookAppointmentPage> {
).onPress(() { ).onPress(() {
bookAppointmentsViewModel.setIsClinicsListLoading(true); bookAppointmentsViewModel.setIsClinicsListLoading(true);
bookAppointmentsViewModel.setLoadSpecificClinic(false); bookAppointmentsViewModel.setLoadSpecificClinic(false);
bookAppointmentsViewModel.setIsLiveCareSchedule(false);
bookAppointmentsViewModel.setProjectID(null); bookAppointmentsViewModel.setProjectID(null);
Navigator.of(context).push( Navigator.of(context).push(
CustomPageRoute( CustomPageRoute(
@ -191,6 +193,112 @@ class _BookAppointmentPageState extends State<BookAppointmentPage> {
), ),
], ],
).paddingSymmetrical(24.h, 0.h); ).paddingSymmetrical(24.h, 0.h);
case 1:
//TODO: Get LiveCare type Select UI from Hussain
return 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() ? true : false, child: Utils.buildSvgWithAssets(icon: AppAssets.forward_arrow_icon, iconColor: AppColors.textColor, width: 15.h, height: 15.h)),
],
).onPress(() {
// bookAppointmentsViewModel.setIsClinicsListLoading(true);
// bookAppointmentsViewModel.setLoadSpecificClinic(false);
// bookAppointmentsViewModel.setProjectID(null);
// 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_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() ? true : false, child: Utils.buildSvgWithAssets(icon: AppAssets.forward_arrow_icon, iconColor: AppColors.textColor, width: 15.h, height: 15.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() ? true : false, child: Utils.buildSvgWithAssets(icon: AppAssets.forward_arrow_icon, iconColor: AppColors.textColor, width: 15.h, height: 15.h)),
],
).onPress(() {
openRegionListBottomSheet(context);
}),
],
),
),
),
],
).paddingSymmetrical(24.h, 0.h);
default: default:
SizedBox.shrink(); SizedBox.shrink();
} }
@ -200,11 +308,7 @@ class _BookAppointmentPageState extends State<BookAppointmentPage> {
void openRegionListBottomSheet(BuildContext context) { void openRegionListBottomSheet(BuildContext context) {
regionalViewModel.flush(); regionalViewModel.flush();
// AppointmentViaRegionViewmodel? viewmodel = null; // AppointmentViaRegionViewmodel? viewmodel = null;
showCommonBottomSheetWithoutHeight(context, showCommonBottomSheetWithoutHeight(context, title: "", titleWidget: Consumer<AppointmentViaRegionViewmodel>(builder: (_, data, __) => getTitle(data)), isDismissible: false,
title: "",
titleWidget: Consumer<AppointmentViaRegionViewmodel>(
builder: (_, data, __) => getTitle(data)),
isDismissible: false,
child: Consumer<AppointmentViaRegionViewmodel>(builder: (_, data, __) { child: Consumer<AppointmentViaRegionViewmodel>(builder: (_, data, __) {
return getRegionalSelectionWidget(data); return getRegionalSelectionWidget(data);
}), callBackFunc: () {}); }), callBackFunc: () {});
@ -238,19 +342,16 @@ class _BookAppointmentPageState extends State<BookAppointmentPage> {
if (data.selectedRegionId == null) { if (data.selectedRegionId == null) {
return LocaleKeys.selectRegion.tr().toText20(weight: FontWeight.w600); return LocaleKeys.selectRegion.tr().toText20(weight: FontWeight.w600);
} else { } else {
return return Transform.flip(
Transform.flip( flipX: data.isArabic ? true : false,
flipX: data.isArabic ? true : false, child: Utils.buildSvgWithAssets(
child: Utils.buildSvgWithAssets( icon: AppAssets.arrow_back,
icon: AppAssets.arrow_back, iconColor: Color(0xff2B353E),
iconColor: Color(0xff2B353E), fit: BoxFit.contain,
),
fit: BoxFit.contain, ).onPress(() {
), data.handleBackPress();
).onPress(() { });
data.handleBackPress();
});
} }
} }
} }

@ -12,6 +12,7 @@ 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/extensions/widget_extensions.dart';
import 'package:hmg_patient_app_new/features/book_appointments/book_appointments_view_model.dart'; import 'package:hmg_patient_app_new/features/book_appointments/book_appointments_view_model.dart';
import 'package:hmg_patient_app_new/features/book_appointments/models/resp_models/get_clinic_list_response_model.dart'; import 'package:hmg_patient_app_new/features/book_appointments/models/resp_models/get_clinic_list_response_model.dart';
import 'package:hmg_patient_app_new/features/book_appointments/models/resp_models/get_livecare_clinics_response_model.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/presentation/book_appointment/select_doctor_page.dart'; import 'package:hmg_patient_app_new/presentation/book_appointment/select_doctor_page.dart';
import 'package:hmg_patient_app_new/presentation/book_appointment/select_livecare_clinic_page.dart'; import 'package:hmg_patient_app_new/presentation/book_appointment/select_livecare_clinic_page.dart';
@ -58,7 +59,7 @@ class _SelectClinicPageState extends State<SelectClinicPage> {
return Scaffold( return Scaffold(
backgroundColor: AppColors.bgScaffoldColor, backgroundColor: AppColors.bgScaffoldColor,
body: CollapsingListView( body: CollapsingListView(
title: LocaleKeys.selectClinic.tr(context: context), title: bookAppointmentsViewModel.isLiveCareSchedule ? "Select LiveCare Clinic".needTranslation : LocaleKeys.selectClinic.tr(context: context),
child: SingleChildScrollView( child: SingleChildScrollView(
child: Padding( child: Padding(
padding: EdgeInsets.symmetric(horizontal: 24.h), padding: EdgeInsets.symmetric(horizontal: 24.h),
@ -94,40 +95,83 @@ class _SelectClinicPageState extends State<SelectClinicPage> {
horizontal: ResponsiveExtension(15).h, horizontal: ResponsiveExtension(15).h,
), ),
), ),
ListView.separated( bookAppointmentsVM.isLiveCareSchedule
padding: EdgeInsets.only(top: 24.h), ? ListView.separated(
shrinkWrap: true, padding: EdgeInsets.only(top: 24.h),
physics: NeverScrollableScrollPhysics(), shrinkWrap: true,
itemCount: bookAppointmentsVM.isClinicsListLoading ? 5 : bookAppointmentsVM.filteredClinicsList.length, physics: NeverScrollableScrollPhysics(),
itemBuilder: (context, index) { itemCount: bookAppointmentsVM.isClinicsListLoading ? 5 : bookAppointmentsVM.liveCareClinicsList.length,
return bookAppointmentsVM.isClinicsListLoading itemBuilder: (context, index) {
? ClinicCard( return bookAppointmentsVM.isClinicsListLoading
clinicsListResponseModel: GetClinicsListResponseModel(), ? ClinicCard(
isLoading: bookAppointmentsVM.isClinicsListLoading, bookAppointmentsVM: bookAppointmentsVM,
) liveCareClinicsResponseModel: GetLiveCareClinicsResponseModel(),
: AnimationConfiguration.staggeredList( clinicsListResponseModel: GetClinicsListResponseModel(),
position: index, isLoading: bookAppointmentsVM.isClinicsListLoading,
duration: const Duration(milliseconds: 500), )
child: SlideAnimation( : AnimationConfiguration.staggeredList(
verticalOffset: 100.0, position: index,
child: FadeInAnimation( duration: const Duration(milliseconds: 500),
child: AnimatedContainer( child: SlideAnimation(
duration: Duration(milliseconds: 300), verticalOffset: 100.0,
curve: Curves.easeInOut, child: FadeInAnimation(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.h, hasShadow: true), child: AnimatedContainer(
child: ClinicCard( duration: Duration(milliseconds: 300),
clinicsListResponseModel: bookAppointmentsVM.filteredClinicsList[index], curve: Curves.easeInOut,
isLoading: bookAppointmentsVM.isClinicsListLoading, decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.h, hasShadow: true),
).onPress(() { child: ClinicCard(
onClinicSelected(bookAppointmentsVM.filteredClinicsList[index]); bookAppointmentsVM: bookAppointmentsVM,
}), liveCareClinicsResponseModel: bookAppointmentsVM.liveCareClinicsList[index],
), clinicsListResponseModel: GetClinicsListResponseModel(),
), isLoading: bookAppointmentsVM.isClinicsListLoading,
), ).onPress(() {
); onLiveCareClinicSelected(bookAppointmentsVM.liveCareClinicsList[index]);
}, }),
separatorBuilder: (BuildContext cxt, int index) => SizedBox(height: 16.h), ),
), ),
),
);
},
separatorBuilder: (BuildContext cxt, int index) => SizedBox(height: 16.h),
)
: ListView.separated(
padding: EdgeInsets.only(top: 24.h),
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemCount: bookAppointmentsVM.isClinicsListLoading ? 5 : bookAppointmentsVM.filteredClinicsList.length,
itemBuilder: (context, index) {
return bookAppointmentsVM.isClinicsListLoading
? ClinicCard(
bookAppointmentsVM: bookAppointmentsVM,
liveCareClinicsResponseModel: GetLiveCareClinicsResponseModel(),
clinicsListResponseModel: GetClinicsListResponseModel(),
isLoading: bookAppointmentsVM.isClinicsListLoading,
)
: AnimationConfiguration.staggeredList(
position: index,
duration: const Duration(milliseconds: 500),
child: SlideAnimation(
verticalOffset: 100.0,
child: FadeInAnimation(
child: AnimatedContainer(
duration: Duration(milliseconds: 300),
curve: Curves.easeInOut,
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.h, hasShadow: true),
child: ClinicCard(
bookAppointmentsVM: bookAppointmentsVM,
liveCareClinicsResponseModel: GetLiveCareClinicsResponseModel(),
clinicsListResponseModel: bookAppointmentsVM.filteredClinicsList[index],
isLoading: bookAppointmentsVM.isClinicsListLoading,
).onPress(() {
onClinicSelected(bookAppointmentsVM.filteredClinicsList[index]);
}),
),
),
),
);
},
separatorBuilder: (BuildContext cxt, int index) => SizedBox(height: 16.h),
),
], ],
); );
}), }),
@ -137,6 +181,16 @@ class _SelectClinicPageState extends State<SelectClinicPage> {
); );
} }
void onLiveCareClinicSelected(GetLiveCareClinicsResponseModel clinic) {
bookAppointmentsViewModel.setLiveCareSelectedClinic(clinic);
bookAppointmentsViewModel.setIsDoctorsListLoading(true);
Navigator.of(context).push(
CustomPageRoute(
page: SelectDoctorPage(),
),
);
}
void onClinicSelected(GetClinicsListResponseModel clinic) { void onClinicSelected(GetClinicsListResponseModel clinic) {
bookAppointmentsViewModel.setSelectedClinic(clinic); bookAppointmentsViewModel.setSelectedClinic(clinic);
bookAppointmentsViewModel.setIsDoctorsListLoading(true); bookAppointmentsViewModel.setIsDoctorsListLoading(true);

@ -42,7 +42,11 @@ class _SelectDoctorPageState extends State<SelectDoctorPage> {
@override @override
void initState() { void initState() {
scheduleMicrotask(() { scheduleMicrotask(() {
bookAppointmentsViewModel.getDoctorsList(); if (bookAppointmentsViewModel.isLiveCareSchedule) {
bookAppointmentsViewModel.getLiveCareDoctorsList();
} else {
bookAppointmentsViewModel.getDoctorsList();
}
}); });
super.initState(); super.initState();
} }
@ -96,7 +100,8 @@ class _SelectDoctorPageState extends State<SelectDoctorPage> {
padding: EdgeInsets.only(top: 24.h), padding: EdgeInsets.only(top: 24.h),
shrinkWrap: true, shrinkWrap: true,
physics: NeverScrollableScrollPhysics(), physics: NeverScrollableScrollPhysics(),
itemCount: bookAppointmentsVM.isDoctorsListLoading ? 5 : bookAppointmentsVM.doctorsList.length, itemCount:
bookAppointmentsVM.isDoctorsListLoading ? 5 : (bookAppointmentsVM.isLiveCareSchedule ? bookAppointmentsVM.liveCareDoctorsList.length : bookAppointmentsVM.doctorsList.length),
itemBuilder: (context, index) { itemBuilder: (context, index) {
return bookAppointmentsVM.isDoctorsListLoading return bookAppointmentsVM.isDoctorsListLoading
? DoctorCard( ? DoctorCard(
@ -115,11 +120,12 @@ class _SelectDoctorPageState extends State<SelectDoctorPage> {
curve: Curves.easeInOut, curve: Curves.easeInOut,
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.h, hasShadow: true), decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.h, hasShadow: true),
child: DoctorCard( child: DoctorCard(
doctorsListResponseModel: bookAppointmentsVM.doctorsList[index], doctorsListResponseModel: bookAppointmentsVM.isLiveCareSchedule ? bookAppointmentsVM.liveCareDoctorsList[index] : bookAppointmentsVM.doctorsList[index],
isLoading: false, isLoading: false,
bookAppointmentsViewModel: bookAppointmentsViewModel, bookAppointmentsViewModel: bookAppointmentsViewModel,
).onPress(() async { ).onPress(() async {
bookAppointmentsVM.setSelectedDoctor(bookAppointmentsVM.doctorsList[index]); bookAppointmentsVM
.setSelectedDoctor(bookAppointmentsVM.isLiveCareSchedule ? bookAppointmentsVM.liveCareDoctorsList[index] : bookAppointmentsVM.doctorsList[index]);
// bookAppointmentsVM.setSelectedDoctor(DoctorsListResponseModel()); // bookAppointmentsVM.setSelectedDoctor(DoctorsListResponseModel());
LoaderBottomSheet.showLoader(); LoaderBottomSheet.showLoader();
await bookAppointmentsVM.getDoctorProfile(onSuccess: (dynamic respData) { await bookAppointmentsVM.getDoctorProfile(onSuccess: (dynamic respData) {

@ -6,14 +6,18 @@ 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/core/utils/utils.dart';
import 'package:hmg_patient_app_new/extensions/string_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/extensions/widget_extensions.dart';
import 'package:hmg_patient_app_new/features/book_appointments/book_appointments_view_model.dart';
import 'package:hmg_patient_app_new/features/book_appointments/models/resp_models/get_clinic_list_response_model.dart'; import 'package:hmg_patient_app_new/features/book_appointments/models/resp_models/get_clinic_list_response_model.dart';
import 'package:hmg_patient_app_new/features/book_appointments/models/resp_models/get_livecare_clinics_response_model.dart';
import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/theme/colors.dart';
class ClinicCard extends StatelessWidget { class ClinicCard extends StatelessWidget {
ClinicCard({super.key, required this.clinicsListResponseModel, required this.isLoading}); ClinicCard({super.key, required this.clinicsListResponseModel, required this.liveCareClinicsResponseModel, required this.isLoading, required this.bookAppointmentsVM});
GetClinicsListResponseModel clinicsListResponseModel; GetClinicsListResponseModel clinicsListResponseModel;
GetLiveCareClinicsResponseModel liveCareClinicsResponseModel;
bool isLoading; bool isLoading;
BookAppointmentsViewModel bookAppointmentsVM;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -35,7 +39,10 @@ class ClinicCard extends StatelessWidget {
]), ]),
SizedBox(height: 16.h), SizedBox(height: 16.h),
Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
Expanded(child: (isLoading ? "Cardiology" : clinicsListResponseModel.clinicDescription!).toText16(isBold: true).toShimmer2(isShow: isLoading)), Expanded(
child: (isLoading ? "Cardiology" : (bookAppointmentsVM.isLiveCareSchedule ? liveCareClinicsResponseModel.clinicDesc! : clinicsListResponseModel.clinicDescription!))
.toText16(isBold: true)
.toShimmer2(isShow: isLoading)),
Transform.flip( Transform.flip(
flipX: appState.isArabic() ? true : false, flipX: appState.isArabic() ? true : false,
child: Utils.buildSvgWithAssets(icon: AppAssets.forward_arrow_icon, width: 15.h, height: 15.h, fit: BoxFit.contain, iconColor: AppColors.textColor).toShimmer2(isShow: isLoading)), child: Utils.buildSvgWithAssets(icon: AppAssets.forward_arrow_icon, width: 15.h, height: 15.h, fit: BoxFit.contain, iconColor: AppColors.textColor).toShimmer2(isShow: isLoading)),

@ -108,29 +108,53 @@ class DoctorCard extends StatelessWidget {
onPressed: () async { onPressed: () async {
bookAppointmentsViewModel.setSelectedDoctor(doctorsListResponseModel); bookAppointmentsViewModel.setSelectedDoctor(doctorsListResponseModel);
LoaderBottomSheet.showLoader(); LoaderBottomSheet.showLoader();
await bookAppointmentsViewModel.getDoctorFreeSlots( bookAppointmentsViewModel.isLiveCareSchedule
isBookingForLiveCare: false, ? await bookAppointmentsViewModel.getLiveCareDoctorFreeSlots(
onSuccess: (dynamic respData) async { isBookingForLiveCare: true,
LoaderBottomSheet.hideLoader(); onSuccess: (dynamic respData) async {
showCommonBottomSheetWithoutHeight( LoaderBottomSheet.hideLoader();
title: "Pick a Date".needTranslation, showCommonBottomSheetWithoutHeight(
context, title: "Pick a Date".needTranslation,
child: AppointmentCalendar(), context,
isFullScreen: false, child: AppointmentCalendar(),
isCloseButtonVisible: true, isFullScreen: false,
callBackFunc: () {}, isCloseButtonVisible: true,
); callBackFunc: () {},
}, );
onError: (err) { },
LoaderBottomSheet.hideLoader(); onError: (err) {
showCommonBottomSheetWithoutHeight( LoaderBottomSheet.hideLoader();
context, showCommonBottomSheetWithoutHeight(
child: Utils.getErrorWidget(loadingText: err), context,
callBackFunc: () {}, child: Utils.getErrorWidget(loadingText: err),
isFullScreen: false, callBackFunc: () {},
isCloseButtonVisible: true, isFullScreen: false,
); isCloseButtonVisible: true,
}); );
})
: await bookAppointmentsViewModel.getDoctorFreeSlots(
isBookingForLiveCare: false,
onSuccess: (dynamic respData) async {
LoaderBottomSheet.hideLoader();
showCommonBottomSheetWithoutHeight(
title: "Pick a Date".needTranslation,
context,
child: AppointmentCalendar(),
isFullScreen: false,
isCloseButtonVisible: true,
callBackFunc: () {},
);
},
onError: (err) {
LoaderBottomSheet.hideLoader();
showCommonBottomSheetWithoutHeight(
context,
child: Utils.getErrorWidget(loadingText: err),
callBackFunc: () {},
isFullScreen: false,
isCloseButtonVisible: true,
);
});
}, },
backgroundColor: Color(0xffFEE9EA), backgroundColor: Color(0xffFEE9EA),
borderColor: Color(0xffFEE9EA), borderColor: Color(0xffFEE9EA),

@ -34,6 +34,7 @@ class _LandingNavigationState extends State<LandingNavigation> {
], ],
), ),
bottomNavigationBar: BottomNavigation( bottomNavigationBar: BottomNavigation(
context: context,
currentIndex: _currentIndex, currentIndex: _currentIndex,
onTap: (index) { onTap: (index) {
setState(() => _currentIndex = index); setState(() => _currentIndex = index);

@ -12,27 +12,26 @@ import 'package:hmg_patient_app_new/theme/colors.dart';
class BottomNavigation extends StatelessWidget { class BottomNavigation extends StatelessWidget {
final int currentIndex; final int currentIndex;
final ValueChanged<int> onTap; final ValueChanged<int> onTap;
BuildContext? context;
const BottomNavigation({ BottomNavigation({super.key, required this.currentIndex, required this.onTap, this.context});
super.key,
required this.currentIndex,
required this.onTap,
});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
AppState appState = getIt.get<AppState>(); AppState appState = getIt.get<AppState>();
final items = [ final items = [
BottomNavItem(icon: AppAssets.homeBottom, label: LocaleKeys.home.tr()), BottomNavItem(icon: AppAssets.homeBottom, label: LocaleKeys.home.tr(context: context)),
appState.isAuthenticated ? BottomNavItem(icon: AppAssets.myFilesBottom, label: LocaleKeys.myFiles.tr()) : BottomNavItem(icon: AppAssets.feedback, label: LocaleKeys.feedback.tr()), appState.isAuthenticated
? BottomNavItem(icon: AppAssets.myFilesBottom, label: LocaleKeys.myFiles.tr(context: context))
: BottomNavItem(icon: AppAssets.feedback, label: LocaleKeys.feedback.tr()),
BottomNavItem( BottomNavItem(
icon: AppAssets.bookAppoBottom, icon: AppAssets.bookAppoBottom,
label: LocaleKeys.appointment.tr(), label: LocaleKeys.appointment.tr(context: context),
iconSize: 27, iconSize: 27,
isSpecial: true, isSpecial: true,
), ),
appState.isAuthenticated ? BottomNavItem(icon: AppAssets.toDoBottom, label: LocaleKeys.todoList.tr()) : BottomNavItem(icon: AppAssets.news, label: LocaleKeys.news.tr()) , appState.isAuthenticated ? BottomNavItem(icon: AppAssets.toDoBottom, label: LocaleKeys.todoList.tr(context: context)) : BottomNavItem(icon: AppAssets.news, label: LocaleKeys.news.tr()),
BottomNavItem(icon: AppAssets.servicesBottom, label: LocaleKeys.services2.tr()), BottomNavItem(icon: AppAssets.servicesBottom, label: LocaleKeys.services2.tr(context: context)),
]; ];
return Container( return Container(
@ -42,7 +41,7 @@ class BottomNavigation extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.spaceAround, mainAxisAlignment: MainAxisAlignment.spaceAround,
children: List.generate( children: List.generate(
items.length, items.length,
(index) => _buildNavItem(items[index], index), (index) => _buildNavItem(items[index], index),
), ),
), ),
); );
@ -57,23 +56,22 @@ class BottomNavigation extends StatelessWidget {
child: Column( child: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
Center( Center(
child: Utils.buildSvgWithAssets( child: Utils.buildSvgWithAssets(
icon: item.icon, icon: item.icon,
height: item.iconSize.h, height: item.iconSize.h,
width: item.iconSize.h, width: item.iconSize.h,
// iconColor: isSelected ? Colors.black87 : Colors.black87, // iconColor: isSelected ? Colors.black87 : Colors.black87,
),
), ),
),
const SizedBox(height: 10), const SizedBox(height: 10),
item.label.toText12( item.label.toText12(
fontWeight:FontWeight.w500, fontWeight: FontWeight.w500,
// color: Colors.black87, // color: Colors.black87,
// textAlign: TextAlign.center, // textAlign: TextAlign.center,
), ),
SizedBox(height: item.isSpecial ? 5:0 ) SizedBox(height: item.isSpecial ? 5 : 0)
], ],
), ),
); );
} }

@ -66,7 +66,7 @@ class CustomButton extends StatelessWidget {
child: Utils.buildSvgWithAssets(icon: icon!, iconColor: iconColor, isDisabled: isDisabled, width: iconSize, height: iconSize), child: Utils.buildSvgWithAssets(icon: icon!, iconColor: iconColor, isDisabled: isDisabled, width: iconSize, height: iconSize),
), ),
Padding( Padding(
padding: EdgeInsets.only(top: 2.5), padding: EdgeInsets.only(top: 0),
child: Text( child: Text(
text, text,
style: context.dynamicTextStyle( style: context.dynamicTextStyle(

Loading…
Cancel
Save