diff --git a/assets/images/png/female_icon.png b/assets/images/png/female_icon.png
new file mode 100644
index 0000000..b41a542
Binary files /dev/null and b/assets/images/png/female_icon.png differ
diff --git a/assets/images/png/male_icon.png b/assets/images/png/male_icon.png
new file mode 100644
index 0000000..fa518fb
Binary files /dev/null and b/assets/images/png/male_icon.png differ
diff --git a/assets/images/svg/calendar-grey.svg b/assets/images/svg/calendar-grey.svg
new file mode 100644
index 0000000..2bcc178
--- /dev/null
+++ b/assets/images/svg/calendar-grey.svg
@@ -0,0 +1,8 @@
+
diff --git a/assets/images/svg/gender.svg b/assets/images/svg/gender.svg
new file mode 100644
index 0000000..6819ba6
--- /dev/null
+++ b/assets/images/svg/gender.svg
@@ -0,0 +1,4 @@
+
diff --git a/assets/images/svg/ruler.svg b/assets/images/svg/ruler.svg
new file mode 100644
index 0000000..a2e8c11
--- /dev/null
+++ b/assets/images/svg/ruler.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/images/svg/tick.svg b/assets/images/svg/tick.svg
new file mode 100644
index 0000000..b6210c0
--- /dev/null
+++ b/assets/images/svg/tick.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/images/svg/weight-scale.svg b/assets/images/svg/weight-scale.svg
new file mode 100644
index 0000000..c3329ff
--- /dev/null
+++ b/assets/images/svg/weight-scale.svg
@@ -0,0 +1,3 @@
+
diff --git a/lib/core/app_assets.dart b/lib/core/app_assets.dart
index b369d62..2f806b6 100644
--- a/lib/core/app_assets.dart
+++ b/lib/core/app_assets.dart
@@ -195,8 +195,13 @@ class AppAssets {
static const String heart = '$svgBasePath/heart.svg';
static const String alertSquare = '$svgBasePath/alert-square.svg';
static const String arrowRight = '$svgBasePath/arrow-right.svg';
+ static const String tickIcon = '$svgBasePath/tick.svg';
// Symptoms Checker
+ static const String calendarGrey = '$svgBasePath/calendar-grey.svg';
+ static const String weightScale = '$svgBasePath/weight-scale.svg';
+ static const String rulerIcon = '$svgBasePath/ruler.svg';
+ static const String genderIcon = '$svgBasePath/gender.svg';
static const String bodyIcon = '$svgBasePath/body_icon.svg';
static const String rotateIcon = '$svgBasePath/rotate_icon.svg';
static const String refreshIcon = '$svgBasePath/refresh.svg';
@@ -218,6 +223,8 @@ class AppAssets {
static const String dummyUser = '$pngBasePath/dummy_user.png';
static const String comprehensiveCheckupEn = '$pngBasePath/cc_en.png';
static const String comprehensiveCheckupAr = '$pngBasePath/cc_er.png';
+ static const String maleIcon = '$pngBasePath/male_icon.png';
+ static const String femaleIcon = '$pngBasePath/female_icon.png';
static const String fullBodyFront = '$pngBasePath/full_body_front.png';
static const String fullBodyBack = '$pngBasePath/full_body_back.png';
@@ -236,9 +243,9 @@ class AppAnimations {
static const String splashLaunching = '$lottieBasePath/splash_launching.json';
static const String noData = '$lottieBasePath/Nodata.json';
static const String ripple = '$lottieBasePath/Ripple.json';
- static const String pending_loading_animation = '$lottieBasePath/pending_loading_animation.json';
+ static const String pendingLoadingAnimation = '$lottieBasePath/pending_loading_animation.json';
static const String ambulance = '$lottieBasePath/ambulance.json';
- static const String ambulance_alert = '$lottieBasePath/ambulance_alert.json';
- static const String rrt_ambulance = '$lottieBasePath/rrt_ambulance.json';
+ static const String ambulanceAlert = '$lottieBasePath/ambulance_alert.json';
+ static const String rrtAmbulance = '$lottieBasePath/rrt_ambulance.json';
}
diff --git a/lib/features/symptoms_checker/symptoms_checker_view_model.dart b/lib/features/symptoms_checker/symptoms_checker_view_model.dart
index a467d01..34a1754 100644
--- a/lib/features/symptoms_checker/symptoms_checker_view_model.dart
+++ b/lib/features/symptoms_checker/symptoms_checker_view_model.dart
@@ -36,10 +36,28 @@ class SymptomsCheckerViewModel extends ChangeNotifier {
// Selected symptoms tracking (organId -> Set of symptom IDs)
final Map> _selectedSymptomsByOrgan = {};
+ // User Info Flow State
+ int _userInfoCurrentPage = 0;
+ String? _selectedGender;
+ int? _selectedAge;
+ double? _selectedHeight;
+ bool _isHeightCm = true;
+ double? _selectedWeight;
+ bool _isWeightKg = true;
+
// Getters
bool isPossibleConditionsLoading = false;
+ // User Info Getters
+ int get userInfoCurrentPage => _userInfoCurrentPage;
+ String? get selectedGender => _selectedGender;
+ int? get selectedAge => _selectedAge;
+ double? get selectedHeight => _selectedHeight;
+ bool get isHeightCm => _isHeightCm;
+ double? get selectedWeight => _selectedWeight;
+ bool get isWeightKg => _isWeightKg;
+
BodyView get currentView => _currentView;
Set get selectedOrganIds => _selectedOrganIds;
@@ -247,6 +265,91 @@ class SymptomsCheckerViewModel extends ChangeNotifier {
_isBottomSheetExpanded = false;
_tooltipTimer?.cancel();
_tooltipOrganId = null;
+ // Reset user info flow
+ _userInfoCurrentPage = 0;
+ _selectedGender = null;
+ _selectedAge = null;
+ _selectedHeight = null;
+ _isHeightCm = true;
+ _selectedWeight = null;
+ _isWeightKg = true;
+ notifyListeners();
+ }
+
+ // User Info Flow Methods
+
+ /// Set current page in user info flow
+ void setUserInfoPage(int page) {
+ _userInfoCurrentPage = page;
+ notifyListeners();
+ }
+
+ /// Navigate to next page in user info flow
+ void nextUserInfoPage() {
+ if (_userInfoCurrentPage < 3) {
+ _userInfoCurrentPage++;
+ notifyListeners();
+ }
+ }
+
+ /// Navigate to previous page in user info flow
+ void previousUserInfoPage() {
+ if (_userInfoCurrentPage > 0) {
+ _userInfoCurrentPage--;
+ notifyListeners();
+ }
+ }
+
+ /// Set selected gender
+ void setGender(String gender) {
+ _selectedGender = gender;
+ notifyListeners();
+ }
+
+ /// Set selected age
+ void setAge(int age) {
+ _selectedAge = age;
+ notifyListeners();
+ }
+
+ /// Set selected height
+ void setHeight(double height, bool isCm) {
+ _selectedHeight = height;
+ _isHeightCm = isCm;
+ notifyListeners();
+ }
+
+ /// Set selected weight
+ void setWeight(double weight, bool isKg) {
+ _selectedWeight = weight;
+ _isWeightKg = isKg;
+ notifyListeners();
+ }
+
+ /// Check if user info page is last
+ bool get isUserInfoLastPage => _userInfoCurrentPage == 3;
+
+ /// Validate and submit user info
+ Map getUserInfoData() {
+ return {
+ 'gender': _selectedGender,
+ 'age': _selectedAge,
+ 'height': _selectedHeight,
+ 'heightUnit': _isHeightCm ? 'cm' : 'ft',
+ 'weight': _selectedWeight,
+ 'weightUnit': _isWeightKg ? 'kg' : 'lbs',
+ };
+ }
+
+ /// Reset user info flow
+ void resetUserInfo() {
+ _userInfoCurrentPage = 0;
+ _selectedGender = null;
+ _selectedAge = null;
+ _selectedHeight = null;
+ _isHeightCm = true;
+ _selectedWeight = null;
+ _isWeightKg = true;
notifyListeners();
}
diff --git a/lib/presentation/authentication/login.dart b/lib/presentation/authentication/login.dart
index 28430a8..c14e957 100644
--- a/lib/presentation/authentication/login.dart
+++ b/lib/presentation/authentication/login.dart
@@ -1,7 +1,6 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
-import 'package:flutter/services.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';
diff --git a/lib/presentation/book_appointment/book_appointment_page.dart b/lib/presentation/book_appointment/book_appointment_page.dart
index 0ad58cc..0e60a28 100644
--- a/lib/presentation/book_appointment/book_appointment_page.dart
+++ b/lib/presentation/book_appointment/book_appointment_page.dart
@@ -4,11 +4,11 @@ import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_staggered_animations/flutter_staggered_animations.dart';
import 'package:hmg_patient_app_new/core/app_assets.dart';
+import 'package:hmg_patient_app_new/core/app_export.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_config.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/route_extensions.dart';
import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
import 'package:hmg_patient_app_new/extensions/widget_extensions.dart';
import 'package:hmg_patient_app_new/features/authentication/authentication_view_model.dart';
@@ -25,7 +25,6 @@ import 'package:hmg_patient_app_new/presentation/book_appointment/livecare/immed
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/presentation/home/navigation_screen.dart';
import 'package:hmg_patient_app_new/theme/colors.dart';
import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart';
import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart';
@@ -71,145 +70,137 @@ class _BookAppointmentPageState extends State {
regionalViewModel = Provider.of(context, listen: true);
return Scaffold(
backgroundColor: AppColors.bgScaffoldColor,
- body: CollapsingListView(
- title: LocaleKeys.bookAppo.tr(context: context),
- isLeading: true,
- leadingCallback: () {
- Navigator.pushAndRemoveUntil(
- context,
- CustomPageRoute(
- page: LandingNavigation(),
- ),
- (r) => false);
- },
- child: SingleChildScrollView(
- child: Consumer(builder: (context, bookAppointmentsVM, child) {
- return Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- SizedBox(height: 16.h),
- CustomTabBar(
- activeTextColor: Color(0xffED1C2B),
- activeBackgroundColor: Color(0xffED1C2B).withValues(alpha: .1),
- tabs: [
- CustomTabBarModel(null, "General".needTranslation),
- CustomTabBarModel(null, "LiveCare".needTranslation),
- ],
- onTabChange: (index) {
- bookAppointmentsVM.onTabChanged(index);
- },
- ).paddingSymmetrical(24.h, 0.h),
- SizedBox(height: 24.h),
- getSelectedTabData(bookAppointmentsVM.selectedTabIndex),
- SizedBox(height: 24.h),
- "Recent Visits".needTranslation.toText18(isBold: true).paddingSymmetrical(24.w, 0.h),
- SizedBox(height: 16.h),
- Consumer(builder: (context, myAppointmentsVM, child) {
- return myAppointmentsVM.isPatientMyDoctorsLoading
- ? Column(
- crossAxisAlignment: CrossAxisAlignment.center,
+ body: Column(
+ children: [
+ Expanded(
+ child: CollapsingListView(
+ title: LocaleKeys.bookAppo.tr(context: context),
+ isLeading: true,
+ child: SingleChildScrollView(
+ child: Consumer(builder: (context, bookAppointmentsVM, child) {
+ return Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
children: [
- Image.network(
- "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown_female.png",
- width: 64.w,
- height: 64.h,
- fit: BoxFit.cover,
- ).circle(100).toShimmer2(isShow: true, radius: 50.r),
- SizedBox(height: 8.h),
- ("Dr. John Smith Smith Smith")
- .toString()
- .toText12(fontWeight: FontWeight.w500, isCenter: true, maxLine: 2)
- .toShimmer2(isShow: true),
- ],
- )
- : myAppointmentsVM.patientMyDoctorsList.isEmpty
- ? Container(
- width: SizeConfig.screenWidth,
- decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
- color: AppColors.whiteColor,
- borderRadius: 12.r,
- hasShadow: false,
- ),
- child: Utils.getNoDataWidget(
- context,
- noDataText: "You don't have any completed visits yet".needTranslation,
- isSmallWidget: true,
- width: 62.w,
- height: 62.h,
- ),
- ).paddingSymmetrical(24.w, 0.h)
- : SizedBox(
- height: 110.h,
- child: ListView.separated(
- scrollDirection: Axis.horizontal,
- itemCount: myAppointmentsVM.patientMyDoctorsList.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: SizedBox(
- // width: 80.w,
- child: Column(
+ SizedBox(height: 16.h),
+ CustomTabBar(
+ activeTextColor: Color(0xffED1C2B),
+ activeBackgroundColor: Color(0xffED1C2B).withValues(alpha: .1),
+ tabs: [
+ CustomTabBarModel(null, "General".needTranslation),
+ CustomTabBarModel(null, "LiveCare".needTranslation),
+ ],
+ onTabChange: (index) {
+ bookAppointmentsVM.onTabChanged(index);
+ },
+ ).paddingSymmetrical(24.h, 0.h),
+ SizedBox(height: 24.h),
+ getSelectedTabData(bookAppointmentsVM.selectedTabIndex),
+ SizedBox(height: 24.h),
+ if (appState.isAuthenticated) ...[
+ Consumer(builder: (context, myAppointmentsVM, child) {
+ return myAppointmentsVM.isPatientMyDoctorsLoading
+ ? Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Image.network(
- myAppointmentsVM.patientMyDoctorsList[index].doctorImageURL!,
+ "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown_female.png",
width: 64.w,
height: 64.h,
fit: BoxFit.cover,
- ).circle(100).toShimmer2(isShow: false, radius: 50.r),
+ ).circle(100).toShimmer2(isShow: true, radius: 50.r),
SizedBox(height: 8.h),
- SizedBox(
- width: 80.w,
- child: (myAppointmentsVM.patientMyDoctorsList[index].doctorName)
- .toString()
- .toText12(fontWeight: FontWeight.w500, isCenter: true, maxLine: 2)
- .toShimmer2(isShow: false),
- ),
+ ("Dr. John Smith Smith Smith")
+ .toString()
+ .toText12(fontWeight: FontWeight.w500, isCenter: true, maxLine: 2)
+ .toShimmer2(isShow: true),
],
- ),
- ).onPress(() async {
- bookAppointmentsViewModel.setSelectedDoctor(DoctorsListResponseModel(
- clinicID: myAppointmentsVM.patientMyDoctorsList[index].clinicID,
- projectID: myAppointmentsVM.patientMyDoctorsList[index].projectID,
- doctorID: myAppointmentsVM.patientMyDoctorsList[index].doctorID,
- ));
- LoaderBottomSheet.showLoader();
- await bookAppointmentsViewModel.getDoctorProfile(onSuccess: (dynamic respData) {
- LoaderBottomSheet.hideLoader();
- Navigator.of(context).push(
- CustomPageRoute(
- page: DoctorProfilePage(),
- ),
- );
- }, onError: (err) {
- LoaderBottomSheet.hideLoader();
- showCommonBottomSheetWithoutHeight(
- context,
- child: Utils.getErrorWidget(loadingText: err),
- callBackFunc: () {},
- isFullScreen: false,
- isCloseButtonVisible: true,
- );
- });
- }),
- ),
- ),
- );
- },
- separatorBuilder: (BuildContext cxt, int index) => SizedBox(width: 8.h),
- ),
+ )
+ : myAppointmentsVM.patientMyDoctorsList.isEmpty
+ ? SizedBox()
+ : Column(
+ children: [
+ if (appState.isAuthenticated) ...[],
+ "Recent Visits".needTranslation.toText18(isBold: true).paddingSymmetrical(24.w, 0.h),
+ SizedBox(height: 16.h),
+ SizedBox(
+ height: 110.h,
+ child: ListView.separated(
+ scrollDirection: Axis.horizontal,
+ itemCount: myAppointmentsVM.patientMyDoctorsList.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: SizedBox(
+ // width: 80.w,
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.center,
+ children: [
+ Image.network(
+ myAppointmentsVM.patientMyDoctorsList[index].doctorImageURL!,
+ width: 64.w,
+ height: 64.h,
+ fit: BoxFit.cover,
+ ).circle(100).toShimmer2(isShow: false, radius: 50.r),
+ SizedBox(height: 8.h),
+ SizedBox(
+ width: 80.w,
+ child: (myAppointmentsVM.patientMyDoctorsList[index].doctorName)
+ .toString()
+ .toText12(fontWeight: FontWeight.w500, isCenter: true, maxLine: 2)
+ .toShimmer2(isShow: false),
+ ),
+ ],
+ ),
+ ).onPress(() async {
+ bookAppointmentsViewModel.setSelectedDoctor(DoctorsListResponseModel(
+ clinicID: myAppointmentsVM.patientMyDoctorsList[index].clinicID,
+ projectID: myAppointmentsVM.patientMyDoctorsList[index].projectID,
+ doctorID: myAppointmentsVM.patientMyDoctorsList[index].doctorID,
+ ));
+ LoaderBottomSheet.showLoader();
+ await bookAppointmentsViewModel.getDoctorProfile(onSuccess: (dynamic respData) {
+ LoaderBottomSheet.hideLoader();
+ Navigator.of(context).push(
+ CustomPageRoute(
+ page: DoctorProfilePage(),
+ ),
+ );
+ }, onError: (err) {
+ LoaderBottomSheet.hideLoader();
+ showCommonBottomSheetWithoutHeight(
+ context,
+ child: Utils.getErrorWidget(loadingText: err),
+ callBackFunc: () {},
+ isFullScreen: false,
+ isCloseButtonVisible: true,
+ );
+ });
+ }),
+ ),
+ ),
+ );
+ },
+ separatorBuilder: (BuildContext cxt, int index) => SizedBox(width: 8.h),
+ ),
+ ),
+ ],
+ );
+ }),
+ ],
+ ],
);
}),
- ],
- );
- }),
- ),
+ ),
+ ),
+ ),
+ _buildSymptomsBottomCard(),
+ ],
),
);
}
@@ -460,6 +451,37 @@ class _BookAppointmentPageState extends State {
return Container();
}
+ Widget _buildSymptomsBottomCard() {
+ return Container(
+ decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r),
+ child: Row(
+ children: [
+ Expanded(
+ child: Column(
+ mainAxisSize: MainAxisSize.min,
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ "Not sure? help me choose a clinic!".needTranslation.toText16(weight: FontWeight.w600, color: AppColors.textColor),
+ SizedBox(height: 4.h),
+ "Mention your symptoms and find the list of doctors accordingly".needTranslation.toText12(
+ fontWeight: FontWeight.w500,
+ color: AppColors.greyTextColor,
+ ),
+ ],
+ ),
+ ),
+ SizedBox(width: 16.w),
+ CustomButton(
+ height: 40.h,
+ text: "",
+ onPressed: () => context.navigateWithName(AppRoutes.userInfoSelection),
+ icon: AppAssets.arrow_forward,
+ )
+ ],
+ ).paddingAll(24.w),
+ );
+ }
+
void openRegionListBottomSheet(BuildContext context, RegionBottomSheetType type) {
regionalViewModel.flush();
regionalViewModel.setBottomSheetType(type);
diff --git a/lib/presentation/emergency_services/emergency_services_page.dart b/lib/presentation/emergency_services/emergency_services_page.dart
index bce7daf..3833d32 100644
--- a/lib/presentation/emergency_services/emergency_services_page.dart
+++ b/lib/presentation/emergency_services/emergency_services_page.dart
@@ -97,7 +97,7 @@ class EmergencyServicesPage extends StatelessWidget {
}),
],
),
- Lottie.asset(AppAnimations.ambulance_alert,
+ Lottie.asset(AppAnimations.ambulanceAlert,
repeat: false, reverse: false, frameRate: FrameRate(60), width: 120.h, height: 120.h, fit: BoxFit.contain),
SizedBox(height: 8.h),
"Confirmation".needTranslation.toText28(color: AppColors.whiteColor, isBold: true),
@@ -200,7 +200,7 @@ class EmergencyServicesPage extends StatelessWidget {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
- Lottie.asset(AppAnimations.ambulance_alert, repeat: false, reverse: false, frameRate: FrameRate(60), width: 120.h, height: 120.h, fit: BoxFit.contain),
+ Lottie.asset(AppAnimations.ambulanceAlert, repeat: false, reverse: false, frameRate: FrameRate(60), width: 120.h, height: 120.h, fit: BoxFit.contain),
SizedBox(height: 8.h),
LocaleKeys.confirm.tr().toText28(color: AppColors.whiteColor, isBold: true),
SizedBox(height: 8.h),
@@ -313,7 +313,7 @@ class EmergencyServicesPage extends StatelessWidget {
}),
],
),
- Lottie.asset(AppAnimations.ambulance_alert,
+ Lottie.asset(AppAnimations.ambulanceAlert,
repeat: false, reverse: false, frameRate: FrameRate(60), width: 120.h, height: 120.h, fit: BoxFit.contain),
SizedBox(height: 8.h),
LocaleKeys.confirm.tr().toText28(color: AppColors.whiteColor, isBold: true),
diff --git a/lib/presentation/home/landing_page.dart b/lib/presentation/home/landing_page.dart
index 454f1e7..96ec558 100644
--- a/lib/presentation/home/landing_page.dart
+++ b/lib/presentation/home/landing_page.dart
@@ -12,7 +12,6 @@ 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/int_extensions.dart';
-import 'package:hmg_patient_app_new/extensions/route_extensions.dart';
import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
import 'package:hmg_patient_app_new/extensions/widget_extensions.dart';
import 'package:hmg_patient_app_new/features/authentication/authentication_view_model.dart';
@@ -40,7 +39,6 @@ import 'package:hmg_patient_app_new/presentation/home/widgets/small_service_card
import 'package:hmg_patient_app_new/presentation/home/widgets/welcome_widget.dart';
import 'package:hmg_patient_app_new/presentation/medical_file/medical_file_page.dart';
import 'package:hmg_patient_app_new/presentation/profile_settings/profile_settings.dart';
-import 'package:hmg_patient_app_new/routes/app_routes.dart';
import 'package:hmg_patient_app_new/services/cache_service.dart';
import 'package:hmg_patient_app_new/theme/colors.dart';
import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart';
@@ -494,8 +492,7 @@ class _LandingPageState extends State {
mainAxisSize: MainAxisSize.min,
spacing: 12.h,
children: [
- Utils.buildSvgWithAssets(icon: AppAssets.bell, height: 18.h, width: 18.h)
- .onPress(() => context.navigateWithName(AppRoutes.organSelectorPage)),
+ Utils.buildSvgWithAssets(icon: AppAssets.bell, height: 18.h, width: 18.h),
Utils.buildSvgWithAssets(icon: AppAssets.search_icon, height: 18.h, width: 18.h).onPress(() {}),
Utils.buildSvgWithAssets(icon: AppAssets.contact_icon, height: 18.h, width: 18.h).onPress(() {
showCommonBottomSheetWithoutHeight(
@@ -581,7 +578,6 @@ class _LandingPageState extends State {
);
},
),
- // height: isDone == false ? ResponsiveExtension.screenHeight * 0.5 : ResponsiveExtension.screenHeight * 0.3,
isFullScreen: false,
callBackFunc: () {
isDone = true;
diff --git a/lib/presentation/home/navigation_screen.dart b/lib/presentation/home/navigation_screen.dart
index f8447d2..7fbcdb3 100644
--- a/lib/presentation/home/navigation_screen.dart
+++ b/lib/presentation/home/navigation_screen.dart
@@ -1,12 +1,13 @@
import 'package:flutter/material.dart';
import 'package:hmg_patient_app_new/core/app_state.dart';
import 'package:hmg_patient_app_new/core/dependencies.dart';
-import 'package:hmg_patient_app_new/presentation/book_appointment/book_appointment_page.dart';
+import 'package:hmg_patient_app_new/extensions/route_extensions.dart';
import 'package:hmg_patient_app_new/presentation/contact_us/feedback_page.dart';
import 'package:hmg_patient_app_new/presentation/hmg_services/services_page.dart';
import 'package:hmg_patient_app_new/presentation/home/landing_page.dart';
import 'package:hmg_patient_app_new/presentation/medical_file/medical_file_page.dart';
import 'package:hmg_patient_app_new/presentation/todo_section/todo_page.dart';
+import 'package:hmg_patient_app_new/routes/app_routes.dart';
import 'package:hmg_patient_app_new/widgets/bottom_navigation/bottom_navigation.dart';
class LandingNavigation extends StatefulWidget {
@@ -18,12 +19,11 @@ class LandingNavigation extends StatefulWidget {
class _LandingNavigationState extends State {
int _currentIndex = 0;
- late AppState appState;
final PageController _pageController = PageController();
@override
Widget build(BuildContext context) {
- appState = getIt.get();
+ AppState appState = getIt.get();
return Scaffold(
body: PageView(
controller: _pageController,
@@ -31,7 +31,7 @@ class _LandingNavigationState extends State {
children: [
const LandingPage(),
appState.isAuthenticated ? MedicalFilePage() : /* need add feedback page */ FeedbackPage(),
- BookAppointmentPage(),
+ SizedBox(),
const ToDoPage(),
ServicesPage(),
],
@@ -40,6 +40,10 @@ class _LandingNavigationState extends State {
currentIndex: _currentIndex,
onTap: (index) {
setState(() => _currentIndex = index);
+ if (_currentIndex == 2) {
+ context.navigateWithName(AppRoutes.bookAppointmentPage);
+ return;
+ }
_pageController.animateToPage(index, duration: const Duration(milliseconds: 300), curve: Curves.easeInOut);
},
),
diff --git a/lib/presentation/symptoms_checker/organ_selector_screen.dart b/lib/presentation/symptoms_checker/organ_selector_screen.dart
index 65d9a00..d5dc32c 100644
--- a/lib/presentation/symptoms_checker/organ_selector_screen.dart
+++ b/lib/presentation/symptoms_checker/organ_selector_screen.dart
@@ -42,7 +42,7 @@ class _OrganSelectorPageState extends State {
return;
}
- context.navigateWithName(AppRoutes.symptomsCheckerScreen);
+ context.navigateWithName(AppRoutes.symptomsSelectorScreen);
}
@override
diff --git a/lib/presentation/symptoms_checker/risk_factors_screen.dart b/lib/presentation/symptoms_checker/risk_factors_screen.dart
index 211aabc..2992593 100644
--- a/lib/presentation/symptoms_checker/risk_factors_screen.dart
+++ b/lib/presentation/symptoms_checker/risk_factors_screen.dart
@@ -148,7 +148,7 @@ class _RiskFactorsScreenState extends State {
Expanded(
child: CollapsingListView(
title: "Risks".needTranslation,
- onLeadingTapped: () => _buildConfirmationBottomSheet(
+ leadingCallback: () => _buildConfirmationBottomSheet(
context: context,
onConfirm: () => {
context.pop(),
diff --git a/lib/presentation/symptoms_checker/suggestions_screen.dart b/lib/presentation/symptoms_checker/suggestions_screen.dart
index f9d922a..2832515 100644
--- a/lib/presentation/symptoms_checker/suggestions_screen.dart
+++ b/lib/presentation/symptoms_checker/suggestions_screen.dart
@@ -148,7 +148,7 @@ class _SuggestionsScreenState extends State {
Expanded(
child: CollapsingListView(
title: "Suggestions".needTranslation,
- onLeadingTapped: () => _buildConfirmationBottomSheet(
+ leadingCallback: () => _buildConfirmationBottomSheet(
context: context,
onConfirm: () => {
context.pop(),
diff --git a/lib/presentation/symptoms_checker/symptoms_selector_screen.dart b/lib/presentation/symptoms_checker/symptoms_selector_screen.dart
index bed232b..522c5f8 100644
--- a/lib/presentation/symptoms_checker/symptoms_selector_screen.dart
+++ b/lib/presentation/symptoms_checker/symptoms_selector_screen.dart
@@ -78,7 +78,7 @@ class _SymptomsSelectorScreenState extends State {
Expanded(
child: CollapsingListView(
title: "Symptoms Selector".needTranslation,
- onLeadingTapped: () => _buildConfirmationBottomSheet(
+ leadingCallback: () => _buildConfirmationBottomSheet(
context: context,
onConfirm: () => {
context.pop(),
diff --git a/lib/presentation/symptoms_checker/triage_screen.dart b/lib/presentation/symptoms_checker/triage_screen.dart
index 4dbe0ca..aa0cd72 100644
--- a/lib/presentation/symptoms_checker/triage_screen.dart
+++ b/lib/presentation/symptoms_checker/triage_screen.dart
@@ -103,7 +103,7 @@ class _TriageScreenState extends State {
// context.pop(),
// }),
- onLeadingTapped: () => context.pop(),
+ leadingCallback: () => context.pop(),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
diff --git a/lib/presentation/symptoms_checker/user_info_selection.dart b/lib/presentation/symptoms_checker/user_info_selection.dart
new file mode 100644
index 0000000..2fb6cc9
--- /dev/null
+++ b/lib/presentation/symptoms_checker/user_info_selection.dart
@@ -0,0 +1,187 @@
+import 'package:flutter/material.dart';
+import 'package:hmg_patient_app_new/core/app_assets.dart';
+import 'package:hmg_patient_app_new/core/app_export.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/utils.dart';
+import 'package:hmg_patient_app_new/extensions/route_extensions.dart';
+import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
+import 'package:hmg_patient_app_new/extensions/widget_extensions.dart';
+import 'package:hmg_patient_app_new/theme/colors.dart';
+import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart';
+import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart';
+
+class UserInfoSelectionScreen extends StatelessWidget {
+ const UserInfoSelectionScreen({super.key});
+
+ _buildEditInfoTile({
+ required String leadingIcon,
+ required String title,
+ required String subTitle,
+ required VoidCallback onTap,
+ required String trailingIcon,
+ required BuildContext context,
+ Color? iconColor,
+ }) {
+ return InkWell(
+ onTap: onTap,
+ child: Row(
+ children: [
+ Expanded(
+ child: Row(
+ children: [
+ Container(
+ height: 40.h,
+ width: 40.h,
+ margin: EdgeInsets.only(right: 10.h),
+ padding: EdgeInsets.all(8.h),
+ decoration: RoundedRectangleBorder().toSmoothCornerDecoration(borderRadius: 12.r, color: AppColors.greyColor),
+ child: Utils.buildSvgWithAssets(icon: leadingIcon, iconColor: iconColor)),
+ Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ title.toText16(weight: FontWeight.w500),
+ subTitle.toText14(color: AppColors.primaryRedColor, weight: FontWeight.w500),
+ ],
+ ),
+ ],
+ ),
+ ),
+ Utils.buildSvgWithAssets(icon: trailingIcon, height: 24.h, width: 24.h),
+ ],
+ ),
+ );
+ }
+
+ Widget _getDivider() {
+ return Divider(
+ color: AppColors.dividerColor,
+ ).paddingSymmetrical(0, 16.h);
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ AppState appState = getIt.get();
+
+ String name = "";
+ if (appState.isAuthenticated) {
+ name = "${appState.getAuthenticatedUser()!.firstName!} ${appState.getAuthenticatedUser()!.lastName!} ";
+ } else {
+ name = "Guest";
+ }
+ return Scaffold(
+ backgroundColor: AppColors.bgScaffoldColor,
+ body: Column(
+ children: [
+ Expanded(
+ child: CollapsingListView(
+ title: "Symptoms Checker".needTranslation,
+ isLeading: true,
+ child: SingleChildScrollView(
+ child: Column(
+ children: [
+ Container(
+ width: double.infinity,
+ decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r),
+ padding: EdgeInsets.symmetric(vertical: 24.h, horizontal: 16.w),
+ child: Column(
+ children: [
+ "Hi $name, Is your information up to date?".needTranslation.toText18(
+ weight: FontWeight.w600,
+ color: AppColors.textColor,
+ ),
+ SizedBox(height: 24.h),
+ _buildEditInfoTile(
+ context: context,
+ leadingIcon: AppAssets.genderIcon,
+ title: "Gender".needTranslation,
+ subTitle: "Male".needTranslation,
+ onTap: () {},
+ trailingIcon: AppAssets.edit_icon,
+ ),
+ _getDivider(),
+ _buildEditInfoTile(
+ context: context,
+ leadingIcon: AppAssets.calendar,
+ title: "Age".needTranslation,
+ subTitle: "32 Years",
+ iconColor: AppColors.greyTextColor,
+ onTap: () {},
+ trailingIcon: AppAssets.edit_icon,
+ ),
+ _getDivider(),
+ _buildEditInfoTile(
+ context: context,
+ leadingIcon: AppAssets.rulerIcon,
+ title: "Height".needTranslation,
+ subTitle: "17 8cm",
+ onTap: () {},
+ trailingIcon: AppAssets.edit_icon,
+ ),
+ _getDivider(),
+ _buildEditInfoTile(
+ context: context,
+ leadingIcon: AppAssets.weightScale,
+ title: "Weight".needTranslation,
+ subTitle: "88 kg",
+ onTap: () {},
+ trailingIcon: AppAssets.edit_icon,
+ ),
+ ],
+ ),
+ ),
+ ],
+ ).paddingAll(24.w),
+ ),
+ ),
+ ),
+ _buildBottomCard(context),
+ ],
+ ),
+ );
+ }
+
+ Widget _buildBottomCard(BuildContext context) {
+ return Container(
+ decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r),
+ child: SafeArea(
+ top: false,
+ child: Column(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ SizedBox(height: 24.h),
+ Row(
+ children: [
+ Expanded(
+ child: CustomButton(
+ text: "No, Edit all".needTranslation,
+ icon: AppAssets.edit_icon,
+ iconColor: AppColors.primaryRedColor,
+ onPressed: () => context.navigateWithName(AppRoutes.userInfoFlowManager),
+ backgroundColor: AppColors.primaryRedColor.withValues(alpha: 0.11),
+ borderColor: Colors.transparent,
+ textColor: AppColors.primaryRedColor,
+ fontSize: 16.f,
+ ),
+ ),
+ SizedBox(width: 12.w),
+ Expanded(
+ child: CustomButton(
+ text: "Yes, It is".needTranslation,
+ icon: AppAssets.tickIcon,
+ iconColor: AppColors.whiteColor,
+ onPressed: () => () {},
+ backgroundColor: AppColors.primaryRedColor,
+ borderColor: AppColors.primaryRedColor,
+ textColor: AppColors.whiteColor,
+ fontSize: 16.f,
+ ),
+ ),
+ ],
+ ),
+ ],
+ ).paddingSymmetrical(24.w, 0),
+ ),
+ );
+ }
+}
diff --git a/lib/presentation/symptoms_checker/user_info_selection/pages/age_selection_page.dart b/lib/presentation/symptoms_checker/user_info_selection/pages/age_selection_page.dart
new file mode 100644
index 0000000..6433b93
--- /dev/null
+++ b/lib/presentation/symptoms_checker/user_info_selection/pages/age_selection_page.dart
@@ -0,0 +1,36 @@
+import 'package:flutter/material.dart';
+import 'package:hmg_patient_app_new/core/app_export.dart';
+import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
+import 'package:hmg_patient_app_new/features/symptoms_checker/symptoms_checker_view_model.dart';
+import 'package:hmg_patient_app_new/theme/colors.dart';
+import 'package:provider/provider.dart';
+
+/// Age selection page content
+class AgeSelectionPage extends StatelessWidget {
+ final int? selectedAge;
+ final Function(int) onAgeSelected;
+
+ const AgeSelectionPage({
+ super.key,
+ required this.selectedAge,
+ required this.onAgeSelected,
+ });
+
+ @override
+ Widget build(BuildContext context) {
+ return SingleChildScrollView(
+ padding: EdgeInsets.all(24.w),
+ child: Consumer(
+ builder: (BuildContext context, symptomsViewModel, Widget? child) {
+ return Column(
+ children: [
+ "What is your gender?".needTranslation.toText18(weight: FontWeight.w600, color: AppColors.textColor),
+ SizedBox(height: 70.h),
+ "< Age Widget Here >".needTranslation.toText18(weight: FontWeight.w600, color: AppColors.greyTextColor),
+ ],
+ );
+ },
+ ),
+ );
+ }
+}
diff --git a/lib/presentation/symptoms_checker/user_info_selection/pages/gender_selection_page.dart b/lib/presentation/symptoms_checker/user_info_selection/pages/gender_selection_page.dart
new file mode 100644
index 0000000..85cb6e2
--- /dev/null
+++ b/lib/presentation/symptoms_checker/user_info_selection/pages/gender_selection_page.dart
@@ -0,0 +1,75 @@
+import 'package:flutter/material.dart';
+import 'package:hmg_patient_app_new/core/app_assets.dart';
+import 'package:hmg_patient_app_new/core/app_export.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/symptoms_checker/symptoms_checker_view_model.dart';
+import 'package:hmg_patient_app_new/theme/colors.dart';
+import 'package:provider/provider.dart';
+
+/// Gender selection page content
+class GenderSelectionPage extends StatelessWidget {
+ final String? selectedGender;
+ final Function(String) onGenderSelected;
+
+ GenderSelectionPage({
+ super.key,
+ required this.selectedGender,
+ required this.onGenderSelected,
+ });
+
+ _buildGenderOption(String iconPng, String label, bool isSelected) {
+ return Container(
+ height: 160.h,
+ width: 160.w,
+ decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
+ color: AppColors.whiteColor, borderRadius: 24.r, side: isSelected ? BorderSide(color: AppColors.primaryRedColor, width: 2.5) : null),
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ Utils.buildImgWithAssets(icon: iconPng, height: 80.h, width: 80.h, fit: BoxFit.contain),
+ SizedBox(height: 8.h),
+ label.toText16(
+ weight: FontWeight.w500,
+ )
+ ],
+ ),
+ );
+ }
+
+ final genders = ["Male", "Female"];
+
+ @override
+ Widget build(BuildContext context) {
+ return SingleChildScrollView(
+ padding: EdgeInsets.all(24.w),
+ child: Consumer(
+ builder: (BuildContext context, symptomsViewModel, Widget? child) {
+ return Column(
+ children: [
+ "What is your gender?".needTranslation.toText18(weight: FontWeight.w600, color: AppColors.textColor),
+ SizedBox(height: 70.h),
+ Row(
+ children: [
+ Expanded(
+ child: InkWell(
+ onTap: () => onGenderSelected(genders[0]),
+ child: _buildGenderOption(AppAssets.maleIcon, "Male".needTranslation, symptomsViewModel.selectedGender == genders[0]),
+ ),
+ ),
+ SizedBox(width: 16.w),
+ Expanded(
+ child: InkWell(
+ onTap: () => onGenderSelected(genders[1]),
+ child: _buildGenderOption(AppAssets.femaleIcon, "Female".needTranslation, symptomsViewModel.selectedGender == genders[1]),
+ ))
+ ],
+ ),
+ ],
+ );
+ },
+ ),
+ );
+ }
+}
diff --git a/lib/presentation/symptoms_checker/user_info_selection/pages/height_selection_page.dart b/lib/presentation/symptoms_checker/user_info_selection/pages/height_selection_page.dart
new file mode 100644
index 0000000..e10aca3
--- /dev/null
+++ b/lib/presentation/symptoms_checker/user_info_selection/pages/height_selection_page.dart
@@ -0,0 +1,175 @@
+import 'package:flutter/material.dart';
+import 'package:hmg_patient_app_new/core/app_export.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/theme/colors.dart';
+
+/// Height selection page content
+class HeightSelectionPage extends StatefulWidget {
+ final double height;
+ final bool isCm;
+ final Function(double, bool) onHeightChanged;
+
+ const HeightSelectionPage({
+ super.key,
+ required this.height,
+ required this.isCm,
+ required this.onHeightChanged,
+ });
+
+ @override
+ State createState() => _HeightSelectionPageState();
+}
+
+class _HeightSelectionPageState extends State {
+ late double heightValue;
+
+ @override
+ void initState() {
+ super.initState();
+ heightValue = widget.height;
+ }
+
+ Widget _unitSelector() {
+ return Container(
+ height: 54.h,
+ padding: EdgeInsets.all(4.h),
+ decoration: BoxDecoration(
+ color: AppColors.whiteColor,
+ borderRadius: BorderRadius.circular(10.r),
+ ),
+ child: LayoutBuilder(
+ builder: (context, constraints) {
+ final tabWidth = (constraints.maxWidth - 8.w) / 2;
+ return Stack(
+ children: [
+ // Animated sliding indicator
+ AnimatedContainer(
+ duration: const Duration(milliseconds: 250),
+ curve: Curves.easeInOut,
+ width: tabWidth,
+ height: constraints.maxHeight,
+ margin: EdgeInsets.only(left: widget.isCm ? 0 : tabWidth + 8.w),
+ decoration: BoxDecoration(
+ color: AppColors.bottomNAVBorder,
+ borderRadius: BorderRadius.circular(7.r),
+ ),
+ ),
+ // Tab buttons
+ Row(
+ children: [
+ Expanded(
+ child: GestureDetector(
+ onTap: () {
+ if (!widget.isCm) {
+ // Convert from FT to CM (1 ft = 30.48 cm)
+ final convertedHeight = heightValue * 30.48;
+ widget.onHeightChanged(convertedHeight, true);
+ }
+ },
+ child: Container(
+ alignment: Alignment.center,
+ color: Colors.transparent,
+ child: Text(
+ 'CM',
+ style: TextStyle(
+ fontWeight: FontWeight.w700,
+ fontSize: 14.f,
+ color: widget.isCm ? AppColors.textColor : AppColors.textColor.withValues(alpha: 0.6),
+ ),
+ ),
+ ),
+ ),
+ ),
+ Expanded(
+ child: GestureDetector(
+ onTap: () {
+ if (widget.isCm) {
+ // Convert from CM to FT (1 cm = 0.0328084 ft)
+ final convertedHeight = heightValue / 30.48;
+ widget.onHeightChanged(convertedHeight, false);
+ }
+ },
+ child: Container(
+ alignment: Alignment.center,
+ color: Colors.transparent,
+ child: Text(
+ 'FT',
+ style: TextStyle(
+ fontWeight: FontWeight.w700,
+ fontSize: 14.f,
+ color: !widget.isCm ? AppColors.textColor : AppColors.textColor.withValues(alpha: 0.6),
+ ),
+ ),
+ ),
+ ),
+ ),
+ ],
+ ),
+ ],
+ );
+ },
+ ),
+ );
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ SizedBox(height: 24.h),
+ Center(
+ child: Text(
+ 'How tall are you?'.needTranslation,
+ style: TextStyle(fontSize: 18.f, fontWeight: FontWeight.w600, color: AppColors.textColor),
+ ),
+ ),
+ SizedBox(height: 24.h),
+ Padding(
+ padding: EdgeInsets.symmetric(horizontal: 24.w),
+ child: _unitSelector(),
+ ),
+ SizedBox(height: 90.h),
+ Row(
+ crossAxisAlignment: CrossAxisAlignment.end,
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ Text(
+ heightValue.round().toString(),
+ style: TextStyle(fontSize: 100.f, color: AppColors.textColor, height: 1),
+ ),
+ SizedBox(width: 8.w),
+ Text(widget.isCm ? 'cm' : 'ft', style: TextStyle(fontWeight: FontWeight.w700, fontSize: 24.f)).paddingOnly(bottom: 10.h, left: 8.w),
+ ],
+ ),
+ ],
+ );
+ }
+}
+
+class _RulerPainter extends CustomPainter {
+ @override
+ void paint(Canvas canvas, Size size) {
+ final paintTick = Paint()..color = const Color(0xFF222222);
+ final paintSmall = Paint()..color = const Color(0xFF222222).withValues(alpha: 0.6);
+
+ final width = size.width;
+ final start = 120;
+ final end = 210;
+ final steps = end - start;
+ for (int i = 0; i <= steps; i++) {
+ final x = (i / steps) * width;
+ if (i % 10 == 0) {
+ canvas.drawLine(Offset(x, size.height * 0.1), Offset(x, size.height * 0.6), paintTick);
+ } else if (i % 5 == 0) {
+ canvas.drawLine(Offset(x, size.height * 0.2), Offset(x, size.height * 0.5), paintSmall);
+ } else {
+ canvas.drawLine(Offset(x, size.height * 0.35), Offset(x, size.height * 0.5), paintSmall);
+ }
+ }
+ }
+
+ @override
+ bool shouldRepaint(covariant CustomPainter oldDelegate) => false;
+}
diff --git a/lib/presentation/symptoms_checker/user_info_selection/pages/weight_selection_page.dart b/lib/presentation/symptoms_checker/user_info_selection/pages/weight_selection_page.dart
new file mode 100644
index 0000000..0319f4b
--- /dev/null
+++ b/lib/presentation/symptoms_checker/user_info_selection/pages/weight_selection_page.dart
@@ -0,0 +1,236 @@
+import 'package:flutter/material.dart';
+import 'package:hmg_patient_app_new/core/app_export.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/theme/colors.dart';
+
+/// Weight selection page content
+class WeightSelectionPage extends StatefulWidget {
+ final double weight;
+ final bool isKg;
+ final Function(double, bool) onWeightChanged;
+
+ const WeightSelectionPage({
+ super.key,
+ required this.weight,
+ required this.isKg,
+ required this.onWeightChanged,
+ });
+
+ @override
+ State createState() => _WeightSelectionPageState();
+}
+
+class _WeightSelectionPageState extends State {
+ late double weightValue;
+
+ @override
+ void initState() {
+ super.initState();
+ weightValue = widget.weight;
+ }
+
+ Widget _unitSelector() {
+ return Container(
+ height: 54.h,
+ padding: EdgeInsets.all(4.h),
+ decoration: BoxDecoration(
+ color: AppColors.whiteColor,
+ borderRadius: BorderRadius.circular(10.r),
+ ),
+ child: LayoutBuilder(
+ builder: (context, constraints) {
+ final tabWidth = (constraints.maxWidth - 8.w) / 2;
+ return Stack(
+ children: [
+ // Animated sliding indicator
+ AnimatedContainer(
+ duration: const Duration(milliseconds: 250),
+ curve: Curves.easeInOut,
+ width: tabWidth,
+ height: constraints.maxHeight,
+ margin: EdgeInsets.only(left: widget.isKg ? 0 : tabWidth + 8.w),
+ decoration: BoxDecoration(
+ color: AppColors.bottomNAVBorder,
+ borderRadius: BorderRadius.circular(7.r),
+ ),
+ ),
+ // Tab buttons
+ Row(
+ children: [
+ Expanded(
+ child: GestureDetector(
+ onTap: () {
+ if (!widget.isKg) {
+ // Convert from LBS to KG (1 lb = 0.453592 kg)
+ final convertedWeight = weightValue / 2.20462;
+ widget.onWeightChanged(convertedWeight, true);
+ }
+ },
+ child: Container(
+ alignment: Alignment.center,
+ color: Colors.transparent,
+ child: Text(
+ 'KG',
+ style: TextStyle(
+ fontWeight: FontWeight.w700,
+ fontSize: 14.f,
+ color: widget.isKg ? AppColors.textColor : AppColors.textColor.withValues(alpha: 0.6),
+ ),
+ ),
+ ),
+ ),
+ ),
+ Expanded(
+ child: GestureDetector(
+ onTap: () {
+ if (widget.isKg) {
+ // Convert from KG to LBS (1 kg = 2.20462 lbs)
+ final convertedWeight = weightValue * 2.20462;
+ widget.onWeightChanged(convertedWeight, false);
+ }
+ },
+ child: Container(
+ alignment: Alignment.center,
+ color: Colors.transparent,
+ child: Text(
+ 'LBS',
+ style: TextStyle(
+ fontWeight: FontWeight.w700,
+ fontSize: 14.f,
+ color: !widget.isKg ? AppColors.textColor : AppColors.textColor.withValues(alpha: 0.6),
+ ),
+ ),
+ ),
+ ),
+ ),
+ ],
+ ),
+ ],
+ );
+ },
+ ),
+ );
+ }
+
+ Widget _weightSlider() {
+ return Column(
+ children: [
+ SizedBox(height: 18.h),
+ SizedBox(height: 12.h),
+ SizedBox(
+ height: 80.h,
+ child: Row(
+ children: [
+ Expanded(child: Container()),
+ Expanded(
+ flex: 6,
+ child: Stack(
+ alignment: Alignment.center,
+ children: [
+ Positioned.fill(
+ child: CustomPaint(
+ painter: _WeightRulerPainter(),
+ ),
+ ),
+ SliderTheme(
+ data: SliderTheme.of(context).copyWith(
+ trackHeight: 6.h,
+ thumbShape: const RoundSliderThumbShape(enabledThumbRadius: 0),
+ overlayShape: const RoundSliderOverlayShape(overlayRadius: 0),
+ activeTrackColor: AppColors.primaryRedColor,
+ inactiveTrackColor: AppColors.lightRedButtonColor,
+ ),
+ child: Slider(
+ min: 30,
+ max: 150,
+ value: weightValue,
+ onChanged: (v) {
+ setState(() => weightValue = v);
+ widget.onWeightChanged(v, widget.isKg);
+ },
+ ),
+ ),
+ Positioned(
+ right: 0,
+ child: Container(
+ width: 18.w,
+ height: 18.h,
+ decoration: BoxDecoration(
+ color: AppColors.primaryRedColor,
+ shape: BoxShape.rectangle,
+ borderRadius: BorderRadius.circular(4.r),
+ ),
+ ),
+ ),
+ ],
+ ),
+ ),
+ Expanded(child: Container()),
+ ],
+ ),
+ ),
+ ],
+ );
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ SizedBox(height: 24.h),
+ Center(
+ child: Text(
+ 'What is your weight?'.needTranslation,
+ style: TextStyle(fontSize: 18.f, fontWeight: FontWeight.w600, color: AppColors.textColor),
+ ),
+ ),
+ SizedBox(height: 20.h),
+ Padding(
+ padding: EdgeInsets.symmetric(horizontal: 24.w),
+ child: _unitSelector(),
+ ),
+ SizedBox(height: 90.h),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.center,
+ crossAxisAlignment: CrossAxisAlignment.end,
+ children: [
+ Text(
+ weightValue.round().toString(),
+ style: TextStyle(fontSize: 100.f, color: AppColors.textColor, height: 1),
+ ),
+ SizedBox(width: 8.w),
+ Text(widget.isKg ? 'kg' : 'lbs', style: TextStyle(fontWeight: FontWeight.w700, fontSize: 24.f)).paddingOnly(bottom: 10.h, left: 8.w),
+ ],
+ ),
+ ],
+ );
+ }
+}
+
+class _WeightRulerPainter extends CustomPainter {
+ @override
+ void paint(Canvas canvas, Size size) {
+ final paintTick = Paint()..color = const Color(0xFF222222);
+ final paintSmall = Paint()..color = const Color(0xFF222222).withValues(alpha: 0.6);
+
+ final width = size.width;
+ final start = 30;
+ final end = 150;
+ final steps = end - start;
+ for (int i = 0; i <= steps; i++) {
+ final x = (i / steps) * width;
+ if (i % 10 == 0) {
+ canvas.drawLine(Offset(x, size.height * 0.1), Offset(x, size.height * 0.6), paintTick);
+ } else if (i % 5 == 0) {
+ canvas.drawLine(Offset(x, size.height * 0.2), Offset(x, size.height * 0.5), paintSmall);
+ } else {
+ canvas.drawLine(Offset(x, size.height * 0.35), Offset(x, size.height * 0.5), paintSmall);
+ }
+ }
+ }
+
+ @override
+ bool shouldRepaint(covariant CustomPainter oldDelegate) => false;
+}
diff --git a/lib/presentation/symptoms_checker/user_info_selection/user_info_flow_manager.dart b/lib/presentation/symptoms_checker/user_info_selection/user_info_flow_manager.dart
new file mode 100644
index 0000000..43d485a
--- /dev/null
+++ b/lib/presentation/symptoms_checker/user_info_selection/user_info_flow_manager.dart
@@ -0,0 +1,209 @@
+import 'dart:developer';
+
+import 'package:flutter/material.dart';
+import 'package:hmg_patient_app_new/core/app_export.dart';
+import 'package:hmg_patient_app_new/extensions/route_extensions.dart';
+import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
+import 'package:hmg_patient_app_new/features/symptoms_checker/symptoms_checker_view_model.dart';
+import 'package:hmg_patient_app_new/presentation/symptoms_checker/user_info_selection/pages/age_selection_page.dart';
+import 'package:hmg_patient_app_new/presentation/symptoms_checker/user_info_selection/pages/gender_selection_page.dart';
+import 'package:hmg_patient_app_new/presentation/symptoms_checker/user_info_selection/pages/height_selection_page.dart';
+import 'package:hmg_patient_app_new/presentation/symptoms_checker/user_info_selection/pages/weight_selection_page.dart';
+import 'package:hmg_patient_app_new/theme/colors.dart';
+import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart';
+import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart';
+import 'package:provider/provider.dart';
+
+/// Manages the user info selection flow with PageView
+/// Only the page content changes, header and footer remain fixed
+class UserInfoFlowManager extends StatefulWidget {
+ const UserInfoFlowManager({super.key});
+
+ @override
+ State createState() => _UserInfoFlowManagerState();
+}
+
+class _UserInfoFlowManagerState extends State {
+ final PageController _pageController = PageController();
+ late SymptomsCheckerViewModel _viewModel;
+
+ // Page titles
+ final List _pageTitles = [
+ "Your Gender",
+ "Your Birth Date",
+ "Your Height",
+ "Your Weight",
+ ];
+
+ @override
+ void initState() {
+ super.initState();
+ _viewModel = context.read();
+ // _viewModel.resetUserInfo();
+ }
+
+ @override
+ void dispose() {
+ _pageController.dispose();
+ super.dispose();
+ }
+
+ void _onNext() {
+ if (_viewModel.userInfoCurrentPage < 3) {
+ _viewModel.nextUserInfoPage();
+ _pageController.animateToPage(
+ _viewModel.userInfoCurrentPage,
+ duration: const Duration(milliseconds: 300),
+ curve: Curves.easeInOut,
+ );
+ } else {
+ // Submit and navigate to next screen
+ _submitUserInfo();
+ }
+ }
+
+ void _onPrevious() {
+ if (_viewModel.userInfoCurrentPage > 0) {
+ _viewModel.previousUserInfoPage();
+ _pageController.animateToPage(
+ _viewModel.userInfoCurrentPage,
+ duration: const Duration(milliseconds: 300),
+ curve: Curves.easeInOut,
+ );
+ } else {
+ context.pop();
+ }
+ }
+
+ void _submitUserInfo() {
+ final userInfo = _viewModel.getUserInfoData();
+
+ // Log user info
+ log('User Info Submitted:');
+ log('Gender: ${userInfo['gender']}');
+ log('Age: ${userInfo['age']}');
+ log('Height: ${userInfo['height']} ${userInfo['heightUnit']}');
+ log('Weight: ${userInfo['weight']} ${userInfo['weightUnit']}');
+
+ // TODO: Save user info to backend/storage
+
+ // Navigate to symptoms checker or next screen
+ context.pop();
+ }
+
+ Widget _buildProgressBar(int currentPage) {
+ return Row(
+ children: List.generate(4, (index) {
+ final isActive = index <= currentPage;
+ return Expanded(
+ child: Container(
+ height: 4.h,
+ margin: EdgeInsets.symmetric(horizontal: 6.w),
+ decoration: BoxDecoration(
+ color: isActive ? AppColors.primaryRedColor : AppColors.greyLightColor,
+ borderRadius: BorderRadius.circular(8.r),
+ ),
+ ),
+ );
+ }),
+ );
+ }
+
+ Widget _buildStickyBottomCard(bool isLastPage) {
+ return Container(
+ decoration: BoxDecoration(
+ color: AppColors.whiteColor,
+ borderRadius: BorderRadius.vertical(top: Radius.circular(24.r)),
+ ),
+ padding: EdgeInsets.symmetric(horizontal: 24.w, vertical: 16.h),
+ child: SafeArea(
+ top: false,
+ child: Row(
+ children: [
+ Expanded(
+ child: CustomButton(
+ text: "Previous".needTranslation,
+ onPressed: _onPrevious,
+ backgroundColor: AppColors.primaryRedColor.withValues(alpha: 0.11),
+ borderColor: Colors.transparent,
+ textColor: AppColors.primaryRedColor,
+ fontSize: 16.f,
+ ),
+ ),
+ SizedBox(width: 12.w),
+ Expanded(
+ child: CustomButton(
+ text: isLastPage ? "Submit".needTranslation : "Next".needTranslation,
+ onPressed: _onNext,
+ backgroundColor: AppColors.primaryRedColor,
+ borderColor: AppColors.primaryRedColor,
+ textColor: AppColors.whiteColor,
+ fontSize: 16.f,
+ ),
+ ),
+ ],
+ ),
+ ),
+ );
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return Consumer(
+ builder: (context, viewModel, child) {
+ return Scaffold(
+ backgroundColor: AppColors.bgScaffoldColor,
+ body: Column(
+ children: [
+ Expanded(
+ child: CollapsingListView(
+ title: _pageTitles[viewModel.userInfoCurrentPage].needTranslation,
+ isLeading: true,
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ SizedBox(height: 24.h),
+ _buildProgressBar(viewModel.userInfoCurrentPage),
+ SizedBox(height: 24.h),
+ SizedBox(
+ height: 600.h,
+ child: PageView(
+ controller: _pageController,
+ physics: const NeverScrollableScrollPhysics(), // Disable swipe
+ onPageChanged: (index) {
+ viewModel.setUserInfoPage(index);
+ },
+ children: [
+ GenderSelectionPage(
+ selectedGender: viewModel.selectedGender,
+ onGenderSelected: viewModel.setGender,
+ ),
+ AgeSelectionPage(
+ selectedAge: viewModel.selectedAge,
+ onAgeSelected: viewModel.setAge,
+ ),
+ HeightSelectionPage(
+ height: viewModel.selectedHeight ?? 178,
+ isCm: viewModel.isHeightCm,
+ onHeightChanged: viewModel.setHeight,
+ ),
+ WeightSelectionPage(
+ weight: viewModel.selectedWeight ?? 70,
+ isKg: viewModel.isWeightKg,
+ onWeightChanged: viewModel.setWeight,
+ ),
+ ],
+ ),
+ ),
+ ],
+ ),
+ ),
+ ),
+ _buildStickyBottomCard(viewModel.isUserInfoLastPage),
+ ],
+ ),
+ );
+ },
+ );
+ }
+}
diff --git a/lib/presentation/symptoms_checker/user_info_selection/widgets/user_info_progress_bar.dart b/lib/presentation/symptoms_checker/user_info_selection/widgets/user_info_progress_bar.dart
new file mode 100644
index 0000000..6e6d762
--- /dev/null
+++ b/lib/presentation/symptoms_checker/user_info_selection/widgets/user_info_progress_bar.dart
@@ -0,0 +1,36 @@
+import 'package:flutter/material.dart';
+import 'package:hmg_patient_app_new/core/app_export.dart';
+import 'package:hmg_patient_app_new/theme/colors.dart';
+
+/// Progress bar widget showing the current step in user info selection flow
+/// Total steps: 4 (Gender -> Age -> Height -> Weight)
+class UserInfoProgressBar extends StatelessWidget {
+ final int currentStep;
+ final int totalSteps;
+
+ const UserInfoProgressBar({
+ super.key,
+ required this.currentStep,
+ this.totalSteps = 4,
+ });
+
+ @override
+ Widget build(BuildContext context) {
+ return Row(
+ children: List.generate(totalSteps, (index) {
+ final isActive = index < currentStep;
+ return Expanded(
+ child: Container(
+ height: 4.h,
+ margin: EdgeInsets.symmetric(horizontal: 6.w),
+ decoration: BoxDecoration(
+ color: isActive ? AppColors.primaryRedColor : AppColors.greyLightColor,
+ borderRadius: BorderRadius.circular(8.r),
+ ),
+ ),
+ );
+ }),
+ );
+ }
+}
+
diff --git a/lib/presentation/symptoms_checker/user_info_selection/widgets/user_info_selection_scaffold.dart b/lib/presentation/symptoms_checker/user_info_selection/widgets/user_info_selection_scaffold.dart
new file mode 100644
index 0000000..3390c31
--- /dev/null
+++ b/lib/presentation/symptoms_checker/user_info_selection/widgets/user_info_selection_scaffold.dart
@@ -0,0 +1,67 @@
+import 'package:flutter/material.dart';
+import 'package:hmg_patient_app_new/core/app_export.dart';
+import 'package:hmg_patient_app_new/presentation/symptoms_checker/user_info_selection/widgets/user_info_progress_bar.dart';
+import 'package:hmg_patient_app_new/presentation/symptoms_checker/user_info_selection/widgets/user_info_sticky_bottom_card.dart';
+import 'package:hmg_patient_app_new/theme/colors.dart';
+import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart';
+
+/// Base scaffold for user info selection flow pages
+/// Provides consistent layout with progress bar and sticky bottom card
+class UserInfoSelectionScaffold extends StatelessWidget {
+ final String title;
+ final int currentStep;
+ final Widget child;
+ final VoidCallback? onPrevious;
+ final VoidCallback? onNext;
+ final bool showPrevious;
+ final String? nextButtonText;
+ final bool isScrollable;
+
+ const UserInfoSelectionScaffold({
+ super.key,
+ required this.title,
+ required this.currentStep,
+ required this.child,
+ this.onPrevious,
+ this.onNext,
+ this.showPrevious = true,
+ this.nextButtonText,
+ this.isScrollable = true,
+ });
+
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ backgroundColor: AppColors.bgScaffoldColor,
+ body: Column(
+ children: [
+ Expanded(
+ child: CollapsingListView(
+ title: title,
+ isLeading: true,
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ SizedBox(height: 24.h),
+ UserInfoProgressBar(currentStep: currentStep),
+ SizedBox(height: 24.h),
+ isScrollable
+ ? SingleChildScrollView(
+ child: child,
+ )
+ : child,
+ ],
+ ),
+ ),
+ ),
+ UserInfoStickyBottomCard(
+ onPrevious: onPrevious,
+ onNext: onNext,
+ showPrevious: showPrevious,
+ nextButtonText: nextButtonText,
+ ),
+ ],
+ ),
+ );
+ }
+}
diff --git a/lib/presentation/symptoms_checker/user_info_selection/widgets/user_info_sticky_bottom_card.dart b/lib/presentation/symptoms_checker/user_info_selection/widgets/user_info_sticky_bottom_card.dart
new file mode 100644
index 0000000..10fd934
--- /dev/null
+++ b/lib/presentation/symptoms_checker/user_info_selection/widgets/user_info_sticky_bottom_card.dart
@@ -0,0 +1,68 @@
+import 'package:flutter/material.dart';
+import 'package:hmg_patient_app_new/core/app_export.dart';
+import 'package:hmg_patient_app_new/extensions/route_extensions.dart';
+import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
+import 'package:hmg_patient_app_new/extensions/widget_extensions.dart';
+import 'package:hmg_patient_app_new/theme/colors.dart';
+import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart';
+
+/// Sticky bottom card with Previous/Next navigation buttons
+class UserInfoStickyBottomCard extends StatelessWidget {
+ final VoidCallback? onPrevious;
+ final VoidCallback? onNext;
+ final bool showPrevious;
+ final String? nextButtonText;
+
+ const UserInfoStickyBottomCard({
+ super.key,
+ this.onPrevious,
+ this.onNext,
+ this.showPrevious = true,
+ this.nextButtonText,
+ });
+
+ @override
+ Widget build(BuildContext context) {
+ return Container(
+ decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
+ color: AppColors.whiteColor,
+ borderRadius: 24.r,
+ ),
+ child: Column(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ SizedBox(height: 16.h),
+ Row(
+ children: [
+ if (showPrevious) ...[
+ Expanded(
+ child: CustomButton(
+ text: "Previous".needTranslation,
+ onPressed: onPrevious ?? () => context.pop(),
+ backgroundColor: AppColors.primaryRedColor.withValues(alpha: 0.11),
+ borderColor: Colors.transparent,
+ textColor: AppColors.primaryRedColor,
+ fontSize: 16.f,
+ ),
+ ),
+ SizedBox(width: 12.w),
+ ],
+ Expanded(
+ child: CustomButton(
+ text: nextButtonText ?? "Next".needTranslation,
+ onPressed: onNext ?? () {},
+ backgroundColor: AppColors.primaryRedColor,
+ borderColor: AppColors.primaryRedColor,
+ textColor: AppColors.whiteColor,
+ fontSize: 16.f,
+ ),
+ ),
+ ],
+ ),
+ SizedBox(height: 24.h),
+ ],
+ ).paddingSymmetrical(24.w, 0),
+ );
+ }
+}
+
diff --git a/lib/routes/app_routes.dart b/lib/routes/app_routes.dart
index f73eba3..183c2a0 100644
--- a/lib/routes/app_routes.dart
+++ b/lib/routes/app_routes.dart
@@ -3,6 +3,7 @@ import 'package:hmg_patient_app_new/presentation/authentication/login.dart';
import 'package:hmg_patient_app_new/presentation/authentication/register.dart';
import 'package:hmg_patient_app_new/presentation/authentication/register_step2.dart';
import 'package:hmg_patient_app_new/presentation/blood_donation/blood_donation_page.dart';
+import 'package:hmg_patient_app_new/presentation/book_appointment/book_appointment_page.dart';
import 'package:hmg_patient_app_new/presentation/comprehensive_checkup/comprehensive_checkup_page.dart';
import 'package:hmg_patient_app_new/presentation/e_referral/new_e_referral.dart';
import 'package:hmg_patient_app_new/presentation/home/navigation_screen.dart';
@@ -14,6 +15,8 @@ import 'package:hmg_patient_app_new/presentation/symptoms_checker/risk_factors_s
import 'package:hmg_patient_app_new/presentation/symptoms_checker/suggestions_screen.dart';
import 'package:hmg_patient_app_new/presentation/symptoms_checker/symptoms_selector_screen.dart';
import 'package:hmg_patient_app_new/presentation/symptoms_checker/triage_screen.dart';
+import 'package:hmg_patient_app_new/presentation/symptoms_checker/user_info_selection.dart';
+import 'package:hmg_patient_app_new/presentation/symptoms_checker/user_info_selection/user_info_flow_manager.dart';
import 'package:hmg_patient_app_new/presentation/tele_consultation/zoom/call_screen.dart';
import 'package:hmg_patient_app_new/splashPage.dart';
@@ -30,14 +33,21 @@ class AppRoutes {
static const String zoomCallPage = '/zoomCallPage';
static const String bloodDonationPage = '/bloodDonationPage';
+ //appointments
+ static const String bookAppointmentPage = '/bookAppointmentPage';
+
// Symptoms Checker
static const String organSelectorPage = '/organSelectorPage';
- static const String symptomsCheckerScreen = '/symptomsCheckerScreen';
+ static const String symptomsSelectorScreen = '/symptomsCheckerScreen';
static const String suggestionsScreen = '/suggestionsScreen';
static const String riskFactorsScreen = '/riskFactorsScreen';
static const String possibleConditionsScreen = '/possibleConditionsScreen';
static const String triageScreen = '/triageProgressScreen';
+ //UserInfoSelection
+ static const String userInfoSelection = '/userInfoSelection';
+ static const String userInfoFlowManager = '/userInfoFlowManager';
+
static Map get routes => {
initialRoute: (context) => SplashPage(),
loginScreen: (context) => LoginScreen(),
@@ -50,12 +60,16 @@ class AppRoutes {
comprehensiveCheckupPage: (context) => ComprehensiveCheckupPage(),
homeHealthCarePage: (context) => HhcProceduresPage(),
organSelectorPage: (context) => OrganSelectorPage(),
- symptomsCheckerScreen: (context) => SymptomsSelectorScreen(),
+ symptomsSelectorScreen: (context) => SymptomsSelectorScreen(),
riskFactorsScreen: (context) => RiskFactorsScreen(),
suggestionsScreen: (context) => SuggestionsScreen(),
possibleConditionsScreen: (context) => PossibleConditionsScreen(),
- triageScreen: (context) => TriageScreen()
- zoomCallPage: (context) => CallScreen(),
- bloodDonationPage: (context) => BloodDonationPage()
+ triageScreen: (context) => TriageScreen(),
+ bloodDonationPage: (context) => BloodDonationPage(),
+ bookAppointmentPage: (context) => BookAppointmentPage(),
+ userInfoSelection: (context) => UserInfoSelectionScreen(),
+ userInfoFlowManager: (context) => UserInfoFlowManager(),
+
+ //
};
}
diff --git a/lib/widgets/appbar/collapsing_list_view.dart b/lib/widgets/appbar/collapsing_list_view.dart
index 3e20689..ad8e743 100644
--- a/lib/widgets/appbar/collapsing_list_view.dart
+++ b/lib/widgets/appbar/collapsing_list_view.dart
@@ -26,7 +26,7 @@ class CollapsingListView extends StatelessWidget {
Widget? trailing;
bool isClose;
bool isLeading;
- VoidCallback? onLeadingTapped;
+ VoidCallback? leadingCallback;
CollapsingListView({
super.key,
@@ -42,7 +42,7 @@ class CollapsingListView extends StatelessWidget {
this.requests,
this.isLeading = true,
this.trailing,
- this.onLeadingTapped,
+ this.leadingCallback,
});
@override
@@ -69,8 +69,8 @@ class CollapsingListView extends StatelessWidget {
icon: Utils.buildSvgWithAssets(icon: isClose ? AppAssets.closeBottomNav : AppAssets.arrow_back, width: 32.h, height: 32.h),
padding: EdgeInsets.only(left: 12),
onPressed: () {
- if (onLeadingTapped != null) {
- onLeadingTapped!();
+ if (leadingCallback != null) {
+ leadingCallback!();
} else {
context.pop();
}
diff --git a/lib/widgets/input_widget.dart b/lib/widgets/input_widget.dart
index c1a38ab..7992ece 100644
--- a/lib/widgets/input_widget.dart
+++ b/lib/widgets/input_widget.dart
@@ -215,8 +215,11 @@ class TextInputWidget extends StatelessWidget {
language: appState.getLanguageCode()!,
initialDate: DateTime.now(),
fontFamily: appState.getLanguageCode() == "ar" ? "GESSTwo" : "Poppins",
- okWidget: Padding(padding: EdgeInsets.only(right: 8.h), child: Utils.buildSvgWithAssets(icon: AppAssets.confirm, width: 24.h, height: 24.h)),
- cancelWidget: Padding(padding: EdgeInsets.only(right: 8.h), child: Utils.buildSvgWithAssets(icon: AppAssets.cancel, iconColor: Colors.white, width: 24.h, height: 24.h)),
+ okWidget:
+ Padding(padding: EdgeInsets.only(right: 8.h), child: Utils.buildSvgWithAssets(icon: AppAssets.confirm, width: 24.h, height: 24.h)),
+ cancelWidget: Padding(
+ padding: EdgeInsets.only(right: 8.h),
+ child: Utils.buildSvgWithAssets(icon: AppAssets.cancel, iconColor: Colors.white, width: 24.h, height: 24.h)),
onCalendarTypeChanged: (bool value) {
isGregorian = value;
});
@@ -276,7 +279,12 @@ class TextInputWidget extends StatelessWidget {
decoration: InputDecoration(
isDense: true,
hintText: hintText,
- hintStyle: TextStyle(fontSize: 14.f, height: 21 / 16, fontWeight: FontWeight.w500, color: hintColor != null ? AppColors.textColor : Color(0xff898A8D), letterSpacing: -0.75),
+ hintStyle: TextStyle(
+ fontSize: 14.f,
+ height: 21 / 16,
+ fontWeight: FontWeight.w500,
+ color: hintColor != null ? AppColors.textColor : Color(0xff898A8D),
+ letterSpacing: -0.75),
prefixIconConstraints: BoxConstraints(minWidth: 30.h),
prefixIcon: prefix == null ? null : "+${prefix!}".toText14(letterSpacing: -1, color: AppColors.textColor, weight: FontWeight.w500),
contentPadding: EdgeInsets.zero,