You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			292 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Dart
		
	
			
		
		
	
	
			292 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Dart
		
	
| import 'dart:async';
 | |
| 
 | |
| 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/utils/size_utils.dart';
 | |
| import 'package:hmg_patient_app_new/core/utils/utils.dart';
 | |
| import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
 | |
| import 'package:hmg_patient_app_new/extensions/widget_extensions.dart';
 | |
| import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/patient_appointment_history_response_model.dart';
 | |
| import 'package:hmg_patient_app_new/features/my_appointments/my_appointments_view_model.dart';
 | |
| import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
 | |
| import 'package:hmg_patient_app_new/presentation/appointments/widgets/appointment_card.dart';
 | |
| import 'package:hmg_patient_app_new/presentation/book_appointment/book_appointment_page.dart';
 | |
| import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart';
 | |
| import 'package:hmg_patient_app_new/theme/colors.dart';
 | |
| import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart';
 | |
| import 'package:hmg_patient_app_new/widgets/custom_tab_bar.dart';
 | |
| import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart';
 | |
| import 'package:hmg_patient_app_new/widgets/shimmer/movies_shimmer_widget.dart';
 | |
| import 'package:provider/provider.dart';
 | |
| 
 | |
| class MyAppointmentsPage extends StatefulWidget {
 | |
|   const MyAppointmentsPage({super.key});
 | |
| 
 | |
|   @override
 | |
|   State<MyAppointmentsPage> createState() => _MyAppointmentsPageState();
 | |
| }
 | |
| 
 | |
| class _MyAppointmentsPageState extends State<MyAppointmentsPage> {
 | |
|   late MyAppointmentsViewModel myAppointmentsViewModel;
 | |
| 
 | |
|   @override
 | |
|   void initState() {
 | |
|     scheduleMicrotask(() {
 | |
|       myAppointmentsViewModel.initAppointmentsViewModel();
 | |
|       myAppointmentsViewModel.getPatientAppointments(true, false);
 | |
|     });
 | |
|     super.initState();
 | |
|   }
 | |
| 
 | |
|   @override
 | |
|   Widget build(BuildContext context) {
 | |
|     myAppointmentsViewModel = Provider.of<MyAppointmentsViewModel>(context, listen: false);
 | |
|     return Scaffold(
 | |
|       backgroundColor: AppColors.bgScaffoldColor,
 | |
|       body: CollapsingListView(
 | |
|         title: "Appointments List".needTranslation,
 | |
|         child: SingleChildScrollView(
 | |
|           child: Column(
 | |
|             children: [
 | |
|               SizedBox(height: 16.h),
 | |
|               CustomTabBar(
 | |
|                 activeTextColor: Color(0xffED1C2B),
 | |
|                 activeBackgroundColor: Color(0xffED1C2B).withValues(alpha: .1),
 | |
|                 tabs: [
 | |
|                   CustomTabBarModel(null, "All Appt.".needTranslation),
 | |
|                   CustomTabBarModel(null, "Upcoming".needTranslation),
 | |
|                   CustomTabBarModel(null, "Completed".needTranslation),
 | |
|                 ],
 | |
|                 onTabChange: (index) {
 | |
|                   myAppointmentsViewModel.onTabChange(index);
 | |
|                 },
 | |
|               ).paddingSymmetrical(24.h, 0.h),
 | |
|               Consumer<MyAppointmentsViewModel>(builder: (context, myAppointmentsVM, child) {
 | |
|                 return getSelectedTabData(myAppointmentsVM.selectedTabIndex, myAppointmentsVM);
 | |
|               }),
 | |
|             ],
 | |
|           ),
 | |
|         ),
 | |
|       ),
 | |
|     );
 | |
|   }
 | |
| 
 | |
|   Widget getSelectedTabData(int index, MyAppointmentsViewModel myAppointmentsVM) {
 | |
|     switch (index) {
 | |
|       case 0:
 | |
|         //All Appointments Tab Data
 | |
|         return Column(
 | |
|           crossAxisAlignment: CrossAxisAlignment.start,
 | |
|           children: [
 | |
|             // Expandable list
 | |
|             ListView.separated(
 | |
|               padding: EdgeInsets.only(top: 24.h),
 | |
|               shrinkWrap: true,
 | |
|               physics: NeverScrollableScrollPhysics(),
 | |
|               itemCount: myAppointmentsVM.isMyAppointmentsLoading
 | |
|                   ? 5
 | |
|                   : myAppointmentsVM.patientAppointmentsHistoryList.isNotEmpty
 | |
|                       ? myAppointmentsVM.patientAppointmentsHistoryList.length
 | |
|                       : 1,
 | |
|               itemBuilder: (context, index) {
 | |
|                 return myAppointmentsVM.isMyAppointmentsLoading
 | |
|                     ? Container(
 | |
|                         decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.h, hasShadow: true),
 | |
|                         child: AppointmentCard(
 | |
|                           patientAppointmentHistoryResponseModel: PatientAppointmentHistoryResponseModel(),
 | |
|                           myAppointmentsViewModel: myAppointmentsViewModel,
 | |
|                           isLoading: true,
 | |
|                           isFromHomePage: false,
 | |
|                         ),
 | |
|                       ).paddingSymmetrical(24.h, 0.h)
 | |
|                     : myAppointmentsVM.patientAppointmentsHistoryList.isNotEmpty
 | |
|                         ? AnimationConfiguration.staggeredList(
 | |
|                             position: index,
 | |
|                             duration: const Duration(milliseconds: 500),
 | |
|                             child: SlideAnimation(
 | |
|                               verticalOffset: 100.0,
 | |
|                               child: FadeInAnimation(
 | |
|                                 child: AnimatedContainer(
 | |
|                                   duration: Duration(milliseconds: 300),
 | |
|                                   curve: Curves.easeInOut,
 | |
|                                   decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.h, hasShadow: true),
 | |
|                                   child: AppointmentCard(
 | |
|                                     patientAppointmentHistoryResponseModel: myAppointmentsVM.patientAppointmentsHistoryList[index],
 | |
|                                     myAppointmentsViewModel: myAppointmentsViewModel,
 | |
|                                     isLoading: false,
 | |
|                                     isFromHomePage: false,
 | |
|                                   ),
 | |
|                                 ).paddingSymmetrical(24.h, 0.h),
 | |
|                               ),
 | |
|                             ),
 | |
|                           )
 | |
|                         : Utils.getNoDataWidget(
 | |
|                             context,
 | |
|                             noDataText: "You don't have any appointments yet.".needTranslation,
 | |
|                             callToActionButton: CustomButton(
 | |
|                               text: LocaleKeys.bookAppo.tr(context: context),
 | |
|                               onPressed: () {
 | |
|                                 Navigator.of(context).push(
 | |
|                                   CustomPageRoute(
 | |
|                                     page: BookAppointmentPage(),
 | |
|                                   ),
 | |
|                                 );
 | |
|                               },
 | |
|                               backgroundColor: Color(0xffFEE9EA),
 | |
|                               borderColor: Color(0xffFEE9EA),
 | |
|                               textColor: Color(0xffED1C2B),
 | |
|                               fontSize: 14,
 | |
|                               fontWeight: FontWeight.w500,
 | |
|                               borderRadius: 12,
 | |
|                               padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
 | |
|                               height: 40,
 | |
|                               icon: AppAssets.add_icon,
 | |
|                               iconColor: AppColors.primaryRedColor,
 | |
|                             ).paddingSymmetrical(48.h, 0.h),
 | |
|                           );
 | |
|               },
 | |
|               separatorBuilder: (BuildContext cxt, int index) => SizedBox(height: 16.h),
 | |
|             ),
 | |
|           ],
 | |
|         );
 | |
|       case 1:
 | |
|         //Upcoming Appointments Tab Data
 | |
|         return Column(
 | |
|           crossAxisAlignment: CrossAxisAlignment.start,
 | |
|           children: [
 | |
|             // Expandable list
 | |
|             ListView.separated(
 | |
|               shrinkWrap: true,
 | |
|               physics: NeverScrollableScrollPhysics(),
 | |
|               itemCount: myAppointmentsVM.isMyAppointmentsLoading
 | |
|                   ? 5
 | |
|                   : myAppointmentsVM.patientUpcomingAppointmentsHistoryList.isNotEmpty
 | |
|                       ? myAppointmentsVM.patientUpcomingAppointmentsHistoryList.length
 | |
|                       : 1,
 | |
|               itemBuilder: (context, index) {
 | |
|                 return myAppointmentsVM.isMyAppointmentsLoading
 | |
|                     ? const MoviesShimmerWidget().paddingSymmetrical(24.h, 0.h)
 | |
|                     : myAppointmentsVM.patientUpcomingAppointmentsHistoryList.isNotEmpty
 | |
|                         ? AnimationConfiguration.staggeredList(
 | |
|                             position: index,
 | |
|                             duration: const Duration(milliseconds: 500),
 | |
|                             child: SlideAnimation(
 | |
|                               verticalOffset: 100.0,
 | |
|                               child: FadeInAnimation(
 | |
|                                 child: AnimatedContainer(
 | |
|                                   duration: Duration(milliseconds: 300),
 | |
|                                   curve: Curves.easeInOut,
 | |
|                                   margin: EdgeInsets.symmetric(vertical: 8.h),
 | |
|                                   decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.h, hasShadow: true),
 | |
|                                   child: AppointmentCard(
 | |
|                                     patientAppointmentHistoryResponseModel: myAppointmentsVM.patientUpcomingAppointmentsHistoryList[index],
 | |
|                                     myAppointmentsViewModel: myAppointmentsViewModel,
 | |
|                                   ),
 | |
|                                 ).paddingSymmetrical(24.h, 0.h),
 | |
|                               ),
 | |
|                             ),
 | |
|                           )
 | |
|                         : Utils.getNoDataWidget(
 | |
|                             context,
 | |
|                             noDataText: "You don't have any appointments yet.".needTranslation,
 | |
|                             callToActionButton: CustomButton(
 | |
|                               text: LocaleKeys.bookAppo.tr(context: context),
 | |
|                               onPressed: () {
 | |
|                                 Navigator.of(context).push(
 | |
|                                   CustomPageRoute(
 | |
|                                     page: BookAppointmentPage(),
 | |
|                                   ),
 | |
|                                 );
 | |
|                               },
 | |
|                               backgroundColor: Color(0xffFEE9EA),
 | |
|                               borderColor: Color(0xffFEE9EA),
 | |
|                               textColor: Color(0xffED1C2B),
 | |
|                               fontSize: 14,
 | |
|                               fontWeight: FontWeight.w500,
 | |
|                               borderRadius: 12,
 | |
|                               padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
 | |
|                               height: 40,
 | |
|                               icon: AppAssets.add_icon,
 | |
|                               iconColor: AppColors.primaryRedColor,
 | |
|                             ).paddingSymmetrical(48.h, 0.h),
 | |
|                           );
 | |
|               },
 | |
|               separatorBuilder: (BuildContext cxt, int index) => SizedBox(height: 16.h),
 | |
|             ),
 | |
|           ],
 | |
|         );
 | |
|       case 2:
 | |
|         //Completed Appointments Tab Data
 | |
|         return Column(
 | |
|           crossAxisAlignment: CrossAxisAlignment.start,
 | |
|           children: [
 | |
|             // Expandable list
 | |
|             ListView.separated(
 | |
|               shrinkWrap: true,
 | |
|               physics: NeverScrollableScrollPhysics(),
 | |
|               itemCount: myAppointmentsVM.isMyAppointmentsLoading
 | |
|                   ? 5
 | |
|                   : myAppointmentsVM.patientArrivedAppointmentsHistoryList.isNotEmpty
 | |
|                       ? myAppointmentsVM.patientArrivedAppointmentsHistoryList.length
 | |
|                       : 1,
 | |
|               itemBuilder: (context, index) {
 | |
|                 return myAppointmentsVM.isMyAppointmentsLoading
 | |
|                     ? const MoviesShimmerWidget().paddingSymmetrical(24.h, 0.h)
 | |
|                     : myAppointmentsVM.patientArrivedAppointmentsHistoryList.isNotEmpty
 | |
|                         ? AnimationConfiguration.staggeredList(
 | |
|                             position: index,
 | |
|                             duration: const Duration(milliseconds: 500),
 | |
|                             child: SlideAnimation(
 | |
|                               verticalOffset: 100.0,
 | |
|                               child: FadeInAnimation(
 | |
|                                 child: AnimatedContainer(
 | |
|                                   duration: Duration(milliseconds: 300),
 | |
|                                   curve: Curves.easeInOut,
 | |
|                                   margin: EdgeInsets.symmetric(vertical: 8.h),
 | |
|                                   decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.h, hasShadow: true),
 | |
|                                   child: AppointmentCard(
 | |
|                                     patientAppointmentHistoryResponseModel: myAppointmentsVM.patientArrivedAppointmentsHistoryList[index],
 | |
|                                     myAppointmentsViewModel: myAppointmentsViewModel,
 | |
|                                   ),
 | |
|                                 ).paddingSymmetrical(24.h, 0.h),
 | |
|                               ),
 | |
|                             ),
 | |
|                           )
 | |
|                         : Utils.getNoDataWidget(
 | |
|                             context,
 | |
|                             noDataText: "You don't have any appointments yet.".needTranslation,
 | |
|                             callToActionButton: CustomButton(
 | |
|                               text: LocaleKeys.bookAppo.tr(context: context),
 | |
|                               onPressed: () {
 | |
|                                 Navigator.of(context).push(
 | |
|                                   CustomPageRoute(
 | |
|                                     page: BookAppointmentPage(),
 | |
|                                   ),
 | |
|                                 );
 | |
|                               },
 | |
|                               backgroundColor: Color(0xffFEE9EA),
 | |
|                               borderColor: Color(0xffFEE9EA),
 | |
|                               textColor: Color(0xffED1C2B),
 | |
|                               fontSize: 14,
 | |
|                               fontWeight: FontWeight.w500,
 | |
|                               borderRadius: 12,
 | |
|                               padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
 | |
|                               height: 40,
 | |
|                               icon: AppAssets.add_icon,
 | |
|                               iconColor: AppColors.primaryRedColor,
 | |
|                             ).paddingSymmetrical(48.h, 0.h),
 | |
|                           );
 | |
|               },
 | |
|               separatorBuilder: (BuildContext cxt, int index) => SizedBox(height: 16.h),
 | |
|             ),
 | |
|           ],
 | |
|         );
 | |
|       default:
 | |
|         return Container();
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 |