dental booking flow implemented

pull/75/head
haroon amjad 4 weeks ago
parent c0606fb530
commit 30eb8bf5de

@ -173,8 +173,8 @@ class ApiClientImp implements ApiClient {
body[_appState.isAuthenticated ? 'TokenID' : 'LogInTokenID'] = _appState.appAuthToken;
}
body['TokenID'] = "@dm!n";
body['PatientID'] = 4767884;
// body['TokenID'] = "@dm!n";
// body['PatientID'] = 4767884;
// body['PatientTypeID'] = 1;
//
// body['PatientOutSA'] = 0;

@ -727,7 +727,7 @@ const FAMILY_FILES= 'Services/Authentication.svc/REST/GetAllSharedRecordsByStatu
class ApiConsts {
static const maxSmallScreen = 660;
static AppEnvironmentTypeEnum appEnvironmentType = AppEnvironmentTypeEnum.uat;
static AppEnvironmentTypeEnum appEnvironmentType = AppEnvironmentTypeEnum.prod;
// static String baseUrl = 'https://uat.hmgwebservices.com/'; // HIS API URL UAT

@ -6,6 +6,7 @@ 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/core/utils/date_util.dart';
import 'package:hmg_patient_app_new/features/book_appointments/models/resp_models/dental_chief_complaints_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/get_clinic_list_response_model.dart';
@ -72,6 +73,12 @@ abstract class BookAppointmentsRepo {
Future<Either<Failure, GenericApiModel<List<PatientDentalPlanEstimationResponseModel>>>> getPatientDentalEstimation(
{required int projectID, Function(dynamic)? onSuccess, Function(String)? onError});
Future<Either<Failure, GenericApiModel<List<DentalChiefComplaintsListResponseModel>>>> getDentalChiefComplaintsList(
{required int projectID, required int clinicID, required int patientID, Function(dynamic)? onSuccess, Function(String)? onError});
Future<Either<Failure, GenericApiModel<List<DoctorsListResponseModel>>>> getDentalChiefComplaintDoctorsList(int projectID, int chiefComplaintID,
{Function(dynamic)? onSuccess, Function(String)? onError});
}
class BookAppointmentsRepoImp implements BookAppointmentsRepo {
@ -701,4 +708,96 @@ class BookAppointmentsRepoImp implements BookAppointmentsRepo {
return Left(UnknownFailure(e.toString()));
}
}
@override
Future<Either<Failure, GenericApiModel<List<DentalChiefComplaintsListResponseModel>>>> getDentalChiefComplaintsList(
{required int projectID, required int clinicID, required int patientID, Function(dynamic)? onSuccess, Function(String)? onError}) async {
Map<String, dynamic> mapDevice = {
"PatientID": patientID,
"ClinicID": clinicID,
"ProjectID": projectID,
"isDentalAllowedBackend": true,
"ContinueDentalPlan": false,
"IsSearchAppointmnetByClinicID": false,
};
try {
GenericApiModel<List<DentalChiefComplaintsListResponseModel>>? apiResponse;
Failure? failure;
await apiClient.post(
GET_DOCTORS_LIST_URL,
body: mapDevice,
onFailure: (error, statusCode, {messageStatus, failureType}) {
failure = failureType;
onError!(error);
},
onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
try {
final list = response['List_DentalChiefComplain'];
final chiefComplaintsList = list.map((item) => DentalChiefComplaintsListResponseModel.fromJson(item as Map<String, dynamic>)).toList().cast<DentalChiefComplaintsListResponseModel>();
apiResponse = GenericApiModel<List<DentalChiefComplaintsListResponseModel>>(
messageStatus: messageStatus,
statusCode: statusCode,
errorMessage: null,
data: chiefComplaintsList,
);
} 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>>>> getDentalChiefComplaintDoctorsList(int projectID, int chiefComplaintID,
{Function(dynamic)? onSuccess, Function(String)? onError}) async {
Map<String, dynamic> mapDevice = {
"ProjectID": projectID,
"ChiefComplaintID": chiefComplaintID,
"isDentalAllowedBackend": true,
"IsPublicRequest": true,
};
try {
GenericApiModel<List<DoctorsListResponseModel>>? apiResponse;
Failure? failure;
await apiClient.post(
GET_DENTAL_DOCTORS_LIST_URL,
body: mapDevice,
onFailure: (error, statusCode, {messageStatus, failureType}) {
failure = failureType;
onError!(error);
},
onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
try {
final list = response['List_DentalDoctorChiefComplaintMapping'];
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()));
}
}
}

@ -12,6 +12,7 @@ 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/features/book_appointments/book_appointments_repo.dart';
import 'package:hmg_patient_app_new/features/book_appointments/models/free_slot.dart';
import 'package:hmg_patient_app_new/features/book_appointments/models/resp_models/dental_chief_complaints_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/get_clinic_list_response_model.dart';
@ -57,8 +58,11 @@ class BookAppointmentsViewModel extends ChangeNotifier {
List<DoctorsListResponseModel> liveCareDoctorsList = [];
List<PatientDentalPlanEstimationResponseModel> patientDentalPlanEstimationList = [];
List<DentalChiefComplaintsListResponseModel> dentalChiefComplaintsList = [];
int totalTimeNeededForDentalProcedure = 0;
bool isContinueDentalPlan = false;
bool isChiefComplaintsListLoading = false;
int selectedChiefComplaintID = 0;
GetClinicsListResponseModel selectedClinic = GetClinicsListResponseModel();
DoctorsListResponseModel selectedDoctor = DoctorsListResponseModel();
@ -134,7 +138,9 @@ class BookAppointmentsViewModel extends ChangeNotifier {
doctorsList.clear();
liveCareClinicsList.clear();
patientDentalPlanEstimationList.clear();
dentalChiefComplaintsList.clear();
isContinueDentalPlan = false;
isChiefComplaintsListLoading = true;
// getLocation();
notifyListeners();
}
@ -201,6 +207,16 @@ class BookAppointmentsViewModel extends ChangeNotifier {
notifyListeners();
}
setIsChiefComplaintsListLoading(bool value) {
isChiefComplaintsListLoading = value;
notifyListeners();
}
setSelectedChiefComplaintID(int id) {
selectedChiefComplaintID = id;
notifyListeners();
}
void onTabChanged(int index) {
selectedTabIndex = index;
notifyListeners();
@ -949,4 +965,56 @@ class BookAppointmentsViewModel extends ChangeNotifier {
},
);
}
Future<void> getDentalChiefComplaintsList({Function(dynamic)? onSuccess, Function(String)? onError}) async {
dentalChiefComplaintsList.clear();
notifyListeners();
int patientID = _appState.isAuthenticated ? _appState.getAuthenticatedUser()!.patientId ?? -1 : -1;
final result = await bookAppointmentsRepo.getDentalChiefComplaintsList(patientID: patientID, projectID: int.parse(currentlySelectedHospitalFromRegionFlow ?? "0"), clinicID: 17);
result.fold(
(failure) async => await errorHandlerService.handleError(failure: failure),
(apiResponse) {
if (apiResponse.messageStatus == 2) {
onError!(apiResponse.errorMessage!);
// dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {});
} else if (apiResponse.messageStatus == 1) {
dentalChiefComplaintsList = apiResponse.data!;
isChiefComplaintsListLoading = false;
notifyListeners();
if (onSuccess != null) {
onSuccess(apiResponse);
}
}
},
);
}
Future<void> getDentalChiefComplaintDoctorsList({int projectID = 0, Function(dynamic)? onSuccess, Function(String)? onError}) async {
doctorsList.clear();
projectID = currentlySelectedHospitalFromRegionFlow != null ? int.parse(currentlySelectedHospitalFromRegionFlow!) : projectID;
final result = await bookAppointmentsRepo.getDentalChiefComplaintDoctorsList(projectID, selectedChiefComplaintID);
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) {
doctorsList = apiResponse.data!;
filteredDoctorList = doctorsList;
isDoctorsListLoading = false;
// initializeFilteredList();
// clearSearchFilters();
// getFiltersFromDoctorList();
notifyListeners();
if (onSuccess != null) {
onSuccess(apiResponse);
}
}
},
);
}
}

@ -0,0 +1,24 @@
class DentalChiefComplaintsListResponseModel {
int? projectID;
int? iD;
String? name;
dynamic nameN;
DentalChiefComplaintsListResponseModel({this.projectID, this.iD, this.name, this.nameN});
DentalChiefComplaintsListResponseModel.fromJson(Map<String, dynamic> json) {
projectID = json['ProjectID'];
iD = json['ID'];
name = json['Name'];
nameN = json['NameN'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['ProjectID'] = this.projectID;
data['ID'] = this.iD;
data['Name'] = this.name;
data['NameN'] = this.nameN;
return data;
}
}

@ -48,7 +48,7 @@ class FacilitySelectionItem extends StatelessWidget {
Transform.flip(
flipX: appState.isArabic() ? true : false,
child: Utils.buildSvgWithAssets(
icon: AppAssets.forward_arrow_icon,
icon: AppAssets.forward_arrow_icon_small,
iconColor: AppColors.blackColor,
width: 18,
height: 13,

@ -45,7 +45,7 @@ class RegionListItem extends StatelessWidget {
Transform.flip(
flipX: appState.isArabic() ? true : false,
child: Utils.buildSvgWithAssets(
icon: AppAssets.forward_arrow_icon,
icon: AppAssets.forward_arrow_icon_small,
iconColor: AppColors.blackColor,
width: 18,
height: 13,

@ -0,0 +1,95 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_staggered_animations/flutter_staggered_animations.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/extensions/string_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/dental_chief_complaints_response_model.dart';
import 'package:hmg_patient_app_new/presentation/book_appointment/select_doctor_page.dart';
import 'package:hmg_patient_app_new/presentation/book_appointment/widgets/chief_complaint_card.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/routes/custom_page_route.dart';
import 'package:provider/provider.dart';
class DentalChiefComplaintsPage extends StatefulWidget {
const DentalChiefComplaintsPage({super.key});
@override
State<DentalChiefComplaintsPage> createState() => _DentalChiefComplaintsPageState();
}
class _DentalChiefComplaintsPageState extends State<DentalChiefComplaintsPage> {
late AppState appState;
late BookAppointmentsViewModel bookAppointmentsViewModel;
@override
void initState() {
scheduleMicrotask(() {
bookAppointmentsViewModel.getDentalChiefComplaintsList();
});
super.initState();
}
@override
Widget build(BuildContext context) {
bookAppointmentsViewModel = Provider.of<BookAppointmentsViewModel>(context, listen: false);
appState = getIt.get<AppState>();
return CollapsingListView(
title: "Dental Chief Complaints".needTranslation,
child: SingleChildScrollView(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 24.h),
child: Consumer<BookAppointmentsViewModel>(builder: (context, bookAppointmentsVM, child) {
return ListView.separated(
padding: EdgeInsets.only(top: 24.h),
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemCount: bookAppointmentsVM.isChiefComplaintsListLoading ? 5 : bookAppointmentsVM.dentalChiefComplaintsList.length,
itemBuilder: (context, index) {
return bookAppointmentsVM.isChiefComplaintsListLoading
? ChiefComplaintCard(
bookAppointmentsVM: bookAppointmentsVM,
dentalChiefComplaintsListResponseModel: DentalChiefComplaintsListResponseModel(),
isLoading: bookAppointmentsVM.isChiefComplaintsListLoading,
)
: 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: ChiefComplaintCard(
bookAppointmentsVM: bookAppointmentsVM,
dentalChiefComplaintsListResponseModel: bookAppointmentsVM.dentalChiefComplaintsList[index],
isLoading: bookAppointmentsVM.isChiefComplaintsListLoading,
).onPress(() {
bookAppointmentsVM.setSelectedChiefComplaintID(bookAppointmentsVM.dentalChiefComplaintsList[index].iD!);
bookAppointmentsViewModel.setIsDoctorsListLoading(true);
Navigator.of(context).push(
CustomPageRoute(
page: SelectDoctorPage(),
),
);
}),
),
),
),
);
},
separatorBuilder: (BuildContext cxt, int index) => SizedBox(height: 16.h),
);
}),
),
),
);
}
}

@ -18,6 +18,7 @@ import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/presentation/appointments/widgets/faculity_selection/facility_type_selection_widget.dart';
import 'package:hmg_patient_app_new/presentation/appointments/widgets/hospital_bottom_sheet/hospital_bottom_sheet_body.dart';
import 'package:hmg_patient_app_new/presentation/appointments/widgets/region_bottomsheet/region_list_widget.dart';
import 'package:hmg_patient_app_new/presentation/book_appointment/dental_chief_complaints_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/widgets/clinic_card.dart';
@ -222,124 +223,13 @@ class _SelectClinicPageState extends State<SelectClinicPage> {
void handleDoctorScreen(GetClinicsListResponseModel clinic) async {
if (widget.isFromRegionFlow) {
//Dental Clinic Flow
if (clinic.clinicID == 17) {
LoaderBottomSheet.showLoader(loadingText: "Checking for an existing dental plan, Please wait...".needTranslation);
await bookAppointmentsViewModel.getPatientDentalEstimation(projectID: int.parse(bookAppointmentsViewModel.currentlySelectedHospitalFromRegionFlow ?? "0")).then((value) {
LoaderBottomSheet.hideLoader();
if (bookAppointmentsViewModel.patientDentalPlanEstimationList.isNotEmpty) {
showCommonBottomSheetWithoutHeight(
// title: LocaleKeys.notice.tr(context: context),
title: "Dental treatment plan".needTranslation,
context,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
"You have an existing treatment plan: ".needTranslation.toText14(weight: FontWeight.w500),
SizedBox(height: 8.h),
Container(
width: double.infinity,
padding: EdgeInsets.all(16.h),
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.whiteColor,
borderRadius: 20.h,
hasShadow: true,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ListView.separated(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemCount: bookAppointmentsViewModel.patientDentalPlanEstimationList.length,
separatorBuilder: (_, __) {
return Column(
children: [
SizedBox(height: 8.h),
Divider(height: 1, color: AppColors.greyColor),
SizedBox(height: 8.h),
],
);
},
itemBuilder: (context, index) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
bookAppointmentsViewModel.patientDentalPlanEstimationList[index].procedureName!.toText12(isBold: true),
AppCustomChipWidget(icon: AppAssets.appointment_time_icon, labelText: "${bookAppointmentsViewModel.totalTimeNeededForDentalProcedure} Mins".needTranslation),
],
);
},
),
SizedBox(
height: 16.h,
),
Divider(height: 1, color: AppColors.greyColor),
SizedBox(
height: 8.h,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
"Total time required".needTranslation.toText14(isBold: true),
AppCustomChipWidget(icon: AppAssets.appointment_time_icon, labelText: "30 Mins".needTranslation),
],
)
],
),
),
SizedBox(height: 16.h),
"Would you like to continue it?".needTranslation.toText14(weight: FontWeight.w500),
SizedBox(height: 16.h),
Row(
children: [
Expanded(
child: CustomButton(
text: LocaleKeys.cancel.tr(),
onPressed: () {
bookAppointmentsViewModel.setIsContinueDentalPlan(false);
Navigator.of(context).pop();
},
backgroundColor: AppColors.primaryRedColor,
borderColor: AppColors.primaryRedColor,
textColor: AppColors.whiteColor,
icon: AppAssets.cancel,
iconColor: AppColors.whiteColor,
),
),
SizedBox(width: 8.h),
Expanded(
child: CustomButton(
text: LocaleKeys.confirm.tr(),
onPressed: () async {
bookAppointmentsViewModel.setIsContinueDentalPlan(true);
Navigator.of(context).push(
CustomPageRoute(
page: SelectDoctorPage(),
),
);
},
backgroundColor: AppColors.bgGreenColor,
borderColor: AppColors.bgGreenColor,
textColor: Colors.white,
icon: AppAssets.confirm,
),
),
],
)
],
),
callBackFunc: () {},
isFullScreen: false,
isCloseButtonVisible: true,
);
} else {
// Navigate to Chief Complaint Screen
}
});
if (clinic.clinicID == 17 && appState.isAuthenticated) {
initDentalAppointmentBookingFlow(int.parse(bookAppointmentsViewModel.currentlySelectedHospitalFromRegionFlow ?? "0"));
} else {
bookAppointmentsViewModel.setIsChiefComplaintsListLoading(true);
Navigator.of(context).push(
CustomPageRoute(
page: SelectDoctorPage(),
page: DentalChiefComplaintsPage(),
),
);
}
@ -361,7 +251,18 @@ class _SelectClinicPageState extends State<SelectClinicPage> {
showCommonBottomSheetWithoutHeight(context, title: "", titleWidget: Consumer<AppointmentViaRegionViewmodel>(builder: (_, data, __) => getTitle(data)), isDismissible: false,
child: Consumer<AppointmentViaRegionViewmodel>(builder: (_, data, __) {
return getRegionalSelectionWidget(data);
}), callBackFunc: () {});
}), callBackFunc: () {
if (type == RegionBottomSheetType.REGION_FOR_DENTAL_AND_LASER && appState.isAuthenticated) {
initDentalAppointmentBookingFlow(regionalViewModel.selectedHospital?.hospitalList.first.iD);
} else {
bookAppointmentsViewModel.setIsChiefComplaintsListLoading(true);
Navigator.of(context).push(
CustomPageRoute(
page: DentalChiefComplaintsPage(),
),
);
}
});
}
Widget getRegionalSelectionWidget(AppointmentViaRegionViewmodel data) {
@ -378,12 +279,12 @@ class _SelectClinicPageState extends State<SelectClinicPage> {
return HospitalBottomSheetBody();
}
if (data.bottomSheetState == AppointmentViaRegionState.DOCTOR_SELECTION) {
//if the region screen is opened for the dental clinic thenthe project id will be in the hospital list as the list is formed form the get project api
//if the region screen is opened for the dental clinic then the project id will be in the hospital list as the list is formed form the get project api
var id = "";
if (data.regionBottomSheetType == RegionBottomSheetType.REGION_FOR_DENTAL_AND_LASER) {
id = regionalViewModel.selectedHospital?.hospitalList?.first?.iD?.toString() ?? "";
id = regionalViewModel.selectedHospital?.hospitalList.first.iD?.toString() ?? "";
} else {
id = regionalViewModel.selectedHospital?.patientDoctorAppointmentList?.first?.projectID?.toString() ?? "";
id = regionalViewModel.selectedHospital?.patientDoctorAppointmentList?.first.projectID?.toString() ?? "";
}
bookAppointmentsViewModel.setProjectID(id);
return SizedBox.shrink();
@ -410,4 +311,128 @@ class _SelectClinicPageState extends State<SelectClinicPage> {
});
}
}
void initDentalAppointmentBookingFlow(int projectID) async {
bookAppointmentsViewModel.setProjectID(projectID.toString());
LoaderBottomSheet.showLoader(loadingText: "Checking for an existing dental plan, Please wait...".needTranslation);
await bookAppointmentsViewModel.getPatientDentalEstimation(projectID: projectID).then((value) {
LoaderBottomSheet.hideLoader();
if (bookAppointmentsViewModel.patientDentalPlanEstimationList.isNotEmpty) {
showCommonBottomSheetWithoutHeight(
// title: LocaleKeys.notice.tr(context: context),
title: "Dental treatment plan".needTranslation,
context,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
"You have an existing treatment plan: ".needTranslation.toText14(weight: FontWeight.w500),
SizedBox(height: 8.h),
Container(
width: double.infinity,
padding: EdgeInsets.all(16.h),
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.whiteColor,
borderRadius: 20.h,
hasShadow: true,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ListView.separated(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemCount: bookAppointmentsViewModel.patientDentalPlanEstimationList.length,
separatorBuilder: (_, __) {
return Column(
children: [
SizedBox(height: 8.h),
Divider(height: 1, color: AppColors.greyColor),
SizedBox(height: 8.h),
],
);
},
itemBuilder: (context, index) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
bookAppointmentsViewModel.patientDentalPlanEstimationList[index].procedureName!.toText12(isBold: true),
AppCustomChipWidget(icon: AppAssets.appointment_time_icon, labelText: "${bookAppointmentsViewModel.totalTimeNeededForDentalProcedure} Mins".needTranslation),
],
);
},
),
SizedBox(
height: 16.h,
),
Divider(height: 1, color: AppColors.greyColor),
SizedBox(
height: 8.h,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
"Total time required".needTranslation.toText14(isBold: true),
AppCustomChipWidget(icon: AppAssets.appointment_time_icon, labelText: "30 Mins".needTranslation),
],
)
],
),
),
SizedBox(height: 16.h),
"Would you like to continue it?".needTranslation.toText14(weight: FontWeight.w500),
SizedBox(height: 16.h),
Row(
children: [
Expanded(
child: CustomButton(
text: LocaleKeys.cancel.tr(),
onPressed: () {
bookAppointmentsViewModel.setIsContinueDentalPlan(false);
bookAppointmentsViewModel.setIsChiefComplaintsListLoading(true);
Navigator.of(context).pop();
Navigator.of(context).push(
CustomPageRoute(
page: DentalChiefComplaintsPage(),
),
);
},
backgroundColor: AppColors.primaryRedColor,
borderColor: AppColors.primaryRedColor,
textColor: AppColors.whiteColor,
icon: AppAssets.cancel,
iconColor: AppColors.whiteColor,
),
),
SizedBox(width: 8.h),
Expanded(
child: CustomButton(
text: LocaleKeys.confirm.tr(),
onPressed: () async {
bookAppointmentsViewModel.setIsContinueDentalPlan(true);
Navigator.of(context).pop();
Navigator.of(context).push(
CustomPageRoute(
page: SelectDoctorPage(),
),
);
},
backgroundColor: AppColors.bgGreenColor,
borderColor: AppColors.bgGreenColor,
textColor: Colors.white,
icon: AppAssets.confirm,
),
),
],
)
],
),
callBackFunc: () {},
isFullScreen: false,
isCloseButtonVisible: true,
);
} else {
// Navigate to Chief Complaint Screen
}
});
}
}

@ -21,7 +21,6 @@ import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart';
import 'package:hmg_patient_app_new/widgets/input_widget.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:hmg_patient_app_new/widgets/transitions/fade_page.dart';
import 'package:provider/provider.dart';
class SelectDoctorPage extends StatefulWidget {
@ -45,7 +44,11 @@ class _SelectDoctorPageState extends State<SelectDoctorPage> {
if (bookAppointmentsViewModel.isLiveCareSchedule) {
bookAppointmentsViewModel.getLiveCareDoctorsList();
} else {
bookAppointmentsViewModel.getDoctorsList();
if (bookAppointmentsViewModel.selectedClinic.clinicID == 17) {
bookAppointmentsViewModel.getDentalChiefComplaintDoctorsList();
} else {
bookAppointmentsViewModel.getDoctorsList();
}
}
});
super.initState();
@ -66,7 +69,6 @@ class _SelectDoctorPageState extends State<SelectDoctorPage> {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// TODO: Implement doctor filter functionality
SizedBox(height: 16.h),
Row(
spacing: 8.h,

@ -0,0 +1,38 @@
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/book_appointments/book_appointments_view_model.dart';
import 'package:hmg_patient_app_new/features/book_appointments/models/resp_models/dental_chief_complaints_response_model.dart';
import 'package:hmg_patient_app_new/theme/colors.dart';
class ChiefComplaintCard extends StatelessWidget {
ChiefComplaintCard({super.key, required this.isLoading, required this.bookAppointmentsVM, required this.dentalChiefComplaintsListResponseModel});
bool isLoading;
BookAppointmentsViewModel bookAppointmentsVM;
DentalChiefComplaintsListResponseModel dentalChiefComplaintsListResponseModel;
@override
Widget build(BuildContext context) {
AppState appState = getIt.get<AppState>();
return Container(
padding: EdgeInsets.all(16.h),
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.whiteColor,
borderRadius: 24.h,
hasShadow: false,
),
child: Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
Expanded(child: (isLoading ? "Cardiology" : dentalChiefComplaintsListResponseModel.name)!.toText16(isBold: true).toShimmer2(isShow: isLoading)),
Transform.flip(
flipX: appState.isArabic(),
child: Utils.buildSvgWithAssets(icon: AppAssets.forward_arrow_icon, width: 40.h, height: 40.h, fit: BoxFit.contain, iconColor: AppColors.textColor).toShimmer2(isShow: isLoading)),
]),
);
}
}

@ -36,7 +36,8 @@ class ClinicCard extends StatelessWidget {
(clinicsListResponseModel.isLiveCareClinicAndOnline ?? true)
? Utils.buildSvgWithAssets(icon: AppAssets.livecare_clinic_icon, width: 32.h, height: 32.h, fit: BoxFit.contain).toShimmer2(isShow: isLoading)
: SizedBox.shrink(),
]),
],
),
SizedBox(height: 16.h),
Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
Expanded(
@ -44,7 +45,7 @@ class ClinicCard extends StatelessWidget {
.toText16(isBold: true)
.toShimmer2(isShow: isLoading)),
Transform.flip(
flipX: appState.isArabic() ? true : false,
flipX: appState.isArabic(),
child: Utils.buildSvgWithAssets(icon: AppAssets.forward_arrow_icon, width: 40.h, height: 40.h, fit: BoxFit.contain, iconColor: AppColors.textColor).toShimmer2(isShow: isLoading)),
]),
],

Loading…
Cancel
Save