diff --git a/assets/animations/lottie/Ripple.json b/assets/animations/lottie/Ripple.json
new file mode 100644
index 0000000..058b4ca
--- /dev/null
+++ b/assets/animations/lottie/Ripple.json
@@ -0,0 +1 @@
+{"nm":"Comp 1","ddd":0,"h":100,"w":100,"meta":{"g":"@lottiefiles/toolkit-js 0.33.2"},"layers":[{"ty":4,"nm":"Shape Layer 2","sr":1,"st":0,"op":300,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[5.277,-32.723,0],"ix":1},"s":{"a":0,"k":[4.91,4.91,100],"ix":6},"sk":{"a":0,"k":0},"p":{"a":0,"k":[50.2,50.18,0],"ix":2},"r":{"a":0,"k":0,"ix":10},"sa":{"a":0,"k":0},"o":{"a":0,"k":100,"ix":11}},"ef":[],"shapes":[{"ty":"gr","bm":0,"hd":false,"mn":"ADBE Vector Group","nm":"Ellipse 2","ix":1,"cix":2,"np":3,"it":[{"ty":"el","bm":0,"hd":false,"mn":"ADBE Vector Shape - Ellipse","nm":"Ellipse Path 1","d":1,"p":{"a":0,"k":[0,0],"ix":3},"s":{"a":0,"k":[102.555,102.555],"ix":2}},{"ty":"fl","bm":0,"hd":false,"mn":"ADBE Vector Graphic - Fill","nm":"Fill 1","c":{"a":0,"k":[0.0941,0.7608,0.451],"ix":4},"r":1,"o":{"a":0,"k":100,"ix":5}},{"ty":"tr","a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"sk":{"a":0,"k":0,"ix":4},"p":{"a":0,"k":[3.277,-34.527],"ix":2},"r":{"a":0,"k":0,"ix":6},"sa":{"a":0,"k":0,"ix":5},"o":{"a":0,"k":100,"ix":7}}]},{"ty":"gr","bm":0,"hd":false,"mn":"ADBE Vector Group","nm":"Ellipse 1","ix":2,"cix":2,"np":3,"it":[{"ty":"el","bm":0,"hd":false,"mn":"ADBE Vector Shape - Ellipse","nm":"Ellipse Path 1","d":1,"p":{"a":0,"k":[0,0],"ix":3},"s":{"a":0,"k":[102.555,102.555],"ix":2}},{"ty":"fl","bm":0,"hd":false,"mn":"ADBE Vector Graphic - Fill","nm":"Fill 1","c":{"a":0,"k":[0.0941,0.7608,0.451],"ix":4},"r":1,"o":{"a":0,"k":100,"ix":5}},{"ty":"tr","a":{"a":0,"k":[0,0],"ix":1},"s":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100,100],"t":0},{"s":[295,295],"t":60}],"ix":3},"sk":{"a":0,"k":0,"ix":4},"p":{"a":0,"k":[3.277,-34.527],"ix":2},"r":{"a":0,"k":0,"ix":6},"sa":{"a":0,"k":0,"ix":5},"o":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100],"t":0},{"s":[0],"t":60}],"ix":7}}]}],"ind":1}],"v":"5.5.7","fr":60,"op":61,"ip":0,"assets":[]}
\ No newline at end of file
diff --git a/assets/images/svg/livecare_online_icon.svg b/assets/images/svg/livecare_online_icon.svg
new file mode 100644
index 0000000..e063de8
--- /dev/null
+++ b/assets/images/svg/livecare_online_icon.svg
@@ -0,0 +1,4 @@
+
diff --git a/lib/core/app_assets.dart b/lib/core/app_assets.dart
index 31b4f32..446bbc2 100644
--- a/lib/core/app_assets.dart
+++ b/lib/core/app_assets.dart
@@ -145,6 +145,7 @@ class AppAssets {
static const String ic_normal_result = '$svgBasePath/normal_result.svg';
static const String ic_low_result = '$svgBasePath/low_result.svg';
static const String ic_critical_low_result = '$svgBasePath/critical_low_result.svg';
+ static const String livecare_online_icon = '$svgBasePath/livecare_online_icon.svg';
//bottom navigation//
static const String homeBottom = '$svgBasePath/home_bottom.svg';
@@ -184,4 +185,5 @@ class AppAnimations {
static const String warningAnimation = '$lottieBasePath/warningAnimation.json';
static const String splashLaunching = '$lottieBasePath/splash_launching.json';
static const String noData = '$lottieBasePath/Nodata.json';
+ static const String ripple = '$lottieBasePath/Ripple.json';
}
diff --git a/lib/features/book_appointments/book_appointments_repo.dart b/lib/features/book_appointments/book_appointments_repo.dart
index 5e99585..18b5330 100644
--- a/lib/features/book_appointments/book_appointments_repo.dart
+++ b/lib/features/book_appointments/book_appointments_repo.dart
@@ -8,6 +8,7 @@ import 'package:hmg_patient_app_new/features/book_appointments/models/resp_model
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_livecare_clinics_response_model.dart';
+import 'package:hmg_patient_app_new/features/book_appointments/models/resp_models/get_livecare_immediate_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/patient_appointment_history_response_model.dart';
import 'package:hmg_patient_app_new/services/logger_service.dart';
@@ -66,6 +67,8 @@ abstract class BookAppointmentsRepo {
required int serviceID,
Function(dynamic)? onSuccess,
Function(String)? onError});
+
+ Future>>> getLiveCareImmediateClinicsList(int age, int genderID, {Function(dynamic)? onSuccess, Function(String)? onError});
}
class BookAppointmentsRepoImp implements BookAppointmentsRepo {
@@ -657,4 +660,47 @@ class BookAppointmentsRepoImp implements BookAppointmentsRepo {
return Left(UnknownFailure(e.toString()));
}
}
+
+ @override
+ Future>>> getLiveCareImmediateClinicsList(int age, int genderID,
+ {Function(dynamic)? onSuccess, Function(String)? onError}) async {
+ Map mapDevice = {
+ "Age": age,
+ "Gender": genderID,
+ };
+
+ try {
+ GenericApiModel>? apiResponse;
+ Failure? failure;
+ await apiClient.post(
+ GET_LIVECARE_CLINICS,
+ body: mapDevice,
+ onFailure: (error, statusCode, {messageStatus, failureType}) {
+ failure = failureType;
+ onError!(error);
+ },
+ onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
+ try {
+ final list = response['PatientER_GetClinicsList'];
+
+ final clinicsList = list.map((item) => GetLiveCareClinicListResponseModel.fromJson(item as Map)).toList().cast();
+
+ apiResponse = GenericApiModel>(
+ 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()));
+ }
+ }
}
diff --git a/lib/features/book_appointments/book_appointments_view_model.dart b/lib/features/book_appointments/book_appointments_view_model.dart
index 5ef653a..ab4ca56 100644
--- a/lib/features/book_appointments/book_appointments_view_model.dart
+++ b/lib/features/book_appointments/book_appointments_view_model.dart
@@ -15,6 +15,7 @@ import 'package:hmg_patient_app_new/features/book_appointments/models/free_slot.
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';
+import 'package:hmg_patient_app_new/features/book_appointments/models/resp_models/get_livecare_immediate_clinics_response_model.dart';
import 'package:hmg_patient_app_new/features/book_appointments/models/timeslots.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';
@@ -60,6 +61,11 @@ class BookAppointmentsViewModel extends ChangeNotifier {
DoctorsListResponseModel selectedDoctor = DoctorsListResponseModel();
GetLiveCareClinicsResponseModel selectedLiveCareClinic = GetLiveCareClinicsResponseModel();
+ //Immediate LiveCare
+ List immediateLiveCareClinicsList = [];
+ bool isImmediateLiveCareClinicsLoading = false;
+ int liveCareSelectedCallType = 1;
+
late DoctorsProfileResponseModel doctorsProfileResponseModel;
List slotsList = [];
@@ -89,7 +95,6 @@ class BookAppointmentsViewModel extends ChangeNotifier {
BookAppointmentsViewModel(
{required this.bookAppointmentsRepo, required this.errorHandlerService, required this.navigationService, required this.myAppointmentsViewModel, required this.locationUtils}) {
- ;
initBookAppointmentViewModel();
}
@@ -117,6 +122,9 @@ class BookAppointmentsViewModel extends ChangeNotifier {
clinicsList.clear();
doctorsList.clear();
liveCareClinicsList.clear();
+
+ immediateLiveCareClinicsList.clear();
+ isImmediateLiveCareClinicsLoading = true;
// getLocation();
notifyListeners();
}
@@ -183,6 +191,12 @@ class BookAppointmentsViewModel extends ChangeNotifier {
notifyListeners();
}
+
+ setLiveCareSelectedCallType(int value) {
+ liveCareSelectedCallType = value;
+ notifyListeners();
+ }
+
/// this function will decide which clinic api to be called
/// either api for region flow or the select clinic api
Future getClinics() async {
@@ -757,4 +771,31 @@ class BookAppointmentsViewModel extends ChangeNotifier {
void getLocation() {
locationUtils.getLocation();
}
+
+ Future getLiveCareImmediateClinicsList({Function(dynamic)? onSuccess, Function(String)? onError}) async {
+ immediateLiveCareClinicsList.clear();
+ isImmediateLiveCareClinicsLoading = true;
+ notifyListeners();
+
+ final result = await bookAppointmentsRepo.getLiveCareImmediateClinicsList(_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) {
+ immediateLiveCareClinicsList = apiResponse.data!;
+
+ immediateLiveCareClinicsList.sort((a, b) => b.isOnline!.compareTo(a.isOnline!));
+
+ isImmediateLiveCareClinicsLoading = false;
+ notifyListeners();
+ if (onSuccess != null) {
+ onSuccess(apiResponse);
+ }
+ }
+ },
+ );
+ }
}
diff --git a/lib/features/book_appointments/models/resp_models/get_livecare_immediate_clinics_response_model.dart b/lib/features/book_appointments/models/resp_models/get_livecare_immediate_clinics_response_model.dart
new file mode 100644
index 0000000..5c5b900
--- /dev/null
+++ b/lib/features/book_appointments/models/resp_models/get_livecare_immediate_clinics_response_model.dart
@@ -0,0 +1,97 @@
+class GetLiveCareClinicListResponseModel {
+ int? iD;
+ int? serviceID;
+ String? serviceName;
+ String? serviceNameN;
+ int? clinicID;
+ int? age;
+ bool? isCheckAgeBelow;
+ int? gender;
+ bool? isActive;
+ String? createdOn;
+ String? createdBy;
+ int? isOnline;
+ bool? projectOutSA;
+ List? shiftTimings;
+
+ GetLiveCareClinicListResponseModel(
+ {this.iD,
+ this.serviceID,
+ this.serviceName,
+ this.serviceNameN,
+ this.clinicID,
+ this.age,
+ this.isCheckAgeBelow,
+ this.gender,
+ this.isActive,
+ this.createdOn,
+ this.createdBy,
+ this.isOnline,
+ this.projectOutSA,
+ this.shiftTimings});
+
+ GetLiveCareClinicListResponseModel.fromJson(Map json) {
+ iD = json['ID'];
+ serviceID = json['ServiceID'];
+ serviceName = json['ServiceName'];
+ serviceNameN = json['ServiceNameN'];
+ clinicID = json['ClinicID'];
+ age = json['Age'];
+ isCheckAgeBelow = json['IsCheckAgeBelow'];
+ gender = json['Gender'];
+ isActive = json['IsActive'];
+ createdOn = json['CreatedOn'];
+ createdBy = json['CreatedBy'];
+ isOnline = json['IsOnline'];
+ projectOutSA = json['ProjectOutSA'];
+ if (json['ShiftTimings'] != null) {
+ shiftTimings = [];
+ json['ShiftTimings'].forEach((v) {
+ shiftTimings!.add(new ShiftTimings.fromJson(v));
+ });
+ }
+ }
+
+ Map toJson() {
+ final Map data = Map();
+ data['ID'] = this.iD;
+ data['ServiceID'] = this.serviceID;
+ data['ServiceName'] = this.serviceName;
+ data['ServiceNameN'] = this.serviceNameN;
+ data['ClinicID'] = this.clinicID;
+ data['Age'] = this.age;
+ data['IsCheckAgeBelow'] = this.isCheckAgeBelow;
+ data['Gender'] = this.gender;
+ data['IsActive'] = this.isActive;
+ data['CreatedOn'] = this.createdOn;
+ data['CreatedBy'] = this.createdBy;
+ data['IsOnline'] = this.isOnline;
+ data['ProjectOutSA'] = this.projectOutSA;
+ if (this.shiftTimings != null) {
+ data['ShiftTimings'] = this.shiftTimings!.map((v) => v.toJson()).toList();
+ }
+ return data;
+ }
+}
+
+class ShiftTimings {
+ String? endTime;
+ int? shiftID;
+ String? startTime;
+
+ ShiftTimings({this.endTime, this.shiftID, this.startTime});
+
+ ShiftTimings.fromJson(Map json) {
+ endTime = json['EndTime'];
+ shiftID = json['ShiftID'];
+ startTime = json['StartTime'];
+ }
+
+ Map toJson() {
+ final Map data = Map();
+ data['EndTime'] = this.endTime;
+ data['ShiftID'] = this.shiftID;
+ data['StartTime'] = this.startTime;
+ return data;
+ }
+}
diff --git a/lib/presentation/book_appointment/book_appointment_page.dart b/lib/presentation/book_appointment/book_appointment_page.dart
index 6ba14f5..012a8db 100644
--- a/lib/presentation/book_appointment/book_appointment_page.dart
+++ b/lib/presentation/book_appointment/book_appointment_page.dart
@@ -15,6 +15,7 @@ import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/
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/region_bottomsheet/region_list_widget.dart' show RegionBottomSheetBody;
+import 'package:hmg_patient_app_new/presentation/book_appointment/livecare/select_immediate_livecare_clinic_page.dart';
import 'package:hmg_patient_app_new/presentation/book_appointment/search_doctor_by_name.dart';
import 'package:hmg_patient_app_new/presentation/book_appointment/select_clinic_page.dart';
import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart';
@@ -230,14 +231,13 @@ class _BookAppointmentPageState extends State {
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(),
- // ),
- // );
+ //TODO Implement API to check for existing LiveCare Requests
+
+ Navigator.of(context).push(
+ CustomPageRoute(
+ page: SelectImmediateLiveCareClinicPage(),
+ ),
+ );
}),
SizedBox(height: 16.h),
Divider(color: AppColors.borderOnlyColor.withValues(alpha: 0.1), height: 1.h),
diff --git a/lib/presentation/book_appointment/livecare/select_immediate_livecare_clinic_page.dart b/lib/presentation/book_appointment/livecare/select_immediate_livecare_clinic_page.dart
new file mode 100644
index 0000000..8ec6e4b
--- /dev/null
+++ b/lib/presentation/book_appointment/livecare/select_immediate_livecare_clinic_page.dart
@@ -0,0 +1,158 @@
+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/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/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/book_appointments/models/resp_models/get_livecare_immediate_clinics_response_model.dart';
+import 'package:hmg_patient_app_new/presentation/book_appointment/livecare/widgets/select_livecare_call_type.dart';
+import 'package:hmg_patient_app_new/presentation/book_appointment/widgets/clinic_card.dart';
+import 'package:hmg_patient_app_new/presentation/book_appointment/widgets/livecare_clinic_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/common_bottom_sheet.dart';
+import 'package:provider/provider.dart';
+
+class SelectImmediateLiveCareClinicPage extends StatefulWidget {
+ const SelectImmediateLiveCareClinicPage({super.key});
+
+ @override
+ State createState() => _SelectImmediateLiveCareClinicPageState();
+}
+
+class _SelectImmediateLiveCareClinicPageState extends State {
+ TextEditingController searchEditingController = TextEditingController();
+ FocusNode textFocusNode = FocusNode();
+ late AppState appState;
+ late BookAppointmentsViewModel bookAppointmentsViewModel;
+
+ @override
+ void initState() {
+ scheduleMicrotask(() {
+ bookAppointmentsViewModel.getLiveCareImmediateClinicsList();
+ });
+ super.initState();
+ }
+
+ @override
+ void dispose() {
+ textFocusNode.dispose();
+ super.dispose();
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ bookAppointmentsViewModel = Provider.of(context, listen: false);
+ appState = getIt.get();
+ return Scaffold(
+ backgroundColor: AppColors.bgScaffoldColor,
+ body: CollapsingListView(
+ title: "Select LiveCare Clinic".needTranslation,
+ child: SingleChildScrollView(
+ child: Padding(
+ padding: EdgeInsets.all(24.h),
+ child: Consumer(builder: (context, bookAppointmentsVM, child) {
+ return Column(
+ children: [
+ // SizedBox(height: 16.h),
+ // TextInputWidget(
+ // labelText: LocaleKeys.search.tr(context: context),
+ // hintText: LocaleKeys.clinicName.tr(context: context),
+ // controller: searchEditingController,
+ // isEnable: true,
+ // prefix: null,
+ // autoFocus: false,
+ // isBorderAllowed: false,
+ // keyboardType: TextInputType.text,
+ // focusNode: textFocusNode,
+ // suffix: searchEditingController.text.isNotEmpty
+ // ? GestureDetector(
+ // onTap: () {
+ // searchEditingController.clear();
+ // bookAppointmentsViewModel.filterClinics("");
+ // textFocusNode.unfocus();
+ // },
+ // child: Utils.buildSvgWithAssets(icon: AppAssets.close_bottom_sheet_icon, width: 20.h, height: 20.h, fit: BoxFit.scaleDown),
+ // )
+ // : null,
+ // onChange: (value) {
+ // bookAppointmentsViewModel.filterClinics(value!);
+ // },
+ // padding: EdgeInsets.symmetric(
+ // vertical: ResponsiveExtension(10).h,
+ // horizontal: ResponsiveExtension(15).h,
+ // ),
+ // ),
+ ListView.separated(
+ padding: EdgeInsets.only(top: 16.h),
+ shrinkWrap: true,
+ physics: NeverScrollableScrollPhysics(),
+ itemCount: bookAppointmentsVM.isImmediateLiveCareClinicsLoading ? 5 : bookAppointmentsVM.immediateLiveCareClinicsList.length,
+ itemBuilder: (context, index) {
+ return bookAppointmentsVM.isImmediateLiveCareClinicsLoading
+ ? ClinicCard(
+ bookAppointmentsVM: bookAppointmentsVM,
+ liveCareClinicsResponseModel: GetLiveCareClinicsResponseModel(),
+ clinicsListResponseModel: GetClinicsListResponseModel(),
+ isLoading: bookAppointmentsVM.isImmediateLiveCareClinicsLoading,
+ )
+ : 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: LiveCareClinicCard(
+ bookAppointmentsVM: bookAppointmentsVM,
+ liveCareClinicListResponseModel: bookAppointmentsVM.immediateLiveCareClinicsList[index],
+ isLoading: bookAppointmentsVM.isImmediateLiveCareClinicsLoading,
+ ).onPress(() {
+ onImmediateLiveCareClinicSelected(bookAppointmentsVM.immediateLiveCareClinicsList[index]);
+ }),
+ ),
+ ),
+ ),
+ );
+ },
+ separatorBuilder: (BuildContext cxt, int index) => SizedBox(height: 16.h),
+ ),
+ ],
+ );
+ }),
+ ),
+ ),
+ ),
+ );
+ }
+
+ onImmediateLiveCareClinicSelected(GetLiveCareClinicListResponseModel liveCareClinic) {
+ //TODO: add implementation to show clinic schedule
+ if (liveCareClinic.isOnline == 1) {
+ showCommonBottomSheetWithoutHeight(context,
+ child: SelectLiveCareCallType(bookAppointmentsViewModel: bookAppointmentsViewModel),
+ callBackFunc: () {},
+ title: "Select LiveCare call type".needTranslation,
+ isCloseButtonVisible: true,
+ isFullScreen: false);
+ } else {
+ showCommonBottomSheetWithoutHeight(context,
+ child: Utils.getErrorWidget(
+ loadingText: "The selected clinic is only available between ${liveCareClinic.shiftTimings!.first.startTime} & ${liveCareClinic.shiftTimings!.first.endTime} hours.".needTranslation),
+ callBackFunc: () {},
+ title: "",
+ isCloseButtonVisible: true,
+ isFullScreen: false);
+ }
+ }
+}
diff --git a/lib/presentation/book_appointment/livecare/widgets/select_livecare_call_type.dart b/lib/presentation/book_appointment/livecare/widgets/select_livecare_call_type.dart
new file mode 100644
index 0000000..689dc9b
--- /dev/null
+++ b/lib/presentation/book_appointment/livecare/widgets/select_livecare_call_type.dart
@@ -0,0 +1,65 @@
+import 'package:flutter/cupertino.dart';
+import 'package:hmg_patient_app_new/core/app_assets.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/presentation/medical_file/widgets/medical_file_card.dart';
+import 'package:hmg_patient_app_new/theme/colors.dart';
+
+class SelectLiveCareCallType extends StatelessWidget {
+ SelectLiveCareCallType({super.key, required this.bookAppointmentsViewModel});
+
+ BookAppointmentsViewModel bookAppointmentsViewModel;
+
+ @override
+ Widget build(BuildContext context) {
+ //TODO: Replace with actual icons
+ return GridView(
+ gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
+ crossAxisCount: 3,
+ crossAxisSpacing: 16,
+ mainAxisSpacing: 16,
+ mainAxisExtent: 130,
+ ),
+ physics: NeverScrollableScrollPhysics(),
+ padding: EdgeInsets.zero,
+ shrinkWrap: true,
+ children: [
+ MedicalFileCard(
+ label: "Video Call".needTranslation,
+ textColor: AppColors.blackColor,
+ backgroundColor: AppColors.whiteColor,
+ svgIcon: AppAssets.eye_result_icon,
+ isLargeText: true,
+ iconSize: 36.h,
+ ).onPress(() {
+ Navigator.of(context).pop();
+ bookAppointmentsViewModel.setLiveCareSelectedCallType(1);
+ }),
+ MedicalFileCard(
+ label: "Audio Call".needTranslation,
+ textColor: AppColors.blackColor,
+ backgroundColor: AppColors.whiteColor,
+ svgIcon: AppAssets.allergy_info_icon,
+ isLargeText: true,
+ iconSize: 36.h,
+ ).onPress(() {
+ Navigator.of(context).pop();
+ bookAppointmentsViewModel.setLiveCareSelectedCallType(2);
+ }),
+ MedicalFileCard(
+ label: "Phone Call".needTranslation,
+ textColor: AppColors.blackColor,
+ backgroundColor: AppColors.whiteColor,
+ svgIcon: AppAssets.vaccine_info_icon,
+ isLargeText: true,
+ iconSize: 36.h,
+ ).onPress(() {
+ Navigator.of(context).pop();
+ bookAppointmentsViewModel.setLiveCareSelectedCallType(3);
+ }),
+ ],
+ );
+ }
+}
diff --git a/lib/presentation/book_appointment/widgets/livecare_clinic_card.dart b/lib/presentation/book_appointment/widgets/livecare_clinic_card.dart
new file mode 100644
index 0000000..1642d60
--- /dev/null
+++ b/lib/presentation/book_appointment/widgets/livecare_clinic_card.dart
@@ -0,0 +1,66 @@
+import 'package:easy_localization/easy_localization.dart';
+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/get_livecare_immediate_clinics_response_model.dart';
+import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
+import 'package:hmg_patient_app_new/theme/colors.dart';
+
+class LiveCareClinicCard extends StatelessWidget {
+ LiveCareClinicCard({super.key, required this.liveCareClinicListResponseModel, required this.isLoading, required this.bookAppointmentsVM});
+
+ GetLiveCareClinicListResponseModel liveCareClinicListResponseModel;
+ bool isLoading;
+ BookAppointmentsViewModel bookAppointmentsVM;
+
+ @override
+ Widget build(BuildContext context) {
+ AppState appState = getIt.get();
+ return Container(
+ padding: EdgeInsets.all(16.h),
+ decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
+ color: AppColors.whiteColor,
+ borderRadius: 24.h,
+ hasShadow: false,
+ ),
+ child: Column(
+ children: [
+ Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
+ Utils.buildSvgWithAssets(icon: AppAssets.generic_clinic_icon, width: 24.h, height: 24.h, fit: BoxFit.contain).toShimmer2(isShow: isLoading),
+ Column(
+ children: [
+ Utils.buildSvgWithAssets(
+ icon: AppAssets.livecare_online_icon,
+ width: 16.h,
+ height: 16.h,
+ fit: BoxFit.contain,
+ iconColor: liveCareClinicListResponseModel.isOnline == 1 ? AppColors.successColor : AppColors.primaryRedColor)
+ .toShimmer2(isShow: isLoading),
+ SizedBox(height: 4.h),
+ liveCareClinicListResponseModel.isOnline == 1
+ ? LocaleKeys.online.tr(context: context).toText10(isBold: true, color: AppColors.successColor).toShimmer2(isShow: isLoading)
+ : "Offline".toText10(isBold: true, color: AppColors.primaryRedColor).toShimmer2(isShow: isLoading),
+ ],
+ ),
+ ]),
+ SizedBox(height: 8.h),
+ Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
+ Expanded(
+ child: (isLoading ? "Cardiology" : (appState.isArabic() ? liveCareClinicListResponseModel.serviceNameN : liveCareClinicListResponseModel.serviceName))!
+ .toText16(isBold: true)
+ .toShimmer2(isShow: isLoading)),
+ Transform.flip(
+ 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)),
+ ]),
+ ],
+ ),
+ );
+ }
+}