From 71030c0fe9fb579ace6957665822c48f62bda6e8 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Wed, 8 Apr 2026 00:27:43 +0300 Subject: [PATCH 1/3] Updates & fixes --- .../book_appointments_view_model.dart | 10 ++- ...nt_appointment_history_response_model.dart | 3 + .../appointments/my_doctors_page.dart | 2 +- .../widgets/appointment_doctor_card.dart | 4 +- .../book_appointment_page.dart | 4 +- .../book_appointment/doctor_profile_page.dart | 8 +- .../immediate_livecare_payment_details.dart | 2 +- .../search_doctor_by_name.dart | 2 +- .../book_appointment/select_doctor_page.dart | 5 +- .../call_ambulance/call_ambulance_page.dart | 4 +- .../medical_file/medical_file_page.dart | 2 +- lib/widgets/map/gms_map.dart | 81 +++++++++++++++++-- lib/widgets/map/map_utility_screen.dart | 2 +- 13 files changed, 106 insertions(+), 23 deletions(-) diff --git a/lib/features/book_appointments/book_appointments_view_model.dart b/lib/features/book_appointments/book_appointments_view_model.dart index e43a49d5..6f2092f9 100644 --- a/lib/features/book_appointments/book_appointments_view_model.dart +++ b/lib/features/book_appointments/book_appointments_view_model.dart @@ -400,9 +400,13 @@ class BookAppointmentsViewModel extends ChangeNotifier { notifyListeners(); } + refreshDoctorsList() { + setIsDoctorsListLoading(true); + getDoctorsList(isNearest: isNearestAppointmentSelected); + } + setIsNearestAppointmentSelected(bool isNearestAppointmentSelected) { this.isNearestAppointmentSelected = isNearestAppointmentSelected; - if (isNearestAppointmentSelected) { for (var group in doctorsListGrouped) { group.sort((a, b) { @@ -646,7 +650,7 @@ class BookAppointmentsViewModel extends ChangeNotifier { } //TODO: Make the API dynamic with parameters for ProjectID, isNearest, languageID, doctorId, doctorName - Future getDoctorsList({int projectID = 0, bool isNearest = true, int doctorId = 0, String doctorName = "", Function(dynamic)? onSuccess, Function(String)? onError}) async { + Future getDoctorsList({int projectID = 0, bool isNearest = false, int doctorId = 0, String doctorName = "", Function(dynamic)? onSuccess, Function(String)? onError}) async { doctorsList.clear(); filteredDoctorList.clear(); doctorsListGrouped.clear(); @@ -674,7 +678,7 @@ class BookAppointmentsViewModel extends ChangeNotifier { clearSearchFilters(); getFiltersFromDoctorList(); _groupDoctorsList(); - setIsNearestAppointmentSelected(true); + setIsNearestAppointmentSelected(isNearest); notifyListeners(); if (onSuccess != null) { onSuccess(apiResponse); diff --git a/lib/features/my_appointments/models/resp_models/patient_appointment_history_response_model.dart b/lib/features/my_appointments/models/resp_models/patient_appointment_history_response_model.dart index c0da3c47..cea2e64b 100644 --- a/lib/features/my_appointments/models/resp_models/patient_appointment_history_response_model.dart +++ b/lib/features/my_appointments/models/resp_models/patient_appointment_history_response_model.dart @@ -51,6 +51,7 @@ class PatientAppointmentHistoryResponseModel { bool? isExecludeDoctor; dynamic isFollowup; bool? isLiveCareAppointment; + bool? isLiveCareClinic; bool? isInOutPatient; bool? isMedicalReportRequested; bool? isOnlineCheckedIN; @@ -128,6 +129,7 @@ class PatientAppointmentHistoryResponseModel { this.isExecludeDoctor, this.isFollowup, this.isLiveCareAppointment, + this.isLiveCareClinic, this.isMedicalReportRequested, this.isOnlineCheckedIN, this.latitude, @@ -205,6 +207,7 @@ class PatientAppointmentHistoryResponseModel { isExecludeDoctor = json['IsExecludeDoctor']; isFollowup = json['IsFollowup']; isLiveCareAppointment = json['IsLiveCareAppointment']; + isLiveCareClinic = json['IsLiveCareClinic']; isInOutPatient = json['IsInOutPatient']; isMedicalReportRequested = json['IsMedicalReportRequested']; isOnlineCheckedIN = json['IsOnlineCheckedIN']; diff --git a/lib/presentation/appointments/my_doctors_page.dart b/lib/presentation/appointments/my_doctors_page.dart index 1a98964b..93733770 100644 --- a/lib/presentation/appointments/my_doctors_page.dart +++ b/lib/presentation/appointments/my_doctors_page.dart @@ -318,7 +318,7 @@ class _MyDoctorsPageState extends State { LoaderBottomSheet.hideLoader(); Navigator.of(context).push( CustomPageRoute( - page: DoctorProfilePage(), + page: DoctorProfilePage(isDoctorAllowedToBook: !doctor?.isLiveCareClinic), ), ); }, onError: (err) { diff --git a/lib/presentation/appointments/widgets/appointment_doctor_card.dart b/lib/presentation/appointments/widgets/appointment_doctor_card.dart index 99f40b67..5de06455 100644 --- a/lib/presentation/appointments/widgets/appointment_doctor_card.dart +++ b/lib/presentation/appointments/widgets/appointment_doctor_card.dart @@ -161,7 +161,9 @@ class AppointmentDoctorCard extends StatelessWidget { LoaderBottomSheet.hideLoader(); Navigator.of(context).push( CustomPageRoute( - page: DoctorProfilePage(), + page: DoctorProfilePage( + isDoctorAllowedToBook: !(patientAppointmentHistoryResponseModel.isLiveCareAppointment ?? false), + ), ), ); }, onError: (err) { diff --git a/lib/presentation/book_appointment/book_appointment_page.dart b/lib/presentation/book_appointment/book_appointment_page.dart index 3d82387b..bbc88214 100644 --- a/lib/presentation/book_appointment/book_appointment_page.dart +++ b/lib/presentation/book_appointment/book_appointment_page.dart @@ -217,7 +217,7 @@ class _BookAppointmentPageState extends State { LoaderBottomSheet.hideLoader(); Navigator.of(context).push( CustomPageRoute( - page: DoctorProfilePage(), + page: DoctorProfilePage(isDoctorAllowedToBook: !(myAppointmentsVM.patientMyDoctorsList[index].isLiveCareClinic ?? false)), ), ); }, onError: (err) { @@ -406,7 +406,7 @@ class _BookAppointmentPageState extends State { LoaderBottomSheet.hideLoader(); Navigator.of(context).push( CustomPageRoute( - page: DoctorProfilePage(), + page: DoctorProfilePage(isDoctorAllowedToBook: true), ), ); }, onError: (err) { diff --git a/lib/presentation/book_appointment/doctor_profile_page.dart b/lib/presentation/book_appointment/doctor_profile_page.dart index 713ee2c0..dbb885b3 100644 --- a/lib/presentation/book_appointment/doctor_profile_page.dart +++ b/lib/presentation/book_appointment/doctor_profile_page.dart @@ -22,7 +22,9 @@ import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart'; import 'package:provider/provider.dart'; class DoctorProfilePage extends StatelessWidget { - const DoctorProfilePage({super.key}); + const DoctorProfilePage({super.key, required this.isDoctorAllowedToBook}); + + final bool isDoctorAllowedToBook; @override Widget build(BuildContext context) { @@ -187,7 +189,7 @@ class DoctorProfilePage extends StatelessWidget { ), ), ), - Container( + isDoctorAllowedToBook ? Container( decoration: RoundedRectangleBorder().toSmoothCornerDecoration( color: AppColors.whiteColor, borderRadius: 24.h, @@ -265,7 +267,7 @@ class DoctorProfilePage extends StatelessWidget { iconColor: Colors.white, iconSize: 20.h, ).paddingSymmetrical(24.h, 24.h), - ), + ) : SizedBox.shrink(), ], ), ); diff --git a/lib/presentation/book_appointment/livecare/immediate_livecare_payment_details.dart b/lib/presentation/book_appointment/livecare/immediate_livecare_payment_details.dart index 29ac4a5d..5f44448a 100644 --- a/lib/presentation/book_appointment/livecare/immediate_livecare_payment_details.dart +++ b/lib/presentation/book_appointment/livecare/immediate_livecare_payment_details.dart @@ -214,7 +214,7 @@ class ImmediateLiveCarePaymentDetails extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ LocaleKeys.amountBeforeTax.tr(context: context).toText14(isBold: true), - Utils.getPaymentAmountWithSymbol(immediateLiveCareVM.liveCareImmediateAppointmentFeesList.amount!.toText16(isBold: true, isEnglishOnly: true), AppColors.blackColor, 13, + Utils.getPaymentAmountWithSymbol((immediateLiveCareVM.liveCareImmediateAppointmentFeesList.amount ?? "").toText16(isBold: true, isEnglishOnly: true), AppColors.blackColor, 13, isSaudiCurrency: immediateLiveCareVM.liveCareImmediateAppointmentFeesList.currency!.toLowerCase() == "sar" || immediateLiveCareVM.liveCareImmediateAppointmentFeesList.currency!.toLowerCase() == "ريال"), ], diff --git a/lib/presentation/book_appointment/search_doctor_by_name.dart b/lib/presentation/book_appointment/search_doctor_by_name.dart index e2ab6808..3222fbd8 100644 --- a/lib/presentation/book_appointment/search_doctor_by_name.dart +++ b/lib/presentation/book_appointment/search_doctor_by_name.dart @@ -218,7 +218,7 @@ class _SearchDoctorByNameState extends State { LoaderBottomSheet.hideLoader(); Navigator.of(context).push( CustomPageRoute( - page: DoctorProfilePage(), + page: DoctorProfilePage(isDoctorAllowedToBook: true), ), ); }, diff --git a/lib/presentation/book_appointment/select_doctor_page.dart b/lib/presentation/book_appointment/select_doctor_page.dart index 6c3427e7..98cc550b 100644 --- a/lib/presentation/book_appointment/select_doctor_page.dart +++ b/lib/presentation/book_appointment/select_doctor_page.dart @@ -239,6 +239,9 @@ class _SelectDoctorPageState extends State { value: bookAppointmentsVM.isNearestAppointmentSelected, onChanged: (newValue) async { bookAppointmentsVM.setIsNearestAppointmentSelected(newValue); + if(newValue) { + bookAppointmentsVM.refreshDoctorsList(); + } }, ), ], @@ -346,7 +349,7 @@ class _SelectDoctorPageState extends State { LoaderBottomSheet.hideLoader(); Navigator.of(context).push( CustomPageRoute( - page: DoctorProfilePage(), + page: DoctorProfilePage(isDoctorAllowedToBook: true,), ), ); }, onError: (err) { diff --git a/lib/presentation/emergency_services/call_ambulance/call_ambulance_page.dart b/lib/presentation/emergency_services/call_ambulance/call_ambulance_page.dart index a1b1839f..55958048 100644 --- a/lib/presentation/emergency_services/call_ambulance/call_ambulance_page.dart +++ b/lib/presentation/emergency_services/call_ambulance/call_ambulance_page.dart @@ -1,3 +1,5 @@ +import 'dart:io'; + import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:hmg_patient_app_new/core/app_assets.dart'; @@ -67,7 +69,7 @@ class CallAmbulancePage extends StatelessWidget { myLocationEnabled: true, inputController: context.read().gmsController, showCenterMarker: true, - bottomPaddingHeight: MediaQuery.of(context).size.height * 0.42, + bottomPaddingHeight: 400.h, ) else HMSMap( diff --git a/lib/presentation/medical_file/medical_file_page.dart b/lib/presentation/medical_file/medical_file_page.dart index e089c057..d04f2ac8 100644 --- a/lib/presentation/medical_file/medical_file_page.dart +++ b/lib/presentation/medical_file/medical_file_page.dart @@ -1019,7 +1019,7 @@ class _MedicalFilePageState extends State { LoaderBottomSheet.hideLoader(); Navigator.of(context).push( CustomPageRoute( - page: DoctorProfilePage(), + page: DoctorProfilePage(isDoctorAllowedToBook: !(myAppointmentsVM.patientMyDoctorsList[index].isLiveCareClinic ?? false)), ), ); }, onError: (err) { diff --git a/lib/widgets/map/gms_map.dart b/lib/widgets/map/gms_map.dart index 24f180cd..1d06fb10 100644 --- a/lib/widgets/map/gms_map.dart +++ b/lib/widgets/map/gms_map.dart @@ -54,10 +54,16 @@ // } import 'dart:async'; +import 'dart:io'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:google_maps_flutter/google_maps_flutter.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/location_util.dart'; +import 'package:hmg_patient_app_new/core/utils/utils.dart'; import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; @@ -72,7 +78,7 @@ class GMSMap extends StatefulWidget { final bool myLocationEnabled; final bool showCenterMarker; final Completer? inputController; - final num bottomPaddingHeight; + final double bottomPaddingHeight; const GMSMap({ super.key, @@ -93,6 +99,7 @@ class GMSMap extends StatefulWidget { class _GMSMapState extends State { late Completer _controller; + GoogleMapController? _activeController; late MapType _selectedMapType; bool _showMapTypeSelector = false; num bottomPaddingHeight = 0; @@ -139,6 +146,37 @@ class _GMSMapState extends State { setState(() => _showMapTypeSelector = !_showMapTypeSelector); } + Future _animateToMyLocation() async { + final appState = getIt.get(); + final locationUtils = getIt.get(); + + void _moveToLocation() { + if (appState.userLat != 0.0 && appState.userLong != 0.0 && _activeController != null) { + _activeController!.animateCamera( + CameraUpdate.newCameraPosition( + CameraPosition( + target: LatLng(appState.userLat, appState.userLong), + zoom: 16, + ), + ), + ); + } + } + + if (appState.userLat != 0.0 && appState.userLong != 0.0) { + _moveToLocation(); + } else { + locationUtils.getLocation( + isShowConfirmDialog: true, + onSuccess: (latLng) { + _moveToLocation(); + }, + onFailure: () {}, + onLocationDeniedForever: () {}, + ); + } + } + @override Widget build(BuildContext context) { return Stack( @@ -146,16 +184,21 @@ class _GMSMapState extends State { // ── Google Map ────────────────────────────────────────────────── GoogleMap( mapType: _selectedMapType, - zoomControlsEnabled: true, - myLocationEnabled: widget.myLocationEnabled, - myLocationButtonEnabled: true, - padding: EdgeInsets.only(bottom: double.parse(widget.bottomPaddingHeight.toString())), + zoomControlsEnabled: false, + // myLocationEnabled: widget.myLocationEnabled, + myLocationEnabled: true, + myLocationButtonEnabled: false, + // padding: EdgeInsets.only(bottom: double.parse(widget.bottomPaddingHeight.toString())), + // padding: EdgeInsets.only(top: Platform.isAndroid ? double.parse(widget.bottomPaddingHeight.toString()) : 0, bottom: Platform.isIOS ? double.parse(widget.bottomPaddingHeight.toString()) : 0), compassEnabled: widget.compassEnabled, initialCameraPosition: widget.currentLocation, onCameraMove: widget.onCameraMoved, onCameraIdle: widget.onCameraIdle, onMapCreated: (GoogleMapController controller) { - _controller.complete(controller); + _activeController = controller; + if (!_controller.isCompleted) { + _controller.complete(controller); + } }, ), @@ -167,9 +210,33 @@ class _GMSMapState extends State { Icons.location_pin, size: 36.h, color: AppColors.primaryRedColor, - ).paddingOnly(bottom: double.parse((widget.bottomPaddingHeight + 25.h).toString())), + ).paddingOnly(bottom: Platform.isAndroid ? 30.h : double.parse((widget.bottomPaddingHeight + 25.h).toString())), ), + // ── My Location button ──────────────────────────────────────────── + PositionedDirectional( + // bottom: 300.h, + // bottom: 400.h, + bottom: widget.bottomPaddingHeight, + start: 16.w, + child: GestureDetector( + onTap: _animateToMyLocation, + child: Container( + width: 42.w, + height: 42.h, + decoration: BoxDecoration( + color: AppColors.whiteColor, + borderRadius: BorderRadius.circular(8.r), + ), + child: Icon( + Icons.my_location, + size: 22.h, + color: AppColors.blackBgColor, + ), + ), + ), + ), + // ── Map-type toggle button ────────────────────────────────────── PositionedDirectional( top: 48.h, diff --git a/lib/widgets/map/map_utility_screen.dart b/lib/widgets/map/map_utility_screen.dart index 6c1d9e89..a24317e6 100644 --- a/lib/widgets/map/map_utility_screen.dart +++ b/lib/widgets/map/map_utility_screen.dart @@ -68,7 +68,7 @@ class MapUtilityScreen extends StatelessWidget { myLocationEnabled: true, inputController: context.read().gmsController, showCenterMarker: true, - bottomPaddingHeight: MediaQuery.of(context).size.height * 0.2, + bottomPaddingHeight: 300.h, ) else HMSMap( -- 2.30.2 From 991f9c7a9bfff9cbcfc2c3db472778071c4ec45f Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Wed, 8 Apr 2026 00:55:45 +0300 Subject: [PATCH 2/3] Pull to refresh implemented --- .../habib_wallet/recharge_wallet_page.dart | 2 +- lib/presentation/home/landing_page.dart | 1135 +++++++++-------- lib/widgets/input_widget.dart | 69 +- 3 files changed, 656 insertions(+), 550 deletions(-) diff --git a/lib/presentation/habib_wallet/recharge_wallet_page.dart b/lib/presentation/habib_wallet/recharge_wallet_page.dart index 1427328a..c671152f 100644 --- a/lib/presentation/habib_wallet/recharge_wallet_page.dart +++ b/lib/presentation/habib_wallet/recharge_wallet_page.dart @@ -270,7 +270,7 @@ class _RechargeWalletPageState extends State { isCloseButtonVisible: true, ); } else { - habibWalletVM.setWalletRechargeAmount(num.parse(amountTextController.text)); + habibWalletVM.setWalletRechargeAmount(num.parse(amountTextController.text.replaceAll(',', ''))); habibWalletVM.setNotesText(notesTextController.text); // habibWalletVM.setDepositorDetails(appState.getAuthenticatedUser()!.patientId.toString(), "${appState.getAuthenticatedUser()!.firstName} ${appState.getAuthenticatedUser()!.lastName}", // appState.getAuthenticatedUser()!.mobileNumber!); diff --git a/lib/presentation/home/landing_page.dart b/lib/presentation/home/landing_page.dart index 7ce46906..93d616da 100644 --- a/lib/presentation/home/landing_page.dart +++ b/lib/presentation/home/landing_page.dart @@ -180,277 +180,310 @@ class _LandingPageState extends State { body: Consumer(builder: (context, insuranceVM, child) { return Stack( children: [ - SingleChildScrollView( - padding: EdgeInsets.only( - top: (appState.isAuthenticated && !insuranceVM.isInsuranceLoading && insuranceVM.isInsuranceExpired && insuranceVM.isInsuranceExpiryBannerShown) - ? (MediaQuery.paddingOf(context).top + 70.h) - : kToolbarHeight + 0.h, - bottom: 24), - child: Column( - spacing: 16.h, - children: [ - Row( - spacing: 8.h, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - appState.isAuthenticated - ? WelcomeWidget( - onTap: () { - // DialogService dialogService = getIt.get(); - // dialogService.showFamilyBottomSheetWithoutH( - // label: LocaleKeys.familyTitle.tr(context: context), - // message: "", - // isShowManageButton: true, - // onSwitchPress: (FamilyFileResponseModelLists profile) { - // getIt.get().switchFamilyFiles(responseID: profile.responseId, patientID: profile.patientId, phoneNumber: profile.mobileNumber); - // }, - // profiles: getIt.get().patientFamilyFiles); + RefreshIndicator( + color: AppColors.primaryRedColor, + onRefresh: () async { + if (appState.isAuthenticated) { + // Refresh Appointments Data + myAppointmentsViewModel.setIsAppointmentDataToBeLoaded(true); + myAppointmentsViewModel.initAppointmentsViewModel(); + myAppointmentsViewModel.getPatientAppointments(true, false); + + // Refresh Appointments Data + habibWalletVM.initHabibWalletProvider(); + habibWalletVM.getPatientBalanceAmount(); + + // Refresh Ancillary Orders + todoSectionViewModel.initializeTodoSectionViewModel(); - Navigator.of(context).push( - CustomPageRoute( - direction: AxisDirection.down, - page: FamilyMedicalScreen(), + // Refresh Immediate LiveCare Data + immediateLiveCareViewModel.initImmediateLiveCare(); + immediateLiveCareViewModel.getPatientLiveCareHistory(); + } + }, + child: SingleChildScrollView( + physics: const AlwaysScrollableScrollPhysics(), + padding: EdgeInsets.only( + top: (appState.isAuthenticated && !insuranceVM.isInsuranceLoading && insuranceVM.isInsuranceExpired && insuranceVM.isInsuranceExpiryBannerShown) + ? (MediaQuery.paddingOf(context).top + 70.h) + : kToolbarHeight + 0.h, + bottom: 24), + child: Column( + spacing: 16.h, + children: [ + Row( + spacing: 8.h, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + appState.isAuthenticated + ? WelcomeWidget( + onTap: () { + // DialogService dialogService = getIt.get(); + // dialogService.showFamilyBottomSheetWithoutH( + // label: LocaleKeys.familyTitle.tr(context: context), + // message: "", + // isShowManageButton: true, + // onSwitchPress: (FamilyFileResponseModelLists profile) { + // getIt.get().switchFamilyFiles(responseID: profile.responseId, patientID: profile.patientId, phoneNumber: profile.mobileNumber); + // }, + // profiles: getIt.get().patientFamilyFiles); + + Navigator.of(context).push( + CustomPageRoute( + direction: AxisDirection.down, + page: FamilyMedicalScreen(), + ), + ); + }, + name: ('${appState.getAuthenticatedUser()!.firstName!} ${appState.getAuthenticatedUser()!.lastName!}'), + // imageUrl: appState.getAuthenticatedUser()?.gender == 1 ? AppAssets.maleImg : AppAssets.femaleImg, + imageUrl: appState + .getAuthenticatedUser() + ?.gender == 1 + ? ((appState + .getAuthenticatedUser() + ?.age ?? 0) < 7 ? AppAssets.babyBoyImg : AppAssets.maleImg) + : ((appState + .getAuthenticatedUser() + ?.age ?? 0) < 7 ? AppAssets.babyGirlImg : AppAssets.femaleImg), + ).expanded + : CustomButton( + text: LocaleKeys.loginOrRegister.tr(context: context), + onPressed: () async { + await authVM.onLoginPressed(); + // Navigator.pushReplacementNamed( + // // context, + // context, + // AppRoutes.zoomCallPage, + // // arguments: CallArguments(appointmentID, "111", "Patient", "40", "1", true, 1), + // arguments: CallArguments("test123", "123", "Patient", "40", "0", true, 1), + // // arguments: CallArguments("SmallDailyStandup9875", "123", "Patient", "40", "0", false, int.parse(widget.incomingCallData!.appointmentNo!)), + // ); + }, + backgroundColor: AppColors.secondaryLightRedColor, + borderColor: AppColors.secondaryLightRedColor, + textColor: AppColors.primaryRedColor, + fontSize: 14.f, + fontWeight: FontWeight.w600, + borderRadius: 12.r, + padding: EdgeInsets.fromLTRB(12.h, 0, 12.h, 0), + height: 40.h, + ), + Consumer(builder: (context, todoSectionVM, child) { + return Row( + mainAxisSize: MainAxisSize.min, + spacing: 18.h, + children: [ + Stack(clipBehavior: Clip.none, children: [ + if (appState.isAuthenticated) + Utils.buildSvgWithAssets(icon: AppAssets.bell, height: 24.h, width: 24.h).onPress(() async { + if (appState.isAuthenticated) { + notificationsViewModel.setNotificationStatusID(2); + notificationsViewModel.getAllNotifications(); + Navigator.of(context).push( + CustomPageRoute( + page: NotificationsListPage(), + // page: LoginScreen(), + ), + ); + } else { + await authVM.onLoginPressed(); + } + }), + (appState.isAuthenticated && (int.parse(todoSectionVM.notificationsCount ?? "0") > 0)) + ? Positioned( + right: appState.isArabic() ? 8.w : -8.w, + top: -8.h, + // left: 4.h, + // bottom: 4.h, + child: Container( + width: 18.w, + height: 18.h, + padding: EdgeInsets.all(2), + decoration: BoxDecoration( + color: AppColors.primaryRedColor, + borderRadius: BorderRadius.circular(20.r), + ), + child: Text( + todoSectionVM.notificationsCount.toString(), + style: TextStyle( + color: Colors.white, + fontFamily: "Poppins", + fontSize: 10.f, + fontWeight: FontWeight.w600, + ), + textAlign: TextAlign.center, + ), ), + ) + : SizedBox.shrink(), + ]), + Utils.buildSvgWithAssets(icon: AppAssets.location, height: 24.h, width: 24.w).onPress(() { + // openIndoorNavigationBottomSheet(context); + showCommonBottomSheetWithoutHeight( + context, + title: LocaleKeys.contactUs.tr(), + child: ContactUs(), + callBackFunc: () {}, + isFullScreen: false, ); - }, - name: ('${appState.getAuthenticatedUser()!.firstName!} ${appState.getAuthenticatedUser()!.lastName!}'), - // imageUrl: appState.getAuthenticatedUser()?.gender == 1 ? AppAssets.maleImg : AppAssets.femaleImg, - imageUrl: appState.getAuthenticatedUser()?.gender == 1 - ? ((appState.getAuthenticatedUser()?.age ?? 0) < 7 ? AppAssets.babyBoyImg : AppAssets.maleImg) - : ((appState.getAuthenticatedUser()?.age ?? 0) < 7 ? AppAssets.babyGirlImg : AppAssets.femaleImg), - ).expanded - : CustomButton( - text: LocaleKeys.loginOrRegister.tr(context: context), - onPressed: () async { - await authVM.onLoginPressed(); - // Navigator.pushReplacementNamed( - // // context, - // context, - // AppRoutes.zoomCallPage, - // // arguments: CallArguments(appointmentID, "111", "Patient", "40", "1", true, 1), - // arguments: CallArguments("test123", "123", "Patient", "40", "0", true, 1), - // // arguments: CallArguments("SmallDailyStandup9875", "123", "Patient", "40", "0", false, int.parse(widget.incomingCallData!.appointmentNo!)), - // ); - }, - backgroundColor: AppColors.secondaryLightRedColor, - borderColor: AppColors.secondaryLightRedColor, - textColor: AppColors.primaryRedColor, - fontSize: 14.f, - fontWeight: FontWeight.w600, - borderRadius: 12.r, - padding: EdgeInsets.fromLTRB(12.h, 0, 12.h, 0), - height: 40.h, + }), + // Utils.buildSvgWithAssets(icon: AppAssets.contact_icon, height: 24.h, width: 24.h).onPress(() { + // showCommonBottomSheetWithoutHeight( + // context, + // title: LocaleKeys.contactUs.tr(), + // child: ContactUs(), + // callBackFunc: () {}, + // isFullScreen: false, + // ); + // }), + !appState.isAuthenticated + ? Utils.buildSvgWithAssets(icon: appState.isArabic() ? AppAssets.enLangIcon : AppAssets.arLangIcon, height: 24.h, width: 24.h).onPress(() { + context.setLocale(appState.isArabic() ? Locale('en', 'US') : Locale('ar', 'SA')); + }) + : SizedBox.shrink() + ], + ); + }), + ], + ).paddingSymmetrical(24.h, 0.h), + !appState.isAuthenticated + ? Container( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 24.r, + hasShadow: false, ), - Consumer(builder: (context, todoSectionVM, child) { - return Row( - mainAxisSize: MainAxisSize.min, - spacing: 18.h, - children: [ - Stack(clipBehavior: Clip.none, children: [ - if (appState.isAuthenticated) - Utils.buildSvgWithAssets(icon: AppAssets.bell, height: 24.h, width: 24.h).onPress(() async { - if (appState.isAuthenticated) { - notificationsViewModel.setNotificationStatusID(2); - notificationsViewModel.getAllNotifications(); - Navigator.of(context).push( - CustomPageRoute( - page: NotificationsListPage(), - // page: LoginScreen(), - ), - ); - } else { - await authVM.onLoginPressed(); - } - }), - (appState.isAuthenticated && (int.parse(todoSectionVM.notificationsCount ?? "0") > 0)) - ? Positioned( - right: appState.isArabic() ? 8.w : -8.w, - top: -8.h, - // left: 4.h, - // bottom: 4.h, - child: Container( - width: 18.w, - height: 18.h, - padding: EdgeInsets.all(2), - decoration: BoxDecoration( - color: AppColors.primaryRedColor, - borderRadius: BorderRadius.circular(20.r), - ), - child: Text( - todoSectionVM.notificationsCount.toString(), - style: TextStyle( - color: Colors.white, fontFamily: "Poppins", fontSize: 10.f, fontWeight: FontWeight.w600,), - textAlign: TextAlign.center, - ), - ), - ) - : SizedBox.shrink(), - ]), - Utils.buildSvgWithAssets(icon: AppAssets.location, height: 24.h, width: 24.w).onPress(() { - // openIndoorNavigationBottomSheet(context); - showCommonBottomSheetWithoutHeight( - context, - title: LocaleKeys.contactUs.tr(), - child: ContactUs(), - callBackFunc: () {}, - isFullScreen: false, - ); - }), - // Utils.buildSvgWithAssets(icon: AppAssets.contact_icon, height: 24.h, width: 24.h).onPress(() { - // showCommonBottomSheetWithoutHeight( - // context, - // title: LocaleKeys.contactUs.tr(), - // child: ContactUs(), - // callBackFunc: () {}, - // isFullScreen: false, - // ); - // }), - !appState.isAuthenticated - ? Utils.buildSvgWithAssets(icon: appState.isArabic() ? AppAssets.enLangIcon : AppAssets.arLangIcon, height: 24.h, width: 24.h).onPress(() { - context.setLocale(appState.isArabic() ? Locale('en', 'US') : Locale('ar', 'SA')); - }) - : SizedBox.shrink() - ], - ); - }), - ], - ).paddingSymmetrical(24.h, 0.h), - !appState.isAuthenticated - ? Container( - decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - color: AppColors.whiteColor, - borderRadius: 24.r, - hasShadow: false, - ), - child: Padding( - padding: EdgeInsets.all(16.h), - child: Row( + child: Padding( + padding: EdgeInsets.all(16.h), + child: Row( + children: [ + Utils.buildSvgWithAssets( + width: 50.w, + height: 60.h, + icon: AppAssets.symptomCheckerIcon, + fit: BoxFit.contain, + ), + SizedBox(width: 12.w), + Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - Utils.buildSvgWithAssets( - width: 50.w, - height: 60.h, - icon: AppAssets.symptomCheckerIcon, - fit: BoxFit.contain, + LocaleKeys.howAreYouFeelingToday.tr(context: context).toText14(isBold: true), + LocaleKeys.checkYourSymptomsWithScale.tr(context: context).toText12(isBold: true), + SizedBox(height: 14.h), + CustomButton( + text: LocaleKeys.checkYourSymptoms.tr(context: context), + onPressed: () async { + context.navigateWithName(AppRoutes.userInfoSelection); + }, + padding: EdgeInsetsGeometry.zero, + backgroundColor: AppColors.primaryRedColor, + borderColor: AppColors.primaryRedColor, + textColor: Colors.white, + fontSize: 14.f, + fontWeight: FontWeight.w600, + borderRadius: 12.r, + height: 40.h, ), - SizedBox(width: 12.w), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - LocaleKeys.howAreYouFeelingToday.tr(context: context).toText14(isBold: true), - LocaleKeys.checkYourSymptomsWithScale.tr(context: context).toText12(isBold: true), - SizedBox(height: 14.h), - CustomButton( - text: LocaleKeys.checkYourSymptoms.tr(context: context), - onPressed: () async { - context.navigateWithName(AppRoutes.userInfoSelection); - }, - padding: EdgeInsetsGeometry.zero, - backgroundColor: AppColors.primaryRedColor, - borderColor: AppColors.primaryRedColor, - textColor: Colors.white, - fontSize: 14.f, - fontWeight: FontWeight.w600, - borderRadius: 12.r, - height: 40.h, - ), - ], - ).expanded ], - ), - ), - ).paddingSymmetrical(24.w, 0.h) - : SizedBox.shrink(), - appState.isAuthenticated - ? Column( + ).expanded + ], + ), + ), + ).paddingSymmetrical(24.w, 0.h) + : SizedBox.shrink(), + appState.isAuthenticated + ? Column( + children: [ + SizedBox(height: 12.h), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - SizedBox(height: 12.h), + LocaleKeys.appointmentsAndVisits.tr(context: context).toText16(isBold: true), Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - LocaleKeys.appointmentsAndVisits.tr(context: context).toText16(isBold: true), - Row( - children: [ - LocaleKeys.viewAll.tr(context: context).toText14(color: AppColors.primaryRedColor, isBold: true), - SizedBox(width: 2.h), - Icon(Icons.arrow_forward_ios, color: AppColors.primaryRedColor, size: 14.h), - ], - ), + LocaleKeys.viewAll.tr(context: context).toText14(color: AppColors.primaryRedColor, isBold: true), + SizedBox(width: 2.h), + Icon(Icons.arrow_forward_ios, color: AppColors.primaryRedColor, size: 14.h), ], - ).paddingSymmetrical(24.h, 0.h).onPress(() { - myAppointmentsViewModel.onTabChange(0); - myAppointmentsViewModel.updateListWRTTab(0); - Navigator.of(context).push(CustomPageRoute(page: MyAppointmentsPage())); - }), - Consumer3( - builder: (context, myAppointmentsVM, immediateLiveCareVM, todoSectionVM, child) { - return myAppointmentsVM.isMyAppointmentsLoading - ? Container( - decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - color: AppColors.whiteColor, - borderRadius: 24.r, - hasShadow: true, - ), - child: AppointmentCard( - patientAppointmentHistoryResponseModel: PatientAppointmentHistoryResponseModel(), - myAppointmentsViewModel: myAppointmentsViewModel, - bookAppointmentsViewModel: bookAppointmentsViewModel, - isLoading: true, - isFromHomePage: true, - ), - ).paddingSymmetrical(24.h, 16.h) - : myAppointmentsVM.patientAppointmentsHistoryList.isNotEmpty - ? myAppointmentsVM.patientAppointmentsHistoryList.length == 1 - ? Container( - decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - color: AppColors.whiteColor, - borderRadius: 24.r, - hasShadow: true, - ), - child: AppointmentCard( - patientAppointmentHistoryResponseModel: myAppointmentsVM.patientAppointmentsHistoryList.first, - myAppointmentsViewModel: myAppointmentsViewModel, - bookAppointmentsViewModel: bookAppointmentsViewModel, - isLoading: false, - isFromHomePage: true, - ), - ).paddingSymmetrical(24.h, 0.h) - : isTablet - ? SizedBox( - height: isFoldable ? 290.h : 255.h, - child: ListView.separated( - scrollDirection: Axis.horizontal, - itemCount: 3, - shrinkWrap: true, - padding: EdgeInsets.only(left: 16.h, right: 16.h), - itemBuilder: (context, index) { - return SizedBox( - height: 255.h, - width: 250.w, - child: getIndexSwiperCard(index), - ); - // return AnimationConfiguration.staggeredList( - // position: index, - // duration: const Duration(milliseconds: 1000), - // child: SlideAnimation( - // horizontalOffset: 100.0, - // child: FadeInAnimation( - // child: SizedBox( - // height: 255.h, - // width: 250.w, - // child: getIndexSwiperCard(index), - // ), - // ), - // ), - // ); - }, - separatorBuilder: (BuildContext cxt, int index) => SizedBox( - width: 10.w, - ), - ), - ) - : SizedBox( - height: 255.h + 20 + 30, // itemHeight + shadow padding (10 top + 10 bottom) + pagination dots space - child: Swiper( + ), + ], + ).paddingSymmetrical(24.h, 0.h).onPress(() { + myAppointmentsViewModel.onTabChange(0); + myAppointmentsViewModel.updateListWRTTab(0); + Navigator.of(context).push(CustomPageRoute(page: MyAppointmentsPage())); + }), + Consumer3( + builder: (context, myAppointmentsVM, immediateLiveCareVM, todoSectionVM, child) { + return myAppointmentsVM.isMyAppointmentsLoading + ? Container( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 24.r, + hasShadow: true, + ), + child: AppointmentCard( + patientAppointmentHistoryResponseModel: PatientAppointmentHistoryResponseModel(), + myAppointmentsViewModel: myAppointmentsViewModel, + bookAppointmentsViewModel: bookAppointmentsViewModel, + isLoading: true, + isFromHomePage: true, + ), + ).paddingSymmetrical(24.h, 16.h) + : myAppointmentsVM.patientAppointmentsHistoryList.isNotEmpty + ? myAppointmentsVM.patientAppointmentsHistoryList.length == 1 + ? Container( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 24.r, + hasShadow: true, + ), + child: AppointmentCard( + patientAppointmentHistoryResponseModel: myAppointmentsVM.patientAppointmentsHistoryList.first, + myAppointmentsViewModel: myAppointmentsViewModel, + bookAppointmentsViewModel: bookAppointmentsViewModel, + isLoading: false, + isFromHomePage: true, + ), + ).paddingSymmetrical(24.h, 0.h) + : isTablet + ? SizedBox( + height: isFoldable ? 290.h : 255.h, + child: ListView.separated( + scrollDirection: Axis.horizontal, + itemCount: 3, + shrinkWrap: true, + padding: EdgeInsets.only(left: 16.h, right: 16.h), + itemBuilder: (context, index) { + return SizedBox( + height: 255.h, + width: 250.w, + child: getIndexSwiperCard(index), + ); + // return AnimationConfiguration.staggeredList( + // position: index, + // duration: const Duration(milliseconds: 1000), + // child: SlideAnimation( + // horizontalOffset: 100.0, + // child: FadeInAnimation( + // child: SizedBox( + // height: 255.h, + // width: 250.w, + // child: getIndexSwiperCard(index), + // ), + // ), + // ), + // ); + }, + separatorBuilder: (BuildContext cxt, int index) => + SizedBox( + width: 10.w, + ), + ), + ) + : SizedBox( + height: 255.h + 20 + 30, // itemHeight + shadow padding (10 top + 10 bottom) + pagination dots space + child: Swiper( itemCount: myAppointmentsVM.isMyAppointmentsLoading ? 3 : myAppointmentsVM.patientAppointmentsHistoryList.length < 3 @@ -476,309 +509,317 @@ class _LandingPageState extends State { ); }, ), - ) - : Container( - width: double.infinity, - decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r, hasShadow: true), - child: Padding( - padding: EdgeInsets.all(16.h), - child: Column( - children: [ - Utils.buildSvgWithAssets(icon: AppAssets.home_calendar_icon, width: 32.h, height: 32.h), - SizedBox(height: 12.h), - LocaleKeys.noUpcomingAppointmentPleaseBook.tr(context: context).toText12(isCenter: true), - SizedBox(height: 12.h), - CustomButton( - text: LocaleKeys.bookAppo.tr(context: context), - onPressed: () { - getIt.get().onTabChanged(0); - Navigator.of(context).push(CustomPageRoute(page: BookAppointmentPage())); - }, - backgroundColor: Color(0xffFEE9EA), - borderColor: Color(0xffFEE9EA), - textColor: Color(0xffED1C2B), - fontSize: 14.f, - fontWeight: FontWeight.w600, - padding: EdgeInsets.fromLTRB(10.h, 0, 10.h, 0), - icon: AppAssets.add_icon, - iconColor: AppColors.primaryRedColor, - height: 40.h, - ), - ], - ), - ), - ).paddingSymmetrical(24.h, 16.h); - }, - ), - - // Consumer for ER Online Check-In pending request - // Consumer( - // builder: (context, emergencyServicesVM, child) { - // return emergencyServicesVM.patientHasAdvanceERBalance - // ? Column( - // children: [ - // SizedBox(height: 16.h), - // Container( - // decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - // color: AppColors.whiteColor, - // borderRadius: 20.r, - // hasShadow: false, - // side: BorderSide(color: AppColors.primaryRedColor, width: 3.h), - // ), - // width: double.infinity, - // child: Padding( - // padding: EdgeInsets.all(16.h), - // child: Column( - // crossAxisAlignment: CrossAxisAlignment.start, - // children: [ - // // Row( - // // mainAxisAlignment: MainAxisAlignment.spaceBetween, - // // children: [ - // // AppCustomChipWidget( - // // labelText: LocaleKeys.erOnlineCheckInRequest.tr(context: context), - // // backgroundColor: AppColors.primaryRedColor.withValues(alpha: 0.10), - // // textColor: AppColors.primaryRedColor, - // // ), - // // Utils.buildSvgWithAssets(icon: AppAssets.appointment_checkin_icon, width: 24.h, height: 24.h, iconColor: AppColors.primaryRedColor), - // // ], - // // ), - // SizedBox(height: 8.h), - // Row( - // mainAxisAlignment: MainAxisAlignment.spaceBetween, - // children: [ - // LocaleKeys.youHaveEROnlineCheckInRequest.tr(context: context).toText12(isBold: true), - // Transform.flip( - // flipX: getIt.get().isArabic(), - // child: Utils.buildSvgWithAssets( - // icon: AppAssets.forward_arrow_icon_small, - // iconColor: AppColors.blackColor, - // width: 20.h, - // height: 15.h, - // fit: BoxFit.contain, - // ), - // ), - // ], - // ), - // ], - // ), - // ), - // ).paddingSymmetrical(24.h, 0.h).onPress(() { - // Navigator.of(context).push(CustomPageRoute(page: ErOnlineCheckinHome())); - // // context.read().navigateToEROnlineCheckIn(); - // }), - // SizedBox(height: 12.h), - // ], - // ) - // : SizedBox(height: 0.h); - // }, - // ), - SizedBox(height: 16.h), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - LocaleKeys.quickLinks.tr(context: context).toText16(isBold: true), - Row( - children: [ - LocaleKeys.viewMedicalFile.tr(context: context).toText12(color: AppColors.primaryRedColor, isBold: true), - SizedBox(width: 2.h), - Icon(Icons.arrow_forward_ios, color: AppColors.primaryRedColor, size: 14.h), - ], - ), - ], - ).paddingSymmetrical(24.h, 0.h).onPress(() { - Navigator.of(context).push(CustomPageRoute(page: MedicalFilePage())); - }), - SizedBox(height: 16.h), - Container( - // height: 121.h, - decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r), - child: Column( - children: [ - todoSectionViewModel.patientAncillaryOrdersList.isNotEmpty - ? Container( - height: 50.h, - decoration: ShapeDecoration( - color: AppColors.eReferralCardColor.withAlpha(50), - shape: SmoothRectangleBorder( - borderRadius: BorderRadius.only(topLeft: Radius.circular(24), topRight: Radius.circular(24)), - smoothness: 1, - ), - ), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - LocaleKeys.pendingAncillaryOrders - .tr(context: context) - .toText14(color: AppColors.eReferralCardColor, isBold: true) - .paddingSymmetrical(24.h, 0.h), - CustomButton( - text: LocaleKeys.view.tr(context: context), - onPressed: () { - getIt.get().setIsAncillaryOrdersNeedReloading(true); - Navigator.of(context).push( - CustomPageRoute( - page: ToDoPage(), + ) + : Container( + width: double.infinity, + decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r, hasShadow: true), + child: Padding( + padding: EdgeInsets.all(16.h), + child: Column( + children: [ + Utils.buildSvgWithAssets(icon: AppAssets.home_calendar_icon, width: 32.h, height: 32.h), + SizedBox(height: 12.h), + LocaleKeys.noUpcomingAppointmentPleaseBook.tr(context: context).toText12(isCenter: true), + SizedBox(height: 12.h), + CustomButton( + text: LocaleKeys.bookAppo.tr(context: context), + onPressed: () { + getIt.get().onTabChanged(0); + Navigator.of(context).push(CustomPageRoute(page: BookAppointmentPage())); + }, + backgroundColor: Color(0xffFEE9EA), + borderColor: Color(0xffFEE9EA), + textColor: Color(0xffED1C2B), + fontSize: 14.f, + fontWeight: FontWeight.w600, + padding: EdgeInsets.fromLTRB(10.h, 0, 10.h, 0), + icon: AppAssets.add_icon, + iconColor: AppColors.primaryRedColor, + height: 40.h, ), - ); - }, - backgroundColor: AppColors.eReferralCardColor, - borderColor: AppColors.eReferralCardColor, - textColor: AppColors.whiteColor, - fontSize: 10.f, - fontWeight: FontWeight.w600, - borderRadius: 8, - padding: EdgeInsets.fromLTRB(15, 0, 15, 0), - height: 30.h, - ).paddingSymmetrical(24.h, 0.h), - ], - ), - ) - : SizedBox.shrink(), - SizedBox( - height: 92.h + 32.h - 4.h, - child: RawScrollbar( - controller: _horizontalScrollController, - thumbVisibility: true, - radius: Radius.circular(10.0), - thumbColor: AppColors.primaryRedColor, - trackVisibility: true, - trackColor: Color(0xffD9D9D9), - trackBorderColor: Colors.transparent, - trackRadius: Radius.circular(10.0), - padding: EdgeInsets.only(top: 92.h + 32.h, left: MediaQuery.sizeOf(context).width / 2.5 - 10, right: MediaQuery.sizeOf(context).width / 2.5 - 10), - child: ListView.separated( - scrollDirection: Axis.horizontal, - itemCount: LandingPageData.getLoggedInServiceCardsList.length, - shrinkWrap: true, - controller: _horizontalScrollController, - padding: EdgeInsets.only(left: 0.h, right: 0.h, top: 16.h, bottom: 12.h), - itemBuilder: (context, index) { - return AnimationConfiguration.staggeredList( - position: index, - duration: const Duration(milliseconds: 1000), - child: SlideAnimation( - horizontalOffset: 100.0, - child: FadeInAnimation( - child: SmallServiceCard( - icon: LandingPageData.getLoggedInServiceCardsList[index].icon, - title: LandingPageData.getLoggedInServiceCardsList[index].title, - subtitle: LandingPageData.getLoggedInServiceCardsList[index].subtitle, - iconColor: LandingPageData.getLoggedInServiceCardsList[index].iconColor!, - textColor: LandingPageData.getLoggedInServiceCardsList[index].textColor, - backgroundColor: LandingPageData.getLoggedInServiceCardsList[index].backgroundColor, - isBold: LandingPageData.getLoggedInServiceCardsList[index].isBold, - serviceName: LandingPageData.getLoggedInServiceCardsList[index].serviceName, + ], ), ), + ).paddingSymmetrical(24.h, 16.h); + }, + ), + + // Consumer for ER Online Check-In pending request + // Consumer( + // builder: (context, emergencyServicesVM, child) { + // return emergencyServicesVM.patientHasAdvanceERBalance + // ? Column( + // children: [ + // SizedBox(height: 16.h), + // Container( + // decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + // color: AppColors.whiteColor, + // borderRadius: 20.r, + // hasShadow: false, + // side: BorderSide(color: AppColors.primaryRedColor, width: 3.h), + // ), + // width: double.infinity, + // child: Padding( + // padding: EdgeInsets.all(16.h), + // child: Column( + // crossAxisAlignment: CrossAxisAlignment.start, + // children: [ + // // Row( + // // mainAxisAlignment: MainAxisAlignment.spaceBetween, + // // children: [ + // // AppCustomChipWidget( + // // labelText: LocaleKeys.erOnlineCheckInRequest.tr(context: context), + // // backgroundColor: AppColors.primaryRedColor.withValues(alpha: 0.10), + // // textColor: AppColors.primaryRedColor, + // // ), + // // Utils.buildSvgWithAssets(icon: AppAssets.appointment_checkin_icon, width: 24.h, height: 24.h, iconColor: AppColors.primaryRedColor), + // // ], + // // ), + // SizedBox(height: 8.h), + // Row( + // mainAxisAlignment: MainAxisAlignment.spaceBetween, + // children: [ + // LocaleKeys.youHaveEROnlineCheckInRequest.tr(context: context).toText12(isBold: true), + // Transform.flip( + // flipX: getIt.get().isArabic(), + // child: Utils.buildSvgWithAssets( + // icon: AppAssets.forward_arrow_icon_small, + // iconColor: AppColors.blackColor, + // width: 20.h, + // height: 15.h, + // fit: BoxFit.contain, + // ), + // ), + // ], + // ), + // ], + // ), + // ), + // ).paddingSymmetrical(24.h, 0.h).onPress(() { + // Navigator.of(context).push(CustomPageRoute(page: ErOnlineCheckinHome())); + // // context.read().navigateToEROnlineCheckIn(); + // }), + // SizedBox(height: 12.h), + // ], + // ) + // : SizedBox(height: 0.h); + // }, + // ), + SizedBox(height: 16.h), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + LocaleKeys.quickLinks.tr(context: context).toText16(isBold: true), + Row( + children: [ + LocaleKeys.viewMedicalFile.tr(context: context).toText12(color: AppColors.primaryRedColor, isBold: true), + SizedBox(width: 2.h), + Icon(Icons.arrow_forward_ios, color: AppColors.primaryRedColor, size: 14.h), + ], + ), + ], + ).paddingSymmetrical(24.h, 0.h).onPress(() { + Navigator.of(context).push(CustomPageRoute(page: MedicalFilePage())); + }), + SizedBox(height: 16.h), + Consumer(builder: (BuildContext context, TodoSectionViewModel todoSectionVM, Widget? child) { + return Container( + // height: 121.h, + decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r), + child: Column( + children: [ + todoSectionVM.patientAncillaryOrdersList.isNotEmpty + ? Container( + height: 50.h, + decoration: ShapeDecoration( + color: AppColors.eReferralCardColor.withAlpha(50), + shape: SmoothRectangleBorder( + borderRadius: BorderRadius.only(topLeft: Radius.circular(24), topRight: Radius.circular(24)), + smoothness: 1, + ), + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + LocaleKeys.pendingAncillaryOrders.tr(context: context).toText14(color: AppColors.eReferralCardColor, isBold: true).paddingSymmetrical(24.h, 0.h), + CustomButton( + text: LocaleKeys.view.tr(context: context), + onPressed: () { + todoSectionVM.setIsAncillaryOrdersNeedReloading(true); + Navigator.of(context).push( + CustomPageRoute( + page: ToDoPage(), ), ); }, - separatorBuilder: (BuildContext cxt, int index) => 10.width, - ).paddingSymmetrical(16.h, 0.h), - ), + backgroundColor: AppColors.eReferralCardColor, + borderColor: AppColors.eReferralCardColor, + textColor: AppColors.whiteColor, + fontSize: 10.f, + fontWeight: FontWeight.w600, + borderRadius: 8, + padding: EdgeInsets.fromLTRB(15, 0, 15, 0), + height: 30.h, + ).paddingSymmetrical(24.h, 0.h), + ], ), - SizedBox(height: 16.h), - ], - ), - ).paddingSymmetrical(24.h, 0.h), - ], - ) - : Container( - decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r), - child: Column( - children: [ - SizedBox( - height: 92.h + 32.h - 4.h, - child: RawScrollbar( - controller: _horizontalScrollController, - thumbVisibility: true, - radius: Radius.circular(10.0), - thumbColor: AppColors.primaryRedColor, - trackVisibility: true, - trackColor: Color(0xffD9D9D9), - trackBorderColor: Colors.transparent, - trackRadius: Radius.circular(10.0), - padding: EdgeInsets.only(top: 92.h + 32.h, left: MediaQuery.sizeOf(context).width / 2.5 - 10, right: MediaQuery.sizeOf(context).width / 2.5 - 10), - child: ListView.separated( - scrollDirection: Axis.horizontal, - itemCount: LandingPageData.getNotLoggedInServiceCardsList.length, - shrinkWrap: true, + ) + : SizedBox.shrink(), + SizedBox( + height: 92.h + 32.h - 4.h, + child: RawScrollbar( controller: _horizontalScrollController, - padding: EdgeInsets.only(left: 0.h, right: 0.h, top: 16.h, bottom: 12.h), - itemBuilder: (context, index) { - return AnimationConfiguration.staggeredList( - position: index, - duration: const Duration(milliseconds: 1000), - child: SlideAnimation( - horizontalOffset: 100.0, - child: FadeInAnimation( - child: SmallServiceCard( - serviceName: LandingPageData.getNotLoggedInServiceCardsList[index].serviceName, - icon: LandingPageData.getNotLoggedInServiceCardsList[index].icon, - title: LandingPageData.getNotLoggedInServiceCardsList[index].title, - subtitle: LandingPageData.getNotLoggedInServiceCardsList[index].subtitle, - iconColor: LandingPageData.getNotLoggedInServiceCardsList[index].iconColor!, - textColor: LandingPageData.getNotLoggedInServiceCardsList[index].textColor, - backgroundColor: LandingPageData.getNotLoggedInServiceCardsList[index].backgroundColor, - isBold: LandingPageData.getNotLoggedInServiceCardsList[index].isBold, + thumbVisibility: true, + radius: Radius.circular(10.0), + thumbColor: AppColors.primaryRedColor, + trackVisibility: true, + trackColor: Color(0xffD9D9D9), + trackBorderColor: Colors.transparent, + trackRadius: Radius.circular(10.0), + padding: EdgeInsets.only(top: 92.h + 32.h, left: MediaQuery + .sizeOf(context) + .width / 2.5 - 10, right: MediaQuery + .sizeOf(context) + .width / 2.5 - 10), + child: ListView.separated( + scrollDirection: Axis.horizontal, + itemCount: LandingPageData.getLoggedInServiceCardsList.length, + shrinkWrap: true, + controller: _horizontalScrollController, + padding: EdgeInsets.only(left: 0.h, right: 0.h, top: 16.h, bottom: 12.h), + itemBuilder: (context, index) { + return AnimationConfiguration.staggeredList( + position: index, + duration: const Duration(milliseconds: 1000), + child: SlideAnimation( + horizontalOffset: 100.0, + child: FadeInAnimation( + child: SmallServiceCard( + icon: LandingPageData.getLoggedInServiceCardsList[index].icon, + title: LandingPageData.getLoggedInServiceCardsList[index].title, + subtitle: LandingPageData.getLoggedInServiceCardsList[index].subtitle, + iconColor: LandingPageData.getLoggedInServiceCardsList[index].iconColor!, + textColor: LandingPageData.getLoggedInServiceCardsList[index].textColor, + backgroundColor: LandingPageData.getLoggedInServiceCardsList[index].backgroundColor, + isBold: LandingPageData.getLoggedInServiceCardsList[index].isBold, + serviceName: LandingPageData.getLoggedInServiceCardsList[index].serviceName, + ), ), ), - ), - ); - }, - separatorBuilder: (BuildContext cxt, int index) => 0.width, - ).paddingSymmetrical(16.h, 0.h), + ); + }, + separatorBuilder: (BuildContext cxt, int index) => 10.width, + ).paddingSymmetrical(16.h, 0.h), + ), ), - ), - SizedBox(height: 16.h), - ], - ), - ).paddingSymmetrical(24.h, 0.h), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - LocaleKeys.services2.tr(context: context).toText18(isBold: true), - Row( + SizedBox(height: 16.h), + ], + ), + ).paddingSymmetrical(24.h, 0.h); + }), + ], + ) + : Container( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r), + child: Column( children: [ - LocaleKeys.viewAllServices.tr(context: context).toText14(color: AppColors.primaryRedColor, isBold: true), - SizedBox(width: 2.h), - Icon(Icons.arrow_forward_ios, color: AppColors.primaryRedColor, size: 14.h), + SizedBox( + height: 92.h + 32.h - 4.h, + child: RawScrollbar( + controller: _horizontalScrollController, + thumbVisibility: true, + radius: Radius.circular(10.0), + thumbColor: AppColors.primaryRedColor, + trackVisibility: true, + trackColor: Color(0xffD9D9D9), + trackBorderColor: Colors.transparent, + trackRadius: Radius.circular(10.0), + padding: EdgeInsets.only(top: 92.h + 32.h, left: MediaQuery + .sizeOf(context) + .width / 2.5 - 10, right: MediaQuery + .sizeOf(context) + .width / 2.5 - 10), + child: ListView.separated( + scrollDirection: Axis.horizontal, + itemCount: LandingPageData.getNotLoggedInServiceCardsList.length, + shrinkWrap: true, + controller: _horizontalScrollController, + padding: EdgeInsets.only(left: 0.h, right: 0.h, top: 16.h, bottom: 12.h), + itemBuilder: (context, index) { + return AnimationConfiguration.staggeredList( + position: index, + duration: const Duration(milliseconds: 1000), + child: SlideAnimation( + horizontalOffset: 100.0, + child: FadeInAnimation( + child: SmallServiceCard( + serviceName: LandingPageData.getNotLoggedInServiceCardsList[index].serviceName, + icon: LandingPageData.getNotLoggedInServiceCardsList[index].icon, + title: LandingPageData.getNotLoggedInServiceCardsList[index].title, + subtitle: LandingPageData.getNotLoggedInServiceCardsList[index].subtitle, + iconColor: LandingPageData.getNotLoggedInServiceCardsList[index].iconColor!, + textColor: LandingPageData.getNotLoggedInServiceCardsList[index].textColor, + backgroundColor: LandingPageData.getNotLoggedInServiceCardsList[index].backgroundColor, + isBold: LandingPageData.getNotLoggedInServiceCardsList[index].isBold, + ), + ), + ), + ); + }, + separatorBuilder: (BuildContext cxt, int index) => 0.width, + ).paddingSymmetrical(16.h, 0.h), + ), + ), + SizedBox(height: 16.h), ], - ).onPress(() { - Navigator.of(context).push(CustomPageRoute(page: ServicesPage())); - }), - ], - ).paddingSymmetrical(24.w, 0.h), - SizedBox( - height: 431.h, - child: ListView.separated( - scrollDirection: Axis.horizontal, - itemCount: LandingPageData.getServiceCardsList.length, - shrinkWrap: true, - padding: EdgeInsets.only(left: 24.w, right: 24.w), - itemBuilder: (context, index) { - return AnimationConfiguration.staggeredList( - position: index, - duration: const Duration(milliseconds: 1000), - child: SlideAnimation( - horizontalOffset: 100.0, - child: FadeInAnimation( - child: FadedLargeServiceCard( - serviceCardData: LandingPageData.getServiceCardsList[index], - image: LandingPageData.getServiceCardsList[index].icon, - title: LandingPageData.getServiceCardsList[index].title, - subtitle: LandingPageData.getServiceCardsList[index].subtitle, - icon: LandingPageData.getServiceCardsList[index].largeCardIcon, + ), + ).paddingSymmetrical(24.h, 0.h), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + LocaleKeys.services2.tr(context: context).toText18(isBold: true), + Row( + children: [ + LocaleKeys.viewAllServices.tr(context: context).toText14(color: AppColors.primaryRedColor, isBold: true), + SizedBox(width: 2.h), + Icon(Icons.arrow_forward_ios, color: AppColors.primaryRedColor, size: 14.h), + ], + ).onPress(() { + Navigator.of(context).push(CustomPageRoute(page: ServicesPage())); + }), + ], + ).paddingSymmetrical(24.w, 0.h), + SizedBox( + height: 431.h, + child: ListView.separated( + scrollDirection: Axis.horizontal, + itemCount: LandingPageData.getServiceCardsList.length, + shrinkWrap: true, + padding: EdgeInsets.only(left: 24.w, right: 24.w), + itemBuilder: (context, index) { + return AnimationConfiguration.staggeredList( + position: index, + duration: const Duration(milliseconds: 1000), + child: SlideAnimation( + horizontalOffset: 100.0, + child: FadeInAnimation( + child: FadedLargeServiceCard( + serviceCardData: LandingPageData.getServiceCardsList[index], + image: LandingPageData.getServiceCardsList[index].icon, + title: LandingPageData.getServiceCardsList[index].title, + subtitle: LandingPageData.getServiceCardsList[index].subtitle, + icon: LandingPageData.getServiceCardsList[index].largeCardIcon, + ), ), ), - ), - ); - }, - separatorBuilder: (BuildContext cxt, int index) => SizedBox(width: 16.w), + ); + }, + separatorBuilder: (BuildContext cxt, int index) => SizedBox(width: 16.w), + ), ), - ), - appState.isAuthenticated ? HabibWalletCard() : SizedBox(), - ], + appState.isAuthenticated ? HabibWalletCard() : SizedBox(), + ], + ), ), ), (appState.isAuthenticated && !insuranceVM.isInsuranceLoading && insuranceVM.isInsuranceExpired && insuranceVM.isInsuranceExpiryBannerShown) diff --git a/lib/widgets/input_widget.dart b/lib/widgets/input_widget.dart index e1010450..5b598c40 100644 --- a/lib/widgets/input_widget.dart +++ b/lib/widgets/input_widget.dart @@ -304,7 +304,7 @@ class TextInputWidget extends StatelessWidget { hintLocales: const [Locale('en', 'US')], enabled: isEnable, scrollPadding: EdgeInsets.zero, - keyboardType: isMultiline ? TextInputType.multiline : keyboardType, + keyboardType: isMultiline ? TextInputType.multiline : (isWalletAmountInput! ? const TextInputType.numberWithOptions(decimal: true) : keyboardType), controller: controller, readOnly: isReadOnly, textAlignVertical: TextAlignVertical.top, @@ -315,7 +315,12 @@ class TextInputWidget extends StatelessWidget { autofocus: autoFocus, textInputAction: TextInputAction.done, cursorHeight: isWalletAmountInput! ? 40.h : 20.h, - maxLength: isWalletAmountInput! ? 6 : 100, + maxLength: isWalletAmountInput! ? 7 : 100, + inputFormatters: isWalletAmountInput! + ? [ + _ThousandSeparatorInputFormatter(), + ] + : null, onTapOutside: (event) { FocusManager.instance.primaryFocus?.unfocus(); }, @@ -407,3 +412,63 @@ class TextInputWidget extends StatelessWidget { ); } } + +class _ThousandSeparatorInputFormatter extends TextInputFormatter { + @override + TextEditingValue formatEditUpdate( + TextEditingValue oldValue, + TextEditingValue newValue, + ) { + // Remove all commas to get the raw number + String newText = newValue.text.replaceAll(',', ''); + + // Allow only digits and one decimal point + if (newText.isNotEmpty && !RegExp(r'^\d*\.?\d{0,2}$').hasMatch(newText)) { + return oldValue; + } + + // Split into integer and decimal parts + String integerPart; + String decimalPart = ''; + + if (newText.contains('.')) { + final parts = newText.split('.'); + integerPart = parts[0]; + decimalPart = '.${parts[1]}'; + } else { + integerPart = newText; + } + + // Add thousand separators to the integer part + if (integerPart.isNotEmpty) { + final buffer = StringBuffer(); + int count = 0; + for (int i = integerPart.length - 1; i >= 0; i--) { + buffer.write(integerPart[i]); + count++; + if (count == 3 && i > 0) { + buffer.write(','); + count = 0; + } + } + integerPart = buffer.toString().split('').reversed.join(); + } + + final formatted = '$integerPart$decimalPart'; + + // Calculate new cursor position + int cursorOffset = newValue.selection.baseOffset; + // Count commas before cursor in the new formatted string + int commasInNew = ','.allMatches(formatted.substring(0, cursorOffset.clamp(0, formatted.length))).length; + // Count commas before cursor in the old value + int commasInOld = ','.allMatches(oldValue.text.substring(0, oldValue.selection.baseOffset.clamp(0, oldValue.text.length))).length; + int newCursorPos = cursorOffset + (commasInNew - commasInOld); + newCursorPos = newCursorPos.clamp(0, formatted.length); + + return TextEditingValue( + text: formatted, + selection: TextSelection.collapsed(offset: newCursorPos), + ); + } +} + -- 2.30.2 From 185f505ed98c73f4fefd55593461904cf50ec5b1 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Wed, 8 Apr 2026 02:10:53 +0300 Subject: [PATCH 3/3] pull down to refresh in appointment queue implemented --- .../my_appointments_view_model.dart | 1 + .../appointments/appointment_queue_page.dart | 310 +++++++++--------- .../book_appointment/select_doctor_page.dart | 10 +- 3 files changed, 152 insertions(+), 169 deletions(-) diff --git a/lib/features/my_appointments/my_appointments_view_model.dart b/lib/features/my_appointments/my_appointments_view_model.dart index 6ba27522..ede63ca9 100644 --- a/lib/features/my_appointments/my_appointments_view_model.dart +++ b/lib/features/my_appointments/my_appointments_view_model.dart @@ -930,6 +930,7 @@ class MyAppointmentsViewModel extends ChangeNotifier { isPatientHasQueueAppointment = false; isAppointmentQueueDetailsLoading = true; notifyListeners(); + final result = await myAppointmentsRepo.getPatientAppointmentQueueDetails( appointmentNo: patientArrivedAppointmentsHistoryList.first.appointmentNo, patientID: patientArrivedAppointmentsHistoryList.first.patientID); diff --git a/lib/presentation/appointments/appointment_queue_page.dart b/lib/presentation/appointments/appointment_queue_page.dart index a07a19dd..cc1c7fd1 100644 --- a/lib/presentation/appointments/appointment_queue_page.dart +++ b/lib/presentation/appointments/appointment_queue_page.dart @@ -33,178 +33,162 @@ class AppointmentQueuePage extends StatelessWidget { Expanded( child: CollapsingListView( title: LocaleKeys.queueing.tr(context: context), - child: SingleChildScrollView( - child: Padding( - padding: EdgeInsets.all(24.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - color: AppColors.whiteColor, - borderRadius: 20.h, - hasShadow: false, - side: BorderSide( - color: myAppointmentsVM.isAppointmentQueueDetailsLoading - ? AppColors.whiteColor - : Utils.getCardBorderColor(myAppointmentsVM.currentQueueStatus), - width: 2.w), - ), - child: Padding( - padding: EdgeInsets.all(16.h), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, + child: RefreshIndicator( + color: AppColors.primaryRedColor, + onRefresh: () async { + await myAppointmentsVM.getPatientAppointmentQueueDetails(); + }, + child: SingleChildScrollView( + child: Padding( + padding: EdgeInsets.all(24.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 20.h, + hasShadow: false, + side: BorderSide( + color: myAppointmentsVM.isAppointmentQueueDetailsLoading ? AppColors.whiteColor : Utils.getCardBorderColor(myAppointmentsVM.currentQueueStatus), width: 2.w), + ), + child: Padding( + padding: EdgeInsets.all(16.h), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - AppCustomChipWidget( - labelText: myAppointmentsVM.currentQueueStatus == 0 ? LocaleKeys.inQueue.tr(context: context) : LocaleKeys.yourTurn.tr(context: context), - backgroundColor: Utils.getCardBorderColor(myAppointmentsVM.currentQueueStatus).withValues(alpha: 0.20), - textColor: Utils.getCardBorderColor(myAppointmentsVM.currentQueueStatus), - ), - Utils.buildSvgWithAssets(icon: AppAssets.waiting_icon, width: 24.h, height: 24.h), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + AppCustomChipWidget( + labelText: myAppointmentsVM.currentQueueStatus == 0 ? LocaleKeys.inQueue.tr(context: context) : LocaleKeys.yourTurn.tr(context: context), + backgroundColor: Utils.getCardBorderColor(myAppointmentsVM.currentQueueStatus).withValues(alpha: 0.20), + textColor: Utils.getCardBorderColor(myAppointmentsVM.currentQueueStatus), + ), + Utils.buildSvgWithAssets(icon: AppAssets.waiting_icon, width: 24.h, height: 24.h), + ], + ).toShimmer2(isShow: myAppointmentsVM.isAppointmentQueueDetailsLoading), + SizedBox(height: 10.h), + "Hala ${appState!.getAuthenticatedUser()!.firstName}!!!".toText16(isBold: true).toShimmer2(isShow: myAppointmentsVM.isAppointmentQueueDetailsLoading), + SizedBox(height: 8.h), + LocaleKeys.thankYouForPatience + .tr(context: context) + .toText12(isBold: true, color: AppColors.textColorLight) + .toShimmer2(isShow: myAppointmentsVM.isAppointmentQueueDetailsLoading), + SizedBox(height: 8.h), + myAppointmentsVM.currentPatientQueueDetails.queueNo!.toText32(isBold: true).toShimmer2(isShow: myAppointmentsVM.isAppointmentQueueDetailsLoading), + SizedBox(height: 8.h), + CustomButton( + text: Utils.getCardButtonText(myAppointmentsVM.currentQueueStatus, myAppointmentsVM.currentPatientQueueDetails.roomNo ?? ""), + onPressed: () {}, + backgroundColor: Utils.getCardButtonColor(myAppointmentsVM.currentQueueStatus), + borderColor: Utils.getCardButtonColor(myAppointmentsVM.currentQueueStatus).withValues(alpha: 0.01), + textColor: Utils.getCardButtonTextColor(myAppointmentsVM.currentQueueStatus), + fontSize: 12.f, + fontWeight: FontWeight.w600, + borderRadius: 12.r, + padding: EdgeInsets.symmetric(horizontal: 10.w), + height: 40.h, + iconColor: AppColors.whiteColor, + iconSize: 18.h, + ).toShimmer2(isShow: myAppointmentsVM.isAppointmentQueueDetailsLoading), ], - ).toShimmer2(isShow: myAppointmentsVM.isAppointmentQueueDetailsLoading), - SizedBox(height: 10.h), - "Hala ${appState!.getAuthenticatedUser()!.firstName}!!!" - .toText16(isBold: true) - .toShimmer2(isShow: myAppointmentsVM.isAppointmentQueueDetailsLoading), - SizedBox(height: 8.h), - LocaleKeys.thankYouForPatience.tr(context: context) - .toText12(isBold: true, color: AppColors.textColorLight) - .toShimmer2(isShow: myAppointmentsVM.isAppointmentQueueDetailsLoading), - SizedBox(height: 8.h), - myAppointmentsVM.currentPatientQueueDetails.queueNo! - .toText32(isBold: true) - .toShimmer2(isShow: myAppointmentsVM.isAppointmentQueueDetailsLoading), - SizedBox(height: 8.h), - CustomButton( - text: Utils.getCardButtonText( - myAppointmentsVM.currentQueueStatus, myAppointmentsVM.currentPatientQueueDetails.roomNo ?? ""), - onPressed: () {}, - backgroundColor: Utils.getCardButtonColor(myAppointmentsVM.currentQueueStatus), - borderColor: Utils.getCardButtonColor(myAppointmentsVM.currentQueueStatus).withValues(alpha: 0.01), - textColor: Utils.getCardButtonTextColor(myAppointmentsVM.currentQueueStatus), - fontSize: 12.f, - fontWeight: FontWeight.w600, - borderRadius: 12.r, - padding: EdgeInsets.symmetric(horizontal: 10.w), - height: 40.h, - iconColor: AppColors.whiteColor, - iconSize: 18.h, - ).toShimmer2(isShow: myAppointmentsVM.isAppointmentQueueDetailsLoading), - ], - ), - ), - ), - SizedBox(height: 16.h), - myAppointmentsVM.patientQueueDetailsList.isNotEmpty - ? Container( - decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - color: AppColors.whiteColor, - borderRadius: 20.h, - hasShadow: true, ), - child: Padding( - padding: EdgeInsets.all(16.h), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - LocaleKeys.servingNow.tr(context: context) - .toText16(isBold: true) - .toShimmer2(isShow: myAppointmentsVM.isAppointmentQueueDetailsLoading), - SizedBox(height: 18.h), - ListView.separated( - padding: EdgeInsets.zero, - shrinkWrap: true, - itemCount: myAppointmentsVM.patientQueueDetailsList.length, - physics: NeverScrollableScrollPhysics(), - itemBuilder: (BuildContext context, int index) { - return Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - myAppointmentsVM.patientQueueDetailsList[index].queueNo!.toText17(isBold: true), - Row( - crossAxisAlignment: CrossAxisAlignment.center, + ), + ), + SizedBox(height: 16.h), + myAppointmentsVM.patientQueueDetailsList.isNotEmpty + ? Container( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 20.h, + hasShadow: true, + ), + child: Padding( + padding: EdgeInsets.all(16.h), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + LocaleKeys.servingNow.tr(context: context).toText16(isBold: true).toShimmer2(isShow: myAppointmentsVM.isAppointmentQueueDetailsLoading), + SizedBox(height: 18.h), + ListView.separated( + padding: EdgeInsets.zero, + shrinkWrap: true, + itemCount: myAppointmentsVM.patientQueueDetailsList.length, + physics: NeverScrollableScrollPhysics(), + itemBuilder: (BuildContext context, int index) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, children: [ - "Room: ${myAppointmentsVM.patientQueueDetailsList[index].roomNo}" - .toText12(isBold: true), - SizedBox(width: 8.w), - AppCustomChipWidget( - deleteIcon: myAppointmentsVM.patientQueueDetailsList[index].callType == 1 - ? AppAssets.call_for_vitals - : AppAssets.call_for_doctor, - labelText: myAppointmentsVM.patientQueueDetailsList[index].callType == 1 - ? LocaleKeys.callForVitalSigns.tr(context: context) - : LocaleKeys.callForDoctor.tr(context: context), - iconColor: myAppointmentsVM.patientQueueDetailsList[index].callType == 1 - ? AppColors.primaryRedColor - : AppColors.successColor, - textColor: myAppointmentsVM.patientQueueDetailsList[index].callType == 1 - ? AppColors.primaryRedColor - : AppColors.successColor, - iconSize: 14.w, - backgroundColor: myAppointmentsVM.patientQueueDetailsList[index].callType == 1 - ? AppColors.primaryRedColor.withValues(alpha: 0.1) - : AppColors.successColor.withValues(alpha: 0.1), - labelPadding: EdgeInsetsDirectional.only(start: 8.h, end: -2.h), + myAppointmentsVM.patientQueueDetailsList[index].queueNo!.toText17(isBold: true), + Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + "Room: ${myAppointmentsVM.patientQueueDetailsList[index].roomNo}".toText12(isBold: true), + SizedBox(width: 8.w), + AppCustomChipWidget( + deleteIcon: myAppointmentsVM.patientQueueDetailsList[index].callType == 1 ? AppAssets.call_for_vitals : AppAssets.call_for_doctor, + labelText: myAppointmentsVM.patientQueueDetailsList[index].callType == 1 + ? LocaleKeys.callForVitalSigns.tr(context: context) + : LocaleKeys.callForDoctor.tr(context: context), + iconColor: myAppointmentsVM.patientQueueDetailsList[index].callType == 1 ? AppColors.primaryRedColor : AppColors.successColor, + textColor: myAppointmentsVM.patientQueueDetailsList[index].callType == 1 ? AppColors.primaryRedColor : AppColors.successColor, + iconSize: 14.w, + backgroundColor: myAppointmentsVM.patientQueueDetailsList[index].callType == 1 + ? AppColors.primaryRedColor.withValues(alpha: 0.1) + : AppColors.successColor.withValues(alpha: 0.1), + labelPadding: EdgeInsetsDirectional.only(start: 8.h, end: -2.h), + ), + ], ), ], - ), - ], - ); - }, - separatorBuilder: (BuildContext cxt, int index) => SizedBox(height: 8.h), - ).toShimmer2(isShow: myAppointmentsVM.isAppointmentQueueDetailsLoading), - ], - ), - ), - ) - : SizedBox.shrink(), - SizedBox(height: 16.h), - Container( - decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - color: AppColors.whiteColor, - borderRadius: 24.4, - hasShadow: true, - ), - child: Padding( - padding: EdgeInsets.all(16.h), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( + ); + }, + separatorBuilder: (BuildContext cxt, int index) => SizedBox(height: 8.h), + ).toShimmer2(isShow: myAppointmentsVM.isAppointmentQueueDetailsLoading), + ], + ), + ), + ) + : SizedBox.shrink(), + SizedBox(height: 16.h), + Container( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 24.4, + hasShadow: true, + ), + child: Padding( + padding: EdgeInsets.all(16.h), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - Utils.buildSvgWithAssets(icon: AppAssets.bulb_icon, width: 24.w, height: 24.h), - SizedBox(width: 8.w), - LocaleKeys.thingsToAskDoctor.tr(context: context).toText16(isBold: true), + Row( + children: [ + Utils.buildSvgWithAssets(icon: AppAssets.bulb_icon, width: 24.w, height: 24.h), + SizedBox(width: 8.w), + LocaleKeys.thingsToAskDoctor.tr(context: context).toText16(isBold: true), + ], + ), + SizedBox(height: 8.h), + "• ${LocaleKeys.improveOverallHealth.tr(context: context)}".toText12(isBold: true, color: AppColors.textColorLight), + SizedBox(height: 4.h), + "• ${LocaleKeys.routineScreenings.tr(context: context)}".toText12(isBold: true, color: AppColors.textColorLight), + SizedBox(height: 4.h), + "• ${LocaleKeys.whatIsThisMedicationFor.tr(context: context)}".toText12(isBold: true, color: AppColors.textColorLight), + SizedBox(height: 4.h), + "• ${LocaleKeys.sideEffectsToKnow.tr(context: context)}".toText12(isBold: true, color: AppColors.textColorLight), + SizedBox(height: 4.h), + "• ${LocaleKeys.whenFollowUp.tr(context: context)}".toText12(isBold: true, color: AppColors.textColorLight), + SizedBox(height: 16.h), ], - ), - SizedBox(height: 8.h), - "• ${LocaleKeys.improveOverallHealth.tr(context: context)}" - .toText12(isBold: true, color: AppColors.textColorLight), - SizedBox(height: 4.h), - "• ${LocaleKeys.routineScreenings.tr(context: context)}" - .toText12(isBold: true, color: AppColors.textColorLight), - SizedBox(height: 4.h), - "• ${LocaleKeys.whatIsThisMedicationFor.tr(context: context)}" - .toText12(isBold: true, color: AppColors.textColorLight), - SizedBox(height: 4.h), - "• ${LocaleKeys.sideEffectsToKnow.tr(context: context)}" - .toText12(isBold: true, color: AppColors.textColorLight), - SizedBox(height: 4.h), - "• ${LocaleKeys.whenFollowUp.tr(context: context)}" - .toText12(isBold: true, color: AppColors.textColorLight), - - SizedBox(height: 16.h), - ], - ).toShimmer2(isShow: myAppointmentsVM.isAppointmentQueueDetailsLoading), - ), + ).toShimmer2(isShow: myAppointmentsVM.isAppointmentQueueDetailsLoading), + ), + ), + ], ), - ], - ), + ), ), ), ), diff --git a/lib/presentation/book_appointment/select_doctor_page.dart b/lib/presentation/book_appointment/select_doctor_page.dart index 98cc550b..de2e2ae8 100644 --- a/lib/presentation/book_appointment/select_doctor_page.dart +++ b/lib/presentation/book_appointment/select_doctor_page.dart @@ -239,12 +239,10 @@ class _SelectDoctorPageState extends State { value: bookAppointmentsVM.isNearestAppointmentSelected, onChanged: (newValue) async { bookAppointmentsVM.setIsNearestAppointmentSelected(newValue); - if(newValue) { - bookAppointmentsVM.refreshDoctorsList(); - } - }, - ), - ], + bookAppointmentsVM.refreshDoctorsList(); + }, + ), + ], ) : SizedBox.shrink(), ListView.separated( -- 2.30.2